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 <windows.h> 6 #include <shlwapi.h> // For SHDeleteKey. 7 8 #include "base/memory/scoped_ptr.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/test/test_reg_util_win.h" 11 #include "base/win/registry.h" 12 #include "chrome/common/chrome_constants.h" 13 #include "chrome/installer/util/browser_distribution.h" 14 #include "chrome/installer/util/channel_info.h" 15 #include "chrome/installer/util/fake_installation_state.h" 16 #include "chrome/installer/util/google_update_constants.h" 17 #include "chrome/installer/util/google_update_experiment_util.h" 18 #include "chrome/installer/util/google_update_settings.h" 19 #include "chrome/installer/util/util_constants.h" 20 #include "chrome/installer/util/work_item_list.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 using base::win::RegKey; 24 using installer::ChannelInfo; 25 26 namespace { 27 28 const wchar_t kGoogleUpdatePoliciesKey[] = 29 L"SOFTWARE\\Policies\\Google\\Update"; 30 const wchar_t kGoogleUpdateUpdateDefault[] = L"UpdateDefault"; 31 const wchar_t kGoogleUpdateUpdatePrefix[] = L"Update"; 32 const GoogleUpdateSettings::UpdatePolicy kDefaultUpdatePolicy = 33 #if defined(GOOGLE_CHROME_BUILD) 34 GoogleUpdateSettings::AUTOMATIC_UPDATES; 35 #else 36 GoogleUpdateSettings::UPDATES_DISABLED; 37 #endif 38 39 const wchar_t kTestProductGuid[] = L"{89F1B351-B15D-48D4-8F10-1298721CF13D}"; 40 const wchar_t kTestExperimentLabel[] = L"test_label_value"; 41 42 // This test fixture redirects the HKLM and HKCU registry hives for 43 // the duration of the test to make it independent of the machine 44 // and user settings. 45 class GoogleUpdateSettingsTest : public testing::Test { 46 protected: 47 virtual void SetUp() OVERRIDE { 48 registry_overrides_.OverrideRegistry(HKEY_LOCAL_MACHINE, L"HKLM_pit"); 49 registry_overrides_.OverrideRegistry(HKEY_CURRENT_USER, L"HKCU_pit"); 50 } 51 52 enum SystemUserInstall { 53 SYSTEM_INSTALL, 54 USER_INSTALL, 55 }; 56 57 void SetApField(SystemUserInstall is_system, const wchar_t* value) { 58 HKEY root = is_system == SYSTEM_INSTALL ? 59 HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 60 61 RegKey update_key; 62 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 63 std::wstring path = dist->GetStateKey(); 64 ASSERT_EQ(ERROR_SUCCESS, update_key.Create(root, path.c_str(), KEY_WRITE)); 65 ASSERT_EQ(ERROR_SUCCESS, update_key.WriteValue(L"ap", value)); 66 } 67 68 // Tests setting the ap= value to various combinations of values with 69 // prefixes and suffixes, while asserting on the correct channel value. 70 // Note that any non-empty ap= value that doesn't match ".*-{dev|beta}.*" 71 // will return the "unknown" channel. 72 void TestCurrentChromeChannelWithVariousApValues(SystemUserInstall install) { 73 static struct Expectations { 74 const wchar_t* ap_value; 75 const wchar_t* channel; 76 } expectations[] = { 77 { L"dev", installer::kChromeChannelDev }, 78 { L"-dev", installer::kChromeChannelDev }, 79 { L"-developer", installer::kChromeChannelDev }, 80 { L"beta", installer::kChromeChannelBeta }, 81 { L"-beta", installer::kChromeChannelBeta }, 82 { L"-betamax", installer::kChromeChannelBeta }, 83 }; 84 bool is_system = install == SYSTEM_INSTALL; 85 const wchar_t* prefixes[] = { 86 L"", 87 L"prefix", 88 L"prefix-with-dash", 89 }; 90 const wchar_t* suffixes[] = { 91 L"", 92 L"suffix", 93 L"suffix-with-dash", 94 }; 95 96 for (size_t i = 0; i < arraysize(prefixes); ++i) { 97 for (size_t j = 0; j < arraysize(expectations); ++j) { 98 for (size_t k = 0; k < arraysize(suffixes); ++k) { 99 std::wstring ap = prefixes[i]; 100 ap += expectations[j].ap_value; 101 ap += suffixes[k]; 102 const wchar_t* channel = expectations[j].channel; 103 104 SetApField(install, ap.c_str()); 105 string16 ret_channel; 106 107 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers( 108 is_system, &ret_channel)); 109 EXPECT_STREQ(channel, ret_channel.c_str()) 110 << "Expecting channel \"" << channel 111 << "\" for ap=\"" << ap << "\""; 112 } 113 } 114 } 115 } 116 117 // Test the writing and deleting functionality of the experiments label 118 // helper. 119 void TestExperimentsLabelHelper(SystemUserInstall install) { 120 BrowserDistribution* chrome = 121 BrowserDistribution::GetSpecificDistribution( 122 BrowserDistribution::CHROME_BROWSER); 123 std::wstring value; 124 #if defined(GOOGLE_CHROME_BUILD) 125 EXPECT_TRUE(chrome->ShouldSetExperimentLabels()); 126 127 // Before anything is set, ReadExperimentLabels should succeed but return 128 // an empty string. 129 EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( 130 install == SYSTEM_INSTALL, &value)); 131 EXPECT_EQ(string16(), value); 132 133 EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels( 134 install == SYSTEM_INSTALL, kTestExperimentLabel)); 135 136 // Validate that something is written. Only worry about the label itself. 137 RegKey key; 138 HKEY root = install == SYSTEM_INSTALL ? 139 HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 140 string16 state_key = install == SYSTEM_INSTALL ? 141 chrome->GetStateMediumKey() : chrome->GetStateKey(); 142 143 EXPECT_EQ(ERROR_SUCCESS, 144 key.Open(root, state_key.c_str(), KEY_QUERY_VALUE)); 145 EXPECT_EQ(ERROR_SUCCESS, 146 key.ReadValue(google_update::kExperimentLabels, &value)); 147 EXPECT_EQ(kTestExperimentLabel, value); 148 EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( 149 install == SYSTEM_INSTALL, &value)); 150 EXPECT_EQ(kTestExperimentLabel, value); 151 key.Close(); 152 153 // Now that the label is set, test the delete functionality. An empty label 154 // should result in deleting the value. 155 EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels( 156 install == SYSTEM_INSTALL, string16())); 157 EXPECT_EQ(ERROR_SUCCESS, 158 key.Open(root, state_key.c_str(), KEY_QUERY_VALUE)); 159 EXPECT_EQ(ERROR_FILE_NOT_FOUND, 160 key.ReadValue(google_update::kExperimentLabels, &value)); 161 EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels( 162 install == SYSTEM_INSTALL, &value)); 163 EXPECT_EQ(string16(), value); 164 key.Close(); 165 #else 166 EXPECT_FALSE(chrome->ShouldSetExperimentLabels()); 167 EXPECT_FALSE(GoogleUpdateSettings::ReadExperimentLabels( 168 install == SYSTEM_INSTALL, &value)); 169 #endif // GOOGLE_CHROME_BUILD 170 } 171 172 // Creates "ap" key with the value given as parameter. Also adds work 173 // items to work_item_list given so that they can be rolled back later. 174 bool CreateApKey(WorkItemList* work_item_list, const std::wstring& value) { 175 HKEY reg_root = HKEY_CURRENT_USER; 176 std::wstring reg_key = GetApKeyPath(); 177 work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key); 178 work_item_list->AddSetRegValueWorkItem(reg_root, reg_key, 179 google_update::kRegApField, value.c_str(), true); 180 if (!work_item_list->Do()) { 181 work_item_list->Rollback(); 182 return false; 183 } 184 return true; 185 } 186 187 // Returns the key path of "ap" key, e.g.: 188 // Google\Update\ClientState\<kTestProductGuid> 189 std::wstring GetApKeyPath() { 190 std::wstring reg_key(google_update::kRegPathClientState); 191 reg_key.append(L"\\"); 192 reg_key.append(kTestProductGuid); 193 return reg_key; 194 } 195 196 // Utility method to read "ap" key value 197 std::wstring ReadApKeyValue() { 198 RegKey key; 199 std::wstring ap_key_value; 200 std::wstring reg_key = GetApKeyPath(); 201 if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) == 202 ERROR_SUCCESS) { 203 key.ReadValue(google_update::kRegApField, &ap_key_value); 204 } 205 206 return ap_key_value; 207 } 208 209 registry_util::RegistryOverrideManager registry_overrides_; 210 }; 211 212 } // namespace 213 214 // Verify that we return success on no registration (which means stable), 215 // whether per-system or per-user install. 216 TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelAbsent) { 217 // Per-system first. 218 string16 channel; 219 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, 220 &channel)); 221 EXPECT_STREQ(L"", channel.c_str()); 222 223 // Then per-user. 224 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, 225 &channel)); 226 EXPECT_STREQ(L"", channel.c_str()); 227 } 228 229 // Test an empty Ap key for system and user. 230 TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptySystem) { 231 SetApField(SYSTEM_INSTALL, L""); 232 string16 channel; 233 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, 234 &channel)); 235 EXPECT_STREQ(L"", channel.c_str()); 236 237 // Per-user lookups still succeed and return empty string. 238 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, 239 &channel)); 240 EXPECT_STREQ(L"", channel.c_str()); 241 } 242 243 TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptyUser) { 244 SetApField(USER_INSTALL, L""); 245 // Per-system lookups still succeed and return empty string. 246 string16 channel; 247 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true, 248 &channel)); 249 EXPECT_STREQ(L"", channel.c_str()); 250 251 // Per-user lookup should succeed. 252 EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false, 253 &channel)); 254 EXPECT_STREQ(L"", channel.c_str()); 255 } 256 257 TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesSystem) { 258 TestCurrentChromeChannelWithVariousApValues(SYSTEM_INSTALL); 259 } 260 261 TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesUser) { 262 TestCurrentChromeChannelWithVariousApValues(USER_INSTALL); 263 } 264 265 // Run through all combinations of diff vs. full install, single vs. multi 266 // install, success and failure results, and a fistful of initial "ap" values 267 // checking that the expected final "ap" value is generated by 268 // GoogleUpdateSettings::UpdateGoogleUpdateApKey. 269 TEST_F(GoogleUpdateSettingsTest, UpdateGoogleUpdateApKey) { 270 const installer::ArchiveType archive_types[] = { 271 installer::UNKNOWN_ARCHIVE_TYPE, 272 installer::FULL_ARCHIVE_TYPE, 273 installer::INCREMENTAL_ARCHIVE_TYPE 274 }; 275 const int results[] = { 276 installer::FIRST_INSTALL_SUCCESS, 277 installer::INSTALL_FAILED 278 }; 279 const wchar_t* const plain[] = { 280 L"", 281 L"1.1", 282 L"1.1-dev" 283 }; 284 const wchar_t* const full[] = { 285 L"-full", 286 L"1.1-full", 287 L"1.1-dev-full" 288 }; 289 COMPILE_ASSERT(arraysize(full) == arraysize(plain), bad_full_array_size); 290 const wchar_t* const multifail[] = { 291 L"-multifail", 292 L"1.1-multifail", 293 L"1.1-dev-multifail" 294 }; 295 COMPILE_ASSERT(arraysize(multifail) == arraysize(plain), 296 bad_multifail_array_size); 297 const wchar_t* const multifail_full[] = { 298 L"-multifail-full", 299 L"1.1-multifail-full", 300 L"1.1-dev-multifail-full" 301 }; 302 COMPILE_ASSERT(arraysize(multifail_full) == arraysize(plain), 303 bad_multifail_full_array_size); 304 const wchar_t* const* input_arrays[] = { 305 plain, 306 full, 307 multifail, 308 multifail_full 309 }; 310 ChannelInfo v; 311 for (int type_idx = 0; type_idx < arraysize(archive_types); ++type_idx) { 312 const installer::ArchiveType archive_type = archive_types[type_idx]; 313 for (int result_idx = 0; result_idx < arraysize(results); ++result_idx) { 314 const int result = results[result_idx]; 315 // The archive type will/must always be known on install success. 316 if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE && 317 result == installer::FIRST_INSTALL_SUCCESS) { 318 continue; 319 } 320 const wchar_t* const* outputs = NULL; 321 if (result == installer::FIRST_INSTALL_SUCCESS || 322 archive_type == installer::FULL_ARCHIVE_TYPE) { 323 outputs = plain; 324 } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) { 325 outputs = full; 326 } // else if (archive_type == UNKNOWN) see below 327 328 for (int inputs_idx = 0; inputs_idx < arraysize(input_arrays); 329 ++inputs_idx) { 330 const wchar_t* const* inputs = input_arrays[inputs_idx]; 331 if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE) { 332 // "-full" is untouched if the archive type is unknown. 333 // "-multifail" is unconditionally removed. 334 if (inputs == full || inputs == multifail_full) 335 outputs = full; 336 else 337 outputs = plain; 338 } 339 for (int input_idx = 0; input_idx < arraysize(plain); ++input_idx) { 340 const wchar_t* input = inputs[input_idx]; 341 const wchar_t* output = outputs[input_idx]; 342 343 v.set_value(input); 344 if (output == v.value()) { 345 EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( 346 archive_type, result, &v)) 347 << "archive_type: " << archive_type 348 << ", result: " << result 349 << ", input ap value: " << input; 350 } else { 351 EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey( 352 archive_type, result, &v)) 353 << "archive_type: " << archive_type 354 << ", result: " << result 355 << ", input ap value: " << input; 356 } 357 EXPECT_EQ(output, v.value()) 358 << "archive_type: " << archive_type 359 << ", result: " << result 360 << ", input ap value: " << input; 361 } 362 } 363 } 364 } 365 } 366 367 TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) { 368 scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList()); 369 // Test incremental install failure 370 ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) 371 << "Failed to create ap key."; 372 GoogleUpdateSettings::UpdateInstallStatus(false, 373 installer::INCREMENTAL_ARCHIVE_TYPE, 374 installer::INSTALL_FAILED, 375 kTestProductGuid); 376 EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); 377 work_item_list->Rollback(); 378 379 work_item_list.reset(WorkItem::CreateWorkItemList()); 380 // Test incremental install success 381 ASSERT_TRUE(CreateApKey(work_item_list.get(), L"")) 382 << "Failed to create ap key."; 383 GoogleUpdateSettings::UpdateInstallStatus(false, 384 installer::INCREMENTAL_ARCHIVE_TYPE, 385 installer::FIRST_INSTALL_SUCCESS, 386 kTestProductGuid); 387 EXPECT_STREQ(ReadApKeyValue().c_str(), L""); 388 work_item_list->Rollback(); 389 390 work_item_list.reset(WorkItem::CreateWorkItemList()); 391 // Test full install failure 392 ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) 393 << "Failed to create ap key."; 394 GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, 395 installer::INSTALL_FAILED, 396 kTestProductGuid); 397 EXPECT_STREQ(ReadApKeyValue().c_str(), L""); 398 work_item_list->Rollback(); 399 400 work_item_list.reset(WorkItem::CreateWorkItemList()); 401 // Test full install success 402 ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full")) 403 << "Failed to create ap key."; 404 GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, 405 installer::FIRST_INSTALL_SUCCESS, 406 kTestProductGuid); 407 EXPECT_STREQ(ReadApKeyValue().c_str(), L""); 408 work_item_list->Rollback(); 409 410 work_item_list.reset(WorkItem::CreateWorkItemList()); 411 // Test the case of when "ap" key doesnt exist at all 412 std::wstring ap_key_value = ReadApKeyValue(); 413 std::wstring reg_key = GetApKeyPath(); 414 HKEY reg_root = HKEY_CURRENT_USER; 415 bool ap_key_deleted = false; 416 RegKey key; 417 if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) != 418 ERROR_SUCCESS) { 419 work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key); 420 ASSERT_TRUE(work_item_list->Do()) << "Failed to create ClientState key."; 421 } else if (key.DeleteValue(google_update::kRegApField) == ERROR_SUCCESS) { 422 ap_key_deleted = true; 423 } 424 // try differential installer 425 GoogleUpdateSettings::UpdateInstallStatus(false, 426 installer::INCREMENTAL_ARCHIVE_TYPE, 427 installer::INSTALL_FAILED, 428 kTestProductGuid); 429 EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full"); 430 // try full installer now 431 GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE, 432 installer::INSTALL_FAILED, 433 kTestProductGuid); 434 EXPECT_STREQ(ReadApKeyValue().c_str(), L""); 435 // Now cleanup to leave the system in unchanged state. 436 // - Diff installer creates an ap key if it didnt exist, so delete this ap key 437 // - If we created any reg key path for ap, roll it back 438 // - Finally restore the original value of ap key. 439 key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS); 440 key.DeleteValue(google_update::kRegApField); 441 work_item_list->Rollback(); 442 if (ap_key_deleted) { 443 work_item_list.reset(WorkItem::CreateWorkItemList()); 444 ASSERT_TRUE(CreateApKey(work_item_list.get(), ap_key_value)) 445 << "Failed to restore ap key."; 446 } 447 } 448 449 TEST_F(GoogleUpdateSettingsTest, SetEULAConsent) { 450 using installer::FakeInstallationState; 451 452 const bool multi_install = true; 453 const bool system_level = true; 454 FakeInstallationState machine_state; 455 456 // Chrome is installed. 457 machine_state.AddChrome(system_level, multi_install, 458 new Version(chrome::kChromeVersion)); 459 460 RegKey key; 461 DWORD value; 462 BrowserDistribution* binaries = 463 BrowserDistribution::GetSpecificDistribution( 464 BrowserDistribution::CHROME_BINARIES); 465 BrowserDistribution* chrome = 466 BrowserDistribution::GetSpecificDistribution( 467 BrowserDistribution::CHROME_BROWSER); 468 469 // eulaconsent is set on both the product and the binaries. 470 EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(machine_state, chrome, 471 true)); 472 EXPECT_EQ(ERROR_SUCCESS, 473 key.Open(HKEY_LOCAL_MACHINE, binaries->GetStateMediumKey().c_str(), 474 KEY_QUERY_VALUE)); 475 EXPECT_EQ(ERROR_SUCCESS, 476 key.ReadValueDW(google_update::kRegEULAAceptedField, &value)); 477 EXPECT_EQ(1U, value); 478 EXPECT_EQ(ERROR_SUCCESS, 479 key.Open(HKEY_LOCAL_MACHINE, chrome->GetStateMediumKey().c_str(), 480 KEY_QUERY_VALUE)); 481 EXPECT_EQ(ERROR_SUCCESS, 482 key.ReadValueDW(google_update::kRegEULAAceptedField, &value)); 483 EXPECT_EQ(1U, value); 484 } 485 486 // Test that the appropriate default is returned if no update override is 487 // present. 488 TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyNoOverride) { 489 // There are no policies at all. 490 EXPECT_EQ(ERROR_FILE_NOT_FOUND, 491 RegKey().Open(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 492 KEY_QUERY_VALUE)); 493 bool is_overridden = true; 494 EXPECT_EQ(kDefaultUpdatePolicy, 495 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 496 &is_overridden)); 497 EXPECT_FALSE(is_overridden); 498 499 // The policy key exists, but there are no values of interest present. 500 EXPECT_EQ(ERROR_SUCCESS, 501 RegKey().Create(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 502 KEY_SET_VALUE)); 503 EXPECT_EQ(ERROR_SUCCESS, 504 RegKey().Open(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 505 KEY_QUERY_VALUE)); 506 is_overridden = true; 507 EXPECT_EQ(kDefaultUpdatePolicy, 508 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 509 &is_overridden)); 510 EXPECT_FALSE(is_overridden); 511 } 512 513 #if defined(GOOGLE_CHROME_BUILD) 514 515 // Test that the default override is returned if no app-specific override is 516 // present. 517 TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyDefaultOverride) { 518 EXPECT_EQ(ERROR_SUCCESS, 519 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 520 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 521 static_cast<DWORD>(0))); 522 bool is_overridden = true; 523 EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, 524 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 525 &is_overridden)); 526 EXPECT_FALSE(is_overridden); 527 528 EXPECT_EQ(ERROR_SUCCESS, 529 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 530 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 531 static_cast<DWORD>(1))); 532 is_overridden = true; 533 EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, 534 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 535 &is_overridden)); 536 EXPECT_FALSE(is_overridden); 537 538 EXPECT_EQ(ERROR_SUCCESS, 539 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 540 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 541 static_cast<DWORD>(2))); 542 is_overridden = true; 543 EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, 544 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 545 &is_overridden)); 546 EXPECT_FALSE(is_overridden); 547 548 EXPECT_EQ(ERROR_SUCCESS, 549 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 550 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 551 static_cast<DWORD>(3))); 552 is_overridden = true; 553 EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, 554 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 555 &is_overridden)); 556 EXPECT_FALSE(is_overridden); 557 558 // The default policy should be in force for bogus values. 559 EXPECT_EQ(ERROR_SUCCESS, 560 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 561 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 562 static_cast<DWORD>(4))); 563 is_overridden = true; 564 EXPECT_EQ(kDefaultUpdatePolicy, 565 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 566 &is_overridden)); 567 EXPECT_FALSE(is_overridden); 568 } 569 570 // Test that an app-specific override is used if present. 571 TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyAppOverride) { 572 std::wstring app_policy_value(kGoogleUpdateUpdatePrefix); 573 app_policy_value.append(kTestProductGuid); 574 575 EXPECT_EQ(ERROR_SUCCESS, 576 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 577 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 578 static_cast<DWORD>(1))); 579 EXPECT_EQ(ERROR_SUCCESS, 580 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 581 KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), 582 static_cast<DWORD>(0))); 583 bool is_overridden = false; 584 EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, 585 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 586 &is_overridden)); 587 EXPECT_TRUE(is_overridden); 588 589 EXPECT_EQ(ERROR_SUCCESS, 590 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 591 KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault, 592 static_cast<DWORD>(0))); 593 EXPECT_EQ(ERROR_SUCCESS, 594 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 595 KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), 596 static_cast<DWORD>(1))); 597 is_overridden = false; 598 EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, 599 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 600 &is_overridden)); 601 EXPECT_TRUE(is_overridden); 602 603 EXPECT_EQ(ERROR_SUCCESS, 604 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 605 KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), 606 static_cast<DWORD>(2))); 607 is_overridden = false; 608 EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY, 609 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 610 &is_overridden)); 611 EXPECT_TRUE(is_overridden); 612 613 EXPECT_EQ(ERROR_SUCCESS, 614 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 615 KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), 616 static_cast<DWORD>(3))); 617 is_overridden = false; 618 EXPECT_EQ(GoogleUpdateSettings::AUTO_UPDATES_ONLY, 619 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 620 &is_overridden)); 621 EXPECT_TRUE(is_overridden); 622 623 // The default policy should be in force for bogus values. 624 EXPECT_EQ(ERROR_SUCCESS, 625 RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey, 626 KEY_SET_VALUE).WriteValue(app_policy_value.c_str(), 627 static_cast<DWORD>(4))); 628 is_overridden = true; 629 EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, 630 GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid, 631 &is_overridden)); 632 EXPECT_FALSE(is_overridden); 633 } 634 635 TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperSystem) { 636 TestExperimentsLabelHelper(SYSTEM_INSTALL); 637 } 638 639 TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperUser) { 640 TestExperimentsLabelHelper(USER_INSTALL); 641 } 642 643 #endif // defined(GOOGLE_CHROME_BUILD) 644 645 // Test GoogleUpdateSettings::GetUninstallCommandLine at system- or user-level, 646 // according to the param. 647 class GetUninstallCommandLine : public GoogleUpdateSettingsTest, 648 public testing::WithParamInterface<bool> { 649 protected: 650 static const wchar_t kDummyCommand[]; 651 652 virtual void SetUp() OVERRIDE { 653 GoogleUpdateSettingsTest::SetUp(); 654 system_install_ = GetParam(); 655 root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 656 } 657 658 HKEY root_key_; 659 bool system_install_; 660 }; 661 662 const wchar_t GetUninstallCommandLine::kDummyCommand[] = 663 L"\"goopdate.exe\" /spam"; 664 665 // Tests that GetUninstallCommandLine returns an empty string if there's no 666 // Software\Google\Update key. 667 TEST_P(GetUninstallCommandLine, TestNoKey) { 668 EXPECT_EQ(string16(), 669 GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); 670 } 671 672 // Tests that GetUninstallCommandLine returns an empty string if there's no 673 // UninstallCmdLine value in the Software\Google\Update key. 674 TEST_P(GetUninstallCommandLine, TestNoValue) { 675 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE); 676 EXPECT_EQ(string16(), 677 GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); 678 } 679 680 // Tests that GetUninstallCommandLine returns an empty string if there's an 681 // empty UninstallCmdLine value in the Software\Google\Update key. 682 TEST_P(GetUninstallCommandLine, TestEmptyValue) { 683 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) 684 .WriteValue(google_update::kRegUninstallCmdLine, L""); 685 EXPECT_EQ(string16(), 686 GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); 687 } 688 689 // Tests that GetUninstallCommandLine returns the correct string if there's an 690 // UninstallCmdLine value in the Software\Google\Update key. 691 TEST_P(GetUninstallCommandLine, TestRealValue) { 692 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) 693 .WriteValue(google_update::kRegUninstallCmdLine, kDummyCommand); 694 EXPECT_EQ(string16(kDummyCommand), 695 GoogleUpdateSettings::GetUninstallCommandLine(system_install_)); 696 // Make sure that there's no value in the other level (user or system). 697 EXPECT_EQ(string16(), 698 GoogleUpdateSettings::GetUninstallCommandLine(!system_install_)); 699 } 700 701 INSTANTIATE_TEST_CASE_P(GetUninstallCommandLineAtLevel, GetUninstallCommandLine, 702 testing::Bool()); 703 704 // Test GoogleUpdateSettings::GetGoogleUpdateVersion at system- or user-level, 705 // according to the param. 706 class GetGoogleUpdateVersion : public GoogleUpdateSettingsTest, 707 public testing::WithParamInterface<bool> { 708 protected: 709 static const wchar_t kDummyVersion[]; 710 711 virtual void SetUp() OVERRIDE { 712 GoogleUpdateSettingsTest::SetUp(); 713 system_install_ = GetParam(); 714 root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 715 } 716 717 HKEY root_key_; 718 bool system_install_; 719 }; 720 721 const wchar_t GetGoogleUpdateVersion::kDummyVersion[] = L"1.2.3.4"; 722 723 // Tests that GetGoogleUpdateVersion returns an empty string if there's no 724 // Software\Google\Update key. 725 TEST_P(GetGoogleUpdateVersion, TestNoKey) { 726 EXPECT_FALSE( 727 GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); 728 } 729 730 // Tests that GetGoogleUpdateVersion returns an empty string if there's no 731 // version value in the Software\Google\Update key. 732 TEST_P(GetGoogleUpdateVersion, TestNoValue) { 733 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE); 734 EXPECT_FALSE( 735 GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); 736 } 737 738 // Tests that GetGoogleUpdateVersion returns an empty string if there's an 739 // empty version value in the Software\Google\Update key. 740 TEST_P(GetGoogleUpdateVersion, TestEmptyValue) { 741 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) 742 .WriteValue(google_update::kRegGoogleUpdateVersion, L""); 743 EXPECT_FALSE( 744 GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid()); 745 } 746 747 // Tests that GetGoogleUpdateVersion returns the correct string if there's a 748 // version value in the Software\Google\Update key. 749 TEST_P(GetGoogleUpdateVersion, TestRealValue) { 750 RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE) 751 .WriteValue(google_update::kRegGoogleUpdateVersion, kDummyVersion); 752 Version expected(UTF16ToUTF8(kDummyVersion)); 753 EXPECT_TRUE(expected.Equals( 754 GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_))); 755 // Make sure that there's no value in the other level (user or system). 756 EXPECT_FALSE( 757 GoogleUpdateSettings::GetGoogleUpdateVersion(!system_install_) 758 .IsValid()); 759 } 760 761 INSTANTIATE_TEST_CASE_P(GetGoogleUpdateVersionAtLevel, GetGoogleUpdateVersion, 762 testing::Bool()); 763 764 // Test values for use by the CollectStatsConsent test fixture. 765 class StatsState { 766 public: 767 enum InstallType { 768 SINGLE_INSTALL, 769 MULTI_INSTALL, 770 }; 771 enum StateSetting { 772 NO_SETTING, 773 FALSE_SETTING, 774 TRUE_SETTING, 775 }; 776 struct UserLevelState {}; 777 struct SystemLevelState {}; 778 static const UserLevelState kUserLevel; 779 static const SystemLevelState kSystemLevel; 780 781 StatsState(const UserLevelState&, 782 InstallType install_type, 783 StateSetting state_value) 784 : system_level_(false), 785 multi_install_(install_type == MULTI_INSTALL), 786 state_value_(state_value), 787 state_medium_value_(NO_SETTING) { 788 } 789 StatsState(const SystemLevelState&, 790 InstallType install_type, 791 StateSetting state_value, 792 StateSetting state_medium_value) 793 : system_level_(true), 794 multi_install_(install_type == MULTI_INSTALL), 795 state_value_(state_value), 796 state_medium_value_(state_medium_value) { 797 } 798 bool system_level() const { return system_level_; } 799 bool multi_install() const { return multi_install_; } 800 HKEY root_key() const { 801 return system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 802 } 803 StateSetting state_value() const { return state_value_; } 804 StateSetting state_medium_value() const { 805 return state_medium_value_; 806 } 807 bool is_consent_granted() const { 808 return (system_level_ && state_medium_value_ != NO_SETTING) ? 809 (state_medium_value_ == TRUE_SETTING) : 810 (state_value_ == TRUE_SETTING); 811 } 812 private: 813 bool system_level_; 814 bool multi_install_; 815 StateSetting state_value_; 816 StateSetting state_medium_value_; 817 }; 818 819 const StatsState::UserLevelState StatsState::kUserLevel; 820 const StatsState::SystemLevelState StatsState::kSystemLevel; 821 822 // A value parameterized test for testing the stats collection consent setting. 823 class CollectStatsConsent : public ::testing::TestWithParam<StatsState> { 824 public: 825 static void SetUpTestCase(); 826 static void TearDownTestCase(); 827 protected: 828 virtual void SetUp() OVERRIDE; 829 static void MakeChromeMultiInstall(HKEY root_key); 830 static void ApplySetting(StatsState::StateSetting setting, 831 HKEY root_key, 832 const std::wstring& reg_key); 833 834 static std::wstring* chrome_version_key_; 835 static std::wstring* chrome_state_key_; 836 static std::wstring* chrome_state_medium_key_; 837 static std::wstring* binaries_state_key_; 838 static std::wstring* binaries_state_medium_key_; 839 registry_util::RegistryOverrideManager override_manager_; 840 }; 841 842 std::wstring* CollectStatsConsent::chrome_version_key_; 843 std::wstring* CollectStatsConsent::chrome_state_key_; 844 std::wstring* CollectStatsConsent::chrome_state_medium_key_; 845 std::wstring* CollectStatsConsent::binaries_state_key_; 846 std::wstring* CollectStatsConsent::binaries_state_medium_key_; 847 848 void CollectStatsConsent::SetUpTestCase() { 849 BrowserDistribution* dist = 850 BrowserDistribution::GetSpecificDistribution( 851 BrowserDistribution::CHROME_BROWSER); 852 chrome_version_key_ = new std::wstring(dist->GetVersionKey()); 853 chrome_state_key_ = new std::wstring(dist->GetStateKey()); 854 chrome_state_medium_key_ = new std::wstring(dist->GetStateMediumKey()); 855 856 dist = BrowserDistribution::GetSpecificDistribution( 857 BrowserDistribution::CHROME_BINARIES); 858 binaries_state_key_ = new std::wstring(dist->GetStateKey()); 859 binaries_state_medium_key_ = new std::wstring(dist->GetStateMediumKey()); 860 } 861 862 void CollectStatsConsent::TearDownTestCase() { 863 delete chrome_version_key_; 864 delete chrome_state_key_; 865 delete chrome_state_medium_key_; 866 delete binaries_state_key_; 867 delete binaries_state_medium_key_; 868 } 869 870 // Install the registry override and apply the settings to the registry. 871 void CollectStatsConsent::SetUp() { 872 const StatsState& stats_state = GetParam(); 873 const HKEY root_key = stats_state.root_key(); 874 std::wstring reg_temp_name(stats_state.system_level() ? L"HKLM_" : L"HKCU_"); 875 reg_temp_name += L"CollectStatsConsent"; 876 override_manager_.OverrideRegistry(root_key, reg_temp_name); 877 878 if (stats_state.multi_install()) { 879 MakeChromeMultiInstall(root_key); 880 ApplySetting(stats_state.state_value(), root_key, *binaries_state_key_); 881 ApplySetting(stats_state.state_medium_value(), root_key, 882 *binaries_state_medium_key_); 883 } else { 884 ApplySetting(stats_state.state_value(), root_key, *chrome_state_key_); 885 ApplySetting(stats_state.state_medium_value(), root_key, 886 *chrome_state_medium_key_); 887 } 888 } 889 890 // Write values into the registry so that Chrome is considered to be installed 891 // as multi-install. 892 void CollectStatsConsent::MakeChromeMultiInstall(HKEY root_key) { 893 ASSERT_EQ( 894 ERROR_SUCCESS, 895 RegKey(root_key, chrome_version_key_->c_str(), 896 KEY_SET_VALUE).WriteValue(google_update::kRegVersionField, 897 L"1.2.3.4")); 898 ASSERT_EQ( 899 ERROR_SUCCESS, 900 RegKey(root_key, chrome_state_key_->c_str(), 901 KEY_SET_VALUE).WriteValue(installer::kUninstallArgumentsField, 902 L"--multi-install")); 903 } 904 905 // Write the correct value to represent |setting| in the registry. 906 void CollectStatsConsent::ApplySetting(StatsState::StateSetting setting, 907 HKEY root_key, 908 const std::wstring& reg_key) { 909 if (setting != StatsState::NO_SETTING) { 910 DWORD value = setting != StatsState::FALSE_SETTING ? 1 : 0; 911 ASSERT_EQ( 912 ERROR_SUCCESS, 913 RegKey(root_key, reg_key.c_str(), 914 KEY_SET_VALUE).WriteValue(google_update::kRegUsageStatsField, 915 value)); 916 } 917 } 918 919 // Test that stats consent can be read. 920 TEST_P(CollectStatsConsent, GetCollectStatsConsentAtLevel) { 921 if (GetParam().is_consent_granted()) { 922 EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( 923 GetParam().system_level())); 924 } else { 925 EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( 926 GetParam().system_level())); 927 } 928 } 929 930 // Test that stats consent can be flipped to the opposite setting, that the new 931 // setting takes affect, and that the correct registry location is modified. 932 TEST_P(CollectStatsConsent, SetCollectStatsConsentAtLevel) { 933 EXPECT_TRUE(GoogleUpdateSettings::SetCollectStatsConsentAtLevel( 934 GetParam().system_level(), 935 !GetParam().is_consent_granted())); 936 const std::wstring* const reg_keys[] = { 937 chrome_state_key_, 938 chrome_state_medium_key_, 939 binaries_state_key_, 940 binaries_state_medium_key_, 941 }; 942 int key_index = ((GetParam().system_level() ? 1 : 0) + 943 (GetParam().multi_install() ? 2 : 0)); 944 const std::wstring& reg_key = *reg_keys[key_index]; 945 DWORD value = 0; 946 EXPECT_EQ( 947 ERROR_SUCCESS, 948 RegKey(GetParam().root_key(), reg_key.c_str(), 949 KEY_QUERY_VALUE).ReadValueDW(google_update::kRegUsageStatsField, 950 &value)); 951 if (GetParam().is_consent_granted()) { 952 EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( 953 GetParam().system_level())); 954 EXPECT_EQ(0UL, value); 955 } else { 956 EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel( 957 GetParam().system_level())); 958 EXPECT_EQ(1UL, value); 959 } 960 } 961 962 INSTANTIATE_TEST_CASE_P( 963 UserLevelSingleInstall, 964 CollectStatsConsent, 965 ::testing::Values( 966 StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, 967 StatsState::NO_SETTING), 968 StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, 969 StatsState::FALSE_SETTING), 970 StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL, 971 StatsState::TRUE_SETTING))); 972 INSTANTIATE_TEST_CASE_P( 973 UserLevelMultiInstall, 974 CollectStatsConsent, 975 ::testing::Values( 976 StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, 977 StatsState::NO_SETTING), 978 StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, 979 StatsState::FALSE_SETTING), 980 StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL, 981 StatsState::TRUE_SETTING))); 982 INSTANTIATE_TEST_CASE_P( 983 SystemLevelSingleInstall, 984 CollectStatsConsent, 985 ::testing::Values( 986 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 987 StatsState::NO_SETTING, StatsState::NO_SETTING), 988 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 989 StatsState::NO_SETTING, StatsState::FALSE_SETTING), 990 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 991 StatsState::NO_SETTING, StatsState::TRUE_SETTING), 992 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 993 StatsState::FALSE_SETTING, StatsState::NO_SETTING), 994 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 995 StatsState::FALSE_SETTING, StatsState::FALSE_SETTING), 996 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 997 StatsState::FALSE_SETTING, StatsState::TRUE_SETTING), 998 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 999 StatsState::TRUE_SETTING, StatsState::NO_SETTING), 1000 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 1001 StatsState::TRUE_SETTING, StatsState::FALSE_SETTING), 1002 StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL, 1003 StatsState::TRUE_SETTING, StatsState::TRUE_SETTING))); 1004 INSTANTIATE_TEST_CASE_P( 1005 SystemLevelMultiInstall, 1006 CollectStatsConsent, 1007 ::testing::Values( 1008 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1009 StatsState::NO_SETTING, StatsState::NO_SETTING), 1010 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1011 StatsState::NO_SETTING, StatsState::FALSE_SETTING), 1012 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1013 StatsState::NO_SETTING, StatsState::TRUE_SETTING), 1014 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1015 StatsState::FALSE_SETTING, StatsState::NO_SETTING), 1016 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1017 StatsState::FALSE_SETTING, StatsState::FALSE_SETTING), 1018 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1019 StatsState::FALSE_SETTING, StatsState::TRUE_SETTING), 1020 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1021 StatsState::TRUE_SETTING, StatsState::NO_SETTING), 1022 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1023 StatsState::TRUE_SETTING, StatsState::FALSE_SETTING), 1024 StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL, 1025 StatsState::TRUE_SETTING, StatsState::TRUE_SETTING))); 1026