Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file defines specific implementation of BrowserDistribution class for | 5 // This file defines specific implementation of BrowserDistribution class for |
| 6 // Google Chrome. | 6 // Google Chrome. |
| 7 | 7 |
| 8 #include "chrome/installer/util/google_chrome_distribution.h" | 8 #include "chrome/installer/util/google_chrome_distribution.h" |
| 9 | 9 |
| 10 #include <windows.h> | 10 #include <windows.h> |
| 11 #include <wtsapi32.h> | 11 #include <wtsapi32.h> |
| 12 #include <msi.h> | 12 #include <msi.h> |
| 13 #include <sddl.h> | 13 #include <sddl.h> |
| 14 | 14 |
|
grt (UTC plus 2)
2012/04/29 02:08:50
looks like this file has been missing a #include <
gab
2012/04/30 12:37:25
Done.
| |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/file_path.h" | 16 #include "base/file_path.h" |
| 17 #include "base/json/json_file_value_serializer.h" | 17 #include "base/json/json_file_value_serializer.h" |
| 18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/process_util.h" | 20 #include "base/process_util.h" |
| 21 #include "base/rand_util.h" | 21 #include "base/rand_util.h" |
| 22 #include "base/string_number_conversions.h" | 22 #include "base/string_number_conversions.h" |
| 23 #include "base/string_split.h" | 23 #include "base/string_split.h" |
| 24 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 const wchar_t kToastExpUninstallGroup[] = L"04"; | 64 const wchar_t kToastExpUninstallGroup[] = L"04"; |
| 65 const wchar_t kToastExpTriesOkGroup[] = L"18"; | 65 const wchar_t kToastExpTriesOkGroup[] = L"18"; |
| 66 const wchar_t kToastExpTriesErrorGroup[] = L"28"; | 66 const wchar_t kToastExpTriesErrorGroup[] = L"28"; |
| 67 const wchar_t kToastActiveGroup[] = L"40"; | 67 const wchar_t kToastActiveGroup[] = L"40"; |
| 68 const wchar_t kToastUDDirFailure[] = L"40"; | 68 const wchar_t kToastUDDirFailure[] = L"40"; |
| 69 const wchar_t kToastExpBaseGroup[] = L"80"; | 69 const wchar_t kToastExpBaseGroup[] = L"80"; |
| 70 | 70 |
| 71 // Substitute the locale parameter in uninstall URL with whatever | 71 // Substitute the locale parameter in uninstall URL with whatever |
| 72 // Google Update tells us is the locale. In case we fail to find | 72 // Google Update tells us is the locale. In case we fail to find |
| 73 // the locale, we use US English. | 73 // the locale, we use US English. |
| 74 std::wstring LocalizeUrl(const wchar_t* url) { | 74 string16 LocalizeUrl(const wchar_t* url) { |
| 75 std::wstring language; | 75 string16 language; |
| 76 if (!GoogleUpdateSettings::GetLanguage(&language)) | 76 if (!GoogleUpdateSettings::GetLanguage(&language)) |
| 77 language = L"en-US"; // Default to US English. | 77 language = L"en-US"; // Default to US English. |
| 78 return ReplaceStringPlaceholders(url, language.c_str(), NULL); | 78 return ReplaceStringPlaceholders(url, language.c_str(), NULL); |
| 79 } | 79 } |
| 80 | 80 |
| 81 std::wstring GetUninstallSurveyUrl() { | 81 string16 GetUninstallSurveyUrl() { |
| 82 const wchar_t kSurveyUrl[] = L"http://www.google.com/support/chrome/bin/" | 82 const wchar_t kSurveyUrl[] = L"http://www.google.com/support/chrome/bin/" |
| 83 L"request.py?hl=$1&contact_type=uninstall"; | 83 L"request.py?hl=$1&contact_type=uninstall"; |
| 84 return LocalizeUrl(kSurveyUrl); | 84 return LocalizeUrl(kSurveyUrl); |
| 85 } | 85 } |
| 86 | 86 |
| 87 std::wstring GetWelcomeBackUrl() { | 87 string16 GetWelcomeBackUrl() { |
| 88 const wchar_t kWelcomeUrl[] = L"http://www.google.com/chrome/intl/$1/" | 88 const wchar_t kWelcomeUrl[] = L"http://www.google.com/chrome/intl/$1/" |
| 89 L"welcomeback-new.html"; | 89 L"welcomeback-new.html"; |
| 90 return LocalizeUrl(kWelcomeUrl); | 90 return LocalizeUrl(kWelcomeUrl); |
| 91 } | 91 } |
| 92 | 92 |
| 93 // Converts FILETIME to hours. FILETIME times are absolute times in | 93 // Converts FILETIME to hours. FILETIME times are absolute times in |
| 94 // 100 nanosecond units. For example 5:30 pm of June 15, 2009 is 3580464. | 94 // 100 nanosecond units. For example 5:30 pm of June 15, 2009 is 3580464. |
| 95 int FileTimeToHours(const FILETIME& time) { | 95 int FileTimeToHours(const FILETIME& time) { |
| 96 const ULONGLONG k100sNanoSecsToHours = 10000000LL * 60 * 60; | 96 const ULONGLONG k100sNanoSecsToHours = 10000000LL * 60 * 60; |
| 97 ULARGE_INTEGER uli = {time.dwLowDateTime, time.dwHighDateTime}; | 97 ULARGE_INTEGER uli = {time.dwLowDateTime, time.dwHighDateTime}; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 DWORD len = sizeof(buff); | 189 DWORD len = sizeof(buff); |
| 190 PSECURITY_DESCRIPTOR sd = reinterpret_cast<PSECURITY_DESCRIPTOR>(buff); | 190 PSECURITY_DESCRIPTOR sd = reinterpret_cast<PSECURITY_DESCRIPTOR>(buff); |
| 191 if (!::GetFileSecurityW(exe.value().c_str(), DACL_SECURITY_INFORMATION, | 191 if (!::GetFileSecurityW(exe.value().c_str(), DACL_SECURITY_INFORMATION, |
| 192 sd, len, &len)) { | 192 sd, len, &len)) { |
| 193 return false; | 193 return false; |
| 194 } | 194 } |
| 195 wchar_t* sddl = 0; | 195 wchar_t* sddl = 0; |
| 196 if (!::ConvertSecurityDescriptorToStringSecurityDescriptorW(sd, | 196 if (!::ConvertSecurityDescriptorToStringSecurityDescriptorW(sd, |
| 197 SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &sddl, NULL)) | 197 SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &sddl, NULL)) |
| 198 return false; | 198 return false; |
| 199 std::wstring new_sddl(sddl); | 199 string16 new_sddl(sddl); |
| 200 ::LocalFree(sddl); | 200 ::LocalFree(sddl); |
| 201 sd = NULL; | 201 sd = NULL; |
| 202 // See MSDN for the security descriptor definition language (SDDL) syntax, | 202 // See MSDN for the security descriptor definition language (SDDL) syntax, |
| 203 // in our case we add "A;" generic read 'GR' and generic execute 'GX' for | 203 // in our case we add "A;" generic read 'GR' and generic execute 'GX' for |
| 204 // the nt\authenticated_users 'AU' group, that becomes: | 204 // the nt\authenticated_users 'AU' group, that becomes: |
| 205 const wchar_t kAllowACE[] = L"(A;;GRGX;;;AU)"; | 205 const wchar_t kAllowACE[] = L"(A;;GRGX;;;AU)"; |
| 206 // We should check that there are no special ACES for the group we | 206 // We should check that there are no special ACES for the group we |
| 207 // are interested, which is nt\authenticated_users. | 207 // are interested, which is nt\authenticated_users. |
| 208 if (std::wstring::npos != new_sddl.find(L";AU)")) | 208 if (string16::npos != new_sddl.find(L";AU)")) |
| 209 return false; | 209 return false; |
| 210 // Specific ACEs (not inherited) need to go to the front. It is ok if we | 210 // Specific ACEs (not inherited) need to go to the front. It is ok if we |
| 211 // are the very first one. | 211 // are the very first one. |
| 212 size_t pos_insert = new_sddl.find(L"("); | 212 size_t pos_insert = new_sddl.find(L"("); |
| 213 if (std::wstring::npos == pos_insert) | 213 if (string16::npos == pos_insert) |
| 214 return false; | 214 return false; |
| 215 // All good, time to change the dacl. | 215 // All good, time to change the dacl. |
| 216 new_sddl.insert(pos_insert, kAllowACE); | 216 new_sddl.insert(pos_insert, kAllowACE); |
| 217 if (!::ConvertStringSecurityDescriptorToSecurityDescriptorW(new_sddl.c_str(), | 217 if (!::ConvertStringSecurityDescriptorToSecurityDescriptorW(new_sddl.c_str(), |
| 218 SDDL_REVISION_1, &sd, NULL)) | 218 SDDL_REVISION_1, &sd, NULL)) |
| 219 return false; | 219 return false; |
| 220 bool rv = ::SetFileSecurityW(exe.value().c_str(), DACL_SECURITY_INFORMATION, | 220 bool rv = ::SetFileSecurityW(exe.value().c_str(), DACL_SECURITY_INFORMATION, |
| 221 sd) == TRUE; | 221 sd) == TRUE; |
| 222 ::LocalFree(sd); | 222 ::LocalFree(sd); |
| 223 return rv; | 223 return rv; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 | 290 |
| 291 GoogleChromeDistribution::GoogleChromeDistribution() | 291 GoogleChromeDistribution::GoogleChromeDistribution() |
| 292 : BrowserDistribution(CHROME_BROWSER), | 292 : BrowserDistribution(CHROME_BROWSER), |
| 293 product_guid_(kChromeGuid) { | 293 product_guid_(kChromeGuid) { |
| 294 } | 294 } |
| 295 | 295 |
| 296 // The functions below are not used by the 64-bit Windows binary - | 296 // The functions below are not used by the 64-bit Windows binary - |
| 297 // see the comment in google_chrome_distribution_dummy.cc | 297 // see the comment in google_chrome_distribution_dummy.cc |
| 298 #ifndef _WIN64 | 298 #ifndef _WIN64 |
| 299 bool GoogleChromeDistribution::BuildUninstallMetricsString( | 299 bool GoogleChromeDistribution::BuildUninstallMetricsString( |
| 300 DictionaryValue* uninstall_metrics_dict, std::wstring* metrics) { | 300 DictionaryValue* uninstall_metrics_dict, string16* metrics) { |
| 301 DCHECK(NULL != metrics); | 301 DCHECK(NULL != metrics); |
| 302 bool has_values = false; | 302 bool has_values = false; |
| 303 | 303 |
| 304 for (DictionaryValue::key_iterator iter(uninstall_metrics_dict->begin_keys()); | 304 for (DictionaryValue::key_iterator iter(uninstall_metrics_dict->begin_keys()); |
| 305 iter != uninstall_metrics_dict->end_keys(); ++iter) { | 305 iter != uninstall_metrics_dict->end_keys(); ++iter) { |
| 306 has_values = true; | 306 has_values = true; |
| 307 metrics->append(L"&"); | 307 metrics->append(L"&"); |
| 308 metrics->append(UTF8ToWide(*iter)); | 308 metrics->append(UTF8ToWide(*iter)); |
| 309 metrics->append(L"="); | 309 metrics->append(L"="); |
| 310 | 310 |
| 311 std::string value; | 311 std::string value; |
| 312 uninstall_metrics_dict->GetStringWithoutPathExpansion(*iter, &value); | 312 uninstall_metrics_dict->GetStringWithoutPathExpansion(*iter, &value); |
| 313 metrics->append(UTF8ToWide(value)); | 313 metrics->append(UTF8ToWide(value)); |
| 314 } | 314 } |
| 315 | 315 |
| 316 return has_values; | 316 return has_values; |
| 317 } | 317 } |
| 318 | 318 |
| 319 bool GoogleChromeDistribution::ExtractUninstallMetricsFromFile( | 319 bool GoogleChromeDistribution::ExtractUninstallMetricsFromFile( |
| 320 const FilePath& file_path, | 320 const FilePath& file_path, |
| 321 std::wstring* uninstall_metrics_string) { | 321 string16* uninstall_metrics_string) { |
| 322 JSONFileValueSerializer json_serializer(file_path); | 322 JSONFileValueSerializer json_serializer(file_path); |
| 323 | 323 |
| 324 std::string json_error_string; | 324 std::string json_error_string; |
| 325 scoped_ptr<Value> root(json_serializer.Deserialize(NULL, NULL)); | 325 scoped_ptr<Value> root(json_serializer.Deserialize(NULL, NULL)); |
| 326 if (!root.get()) | 326 if (!root.get()) |
| 327 return false; | 327 return false; |
| 328 | 328 |
| 329 // Preferences should always have a dictionary root. | 329 // Preferences should always have a dictionary root. |
| 330 if (!root->IsType(Value::TYPE_DICTIONARY)) | 330 if (!root->IsType(Value::TYPE_DICTIONARY)) |
| 331 return false; | 331 return false; |
| 332 | 332 |
| 333 return ExtractUninstallMetrics(*static_cast<DictionaryValue*>(root.get()), | 333 return ExtractUninstallMetrics(*static_cast<DictionaryValue*>(root.get()), |
| 334 uninstall_metrics_string); | 334 uninstall_metrics_string); |
| 335 } | 335 } |
| 336 | 336 |
| 337 bool GoogleChromeDistribution::ExtractUninstallMetrics( | 337 bool GoogleChromeDistribution::ExtractUninstallMetrics( |
| 338 const DictionaryValue& root, std::wstring* uninstall_metrics_string) { | 338 const DictionaryValue& root, |
| 339 string16* uninstall_metrics_string) { | |
| 339 // Make sure that the user wants us reporting metrics. If not, don't | 340 // Make sure that the user wants us reporting metrics. If not, don't |
| 340 // add our uninstall metrics. | 341 // add our uninstall metrics. |
| 341 bool metrics_reporting_enabled = false; | 342 bool metrics_reporting_enabled = false; |
| 342 if (!root.GetBoolean(prefs::kMetricsReportingEnabled, | 343 if (!root.GetBoolean(prefs::kMetricsReportingEnabled, |
| 343 &metrics_reporting_enabled) || | 344 &metrics_reporting_enabled) || |
| 344 !metrics_reporting_enabled) { | 345 !metrics_reporting_enabled) { |
| 345 return false; | 346 return false; |
| 346 } | 347 } |
| 347 | 348 |
| 348 DictionaryValue* uninstall_metrics_dict; | 349 DictionaryValue* uninstall_metrics_dict; |
| 349 if (!root.HasKey(installer::kUninstallMetricsName) || | 350 if (!root.HasKey(installer::kUninstallMetricsName) || |
| 350 !root.GetDictionary(installer::kUninstallMetricsName, | 351 !root.GetDictionary(installer::kUninstallMetricsName, |
| 351 &uninstall_metrics_dict)) { | 352 &uninstall_metrics_dict)) { |
| 352 return false; | 353 return false; |
| 353 } | 354 } |
| 354 | 355 |
| 355 if (!BuildUninstallMetricsString(uninstall_metrics_dict, | 356 if (!BuildUninstallMetricsString(uninstall_metrics_dict, |
| 356 uninstall_metrics_string)) { | 357 uninstall_metrics_string)) { |
| 357 return false; | 358 return false; |
| 358 } | 359 } |
| 359 | 360 |
| 360 return true; | 361 return true; |
| 361 } | 362 } |
| 362 #endif | 363 #endif |
| 363 | 364 |
| 364 void GoogleChromeDistribution::DoPostUninstallOperations( | 365 void GoogleChromeDistribution::DoPostUninstallOperations( |
| 365 const Version& version, | 366 const Version& version, |
| 366 const FilePath& local_data_path, | 367 const FilePath& local_data_path, |
| 367 const std::wstring& distribution_data) { | 368 const string16& distribution_data) { |
| 368 // Send the Chrome version and OS version as params to the form. | 369 // Send the Chrome version and OS version as params to the form. |
| 369 // It would be nice to send the locale, too, but I don't see an | 370 // It would be nice to send the locale, too, but I don't see an |
| 370 // easy way to get that in the existing code. It's something we | 371 // easy way to get that in the existing code. It's something we |
| 371 // can add later, if needed. | 372 // can add later, if needed. |
| 372 // We depend on installed_version.GetString() not having spaces or other | 373 // We depend on installed_version.GetString() not having spaces or other |
| 373 // characters that need escaping: 0.2.13.4. Should that change, we will | 374 // characters that need escaping: 0.2.13.4. Should that change, we will |
| 374 // need to escape the string before using it in a URL. | 375 // need to escape the string before using it in a URL. |
| 375 const std::wstring kVersionParam = L"crversion"; | 376 const string16 kVersionParam = L"crversion"; |
| 376 const std::wstring kOSParam = L"os"; | 377 const string16 kOSParam = L"os"; |
| 377 base::win::OSInfo::VersionNumber version_number = | 378 base::win::OSInfo::VersionNumber version_number = |
| 378 base::win::OSInfo::GetInstance()->version_number(); | 379 base::win::OSInfo::GetInstance()->version_number(); |
| 379 std::wstring os_version = base::StringPrintf(L"%d.%d.%d", | 380 string16 os_version = base::StringPrintf(L"%d.%d.%d", |
| 380 version_number.major, version_number.minor, version_number.build); | 381 version_number.major, version_number.minor, version_number.build); |
| 381 | 382 |
| 382 FilePath iexplore; | 383 FilePath iexplore; |
| 383 if (!PathService::Get(base::DIR_PROGRAM_FILES, &iexplore)) | 384 if (!PathService::Get(base::DIR_PROGRAM_FILES, &iexplore)) |
| 384 return; | 385 return; |
| 385 | 386 |
| 386 iexplore = iexplore.AppendASCII("Internet Explorer"); | 387 iexplore = iexplore.AppendASCII("Internet Explorer"); |
| 387 iexplore = iexplore.AppendASCII("iexplore.exe"); | 388 iexplore = iexplore.AppendASCII("iexplore.exe"); |
| 388 | 389 |
| 389 std::wstring command = iexplore.value() + L" " + GetUninstallSurveyUrl() + | 390 string16 command = iexplore.value() + L" " + GetUninstallSurveyUrl() + |
| 390 L"&" + kVersionParam + L"=" + UTF8ToWide(version.GetString()) + L"&" + | 391 L"&" + kVersionParam + L"=" + UTF8ToWide(version.GetString()) + L"&" + |
| 391 kOSParam + L"=" + os_version; | 392 kOSParam + L"=" + os_version; |
| 392 | 393 |
| 393 std::wstring uninstall_metrics; | 394 string16 uninstall_metrics; |
| 394 if (ExtractUninstallMetricsFromFile(local_data_path, &uninstall_metrics)) { | 395 if (ExtractUninstallMetricsFromFile(local_data_path, &uninstall_metrics)) { |
| 395 // The user has opted into anonymous usage data collection, so append | 396 // The user has opted into anonymous usage data collection, so append |
| 396 // metrics and distribution data. | 397 // metrics and distribution data. |
| 397 command += uninstall_metrics; | 398 command += uninstall_metrics; |
| 398 if (!distribution_data.empty()) { | 399 if (!distribution_data.empty()) { |
| 399 command += L"&"; | 400 command += L"&"; |
| 400 command += distribution_data; | 401 command += distribution_data; |
| 401 } | 402 } |
| 402 } | 403 } |
| 403 | 404 |
| 404 int pid = 0; | 405 int pid = 0; |
| 405 // The reason we use WMI to launch the process is because the uninstall | 406 // The reason we use WMI to launch the process is because the uninstall |
| 406 // process runs inside a Job object controlled by the shell. As long as there | 407 // process runs inside a Job object controlled by the shell. As long as there |
| 407 // are processes running, the shell will not close the uninstall applet. WMI | 408 // are processes running, the shell will not close the uninstall applet. WMI |
| 408 // allows us to escape from the Job object so the applet will close. | 409 // allows us to escape from the Job object so the applet will close. |
| 409 installer::WMIProcess::Launch(command, &pid); | 410 installer::WMIProcess::Launch(command, &pid); |
| 410 } | 411 } |
| 411 | 412 |
| 412 std::wstring GoogleChromeDistribution::GetAppGuid() { | 413 string16 GoogleChromeDistribution::GetAppGuid() { |
| 413 return product_guid(); | 414 return product_guid(); |
| 414 } | 415 } |
| 415 | 416 |
| 416 std::wstring GoogleChromeDistribution::GetApplicationName() { | 417 string16 GoogleChromeDistribution::GetApplicationName() { |
| 417 // I'd really like to return L ## PRODUCT_FULLNAME_STRING; but that's no good | 418 // I'd really like to return L ## PRODUCT_FULLNAME_STRING; but that's no good |
| 418 // since it'd be "Chromium" in a non-Chrome build, which isn't at all what I | 419 // since it'd be "Chromium" in a non-Chrome build, which isn't at all what I |
| 419 // want. Sigh. | 420 // want. Sigh. |
| 420 return L"Google Chrome"; | 421 return L"Google Chrome"; |
| 421 } | 422 } |
| 422 | 423 |
| 423 std::wstring GoogleChromeDistribution::GetAlternateApplicationName() { | 424 string16 GoogleChromeDistribution::GetAppShortCutName() { |
| 424 const std::wstring& alt_product_name = | 425 const string16& app_shortcut_name = |
| 426 installer::GetLocalizedString(IDS_PRODUCT_NAME_BASE); | |
| 427 return app_shortcut_name; | |
| 428 } | |
| 429 | |
| 430 string16 GoogleChromeDistribution::GetAlternateApplicationName() { | |
| 431 const string16& alt_product_name = | |
| 425 installer::GetLocalizedString(IDS_OEM_MAIN_SHORTCUT_NAME_BASE); | 432 installer::GetLocalizedString(IDS_OEM_MAIN_SHORTCUT_NAME_BASE); |
| 426 return alt_product_name; | 433 return alt_product_name; |
| 427 } | 434 } |
| 428 | 435 |
| 429 std::wstring GoogleChromeDistribution::GetBrowserAppId() { | 436 string16 GoogleChromeDistribution::GetBrowserAppId() { |
| 430 return kBrowserAppId; | 437 return kBrowserAppId; |
| 431 } | 438 } |
| 432 | 439 |
| 433 std::wstring GoogleChromeDistribution::GetInstallSubDir() { | 440 string16 GoogleChromeDistribution::GetInstallSubDir() { |
| 434 std::wstring sub_dir(installer::kGoogleChromeInstallSubDir1); | 441 string16 sub_dir(installer::kGoogleChromeInstallSubDir1); |
| 435 sub_dir.append(L"\\"); | 442 sub_dir.append(L"\\"); |
| 436 sub_dir.append(installer::kGoogleChromeInstallSubDir2); | 443 sub_dir.append(installer::kGoogleChromeInstallSubDir2); |
| 437 return sub_dir; | 444 return sub_dir; |
| 438 } | 445 } |
| 439 | 446 |
| 440 std::wstring GoogleChromeDistribution::GetPublisherName() { | 447 string16 GoogleChromeDistribution::GetPublisherName() { |
| 441 const std::wstring& publisher_name = | 448 const string16& publisher_name = |
| 442 installer::GetLocalizedString(IDS_ABOUT_VERSION_COMPANY_NAME_BASE); | 449 installer::GetLocalizedString(IDS_ABOUT_VERSION_COMPANY_NAME_BASE); |
| 443 return publisher_name; | 450 return publisher_name; |
| 444 } | 451 } |
| 445 | 452 |
| 446 std::wstring GoogleChromeDistribution::GetAppDescription() { | 453 string16 GoogleChromeDistribution::GetAppDescription() { |
| 447 const std::wstring& app_description = | 454 const string16& app_description = |
| 448 installer::GetLocalizedString(IDS_SHORTCUT_TOOLTIP_BASE); | 455 installer::GetLocalizedString(IDS_SHORTCUT_TOOLTIP_BASE); |
| 449 return app_description; | 456 return app_description; |
| 450 } | 457 } |
| 451 | 458 |
| 452 std::string GoogleChromeDistribution::GetSafeBrowsingName() { | 459 std::string GoogleChromeDistribution::GetSafeBrowsingName() { |
| 453 return "googlechrome"; | 460 return "googlechrome"; |
| 454 } | 461 } |
| 455 | 462 |
| 456 std::wstring GoogleChromeDistribution::GetStateKey() { | 463 string16 GoogleChromeDistribution::GetStateKey() { |
| 457 std::wstring key(google_update::kRegPathClientState); | 464 string16 key(google_update::kRegPathClientState); |
| 458 key.append(L"\\"); | 465 key.append(L"\\"); |
| 459 key.append(product_guid()); | 466 key.append(product_guid()); |
| 460 return key; | 467 return key; |
| 461 } | 468 } |
| 462 | 469 |
| 463 std::wstring GoogleChromeDistribution::GetStateMediumKey() { | 470 string16 GoogleChromeDistribution::GetStateMediumKey() { |
| 464 std::wstring key(google_update::kRegPathClientStateMedium); | 471 string16 key(google_update::kRegPathClientStateMedium); |
| 465 key.append(L"\\"); | 472 key.append(L"\\"); |
| 466 key.append(product_guid()); | 473 key.append(product_guid()); |
| 467 return key; | 474 return key; |
| 468 } | 475 } |
| 469 | 476 |
| 470 std::wstring GoogleChromeDistribution::GetStatsServerURL() { | 477 string16 GoogleChromeDistribution::GetStatsServerURL() { |
| 471 return L"https://clients4.google.com/firefox/metrics/collect"; | 478 return L"https://clients4.google.com/firefox/metrics/collect"; |
| 472 } | 479 } |
| 473 | 480 |
| 474 std::string GoogleChromeDistribution::GetNetworkStatsServer() const { | 481 std::string GoogleChromeDistribution::GetNetworkStatsServer() const { |
| 475 return chrome_common_net::kEchoTestServerLocation; | 482 return chrome_common_net::kEchoTestServerLocation; |
| 476 } | 483 } |
| 477 | 484 |
| 478 std::string GoogleChromeDistribution::GetHttpPipeliningTestServer() const { | 485 std::string GoogleChromeDistribution::GetHttpPipeliningTestServer() const { |
| 479 return chrome_common_net::kPipelineTestServerBaseUrl; | 486 return chrome_common_net::kPipelineTestServerBaseUrl; |
| 480 } | 487 } |
| 481 | 488 |
| 482 std::wstring GoogleChromeDistribution::GetDistributionData(HKEY root_key) { | 489 string16 GoogleChromeDistribution::GetDistributionData(HKEY root_key) { |
| 483 std::wstring sub_key(google_update::kRegPathClientState); | 490 string16 sub_key(google_update::kRegPathClientState); |
| 484 sub_key.append(L"\\"); | 491 sub_key.append(L"\\"); |
| 485 sub_key.append(product_guid()); | 492 sub_key.append(product_guid()); |
| 486 | 493 |
| 487 base::win::RegKey client_state_key(root_key, sub_key.c_str(), KEY_READ); | 494 base::win::RegKey client_state_key(root_key, sub_key.c_str(), KEY_READ); |
| 488 std::wstring result; | 495 string16 result; |
| 489 std::wstring brand_value; | 496 string16 brand_value; |
| 490 if (client_state_key.ReadValue(google_update::kRegRLZBrandField, | 497 if (client_state_key.ReadValue(google_update::kRegRLZBrandField, |
| 491 &brand_value) == ERROR_SUCCESS) { | 498 &brand_value) == ERROR_SUCCESS) { |
| 492 result = google_update::kRegRLZBrandField; | 499 result = google_update::kRegRLZBrandField; |
| 493 result.append(L"="); | 500 result.append(L"="); |
| 494 result.append(brand_value); | 501 result.append(brand_value); |
| 495 result.append(L"&"); | 502 result.append(L"&"); |
| 496 } | 503 } |
| 497 | 504 |
| 498 std::wstring client_value; | 505 string16 client_value; |
| 499 if (client_state_key.ReadValue(google_update::kRegClientField, | 506 if (client_state_key.ReadValue(google_update::kRegClientField, |
| 500 &client_value) == ERROR_SUCCESS) { | 507 &client_value) == ERROR_SUCCESS) { |
| 501 result.append(google_update::kRegClientField); | 508 result.append(google_update::kRegClientField); |
| 502 result.append(L"="); | 509 result.append(L"="); |
| 503 result.append(client_value); | 510 result.append(client_value); |
| 504 result.append(L"&"); | 511 result.append(L"&"); |
| 505 } | 512 } |
| 506 | 513 |
| 507 std::wstring ap_value; | 514 string16 ap_value; |
| 508 // If we fail to read the ap key, send up "&ap=" anyway to indicate | 515 // If we fail to read the ap key, send up "&ap=" anyway to indicate |
| 509 // that this was probably a stable channel release. | 516 // that this was probably a stable channel release. |
| 510 client_state_key.ReadValue(google_update::kRegApField, &ap_value); | 517 client_state_key.ReadValue(google_update::kRegApField, &ap_value); |
| 511 result.append(google_update::kRegApField); | 518 result.append(google_update::kRegApField); |
| 512 result.append(L"="); | 519 result.append(L"="); |
| 513 result.append(ap_value); | 520 result.append(ap_value); |
| 514 | 521 |
| 515 return result; | 522 return result; |
| 516 } | 523 } |
| 517 | 524 |
| 518 std::wstring GoogleChromeDistribution::GetUninstallLinkName() { | 525 string16 GoogleChromeDistribution::GetUninstallLinkName() { |
| 519 const std::wstring& link_name = | 526 const string16& link_name = |
| 520 installer::GetLocalizedString(IDS_UNINSTALL_CHROME_BASE); | 527 installer::GetLocalizedString(IDS_UNINSTALL_CHROME_BASE); |
| 521 return link_name; | 528 return link_name; |
| 522 } | 529 } |
| 523 | 530 |
| 524 std::wstring GoogleChromeDistribution::GetUninstallRegPath() { | 531 string16 GoogleChromeDistribution::GetUninstallRegPath() { |
| 525 return L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" | 532 return L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" |
| 526 L"Google Chrome"; | 533 L"Google Chrome"; |
| 527 } | 534 } |
| 528 | 535 |
| 529 std::wstring GoogleChromeDistribution::GetVersionKey() { | 536 string16 GoogleChromeDistribution::GetVersionKey() { |
| 530 std::wstring key(google_update::kRegPathClients); | 537 string16 key(google_update::kRegPathClients); |
| 531 key.append(L"\\"); | 538 key.append(L"\\"); |
| 532 key.append(product_guid()); | 539 key.append(product_guid()); |
| 533 return key; | 540 return key; |
| 534 } | 541 } |
| 535 | 542 |
| 536 bool GoogleChromeDistribution::GetDelegateExecuteHandlerData( | 543 bool GoogleChromeDistribution::GetDelegateExecuteHandlerData( |
| 537 string16* handler_class_uuid, | 544 string16* handler_class_uuid, |
| 538 string16* type_lib_uuid, | 545 string16* type_lib_uuid, |
| 539 string16* type_lib_version, | 546 string16* type_lib_version, |
| 540 string16* interface_uuid) { | 547 string16* interface_uuid) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 569 product_guid()); | 576 product_guid()); |
| 570 } | 577 } |
| 571 | 578 |
| 572 // The functions below are not used by the 64-bit Windows binary - | 579 // The functions below are not used by the 64-bit Windows binary - |
| 573 // see the comment in google_chrome_distribution_dummy.cc | 580 // see the comment in google_chrome_distribution_dummy.cc |
| 574 #ifndef _WIN64 | 581 #ifndef _WIN64 |
| 575 // A helper function that writes to HKLM if the handle was passed through the | 582 // A helper function that writes to HKLM if the handle was passed through the |
| 576 // command line, but HKCU otherwise. |experiment_group| is the value to write | 583 // command line, but HKCU otherwise. |experiment_group| is the value to write |
| 577 // and |last_write| is used when writing to HKLM to determine whether to close | 584 // and |last_write| is used when writing to HKLM to determine whether to close |
| 578 // the handle when done. | 585 // the handle when done. |
| 579 void SetClient(const std::wstring& experiment_group, bool last_write) { | 586 void SetClient(const string16& experiment_group, bool last_write) { |
| 580 static int reg_key_handle = -1; | 587 static int reg_key_handle = -1; |
| 581 if (reg_key_handle == -1) { | 588 if (reg_key_handle == -1) { |
| 582 // If a specific Toast Results key handle (presumably to our HKLM key) was | 589 // If a specific Toast Results key handle (presumably to our HKLM key) was |
| 583 // passed in to the command line (such as for system level installs), we use | 590 // passed in to the command line (such as for system level installs), we use |
| 584 // it. Otherwise, we write to the key under HKCU. | 591 // it. Otherwise, we write to the key under HKCU. |
| 585 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); | 592 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); |
| 586 if (cmd_line.HasSwitch(installer::switches::kToastResultsKey)) { | 593 if (cmd_line.HasSwitch(installer::switches::kToastResultsKey)) { |
| 587 // Get the handle to the key under HKLM. | 594 // Get the handle to the key under HKLM. |
| 588 base::StringToInt(cmd_line.GetSwitchValueASCII( | 595 base::StringToInt(cmd_line.GetSwitchValueASCII( |
| 589 installer::switches::kToastResultsKey).c_str(), | 596 installer::switches::kToastResultsKey).c_str(), |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 | 644 |
| 638 // The experiment with the more compact bubble. This one is a bit special | 645 // The experiment with the more compact bubble. This one is a bit special |
| 639 // because it is split into two: CAxx is regular style bubble and CBxx is | 646 // because it is split into two: CAxx is regular style bubble and CBxx is |
| 640 // compact style bubble. See |compact_bubble| below. | 647 // compact style bubble. See |compact_bubble| below. |
| 641 {L"en-US", kBrief, 1, L'C', L'A', 2, { kEnUs3, kEnUs3, 0, 0 } }, | 648 {L"en-US", kBrief, 1, L'C', L'A', 2, { kEnUs3, kEnUs3, 0, 0 } }, |
| 642 | 649 |
| 643 // Catch-all rules. | 650 // Catch-all rules. |
| 644 {kAll, kAll, 1, L'B', L'A', 1, {kEnUs3, 0, 0, 0} }, | 651 {kAll, kAll, 1, L'B', L'A', 1, {kEnUs3, 0, 0, 0} }, |
| 645 }; | 652 }; |
| 646 | 653 |
| 647 std::wstring locale; | 654 string16 locale; |
| 648 std::wstring brand; | 655 string16 brand; |
| 649 | 656 |
| 650 if (!GoogleUpdateSettings::GetLanguage(&locale)) | 657 if (!GoogleUpdateSettings::GetLanguage(&locale)) |
| 651 locale = ASCIIToWide("en-US"); | 658 locale = ASCIIToWide("en-US"); |
| 652 if (!GoogleUpdateSettings::GetBrand(&brand)) | 659 if (!GoogleUpdateSettings::GetBrand(&brand)) |
| 653 brand = ASCIIToWide(""); // Could still be viable for catch-all rules. | 660 brand = ASCIIToWide(""); // Could still be viable for catch-all rules. |
| 654 if (brand == kEnterprise) | 661 if (brand == kEnterprise) |
| 655 return false; | 662 return false; |
| 656 | 663 |
| 657 for (int i = 0; i < arraysize(kExperimentFlavors); ++i) { | 664 for (int i = 0; i < arraysize(kExperimentFlavors); ++i) { |
| 658 // A maximum of four flavors are supported at the moment. | 665 // A maximum of four flavors are supported at the moment. |
| 659 DCHECK_LE(kExperimentFlavors[i].flavors, kMax); | 666 DCHECK_LE(kExperimentFlavors[i].flavors, kMax); |
| 660 DCHECK_GT(kExperimentFlavors[i].flavors, 0); | 667 DCHECK_GT(kExperimentFlavors[i].flavors, 0); |
| 661 // Make sure each experiment has valid headings. | 668 // Make sure each experiment has valid headings. |
| 662 for (int f = 0; f < kMax; ++f) { | 669 for (int f = 0; f < kMax; ++f) { |
| 663 if (f < kExperimentFlavors[i].flavors) { | 670 if (f < kExperimentFlavors[i].flavors) { |
| 664 DCHECK_GT(kExperimentFlavors[i].headings[f], 0); | 671 DCHECK_GT(kExperimentFlavors[i].headings[f], 0); |
| 665 } else { | 672 } else { |
| 666 DCHECK_EQ(kExperimentFlavors[i].headings[f], 0); | 673 DCHECK_EQ(kExperimentFlavors[i].headings[f], 0); |
| 667 } | 674 } |
| 668 } | 675 } |
| 669 // Make sure we don't overflow on the second letter of the experiment code. | 676 // Make sure we don't overflow on the second letter of the experiment code. |
| 670 DCHECK(kExperimentFlavors[i].prefix2 + | 677 DCHECK(kExperimentFlavors[i].prefix2 + |
| 671 kExperimentFlavors[i].flavors - 1 <= 'Z'); | 678 kExperimentFlavors[i].flavors - 1 <= 'Z'); |
| 672 | 679 |
| 673 if (kExperimentFlavors[i].locale != locale && | 680 if (kExperimentFlavors[i].locale != locale && |
| 674 kExperimentFlavors[i].locale != ASCIIToWide("*")) | 681 kExperimentFlavors[i].locale != ASCIIToWide("*")) |
| 675 continue; | 682 continue; |
| 676 | 683 |
| 677 std::vector<std::wstring> brand_codes; | 684 std::vector<string16> brand_codes; |
| 678 base::SplitString(kExperimentFlavors[i].brands, L',', &brand_codes); | 685 base::SplitString(kExperimentFlavors[i].brands, L',', &brand_codes); |
| 679 if (brand_codes.empty()) | 686 if (brand_codes.empty()) |
| 680 return false; | 687 return false; |
| 681 for (std::vector<std::wstring>::iterator it = brand_codes.begin(); | 688 for (std::vector<string16>::iterator it = brand_codes.begin(); |
| 682 it != brand_codes.end(); ++it) { | 689 it != brand_codes.end(); ++it) { |
| 683 if (*it != brand && *it != L"*") | 690 if (*it != brand && *it != L"*") |
| 684 continue; | 691 continue; |
| 685 | 692 |
| 686 // We have found our match. | 693 // We have found our match. |
| 687 if (flavor < 0) | 694 if (flavor < 0) |
| 688 flavor = base::RandInt(0, kExperimentFlavors[i].flavors - 1); | 695 flavor = base::RandInt(0, kExperimentFlavors[i].flavors - 1); |
| 689 experiment->flavor = flavor; | 696 experiment->flavor = flavor; |
| 690 experiment->heading = kExperimentFlavors[i].headings[flavor]; | 697 experiment->heading = kExperimentFlavors[i].headings[flavor]; |
| 691 experiment->control_group = kExperimentFlavors[i].control_group; | 698 experiment->control_group = kExperimentFlavors[i].control_group; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 } | 740 } |
| 734 | 741 |
| 735 // The |flavor| value ends up being processed by TryChromeDialogView to show | 742 // The |flavor| value ends up being processed by TryChromeDialogView to show |
| 736 // different experiments. | 743 // different experiments. |
| 737 UserExperiment experiment; | 744 UserExperiment experiment; |
| 738 if (!GetExperimentDetails(&experiment, -1)) { | 745 if (!GetExperimentDetails(&experiment, -1)) { |
| 739 VLOG(1) << "Failed to get experiment details."; | 746 VLOG(1) << "Failed to get experiment details."; |
| 740 return; | 747 return; |
| 741 } | 748 } |
| 742 int flavor = experiment.flavor; | 749 int flavor = experiment.flavor; |
| 743 std::wstring base_group = experiment.prefix; | 750 string16 base_group = experiment.prefix; |
| 744 | 751 |
| 745 std::wstring brand; | 752 string16 brand; |
| 746 if (GoogleUpdateSettings::GetBrand(&brand) && (brand == L"CHXX")) { | 753 if (GoogleUpdateSettings::GetBrand(&brand) && (brand == L"CHXX")) { |
| 747 // Testing only: the user automatically qualifies for the experiment. | 754 // Testing only: the user automatically qualifies for the experiment. |
| 748 VLOG(1) << "Experiment qualification bypass"; | 755 VLOG(1) << "Experiment qualification bypass"; |
| 749 } else { | 756 } else { |
| 750 // Check browser usage inactivity by the age of the last-write time of the | 757 // Check browser usage inactivity by the age of the last-write time of the |
| 751 // chrome user data directory. | 758 // chrome user data directory. |
| 752 FilePath user_data_dir(product.GetUserDataPath()); | 759 FilePath user_data_dir(product.GetUserDataPath()); |
| 753 | 760 |
| 754 const bool experiment_enabled = false; | 761 const bool experiment_enabled = false; |
| 755 const int kThirtyDays = 30 * 24; | 762 const int kThirtyDays = 30 * 24; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 790 cmd_line.AppendSwitchASCII(installer::switches::kInactiveUserToast, | 797 cmd_line.AppendSwitchASCII(installer::switches::kInactiveUserToast, |
| 791 base::IntToString(flavor)); | 798 base::IntToString(flavor)); |
| 792 cmd_line.AppendSwitchASCII(installer::switches::kExperimentGroup, | 799 cmd_line.AppendSwitchASCII(installer::switches::kExperimentGroup, |
| 793 WideToASCII(base_group)); | 800 WideToASCII(base_group)); |
| 794 LaunchSetup(&cmd_line, product, system_level); | 801 LaunchSetup(&cmd_line, product, system_level); |
| 795 } | 802 } |
| 796 | 803 |
| 797 // User qualifies for the experiment. To test, use --try-chrome-again=|flavor| | 804 // User qualifies for the experiment. To test, use --try-chrome-again=|flavor| |
| 798 // as a parameter to chrome.exe. | 805 // as a parameter to chrome.exe. |
| 799 void GoogleChromeDistribution::InactiveUserToastExperiment(int flavor, | 806 void GoogleChromeDistribution::InactiveUserToastExperiment(int flavor, |
| 800 const std::wstring& experiment_group, | 807 const string16& experiment_group, |
| 801 const installer::Product& installation, | 808 const installer::Product& installation, |
| 802 const FilePath& application_path) { | 809 const FilePath& application_path) { |
| 803 bool has_welcome_url = (flavor == 0); | 810 bool has_welcome_url = (flavor == 0); |
| 804 // Possibly add a url to launch depending on the experiment flavor. | 811 // Possibly add a url to launch depending on the experiment flavor. |
| 805 CommandLine options(CommandLine::NO_PROGRAM); | 812 CommandLine options(CommandLine::NO_PROGRAM); |
| 806 options.AppendSwitchNative(switches::kTryChromeAgain, | 813 options.AppendSwitchNative(switches::kTryChromeAgain, |
| 807 base::IntToString16(flavor)); | 814 base::IntToString16(flavor)); |
| 808 if (has_welcome_url) { | 815 if (has_welcome_url) { |
| 809 // Prepend the url with a space. | 816 // Prepend the url with a space. |
| 810 std::wstring url(GetWelcomeBackUrl()); | 817 string16 url(GetWelcomeBackUrl()); |
| 811 options.AppendArg("--"); | 818 options.AppendArg("--"); |
| 812 options.AppendArgNative(url); | 819 options.AppendArgNative(url); |
| 813 // The command line should now have the url added as: | 820 // The command line should now have the url added as: |
| 814 // "chrome.exe -- <url>" | 821 // "chrome.exe -- <url>" |
| 815 DCHECK_NE(std::wstring::npos, | 822 DCHECK_NE(string16::npos, |
| 816 options.GetCommandLineString().find(L" -- " + url)); | 823 options.GetCommandLineString().find(L" -- " + url)); |
| 817 } | 824 } |
| 818 // Launch chrome now. It will show the toast UI. | 825 // Launch chrome now. It will show the toast UI. |
| 819 int32 exit_code = 0; | 826 int32 exit_code = 0; |
| 820 if (!installation.LaunchChromeAndWait(application_path, options, &exit_code)) | 827 if (!installation.LaunchChromeAndWait(application_path, options, &exit_code)) |
| 821 return; | 828 return; |
| 822 | 829 |
| 823 // The chrome process has exited, figure out what happened. | 830 // The chrome process has exited, figure out what happened. |
| 824 const wchar_t* outcome = NULL; | 831 const wchar_t* outcome = NULL; |
| 825 switch (exit_code) { | 832 switch (exit_code) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 846 // we waited for chrome to exit so the uninstall would not detect chrome | 853 // we waited for chrome to exit so the uninstall would not detect chrome |
| 847 // running. | 854 // running. |
| 848 bool system_level_toast = CommandLine::ForCurrentProcess()->HasSwitch( | 855 bool system_level_toast = CommandLine::ForCurrentProcess()->HasSwitch( |
| 849 installer::switches::kSystemLevelToast); | 856 installer::switches::kSystemLevelToast); |
| 850 | 857 |
| 851 CommandLine cmd(InstallUtil::GetChromeUninstallCmd(system_level_toast, | 858 CommandLine cmd(InstallUtil::GetChromeUninstallCmd(system_level_toast, |
| 852 GetType())); | 859 GetType())); |
| 853 base::LaunchProcess(cmd, base::LaunchOptions(), NULL); | 860 base::LaunchProcess(cmd, base::LaunchOptions(), NULL); |
| 854 } | 861 } |
| 855 #endif | 862 #endif |
| OLD | NEW |