Home | History | Annotate | Download | only in search_engines
      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.
      4 
      5 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
      6 
      7 #if defined(OS_POSIX) && !defined(OS_MACOSX)
      8 #include <locale.h>
      9 #endif
     10 
     11 #include "base/command_line.h"
     12 #include "base/logging.h"
     13 #include "base/memory/scoped_vector.h"
     14 #include "base/prefs/pref_service.h"
     15 #include "base/stl_util.h"
     16 #include "base/strings/string16.h"
     17 #include "base/strings/string_piece.h"
     18 #include "base/strings/string_util.h"
     19 #include "base/strings/utf_string_conversions.h"
     20 #include "chrome/browser/google/google_util.h"
     21 #include "chrome/browser/profiles/profile.h"
     22 #include "chrome/browser/search_engines/prepopulated_engines.h"
     23 #include "chrome/browser/search_engines/search_terms_data.h"
     24 #include "chrome/browser/search_engines/template_url.h"
     25 #include "chrome/browser/search_engines/template_url_service.h"
     26 #include "chrome/common/chrome_switches.h"
     27 #include "chrome/common/pref_names.h"
     28 #include "components/user_prefs/pref_registry_syncable.h"
     29 #include "content/public/browser/browser_thread.h"
     30 #include "grit/generated_resources.h"
     31 #include "grit/theme_resources.h"
     32 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
     33 #include "ui/base/l10n/l10n_util.h"
     34 #include "url/gurl.h"
     35 
     36 #if defined(OS_WIN)
     37 #undef IN  // On Windows, windef.h defines this, which screws up "India" cases.
     38 #elif defined(OS_MACOSX)
     39 #include "base/mac/scoped_cftyperef.h"
     40 #endif
     41 
     42 namespace TemplateURLPrepopulateData {
     43 
     44 
     45 // Helpers --------------------------------------------------------------------
     46 
     47 namespace {
     48 
     49 // NOTE: You should probably not change the data in this file without changing
     50 // |kCurrentDataVersion| in prepopulated_engines.json. See comments in
     51 // GetDataVersion() below!
     52 
     53 // Put the engines within each country in order with most interesting/important
     54 // first.  The default will be the first engine.
     55 
     56 // Default (for countries with no better engine set)
     57 const PrepopulatedEngine* engines_default[] =
     58     { &google, &bing, &yahoo, };
     59 
     60 // United Arab Emirates
     61 const PrepopulatedEngine* engines_AE[] =
     62     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
     63 
     64 // Albania
     65 const PrepopulatedEngine* engines_AL[] =
     66     { &google, &yahoo, &bing_en_XA, &bing_ar_XA, };
     67 
     68 // Argentina
     69 const PrepopulatedEngine* engines_AR[] =
     70     { &google, &bing_es_AR, &yahoo_ar, };
     71 
     72 // Austria
     73 const PrepopulatedEngine* engines_AT[] =
     74     { &google, &bing_de_AT, &yahoo_at, };
     75 
     76 // Australia
     77 const PrepopulatedEngine* engines_AU[] =
     78     { &google, &bing_en_AU, &yahoo_au, };
     79 
     80 // Bosnia and Herzegovina
     81 const PrepopulatedEngine* engines_BA[] =
     82     { &google, &yahoo, &bing, };
     83 
     84 // Belgium
     85 const PrepopulatedEngine* engines_BE[] =
     86     { &google, &bing_nl_BE, &bing_fr_BE, &yahoo_be, &yahoo_fr_be, };
     87 
     88 // Bulgaria
     89 const PrepopulatedEngine* engines_BG[] =
     90     { &google, &bing, &ask, };
     91 
     92 // Bahrain
     93 const PrepopulatedEngine* engines_BH[] =
     94     { &google, &yahoo_maktoob, &bing_en_XA, &bing_ar_XA, };
     95 
     96 // Burundi
     97 const PrepopulatedEngine* engines_BI[] =
     98     { &google, &yahoo, &bing, };
     99 
    100 // Brunei
    101 const PrepopulatedEngine* engines_BN[] =
    102     { &google, &yahoo_my, &bing, };
    103 
    104 // Bolivia
    105 const PrepopulatedEngine* engines_BO[] =
    106     { &google, &bing_es_XL, &yahoo, };
    107 
    108 // Brazil
    109 const PrepopulatedEngine* engines_BR[] =
    110     { &google, &ask_br, &bing_pt_BR, &yahoo_br, };
    111 
    112 // Belarus
    113 const PrepopulatedEngine* engines_BY[] =
    114     { &google, &yahoo_ru, &bing_ru_RU, };
    115 
    116 // Belize
    117 const PrepopulatedEngine* engines_BZ[] =
    118     { &google, &yahoo, &bing, };
    119 
    120 // Canada
    121 const PrepopulatedEngine* engines_CA[] =
    122     { &google, &bing_en_CA, &bing_fr_CA, &ask, &yahoo_ca, &yahoo_qc, };
    123 
    124 // Switzerland
    125 const PrepopulatedEngine* engines_CH[] =
    126     { &google, &bing_de_CH, &bing_fr_CH, &yahoo_ch, };
    127 
    128 // Chile
    129 const PrepopulatedEngine* engines_CL[] =
    130     { &google, &bing_es_CL, &yahoo_cl, };
    131 
    132 // China
    133 const PrepopulatedEngine* engines_CN[] =
    134     { &google, &baidu, &sogou, &soso, };
    135 
    136 // Colombia
    137 const PrepopulatedEngine* engines_CO[] =
    138     { &google, &bing_es_XL, &yahoo_co, };
    139 
    140 // Costa Rica
    141 const PrepopulatedEngine* engines_CR[] =
    142     { &google, &yahoo, &bing_es_XL, };
    143 
    144 // Czech Republic
    145 const PrepopulatedEngine* engines_CZ[] =
    146     { &google, &seznam, &bing, };
    147 
    148 // Germany
    149 const PrepopulatedEngine* engines_DE[] =
    150     { &google, &bing_de_DE, &yahoo_de };
    151 
    152 // Denmark
    153 const PrepopulatedEngine* engines_DK[] =
    154     { &google, &bing_da_DK, &yahoo_dk, };
    155 
    156 // Dominican Republic
    157 const PrepopulatedEngine* engines_DO[] =
    158     { &google, &yahoo, &bing_es_XL, };
    159 
    160 // Algeria
    161 const PrepopulatedEngine* engines_DZ[] =
    162     { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, };
    163 
    164 // Ecuador
    165 const PrepopulatedEngine* engines_EC[] =
    166     { &google, &bing_es_XL, &yahoo, };
    167 
    168 // Estonia
    169 const PrepopulatedEngine* engines_EE[] =
    170     { &google, &bing, &yahoo, };
    171 
    172 // Egypt
    173 const PrepopulatedEngine* engines_EG[] =
    174     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    175 
    176 // Spain
    177 const PrepopulatedEngine* engines_ES[] =
    178     { &google, &bing_es_ES, &yahoo_es, };
    179 
    180 // Faroe Islands
    181 const PrepopulatedEngine* engines_FO[] =
    182     { &google, &bing_da_DK, &ask, };
    183 
    184 // Finland
    185 const PrepopulatedEngine* engines_FI[] =
    186     { &google, &bing_fi_FI, &yahoo_fi, };
    187 
    188 // France
    189 const PrepopulatedEngine* engines_FR[] =
    190     { &google, &bing_fr_FR, &yahoo_fr, };
    191 
    192 // United Kingdom
    193 const PrepopulatedEngine* engines_GB[] =
    194     { &google, &bing_en_GB, &yahoo_uk, &ask_uk, };
    195 
    196 // Greece
    197 const PrepopulatedEngine* engines_GR[] =
    198     { &google, &bing, &yahoo_gr, };
    199 
    200 // Guatemala
    201 const PrepopulatedEngine* engines_GT[] =
    202     { &google, &yahoo, &bing_es_XL, };
    203 
    204 // Hong Kong
    205 const PrepopulatedEngine* engines_HK[] =
    206     { &google, &yahoo_hk, &baidu, &bing_zh_HK, };
    207 
    208 // Honduras
    209 const PrepopulatedEngine* engines_HN[] =
    210     { &google, &yahoo, &bing_es_XL, };
    211 
    212 // Croatia
    213 const PrepopulatedEngine* engines_HR[] =
    214     { &google, &bing, &yahoo, };
    215 
    216 // Hungary
    217 const PrepopulatedEngine* engines_HU[] =
    218     { &google, &bing, &yahoo, };
    219 
    220 // Indonesia
    221 const PrepopulatedEngine* engines_ID[] =
    222     { &google, &yahoo_id, &bing, };
    223 
    224 // Ireland
    225 const PrepopulatedEngine* engines_IE[] =
    226     { &google, &bing_en_IE, &yahoo_uk, };
    227 
    228 // Israel
    229 const PrepopulatedEngine* engines_IL[] =
    230     { &google, &yahoo, &bing, };
    231 
    232 // India
    233 const PrepopulatedEngine* engines_IN[] =
    234     { &google, &bing_en_IN, &yahoo_in, };
    235 
    236 // Iraq
    237 const PrepopulatedEngine* engines_IQ[] =
    238     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    239 
    240 // Iran
    241 const PrepopulatedEngine* engines_IR[] =
    242     { &google, &yahoo, &bing, };
    243 
    244 // Iceland
    245 const PrepopulatedEngine* engines_IS[] =
    246     { &google, &bing, &yahoo, };
    247 
    248 // Italy
    249 const PrepopulatedEngine* engines_IT[] =
    250     { &google, &virgilio, &bing_it_IT, };
    251 
    252 // Jamaica
    253 const PrepopulatedEngine* engines_JM[] =
    254     { &google, &yahoo, &bing, };
    255 
    256 // Jordan
    257 const PrepopulatedEngine* engines_JO[] =
    258     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    259 
    260 // Japan
    261 const PrepopulatedEngine* engines_JP[] =
    262     { &google, &yahoo_jp, &bing_ja_JP, };
    263 
    264 // Kenya
    265 const PrepopulatedEngine* engines_KE[] =
    266     { &google, &yahoo, &bing, };
    267 
    268 // Kuwait
    269 const PrepopulatedEngine* engines_KW[] =
    270     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    271 
    272 // South Korea
    273 const PrepopulatedEngine* engines_KR[] =
    274     { &google, &naver, &daum, &nate, };
    275 
    276 // Kazakhstan
    277 const PrepopulatedEngine* engines_KZ[] =
    278     { &google, &bing, &yahoo, };
    279 
    280 // Lebanon
    281 const PrepopulatedEngine* engines_LB[] =
    282     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    283 
    284 // Liechtenstein
    285 const PrepopulatedEngine* engines_LI[] =
    286     { &google, &bing_de_DE, &yahoo_de, };
    287 
    288 // Lithuania
    289 const PrepopulatedEngine* engines_LT[] =
    290     { &google, &bing, &yandex_ru, };
    291 
    292 // Luxembourg
    293 const PrepopulatedEngine* engines_LU[] =
    294     { &google, &bing_fr_FR, &yahoo_fr, };
    295 
    296 // Latvia
    297 const PrepopulatedEngine* engines_LV[] =
    298     { &google, &yandex_ru, &bing, };
    299 
    300 // Libya
    301 const PrepopulatedEngine* engines_LY[] =
    302     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    303 
    304 // Morocco
    305 const PrepopulatedEngine* engines_MA[] =
    306     { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, };
    307 
    308 // Monaco
    309 const PrepopulatedEngine* engines_MC[] =
    310     { &google, &yahoo_fr, &bing_fr_FR, };
    311 
    312 // Moldova
    313 const PrepopulatedEngine* engines_MD[] =
    314     { &google, &bing, &yahoo, };
    315 
    316 // Montenegro
    317 const PrepopulatedEngine* engines_ME[] =
    318     { &google, &bing, &yahoo, };
    319 
    320 // Macedonia
    321 const PrepopulatedEngine* engines_MK[] =
    322     { &google, &yahoo, &bing, };
    323 
    324 // Mexico
    325 const PrepopulatedEngine* engines_MX[] =
    326     { &google, &bing_es_MX, &yahoo_mx, };
    327 
    328 // Malaysia
    329 const PrepopulatedEngine* engines_MY[] =
    330     { &google, &yahoo_my, &bing, };
    331 
    332 // Nicaragua
    333 const PrepopulatedEngine* engines_NI[] =
    334     { &google, &yahoo, &bing_es_XL, };
    335 
    336 // Netherlands
    337 const PrepopulatedEngine* engines_NL[] =
    338     { &google, &yahoo_nl, &vinden, };
    339 
    340 // Norway
    341 const PrepopulatedEngine* engines_NO[] =
    342     { &google, &bing_nb_NO, &kvasir, };
    343 
    344 // New Zealand
    345 const PrepopulatedEngine* engines_NZ[] =
    346     { &google, &bing_en_NZ, &yahoo_nz, };
    347 
    348 // Oman
    349 const PrepopulatedEngine* engines_OM[] =
    350     { &google, &bing_ar_XA, &yahoo_maktoob, &bing_en_XA, };
    351 
    352 // Panama
    353 const PrepopulatedEngine* engines_PA[] =
    354     { &google, &yahoo, &bing_es_XL, };
    355 
    356 // Peru
    357 const PrepopulatedEngine* engines_PE[] =
    358     { &google, &bing_es_XL, &yahoo_pe, };
    359 
    360 // Philippines
    361 const PrepopulatedEngine* engines_PH[] =
    362     { &google, &yahoo_ph, &bing_en_PH, };
    363 
    364 // Pakistan
    365 const PrepopulatedEngine* engines_PK[] =
    366     { &google, &yahoo, &bing, };
    367 
    368 // Puerto Rico
    369 const PrepopulatedEngine* engines_PR[] =
    370     { &google, &yahoo, &bing_es_XL, };
    371 
    372 // Poland
    373 const PrepopulatedEngine* engines_PL[] =
    374     { &google, &onet, &bing_pl_PL, };
    375 
    376 // Portugal
    377 const PrepopulatedEngine* engines_PT[] =
    378     { &google, &bing_pt_PT, &yahoo, };
    379 
    380 // Paraguay
    381 const PrepopulatedEngine* engines_PY[] =
    382     { &google, &bing_es_XL, &yahoo, };
    383 
    384 // Qatar
    385 const PrepopulatedEngine* engines_QA[] =
    386     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    387 
    388 // Romania
    389 const PrepopulatedEngine* engines_RO[] =
    390     { &google, &yahoo_ro, &bing, };
    391 
    392 // Serbia
    393 const PrepopulatedEngine* engines_RS[] =
    394     { &google, &bing, &yahoo, };
    395 
    396 // Russia
    397 const PrepopulatedEngine* engines_RU[] =
    398     { &google, &yandex_ru, &mail_ru, };
    399 
    400 // Rwanda
    401 const PrepopulatedEngine* engines_RW[] =
    402     { &google, &bing, &yahoo, };
    403 
    404 // Saudi Arabia
    405 const PrepopulatedEngine* engines_SA[] =
    406     { &google, &yahoo_maktoob, &bing_ar_XA, &bing_en_XA, };
    407 
    408 // Sweden
    409 const PrepopulatedEngine* engines_SE[] =
    410     { &google, &bing_sv_SE, &yahoo_se, };
    411 
    412 // Singapore
    413 const PrepopulatedEngine* engines_SG[] =
    414     { &google, &yahoo_sg, &bing_en_SG, };
    415 
    416 // Slovenia
    417 const PrepopulatedEngine* engines_SI[] =
    418     { &google, &najdi, &ask, };
    419 
    420 // Slovakia
    421 const PrepopulatedEngine* engines_SK[] =
    422     { &google, &bing, &yahoo, };
    423 
    424 // El Salvador
    425 const PrepopulatedEngine* engines_SV[] =
    426     { &google, &yahoo, &bing_es_XL, };
    427 
    428 // Syria
    429 const PrepopulatedEngine* engines_SY[] =
    430     { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, };
    431 
    432 // Thailand
    433 const PrepopulatedEngine* engines_TH[] =
    434     { &google, &yahoo_th, &bing, };
    435 
    436 // Tunisia
    437 const PrepopulatedEngine* engines_TN[] =
    438     { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, };
    439 
    440 // Turkey
    441 const PrepopulatedEngine* engines_TR[] =
    442     { &google, &bing_tr_TR, &yahoo_tr, };
    443 
    444 // Trinidad and Tobago
    445 const PrepopulatedEngine* engines_TT[] =
    446     { &google, &bing, &yahoo, };
    447 
    448 // Taiwan
    449 const PrepopulatedEngine* engines_TW[] =
    450     { &google, &yahoo_tw, &bing_zh_TW, };
    451 
    452 // Tanzania
    453 const PrepopulatedEngine* engines_TZ[] =
    454     { &google, &yahoo, &bing, };
    455 
    456 // Ukraine
    457 const PrepopulatedEngine* engines_UA[] =
    458     { &google, &yandex_ua, &bing_ru_RU, };
    459 
    460 // United States
    461 const PrepopulatedEngine* engines_US[] =
    462     { &google, &bing_en_US, &yahoo, &aol, &ask, };
    463 
    464 // Uruguay
    465 const PrepopulatedEngine* engines_UY[] =
    466     { &google, &bing_es_XL, &yahoo, };
    467 
    468 // Venezuela
    469 const PrepopulatedEngine* engines_VE[] =
    470     { &google, &bing_es_XL, &yahoo_ve, };
    471 
    472 // Vietnam
    473 const PrepopulatedEngine* engines_VN[] =
    474     { &google, &yahoo_vn, &bing, };
    475 
    476 // Yemen
    477 const PrepopulatedEngine* engines_YE[] =
    478     { &google, &bing_ar_XA, &bing_en_XA, &yahoo_maktoob, };
    479 
    480 // South Africa
    481 const PrepopulatedEngine* engines_ZA[] =
    482     { &google, &bing, &yahoo_za, };
    483 
    484 // Zimbabwe
    485 const PrepopulatedEngine* engines_ZW[] =
    486     { &google, &bing, &yahoo, &ask, };
    487 
    488 // A list of all the engines that we know about.
    489 const PrepopulatedEngine* kAllEngines[] = {
    490   // Prepopulated engines:
    491   &aol,          &ask,          &ask_br,       &ask_uk,       &baidu,
    492   &bing,         &bing_ar_XA,   &bing_da_DK,   &bing_de_AT,   &bing_de_CH,
    493   &bing_de_DE,   &bing_en_AU,   &bing_en_CA,   &bing_en_GB,   &bing_en_IE,
    494   &bing_en_IN,   &bing_en_NZ,   &bing_en_PH,   &bing_en_SG,   &bing_en_US,
    495   &bing_en_XA,   &bing_es_AR,   &bing_es_CL,   &bing_es_ES,   &bing_es_MX,
    496   &bing_es_XL,   &bing_fi_FI,   &bing_fr_BE,   &bing_fr_CA,   &bing_fr_CH,
    497   &bing_fr_FR,   &bing_it_IT,   &bing_ja_JP,   &bing_lv_LV,   &bing_nb_NO,
    498   &bing_nl_BE,   &bing_pl_PL,   &bing_pt_BR,   &bing_pt_PT,   &bing_ru_RU,
    499   &bing_sv_SE,   &bing_tr_TR,   &bing_zh_HK,   &bing_zh_TW,   &daum,
    500   &google,       &kvasir,       &mail_ru,      &najdi,        &nate,
    501   &naver,        &onet,         &seznam,       &sogou,        &soso,
    502   &vinden,       &virgilio,     &yahoo,        &yahoo_ar,     &yahoo_at,
    503   &yahoo_au,     &yahoo_be,     &yahoo_br,     &yahoo_ca,     &yahoo_ch,
    504   &yahoo_cl,     &yahoo_co,     &yahoo_de,     &yahoo_dk,     &yahoo_es,
    505   &yahoo_fi,     &yahoo_fr,     &yahoo_fr_be,  &yahoo_gr,     &yahoo_hk,
    506   &yahoo_id,     &yahoo_in,     &yahoo_jp,     &yahoo_maktoob, &yahoo_mx,
    507   &yahoo_my,     &yahoo_nl,     &yahoo_nz,     &yahoo_pe,     &yahoo_ph,
    508   &yahoo_qc,     &yahoo_ro,     &yahoo_ru,     &yahoo_se,     &yahoo_sg,
    509   &yahoo_th,     &yahoo_tr,     &yahoo_tw,     &yahoo_uk,     &yahoo_ve,
    510   &yahoo_vn,     &yahoo_za,     &yandex_ru,    &yandex_ua,
    511 
    512   // UMA-only engines:
    513   &atlas_cz,     &atlas_sk,     &avg,          &babylon,      &conduit,
    514   &delfi_lt,     &delfi_lv,     &delta,        &funmoods,     &goo,
    515   &imesh,        &iminent,      &in,           &incredibar,   &libero,
    516   &neti,         &nigma,        &ok,           &rambler,      &sapo,
    517   &search_results, &searchnu,   &snapdo,       &softonic,     &sweetim,
    518   &terra_ar,     &terra_es,     &tut,          &walla,        &wp,
    519   &yandex_tr,    &zoznam,
    520 };
    521 
    522 const struct LogoURLs {
    523   const char* const logo_100_percent_url;
    524   const char* const logo_200_percent_url;
    525 } google_logos = {
    526   "https://www.google.com/images/chrome_search/google_logo.png",
    527   "https://www.google.com/images/chrome_search/google_logo_2x.png",
    528 };
    529 
    530 // Please refer to ISO 3166-1 for information about the two-character country
    531 // codes; http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 is useful. In the
    532 // following (C++) code, we pack the two letters of the country code into an int
    533 // value we call the CountryID.
    534 
    535 const int kCountryIDUnknown = -1;
    536 
    537 inline int CountryCharsToCountryID(char c1, char c2) {
    538   return c1 << 8 | c2;
    539 }
    540 
    541 int CountryCharsToCountryIDWithUpdate(char c1, char c2) {
    542   // SPECIAL CASE: In 2003, Yugoslavia renamed itself to Serbia and Montenegro.
    543   // Serbia and Montenegro dissolved their union in June 2006. Yugoslavia was
    544   // ISO 'YU' and Serbia and Montenegro were ISO 'CS'. Serbia was subsequently
    545   // issued 'RS' and Montenegro 'ME'. Windows XP and Mac OS X Leopard still use
    546   // the value 'YU'. If we get a value of 'YU' or 'CS' we will map it to 'RS'.
    547   if ((c1 == 'Y' && c2 == 'U') ||
    548       (c1 == 'C' && c2 == 'S')) {
    549     c1 = 'R';
    550     c2 = 'S';
    551   }
    552 
    553   // SPECIAL CASE: Timor-Leste changed from 'TP' to 'TL' in 2002. Windows XP
    554   // predates this; we therefore map this value.
    555   if (c1 == 'T' && c2 == 'P')
    556     c2 = 'L';
    557 
    558   return CountryCharsToCountryID(c1, c2);
    559 }
    560 
    561 #if defined(OS_WIN)
    562 
    563 // For reference, a list of GeoIDs can be found at
    564 // http://msdn.microsoft.com/en-us/library/dd374073.aspx .
    565 int GeoIDToCountryID(GEOID geo_id) {
    566   const int kISOBufferSize = 3;  // Two plus one for the terminator.
    567   wchar_t isobuf[kISOBufferSize] = { 0 };
    568   int retval = GetGeoInfo(geo_id, GEO_ISO2, isobuf, kISOBufferSize, 0);
    569 
    570   if (retval == kISOBufferSize &&
    571       !(isobuf[0] == L'X' && isobuf[1] == L'X'))
    572     return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]),
    573                                              static_cast<char>(isobuf[1]));
    574 
    575   // Various locations have ISO codes that Windows does not return.
    576   switch (geo_id) {
    577     case 0x144:   // Guernsey
    578       return CountryCharsToCountryID('G', 'G');
    579     case 0x148:   // Jersey
    580       return CountryCharsToCountryID('J', 'E');
    581     case 0x3B16:  // Isle of Man
    582       return CountryCharsToCountryID('I', 'M');
    583 
    584     // 'UM' (U.S. Minor Outlying Islands)
    585     case 0x7F:    // Johnston Atoll
    586     case 0x102:   // Wake Island
    587     case 0x131:   // Baker Island
    588     case 0x146:   // Howland Island
    589     case 0x147:   // Jarvis Island
    590     case 0x149:   // Kingman Reef
    591     case 0x152:   // Palmyra Atoll
    592     case 0x52FA:  // Midway Islands
    593       return CountryCharsToCountryID('U', 'M');
    594 
    595     // 'SH' (Saint Helena)
    596     case 0x12F:  // Ascension Island
    597     case 0x15C:  // Tristan da Cunha
    598       return CountryCharsToCountryID('S', 'H');
    599 
    600     // 'IO' (British Indian Ocean Territory)
    601     case 0x13A:  // Diego Garcia
    602       return CountryCharsToCountryID('I', 'O');
    603 
    604     // Other cases where there is no ISO country code; we assign countries that
    605     // can serve as reasonable defaults.
    606     case 0x154:  // Rota Island
    607     case 0x155:  // Saipan
    608     case 0x15A:  // Tinian Island
    609       return CountryCharsToCountryID('U', 'S');
    610     case 0x134:  // Channel Islands
    611       return CountryCharsToCountryID('G', 'B');
    612     case 0x143:  // Guantanamo Bay
    613     default:
    614       return kCountryIDUnknown;
    615   }
    616 }
    617 
    618 int GetCurrentCountryID() {
    619   GEOID geo_id = GetUserGeoID(GEOCLASS_NATION);
    620 
    621   return GeoIDToCountryID(geo_id);
    622 }
    623 
    624 #elif defined(OS_MACOSX)
    625 
    626 int GetCurrentCountryID() {
    627   base::ScopedCFTypeRef<CFLocaleRef> locale(CFLocaleCopyCurrent());
    628   CFStringRef country = (CFStringRef)CFLocaleGetValue(locale.get(),
    629                                                       kCFLocaleCountryCode);
    630   if (!country)
    631     return kCountryIDUnknown;
    632 
    633   UniChar isobuf[2];
    634   CFRange char_range = CFRangeMake(0, 2);
    635   CFStringGetCharacters(country, char_range, isobuf);
    636 
    637   return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]),
    638                                            static_cast<char>(isobuf[1]));
    639 }
    640 
    641 #elif defined(OS_ANDROID)
    642 
    643 // Initialized by InitCountryCode().
    644 int g_country_code_at_install = kCountryIDUnknown;
    645 
    646 int GetCurrentCountryID() {
    647   return g_country_code_at_install;
    648 }
    649 
    650 #elif defined(OS_POSIX)
    651 
    652 int GetCurrentCountryID() {
    653   const char* locale = setlocale(LC_MESSAGES, NULL);
    654 
    655   if (!locale)
    656     return kCountryIDUnknown;
    657 
    658   // The format of a locale name is:
    659   // language[_territory][.codeset][@modifier], where territory is an ISO 3166
    660   // country code, which is what we want.
    661   std::string locale_str(locale);
    662   size_t begin = locale_str.find('_');
    663   if (begin == std::string::npos || locale_str.size() - begin < 3)
    664     return kCountryIDUnknown;
    665 
    666   ++begin;
    667   size_t end = locale_str.find_first_of(".@", begin);
    668   if (end == std::string::npos)
    669     end = locale_str.size();
    670 
    671   // The territory part must contain exactly two characters.
    672   if (end - begin == 2) {
    673     return CountryCharsToCountryIDWithUpdate(
    674         base::ToUpperASCII(locale_str[begin]),
    675         base::ToUpperASCII(locale_str[begin + 1]));
    676   }
    677 
    678   return kCountryIDUnknown;
    679 }
    680 
    681 #endif  // OS_*
    682 
    683 int GetCountryIDFromPrefs(PrefService* prefs) {
    684   // See if the user overrode the country on the command line.
    685   const std::string country(
    686       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
    687           switches::kCountry));
    688   if (country.length() == 2)
    689     return CountryCharsToCountryIDWithUpdate(country[0], country[1]);
    690 
    691   // Cache first run Country ID value in prefs, and use it afterwards.  This
    692   // ensures that just because the user moves around, we won't automatically
    693   // make major changes to their available search providers, which would feel
    694   // surprising.
    695   if (!prefs)
    696     return GetCurrentCountryID();
    697 
    698   int new_country_id = GetCurrentCountryID();
    699 #if defined(OS_WIN)
    700   // Migrate the old platform-specific value if it's present.
    701   if (prefs->HasPrefPath(prefs::kGeoIDAtInstall)) {
    702     int geo_id = prefs->GetInteger(prefs::kGeoIDAtInstall);
    703     prefs->ClearPref(prefs::kGeoIDAtInstall);
    704     new_country_id = GeoIDToCountryID(geo_id);
    705   }
    706 #endif
    707 
    708   if (!prefs->HasPrefPath(prefs::kCountryIDAtInstall))
    709     prefs->SetInteger(prefs::kCountryIDAtInstall, new_country_id);
    710 
    711   return prefs->GetInteger(prefs::kCountryIDAtInstall);
    712 }
    713 
    714 void GetPrepopulationSetFromCountryID(PrefService* prefs,
    715                                       const PrepopulatedEngine*** engines,
    716                                       size_t* num_engines) {
    717   // NOTE: This function should ALWAYS set its outparams.
    718 
    719   // If you add a new country make sure to update the unit test for coverage.
    720   switch (GetCountryIDFromPrefs(prefs)) {
    721 
    722 #define CHAR_A 'A'
    723 #define CHAR_B 'B'
    724 #define CHAR_C 'C'
    725 #define CHAR_D 'D'
    726 #define CHAR_E 'E'
    727 #define CHAR_F 'F'
    728 #define CHAR_G 'G'
    729 #define CHAR_H 'H'
    730 #define CHAR_I 'I'
    731 #define CHAR_J 'J'
    732 #define CHAR_K 'K'
    733 #define CHAR_L 'L'
    734 #define CHAR_M 'M'
    735 #define CHAR_N 'N'
    736 #define CHAR_O 'O'
    737 #define CHAR_P 'P'
    738 #define CHAR_Q 'Q'
    739 #define CHAR_R 'R'
    740 #define CHAR_S 'S'
    741 #define CHAR_T 'T'
    742 #define CHAR_U 'U'
    743 #define CHAR_V 'V'
    744 #define CHAR_W 'W'
    745 #define CHAR_X 'X'
    746 #define CHAR_Y 'Y'
    747 #define CHAR_Z 'Z'
    748 #define CHAR(ch) CHAR_##ch
    749 #define CODE_TO_ID(code1, code2)\
    750     (CHAR(code1) << 8 | CHAR(code2))
    751 
    752 #define UNHANDLED_COUNTRY(code1, code2)\
    753     case CODE_TO_ID(code1, code2):
    754 #define END_UNHANDLED_COUNTRIES(code1, code2)\
    755       *engines = engines_##code1##code2;\
    756       *num_engines = arraysize(engines_##code1##code2);\
    757       return;
    758 #define DECLARE_COUNTRY(code1, code2)\
    759     UNHANDLED_COUNTRY(code1, code2)\
    760     END_UNHANDLED_COUNTRIES(code1, code2)
    761 
    762     // Countries with their own, dedicated engine set.
    763     DECLARE_COUNTRY(A, E)  // United Arab Emirates
    764     DECLARE_COUNTRY(A, L)  // Albania
    765     DECLARE_COUNTRY(A, R)  // Argentina
    766     DECLARE_COUNTRY(A, T)  // Austria
    767     DECLARE_COUNTRY(A, U)  // Australia
    768     DECLARE_COUNTRY(B, A)  // Bosnia and Herzegovina
    769     DECLARE_COUNTRY(B, E)  // Belgium
    770     DECLARE_COUNTRY(B, G)  // Bulgaria
    771     DECLARE_COUNTRY(B, H)  // Bahrain
    772     DECLARE_COUNTRY(B, I)  // Burundi
    773     DECLARE_COUNTRY(B, N)  // Brunei
    774     DECLARE_COUNTRY(B, O)  // Bolivia
    775     DECLARE_COUNTRY(B, R)  // Brazil
    776     DECLARE_COUNTRY(B, Y)  // Belarus
    777     DECLARE_COUNTRY(B, Z)  // Belize
    778     DECLARE_COUNTRY(C, A)  // Canada
    779     DECLARE_COUNTRY(C, H)  // Switzerland
    780     DECLARE_COUNTRY(C, L)  // Chile
    781     DECLARE_COUNTRY(C, N)  // China
    782     DECLARE_COUNTRY(C, O)  // Colombia
    783     DECLARE_COUNTRY(C, R)  // Costa Rica
    784     DECLARE_COUNTRY(C, Z)  // Czech Republic
    785     DECLARE_COUNTRY(D, E)  // Germany
    786     DECLARE_COUNTRY(D, K)  // Denmark
    787     DECLARE_COUNTRY(D, O)  // Dominican Republic
    788     DECLARE_COUNTRY(D, Z)  // Algeria
    789     DECLARE_COUNTRY(E, C)  // Ecuador
    790     DECLARE_COUNTRY(E, E)  // Estonia
    791     DECLARE_COUNTRY(E, G)  // Egypt
    792     DECLARE_COUNTRY(E, S)  // Spain
    793     DECLARE_COUNTRY(F, I)  // Finland
    794     DECLARE_COUNTRY(F, O)  // Faroe Islands
    795     DECLARE_COUNTRY(F, R)  // France
    796     DECLARE_COUNTRY(G, B)  // United Kingdom
    797     DECLARE_COUNTRY(G, R)  // Greece
    798     DECLARE_COUNTRY(G, T)  // Guatemala
    799     DECLARE_COUNTRY(H, K)  // Hong Kong
    800     DECLARE_COUNTRY(H, N)  // Honduras
    801     DECLARE_COUNTRY(H, R)  // Croatia
    802     DECLARE_COUNTRY(H, U)  // Hungary
    803     DECLARE_COUNTRY(I, D)  // Indonesia
    804     DECLARE_COUNTRY(I, E)  // Ireland
    805     DECLARE_COUNTRY(I, L)  // Israel
    806     DECLARE_COUNTRY(I, N)  // India
    807     DECLARE_COUNTRY(I, Q)  // Iraq
    808     DECLARE_COUNTRY(I, R)  // Iran
    809     DECLARE_COUNTRY(I, S)  // Iceland
    810     DECLARE_COUNTRY(I, T)  // Italy
    811     DECLARE_COUNTRY(J, M)  // Jamaica
    812     DECLARE_COUNTRY(J, O)  // Jordan
    813     DECLARE_COUNTRY(J, P)  // Japan
    814     DECLARE_COUNTRY(K, E)  // Kenya
    815     DECLARE_COUNTRY(K, R)  // South Korea
    816     DECLARE_COUNTRY(K, W)  // Kuwait
    817     DECLARE_COUNTRY(K, Z)  // Kazakhstan
    818     DECLARE_COUNTRY(L, B)  // Lebanon
    819     DECLARE_COUNTRY(L, I)  // Liechtenstein
    820     DECLARE_COUNTRY(L, T)  // Lithuania
    821     DECLARE_COUNTRY(L, U)  // Luxembourg
    822     DECLARE_COUNTRY(L, V)  // Latvia
    823     DECLARE_COUNTRY(L, Y)  // Libya
    824     DECLARE_COUNTRY(M, A)  // Morocco
    825     DECLARE_COUNTRY(M, C)  // Monaco
    826     DECLARE_COUNTRY(M, D)  // Moldova
    827     DECLARE_COUNTRY(M, E)  // Montenegro
    828     DECLARE_COUNTRY(M, K)  // Macedonia
    829     DECLARE_COUNTRY(M, X)  // Mexico
    830     DECLARE_COUNTRY(M, Y)  // Malaysia
    831     DECLARE_COUNTRY(N, I)  // Nicaragua
    832     DECLARE_COUNTRY(N, L)  // Netherlands
    833     DECLARE_COUNTRY(N, O)  // Norway
    834     DECLARE_COUNTRY(N, Z)  // New Zealand
    835     DECLARE_COUNTRY(O, M)  // Oman
    836     DECLARE_COUNTRY(P, A)  // Panama
    837     DECLARE_COUNTRY(P, E)  // Peru
    838     DECLARE_COUNTRY(P, H)  // Philippines
    839     DECLARE_COUNTRY(P, K)  // Pakistan
    840     DECLARE_COUNTRY(P, L)  // Poland
    841     DECLARE_COUNTRY(P, R)  // Puerto Rico
    842     DECLARE_COUNTRY(P, T)  // Portugal
    843     DECLARE_COUNTRY(P, Y)  // Paraguay
    844     DECLARE_COUNTRY(Q, A)  // Qatar
    845     DECLARE_COUNTRY(R, O)  // Romania
    846     DECLARE_COUNTRY(R, S)  // Serbia
    847     DECLARE_COUNTRY(R, U)  // Russia
    848     DECLARE_COUNTRY(R, W)  // Rwanda
    849     DECLARE_COUNTRY(S, A)  // Saudi Arabia
    850     DECLARE_COUNTRY(S, E)  // Sweden
    851     DECLARE_COUNTRY(S, G)  // Singapore
    852     DECLARE_COUNTRY(S, I)  // Slovenia
    853     DECLARE_COUNTRY(S, K)  // Slovakia
    854     DECLARE_COUNTRY(S, V)  // El Salvador
    855     DECLARE_COUNTRY(S, Y)  // Syria
    856     DECLARE_COUNTRY(T, H)  // Thailand
    857     DECLARE_COUNTRY(T, N)  // Tunisia
    858     DECLARE_COUNTRY(T, R)  // Turkey
    859     DECLARE_COUNTRY(T, T)  // Trinidad and Tobago
    860     DECLARE_COUNTRY(T, W)  // Taiwan
    861     DECLARE_COUNTRY(T, Z)  // Tanzania
    862     DECLARE_COUNTRY(U, A)  // Ukraine
    863     DECLARE_COUNTRY(U, S)  // United States
    864     DECLARE_COUNTRY(U, Y)  // Uruguay
    865     DECLARE_COUNTRY(V, E)  // Venezuela
    866     DECLARE_COUNTRY(V, N)  // Vietnam
    867     DECLARE_COUNTRY(Y, E)  // Yemen
    868     DECLARE_COUNTRY(Z, A)  // South Africa
    869     DECLARE_COUNTRY(Z, W)  // Zimbabwe
    870 
    871     // Countries using the "Australia" engine set.
    872     UNHANDLED_COUNTRY(C, C)  // Cocos Islands
    873     UNHANDLED_COUNTRY(C, X)  // Christmas Island
    874     UNHANDLED_COUNTRY(H, M)  // Heard Island and McDonald Islands
    875     UNHANDLED_COUNTRY(N, F)  // Norfolk Island
    876     END_UNHANDLED_COUNTRIES(A, U)
    877 
    878     // Countries using the "China" engine set.
    879     UNHANDLED_COUNTRY(M, O)  // Macao
    880     END_UNHANDLED_COUNTRIES(C, N)
    881 
    882     // Countries using the "Denmark" engine set.
    883     UNHANDLED_COUNTRY(G, L)  // Greenland
    884     END_UNHANDLED_COUNTRIES(D, K)
    885 
    886     // Countries using the "Spain" engine set.
    887     UNHANDLED_COUNTRY(A, D)  // Andorra
    888     END_UNHANDLED_COUNTRIES(E, S)
    889 
    890     // Countries using the "Finland" engine set.
    891     UNHANDLED_COUNTRY(A, X)  // Aland Islands
    892     END_UNHANDLED_COUNTRIES(F, I)
    893 
    894     // Countries using the "France" engine set.
    895     UNHANDLED_COUNTRY(B, F)  // Burkina Faso
    896     UNHANDLED_COUNTRY(B, J)  // Benin
    897     UNHANDLED_COUNTRY(C, D)  // Congo - Kinshasa
    898     UNHANDLED_COUNTRY(C, F)  // Central African Republic
    899     UNHANDLED_COUNTRY(C, G)  // Congo - Brazzaville
    900     UNHANDLED_COUNTRY(C, I)  // Ivory Coast
    901     UNHANDLED_COUNTRY(C, M)  // Cameroon
    902     UNHANDLED_COUNTRY(D, J)  // Djibouti
    903     UNHANDLED_COUNTRY(G, A)  // Gabon
    904     UNHANDLED_COUNTRY(G, F)  // French Guiana
    905     UNHANDLED_COUNTRY(G, N)  // Guinea
    906     UNHANDLED_COUNTRY(G, P)  // Guadeloupe
    907     UNHANDLED_COUNTRY(H, T)  // Haiti
    908 #if defined(OS_WIN)
    909     UNHANDLED_COUNTRY(I, P)  // Clipperton Island ('IP' is an WinXP-ism; ISO
    910                              //                    includes it with France)
    911 #endif
    912     UNHANDLED_COUNTRY(M, L)  // Mali
    913     UNHANDLED_COUNTRY(M, Q)  // Martinique
    914     UNHANDLED_COUNTRY(N, C)  // New Caledonia
    915     UNHANDLED_COUNTRY(N, E)  // Niger
    916     UNHANDLED_COUNTRY(P, F)  // French Polynesia
    917     UNHANDLED_COUNTRY(P, M)  // Saint Pierre and Miquelon
    918     UNHANDLED_COUNTRY(R, E)  // Reunion
    919     UNHANDLED_COUNTRY(S, N)  // Senegal
    920     UNHANDLED_COUNTRY(T, D)  // Chad
    921     UNHANDLED_COUNTRY(T, F)  // French Southern Territories
    922     UNHANDLED_COUNTRY(T, G)  // Togo
    923     UNHANDLED_COUNTRY(W, F)  // Wallis and Futuna
    924     UNHANDLED_COUNTRY(Y, T)  // Mayotte
    925     END_UNHANDLED_COUNTRIES(F, R)
    926 
    927     // Countries using the "Greece" engine set.
    928     UNHANDLED_COUNTRY(C, Y)  // Cyprus
    929     END_UNHANDLED_COUNTRIES(G, R)
    930 
    931     // Countries using the "Italy" engine set.
    932     UNHANDLED_COUNTRY(S, M)  // San Marino
    933     UNHANDLED_COUNTRY(V, A)  // Vatican
    934     END_UNHANDLED_COUNTRIES(I, T)
    935 
    936     // Countries using the "Morocco" engine set.
    937     UNHANDLED_COUNTRY(E, H)  // Western Sahara
    938     END_UNHANDLED_COUNTRIES(M, A)
    939 
    940     // Countries using the "Netherlands" engine set.
    941     UNHANDLED_COUNTRY(A, N)  // Netherlands Antilles
    942     UNHANDLED_COUNTRY(A, W)  // Aruba
    943     END_UNHANDLED_COUNTRIES(N, L)
    944 
    945     // Countries using the "Norway" engine set.
    946     UNHANDLED_COUNTRY(B, V)  // Bouvet Island
    947     UNHANDLED_COUNTRY(S, J)  // Svalbard and Jan Mayen
    948     END_UNHANDLED_COUNTRIES(N, O)
    949 
    950     // Countries using the "New Zealand" engine set.
    951     UNHANDLED_COUNTRY(C, K)  // Cook Islands
    952     UNHANDLED_COUNTRY(N, U)  // Niue
    953     UNHANDLED_COUNTRY(T, K)  // Tokelau
    954     END_UNHANDLED_COUNTRIES(N, Z)
    955 
    956     // Countries using the "Portugal" engine set.
    957     UNHANDLED_COUNTRY(C, V)  // Cape Verde
    958     UNHANDLED_COUNTRY(G, W)  // Guinea-Bissau
    959     UNHANDLED_COUNTRY(M, Z)  // Mozambique
    960     UNHANDLED_COUNTRY(S, T)  // Sao Tome and Principe
    961     UNHANDLED_COUNTRY(T, L)  // Timor-Leste
    962     END_UNHANDLED_COUNTRIES(P, T)
    963 
    964     // Countries using the "Russia" engine set.
    965     UNHANDLED_COUNTRY(A, M)  // Armenia
    966     UNHANDLED_COUNTRY(A, Z)  // Azerbaijan
    967     UNHANDLED_COUNTRY(K, G)  // Kyrgyzstan
    968     UNHANDLED_COUNTRY(T, J)  // Tajikistan
    969     UNHANDLED_COUNTRY(T, M)  // Turkmenistan
    970     UNHANDLED_COUNTRY(U, Z)  // Uzbekistan
    971     END_UNHANDLED_COUNTRIES(R, U)
    972 
    973     // Countries using the "Saudi Arabia" engine set.
    974     UNHANDLED_COUNTRY(M, R)  // Mauritania
    975     UNHANDLED_COUNTRY(P, S)  // Palestinian Territory
    976     UNHANDLED_COUNTRY(S, D)  // Sudan
    977     END_UNHANDLED_COUNTRIES(S, A)
    978 
    979     // Countries using the "United Kingdom" engine set.
    980     UNHANDLED_COUNTRY(B, M)  // Bermuda
    981     UNHANDLED_COUNTRY(F, K)  // Falkland Islands
    982     UNHANDLED_COUNTRY(G, G)  // Guernsey
    983     UNHANDLED_COUNTRY(G, I)  // Gibraltar
    984     UNHANDLED_COUNTRY(G, S)  // South Georgia and the South Sandwich
    985                              //   Islands
    986     UNHANDLED_COUNTRY(I, M)  // Isle of Man
    987     UNHANDLED_COUNTRY(I, O)  // British Indian Ocean Territory
    988     UNHANDLED_COUNTRY(J, E)  // Jersey
    989     UNHANDLED_COUNTRY(K, Y)  // Cayman Islands
    990     UNHANDLED_COUNTRY(M, S)  // Montserrat
    991     UNHANDLED_COUNTRY(M, T)  // Malta
    992     UNHANDLED_COUNTRY(P, N)  // Pitcairn Islands
    993     UNHANDLED_COUNTRY(S, H)  // Saint Helena, Ascension Island, and Tristan da
    994                              //   Cunha
    995     UNHANDLED_COUNTRY(T, C)  // Turks and Caicos Islands
    996     UNHANDLED_COUNTRY(V, G)  // British Virgin Islands
    997     END_UNHANDLED_COUNTRIES(G, B)
    998 
    999     // Countries using the "United States" engine set.
   1000     UNHANDLED_COUNTRY(A, S)  // American Samoa
   1001     UNHANDLED_COUNTRY(G, U)  // Guam
   1002     UNHANDLED_COUNTRY(M, P)  // Northern Mariana Islands
   1003     UNHANDLED_COUNTRY(U, M)  // U.S. Minor Outlying Islands
   1004     UNHANDLED_COUNTRY(V, I)  // U.S. Virgin Islands
   1005     END_UNHANDLED_COUNTRIES(U, S)
   1006 
   1007     // Countries using the "default" engine set.
   1008     UNHANDLED_COUNTRY(A, F)  // Afghanistan
   1009     UNHANDLED_COUNTRY(A, G)  // Antigua and Barbuda
   1010     UNHANDLED_COUNTRY(A, I)  // Anguilla
   1011     UNHANDLED_COUNTRY(A, O)  // Angola
   1012     UNHANDLED_COUNTRY(A, Q)  // Antarctica
   1013     UNHANDLED_COUNTRY(B, B)  // Barbados
   1014     UNHANDLED_COUNTRY(B, D)  // Bangladesh
   1015     UNHANDLED_COUNTRY(B, S)  // Bahamas
   1016     UNHANDLED_COUNTRY(B, T)  // Bhutan
   1017     UNHANDLED_COUNTRY(B, W)  // Botswana
   1018     UNHANDLED_COUNTRY(C, U)  // Cuba
   1019     UNHANDLED_COUNTRY(D, M)  // Dominica
   1020     UNHANDLED_COUNTRY(E, R)  // Eritrea
   1021     UNHANDLED_COUNTRY(E, T)  // Ethiopia
   1022     UNHANDLED_COUNTRY(F, J)  // Fiji
   1023     UNHANDLED_COUNTRY(F, M)  // Micronesia
   1024     UNHANDLED_COUNTRY(G, D)  // Grenada
   1025     UNHANDLED_COUNTRY(G, E)  // Georgia
   1026     UNHANDLED_COUNTRY(G, H)  // Ghana
   1027     UNHANDLED_COUNTRY(G, M)  // Gambia
   1028     UNHANDLED_COUNTRY(G, Q)  // Equatorial Guinea
   1029     UNHANDLED_COUNTRY(G, Y)  // Guyana
   1030     UNHANDLED_COUNTRY(K, H)  // Cambodia
   1031     UNHANDLED_COUNTRY(K, I)  // Kiribati
   1032     UNHANDLED_COUNTRY(K, M)  // Comoros
   1033     UNHANDLED_COUNTRY(K, N)  // Saint Kitts and Nevis
   1034     UNHANDLED_COUNTRY(K, P)  // North Korea
   1035     UNHANDLED_COUNTRY(L, A)  // Laos
   1036     UNHANDLED_COUNTRY(L, C)  // Saint Lucia
   1037     UNHANDLED_COUNTRY(L, K)  // Sri Lanka
   1038     UNHANDLED_COUNTRY(L, R)  // Liberia
   1039     UNHANDLED_COUNTRY(L, S)  // Lesotho
   1040     UNHANDLED_COUNTRY(M, G)  // Madagascar
   1041     UNHANDLED_COUNTRY(M, H)  // Marshall Islands
   1042     UNHANDLED_COUNTRY(M, M)  // Myanmar
   1043     UNHANDLED_COUNTRY(M, N)  // Mongolia
   1044     UNHANDLED_COUNTRY(M, U)  // Mauritius
   1045     UNHANDLED_COUNTRY(M, V)  // Maldives
   1046     UNHANDLED_COUNTRY(M, W)  // Malawi
   1047     UNHANDLED_COUNTRY(N, A)  // Namibia
   1048     UNHANDLED_COUNTRY(N, G)  // Nigeria
   1049     UNHANDLED_COUNTRY(N, P)  // Nepal
   1050     UNHANDLED_COUNTRY(N, R)  // Nauru
   1051     UNHANDLED_COUNTRY(P, G)  // Papua New Guinea
   1052     UNHANDLED_COUNTRY(P, W)  // Palau
   1053     UNHANDLED_COUNTRY(S, B)  // Solomon Islands
   1054     UNHANDLED_COUNTRY(S, C)  // Seychelles
   1055     UNHANDLED_COUNTRY(S, L)  // Sierra Leone
   1056     UNHANDLED_COUNTRY(S, O)  // Somalia
   1057     UNHANDLED_COUNTRY(S, R)  // Suriname
   1058     UNHANDLED_COUNTRY(S, Z)  // Swaziland
   1059     UNHANDLED_COUNTRY(T, O)  // Tonga
   1060     UNHANDLED_COUNTRY(T, V)  // Tuvalu
   1061     UNHANDLED_COUNTRY(U, G)  // Uganda
   1062     UNHANDLED_COUNTRY(V, C)  // Saint Vincent and the Grenadines
   1063     UNHANDLED_COUNTRY(V, U)  // Vanuatu
   1064     UNHANDLED_COUNTRY(W, S)  // Samoa
   1065     UNHANDLED_COUNTRY(Z, M)  // Zambia
   1066     case kCountryIDUnknown:
   1067     default:                // Unhandled location
   1068     END_UNHANDLED_COUNTRIES(def, ault)
   1069   }
   1070 }
   1071 
   1072 TemplateURL* MakePrepopulatedTemplateURL(
   1073     Profile* profile,
   1074     const string16& name,
   1075     const string16& keyword,
   1076     const base::StringPiece& search_url,
   1077     const base::StringPiece& suggest_url,
   1078     const base::StringPiece& instant_url,
   1079     const base::StringPiece& image_url,
   1080     const base::StringPiece& search_url_post_params,
   1081     const base::StringPiece& suggest_url_post_params,
   1082     const base::StringPiece& instant_url_post_params,
   1083     const base::StringPiece& image_url_post_params,
   1084     const base::StringPiece& favicon_url,
   1085     const base::StringPiece& encoding,
   1086     const ListValue& alternate_urls,
   1087     const base::StringPiece& search_terms_replacement_key,
   1088     int id) {
   1089 
   1090   TemplateURLData data;
   1091 
   1092   data.short_name = name;
   1093   data.SetKeyword(keyword);
   1094   data.SetURL(search_url.as_string());
   1095   data.suggestions_url = suggest_url.as_string();
   1096   data.instant_url = instant_url.as_string();
   1097   data.image_url = image_url.as_string();
   1098   data.search_url_post_params = search_url_post_params.as_string();
   1099   data.suggestions_url_post_params = suggest_url_post_params.as_string();
   1100   data.instant_url_post_params = instant_url_post_params.as_string();
   1101   data.image_url_post_params = image_url_post_params.as_string();
   1102   data.favicon_url = GURL(favicon_url.as_string());
   1103   data.show_in_default_list = true;
   1104   data.safe_for_autoreplace = true;
   1105   data.input_encodings.push_back(encoding.as_string());
   1106   data.date_created = base::Time();
   1107   data.last_modified = base::Time();
   1108   data.prepopulate_id = id;
   1109   for (size_t i = 0; i < alternate_urls.GetSize(); ++i) {
   1110     std::string alternate_url;
   1111     alternate_urls.GetString(i, &alternate_url);
   1112     DCHECK(!alternate_url.empty());
   1113     data.alternate_urls.push_back(alternate_url);
   1114   }
   1115   data.search_terms_replacement_key = search_terms_replacement_key.as_string();
   1116   return new TemplateURL(profile, data);
   1117 }
   1118 
   1119 void GetPrepopulatedTemplateFromPrefs(Profile* profile,
   1120                                       std::vector<TemplateURL*>* t_urls) {
   1121   if (!profile)
   1122     return;
   1123 
   1124   const ListValue* list =
   1125       profile->GetPrefs()->GetList(prefs::kSearchProviderOverrides);
   1126   if (!list)
   1127     return;
   1128 
   1129   size_t num_engines = list->GetSize();
   1130   for (size_t i = 0; i != num_engines; ++i) {
   1131     const DictionaryValue* engine;
   1132     string16 name;
   1133     string16 keyword;
   1134     std::string search_url;
   1135     std::string favicon_url;
   1136     std::string encoding;
   1137     int id;
   1138     // The following fields are required for each search engine configuration.
   1139     if (list->GetDictionary(i, &engine) &&
   1140         engine->GetString("name", &name) && !name.empty() &&
   1141         engine->GetString("keyword", &keyword) && !keyword.empty() &&
   1142         engine->GetString("search_url", &search_url) && !search_url.empty() &&
   1143         engine->GetString("favicon_url", &favicon_url) &&
   1144         !favicon_url.empty() &&
   1145         engine->GetString("encoding", &encoding) && !encoding.empty() &&
   1146         engine->GetInteger("id", &id)) {
   1147       // These fields are optional.
   1148       std::string suggest_url;
   1149       std::string instant_url;
   1150       std::string image_url;
   1151       std::string search_url_post_params;
   1152       std::string suggest_url_post_params;
   1153       std::string instant_url_post_params;
   1154       std::string image_url_post_params;
   1155       ListValue empty_list;
   1156       const ListValue* alternate_urls = &empty_list;
   1157       std::string search_terms_replacement_key;
   1158       engine->GetString("suggest_url", &suggest_url);
   1159       engine->GetString("instant_url", &instant_url);
   1160       engine->GetString("image_url", &image_url);
   1161       engine->GetString("search_url_post_params", &search_url_post_params);
   1162       engine->GetString("suggest_url_post_params", &suggest_url_post_params);
   1163       engine->GetString("instant_url_post_params", &instant_url_post_params);
   1164       engine->GetString("image_url_post_params", &image_url_post_params);
   1165       engine->GetList("alternate_urls", &alternate_urls);
   1166       engine->GetString("search_terms_replacement_key",
   1167           &search_terms_replacement_key);
   1168       t_urls->push_back(MakePrepopulatedTemplateURL(profile, name, keyword,
   1169           search_url, suggest_url, instant_url, image_url,
   1170           search_url_post_params, suggest_url_post_params,
   1171           instant_url_post_params, image_url_post_params,
   1172           favicon_url, encoding, *alternate_urls, search_terms_replacement_key,
   1173           id));
   1174     }
   1175   }
   1176 }
   1177 
   1178 // The caller owns the returned TemplateURL.
   1179 TemplateURL* MakePrepopulatedTemplateURLFromPrepopulateEngine(
   1180     Profile* profile,
   1181     const PrepopulatedEngine& engine) {
   1182 
   1183   ListValue alternate_urls;
   1184   if (engine.alternate_urls) {
   1185     for (size_t i = 0; i < engine.alternate_urls_size; ++i)
   1186       alternate_urls.AppendString(std::string(engine.alternate_urls[i]));
   1187   }
   1188 
   1189   return MakePrepopulatedTemplateURL(profile, WideToUTF16(engine.name),
   1190       WideToUTF16(engine.keyword), engine.search_url, engine.suggest_url,
   1191       engine.instant_url, engine.image_url, engine.search_url_post_params,
   1192       engine.suggest_url_post_params, engine.instant_url_post_params,
   1193       engine.image_url_post_params, engine.favicon_url, engine.encoding,
   1194       alternate_urls, engine.search_terms_replacement_key, engine.id);
   1195 }
   1196 
   1197 bool SameDomain(const GURL& given_url, const GURL& prepopulated_url) {
   1198   return prepopulated_url.is_valid() &&
   1199       net::registry_controlled_domains::SameDomainOrHost(
   1200           given_url, prepopulated_url,
   1201           net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
   1202 }
   1203 
   1204 }  // namespace
   1205 
   1206 
   1207 // Global functions -----------------------------------------------------------
   1208 
   1209 #if defined(OS_ANDROID)
   1210 void InitCountryCode(const std::string& country_code) {
   1211   if (country_code.size() != 2) {
   1212     DLOG(ERROR) << "Invalid country code: " << country_code;
   1213     g_country_code_at_install = kCountryIDUnknown;
   1214   } else {
   1215     g_country_code_at_install =
   1216         CountryCharsToCountryIDWithUpdate(country_code[0], country_code[1]);
   1217   }
   1218 }
   1219 #endif
   1220 
   1221 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   1222   registry->RegisterIntegerPref(
   1223       prefs::kCountryIDAtInstall,
   1224       kCountryIDUnknown,
   1225       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   1226   registry->RegisterListPref(prefs::kSearchProviderOverrides,
   1227                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   1228   registry->RegisterIntegerPref(
   1229       prefs::kSearchProviderOverridesVersion,
   1230       -1,
   1231       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   1232   // Obsolete pref, for migration.
   1233   registry->RegisterIntegerPref(
   1234       prefs::kGeoIDAtInstall,
   1235       -1,
   1236       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   1237 }
   1238 
   1239 int GetDataVersion(PrefService* prefs) {
   1240   // Allow tests to override the local version.
   1241   return (prefs && prefs->HasPrefPath(prefs::kSearchProviderOverridesVersion)) ?
   1242       prefs->GetInteger(prefs::kSearchProviderOverridesVersion) :
   1243       kCurrentDataVersion;
   1244 }
   1245 
   1246 void GetPrepopulatedEngines(Profile* profile,
   1247                             std::vector<TemplateURL*>* t_urls,
   1248                             size_t* default_search_provider_index) {
   1249   // If there is a set of search engines in the preferences file, it overrides
   1250   // the built-in set.
   1251   *default_search_provider_index = 0;
   1252   GetPrepopulatedTemplateFromPrefs(profile, t_urls);
   1253   if (!t_urls->empty())
   1254     return;
   1255 
   1256   const PrepopulatedEngine** engines;
   1257   size_t num_engines;
   1258   GetPrepopulationSetFromCountryID(profile ? profile->GetPrefs() : NULL,
   1259                                    &engines, &num_engines);
   1260   for (size_t i = 0; i != num_engines; ++i) {
   1261     t_urls->push_back(
   1262         MakePrepopulatedTemplateURLFromPrepopulateEngine(profile, *engines[i]));
   1263   }
   1264 }
   1265 
   1266 void ClearPrepopulatedEnginesInPrefs(Profile* profile) {
   1267   if (!profile)
   1268     return;
   1269 
   1270   PrefService* prefs = profile->GetPrefs();
   1271   DCHECK(prefs);
   1272   prefs->ClearPref(prefs::kSearchProviderOverrides);
   1273   prefs->ClearPref(prefs::kSearchProviderOverridesVersion);
   1274 }
   1275 
   1276 TemplateURL* GetPrepopulatedDefaultSearch(Profile* profile) {
   1277   TemplateURL* default_search_provider = NULL;
   1278   ScopedVector<TemplateURL> loaded_urls;
   1279   size_t default_search_index;
   1280   // This could be more efficient.  We are loading all the URLs to only keep
   1281   // the first one.
   1282   GetPrepopulatedEngines(profile, &loaded_urls.get(), &default_search_index);
   1283   if (default_search_index < loaded_urls.size()) {
   1284     default_search_provider = loaded_urls[default_search_index];
   1285     loaded_urls.weak_erase(loaded_urls.begin() + default_search_index);
   1286   }
   1287   return default_search_provider;
   1288 }
   1289 
   1290 SearchEngineType GetEngineType(const TemplateURL& url) {
   1291   // Restricted to UI thread because ReplaceSearchTerms() is so restricted.
   1292   using content::BrowserThread;
   1293   DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
   1294          BrowserThread::CurrentlyOn(BrowserThread::UI));
   1295 
   1296   // By calling ReplaceSearchTerms, we ensure that even TemplateURLs whose URLs
   1297   // can't be directly inspected (e.g. due to containing {google:baseURL}) can
   1298   // be converted to GURLs we can look at.
   1299   GURL gurl(url.url_ref().ReplaceSearchTerms(TemplateURLRef::SearchTermsArgs(
   1300       ASCIIToUTF16("x"))));
   1301   return gurl.is_valid() ? GetEngineType(gurl) : SEARCH_ENGINE_OTHER;
   1302 }
   1303 
   1304 SearchEngineType GetEngineType(const GURL& url) {
   1305   DCHECK(url.is_valid());
   1306 
   1307   // Check using TLD+1s, in order to more aggressively match search engine types
   1308   // for data imported from other browsers.
   1309   //
   1310   // First special-case Google, because the prepopulate URL for it will not
   1311   // convert to a GURL and thus won't have an origin.  Instead see if the
   1312   // incoming URL's host is "[*.]google.<TLD>".
   1313   if (google_util::IsGoogleHostname(url.host(),
   1314                                     google_util::DISALLOW_SUBDOMAIN))
   1315     return google.type;
   1316 
   1317   // Now check the rest of the prepopulate data.
   1318   for (size_t i = 0; i < arraysize(kAllEngines); ++i) {
   1319     // First check the main search URL.
   1320     if (SameDomain(url, GURL(kAllEngines[i]->search_url)))
   1321       return kAllEngines[i]->type;
   1322 
   1323     // Then check the alternate URLs.
   1324     for (size_t j = 0; j < kAllEngines[i]->alternate_urls_size; ++j) {
   1325       if (SameDomain(url, GURL(kAllEngines[i]->alternate_urls[j])))
   1326         return kAllEngines[i]->type;
   1327     }
   1328   }
   1329 
   1330   return SEARCH_ENGINE_OTHER;
   1331 }
   1332 
   1333 GURL GetLogoURL(const TemplateURL& template_url, LogoSize size) {
   1334   if (GetEngineType(template_url) != SEARCH_ENGINE_GOOGLE)
   1335     return GURL();
   1336   return GURL((size == LOGO_200_PERCENT) ?
   1337       google_logos.logo_200_percent_url : google_logos.logo_100_percent_url);
   1338 }
   1339 
   1340 }  // namespace TemplateURLPrepopulateData
   1341