Componentize AccountReconcilor.
[chromium-blink-merge.git] / chrome / browser / google / google_util.cc
blob359cb73128b92384ef5f90be9f943742bed889d8
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/google/google_util.h"
7 #include <string>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/google/google_url_tracker.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/net/url_fixer_upper.h"
20 #include "chrome/installer/util/google_update_settings.h"
21 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
22 #include "net/base/url_util.h"
23 #include "url/gurl.h"
25 #if defined(OS_MACOSX)
26 #include "chrome/browser/mac/keystone_glue.h"
27 #elif defined(OS_CHROMEOS)
28 #include "chrome/browser/google/google_util_chromeos.h"
29 #endif
31 // Only use Link Doctor on official builds. It uses an API key, too, but
32 // seems best to just disable it, for more responsive error pages and to reduce
33 // server load.
34 #if defined(GOOGLE_CHROME_BUILD)
35 #define LINKDOCTOR_SERVER_REQUEST_URL "https://www.googleapis.com/rpc"
36 #else
37 #define LINKDOCTOR_SERVER_REQUEST_URL ""
38 #endif
41 // Helpers --------------------------------------------------------------------
43 namespace {
45 const char* brand_for_testing = NULL;
46 bool gUseMockLinkDoctorBaseURLForTesting = false;
48 bool IsPathHomePageBase(const std::string& path) {
49 return (path == "/") || (path == "/webhp");
52 } // namespace
55 namespace google_util {
57 // Global functions -----------------------------------------------------------
59 bool HasGoogleSearchQueryParam(const std::string& str) {
60 url_parse::Component query(0, str.length()), key, value;
61 while (url_parse::ExtractQueryKeyValue(str.c_str(), &query, &key,
62 &value)) {
63 if ((key.len == 1) && (str[key.begin] == 'q') && value.is_nonempty())
64 return true;
66 return false;
69 GURL LinkDoctorBaseURL() {
70 if (gUseMockLinkDoctorBaseURLForTesting)
71 return GURL("http://mock.linkdoctor.url/for?testing");
72 return GURL(LINKDOCTOR_SERVER_REQUEST_URL);
75 void SetMockLinkDoctorBaseURLForTesting() {
76 gUseMockLinkDoctorBaseURLForTesting = true;
79 std::string GetGoogleLocale() {
80 std::string locale = g_browser_process->GetApplicationLocale();
81 // Google does not yet recognize 'nb' for Norwegian Bokmal, but it uses
82 // 'no' for that.
83 if (locale == "nb")
84 return "no";
85 return locale;
88 GURL AppendGoogleLocaleParam(const GURL& url) {
89 return net::AppendQueryParameter(url, "hl", GetGoogleLocale());
92 std::string StringAppendGoogleLocaleParam(const std::string& url) {
93 GURL original_url(url);
94 DCHECK(original_url.is_valid());
95 GURL localized_url = AppendGoogleLocaleParam(original_url);
96 return localized_url.spec();
99 std::string GetGoogleCountryCode(Profile* profile) {
100 const std::string google_hostname =
101 GoogleURLTracker::GoogleURL(profile).host();
102 const size_t last_dot = google_hostname.find_last_of('.');
103 if (last_dot == std::string::npos) {
104 NOTREACHED();
106 std::string country_code = google_hostname.substr(last_dot + 1);
107 // Assume the com TLD implies the US.
108 if (country_code == "com")
109 return "us";
110 // Google uses the Unicode Common Locale Data Repository (CLDR), and the CLDR
111 // code for the UK is "gb".
112 if (country_code == "uk")
113 return "gb";
114 // Catalonia does not have a CLDR country code, since it's a region in Spain,
115 // so use Spain instead.
116 if (country_code == "cat")
117 return "es";
118 return country_code;
121 GURL GetGoogleSearchURL(Profile* profile) {
122 // The url returned by the tracker does not include the "/search" or the
123 // "q=" query string.
124 std::string search_path = "search";
125 std::string query_string = "q=";
126 GURL::Replacements replacements;
127 replacements.SetPathStr(search_path);
128 replacements.SetQueryStr(query_string);
129 return GoogleURLTracker::GoogleURL(profile).ReplaceComponents(replacements);
132 #if defined(OS_WIN)
134 bool GetBrand(std::string* brand) {
135 if (brand_for_testing) {
136 brand->assign(brand_for_testing);
137 return true;
140 base::string16 brand16;
141 bool ret = GoogleUpdateSettings::GetBrand(&brand16);
142 if (ret)
143 brand->assign(base::UTF16ToASCII(brand16));
144 return ret;
147 bool GetReactivationBrand(std::string* brand) {
148 base::string16 brand16;
149 bool ret = GoogleUpdateSettings::GetReactivationBrand(&brand16);
150 if (ret)
151 brand->assign(base::UTF16ToASCII(brand16));
152 return ret;
155 #else
157 bool GetBrand(std::string* brand) {
158 if (brand_for_testing) {
159 brand->assign(brand_for_testing);
160 return true;
163 #if defined(OS_MACOSX)
164 brand->assign(keystone_glue::BrandCode());
165 #elif defined(OS_CHROMEOS)
166 brand->assign(google_util::chromeos::GetBrand());
167 #else
168 brand->clear();
169 #endif
170 return true;
173 bool GetReactivationBrand(std::string* brand) {
174 brand->clear();
175 return true;
178 #endif
180 GURL CommandLineGoogleBaseURL() {
181 // Unit tests may add command-line flags after the first call to this
182 // function, so we don't simply initialize a static |base_url| directly and
183 // then unconditionally return it.
184 CR_DEFINE_STATIC_LOCAL(std::string, switch_value, ());
185 CR_DEFINE_STATIC_LOCAL(GURL, base_url, ());
186 std::string current_switch_value(
187 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
188 switches::kGoogleBaseURL));
189 if (current_switch_value != switch_value) {
190 switch_value = current_switch_value;
191 base_url = URLFixerUpper::FixupURL(switch_value, std::string());
192 if (!base_url.is_valid() || base_url.has_query() || base_url.has_ref())
193 base_url = GURL();
195 return base_url;
198 bool StartsWithCommandLineGoogleBaseURL(const GURL& url) {
199 GURL base_url(CommandLineGoogleBaseURL());
200 return base_url.is_valid() &&
201 StartsWithASCII(url.possibly_invalid_spec(), base_url.spec(), true);
204 bool IsGoogleHostname(const std::string& host,
205 SubdomainPermission subdomain_permission) {
206 GURL base_url(CommandLineGoogleBaseURL());
207 if (base_url.is_valid() && (host == base_url.host()))
208 return true;
210 size_t tld_length = net::registry_controlled_domains::GetRegistryLength(
211 host,
212 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
213 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
214 if ((tld_length == 0) || (tld_length == std::string::npos))
215 return false;
216 std::string host_minus_tld(host, 0, host.length() - tld_length);
217 if (LowerCaseEqualsASCII(host_minus_tld, "google."))
218 return true;
219 if (subdomain_permission == ALLOW_SUBDOMAIN)
220 return EndsWith(host_minus_tld, ".google.", false);
221 return LowerCaseEqualsASCII(host_minus_tld, "www.google.");
224 bool IsGoogleDomainUrl(const GURL& url,
225 SubdomainPermission subdomain_permission,
226 PortPermission port_permission) {
227 return url.is_valid() && url.SchemeIsHTTPOrHTTPS() &&
228 (url.port().empty() || (port_permission == ALLOW_NON_STANDARD_PORTS)) &&
229 google_util::IsGoogleHostname(url.host(), subdomain_permission);
232 bool IsGoogleHomePageUrl(const GURL& url) {
233 // First check to see if this has a Google domain.
234 if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
235 return false;
237 // Make sure the path is a known home page path.
238 std::string path(url.path());
239 return IsPathHomePageBase(path) || StartsWithASCII(path, "/ig", false);
242 bool IsGoogleSearchUrl(const GURL& url) {
243 // First check to see if this has a Google domain.
244 if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
245 return false;
247 // Make sure the path is a known search path.
248 std::string path(url.path());
249 bool is_home_page_base = IsPathHomePageBase(path);
250 if (!is_home_page_base && (path != "/search"))
251 return false;
253 // Check for query parameter in URL parameter and hash fragment, depending on
254 // the path type.
255 return HasGoogleSearchQueryParam(url.ref()) ||
256 (!is_home_page_base && HasGoogleSearchQueryParam(url.query()));
259 bool IsOrganic(const std::string& brand) {
260 #if defined(OS_MACOSX)
261 if (brand.empty()) {
262 // An empty brand string on Mac is used for channels other than stable,
263 // which are always organic.
264 return true;
266 #endif
268 const char* const kBrands[] = {
269 "CHCA", "CHCB", "CHCG", "CHCH", "CHCI", "CHCJ", "CHCK", "CHCL",
270 "CHFO", "CHFT", "CHHS", "CHHM", "CHMA", "CHMB", "CHME", "CHMF",
271 "CHMG", "CHMH", "CHMI", "CHMQ", "CHMV", "CHNB", "CHNC", "CHNG",
272 "CHNH", "CHNI", "CHOA", "CHOB", "CHOC", "CHON", "CHOO", "CHOP",
273 "CHOQ", "CHOR", "CHOS", "CHOT", "CHOU", "CHOX", "CHOY", "CHOZ",
274 "CHPD", "CHPE", "CHPF", "CHPG", "ECBA", "ECBB", "ECDA", "ECDB",
275 "ECSA", "ECSB", "ECVA", "ECVB", "ECWA", "ECWB", "ECWC", "ECWD",
276 "ECWE", "ECWF", "EUBB", "EUBC", "GGLA", "GGLS"
278 const char* const* end = &kBrands[arraysize(kBrands)];
279 const char* const* found = std::find(&kBrands[0], end, brand);
280 if (found != end)
281 return true;
283 return StartsWithASCII(brand, "EUB", true) ||
284 StartsWithASCII(brand, "EUC", true) ||
285 StartsWithASCII(brand, "GGR", true);
288 bool IsOrganicFirstRun(const std::string& brand) {
289 #if defined(OS_MACOSX)
290 if (brand.empty()) {
291 // An empty brand string on Mac is used for channels other than stable,
292 // which are always organic.
293 return true;
295 #endif
297 return StartsWithASCII(brand, "GG", true) ||
298 StartsWithASCII(brand, "EU", true);
301 bool IsInternetCafeBrandCode(const std::string& brand) {
302 const char* const kBrands[] = {
303 "CHIQ", "CHSG", "HLJY", "NTMO", "OOBA", "OOBB", "OOBC", "OOBD", "OOBE",
304 "OOBF", "OOBG", "OOBH", "OOBI", "OOBJ", "IDCM",
306 const char* const* end = &kBrands[arraysize(kBrands)];
307 const char* const* found = std::find(&kBrands[0], end, brand);
308 return found != end;
312 // BrandForTesting ------------------------------------------------------------
314 BrandForTesting::BrandForTesting(const std::string& brand) : brand_(brand) {
315 DCHECK(brand_for_testing == NULL);
316 brand_for_testing = brand_.c_str();
319 BrandForTesting::~BrandForTesting() {
320 brand_for_testing = NULL;
324 } // namespace google_util