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