Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: chrome/browser/extensions/extension_service_sync_unittest.cc

Issue 2923013006: [Extensions Sync] Don't apply sync data for unsyncable extensions (Closed)
Patch Set: lazyboy's Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <map> 7 #include <map>
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/memory/weak_ptr.h" 17 #include "base/memory/weak_ptr.h"
18 #include "base/metrics/field_trial.h" 18 #include "base/metrics/field_trial.h"
19 #include "base/test/mock_entropy_provider.h" 19 #include "base/test/mock_entropy_provider.h"
20 #include "base/test/scoped_feature_list.h" 20 #include "base/test/scoped_feature_list.h"
21 #include "chrome/browser/chrome_notification_types.h" 21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h" 22 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
23 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
23 #include "chrome/browser/extensions/component_loader.h" 24 #include "chrome/browser/extensions/component_loader.h"
24 #include "chrome/browser/extensions/extension_service.h" 25 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_service_test_with_install.h" 26 #include "chrome/browser/extensions/extension_service_test_with_install.h"
26 #include "chrome/browser/extensions/extension_sync_data.h" 27 #include "chrome/browser/extensions/extension_sync_data.h"
27 #include "chrome/browser/extensions/extension_sync_service.h" 28 #include "chrome/browser/extensions/extension_sync_service.h"
28 #include "chrome/browser/extensions/extension_util.h" 29 #include "chrome/browser/extensions/extension_util.h"
29 #include "chrome/browser/extensions/scripting_permissions_modifier.h" 30 #include "chrome/browser/extensions/scripting_permissions_modifier.h"
30 #include "chrome/browser/extensions/updater/extension_updater.h" 31 #include "chrome/browser/extensions/updater/extension_updater.h"
31 #include "chrome/browser/sync/profile_sync_service_factory.h" 32 #include "chrome/browser/sync/profile_sync_service_factory.h"
32 #include "chrome/browser/themes/theme_service.h" 33 #include "chrome/browser/themes/theme_service.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 88
88 const char autoupdate[] = "ogjcoiohnmldgjemafoockdghcjciccf"; 89 const char autoupdate[] = "ogjcoiohnmldgjemafoockdghcjciccf";
89 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 90 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
90 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 91 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
91 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh"; 92 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
92 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 93 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
93 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln"; 94 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
94 const char permissions_increase[] = "pgdpcfcocojkjfbgpiianjngphoopgmo"; 95 const char permissions_increase[] = "pgdpcfcocojkjfbgpiianjngphoopgmo";
95 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; 96 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
96 97
98 ExtensionSyncData GetDisableSyncData(const Extension& extension,
99 int disable_reasons) {
100 bool enabled = false;
101 bool incognito_enabled = false;
102 bool remote_install = false;
103 bool installed_by_custodian = false;
104 ExtensionSyncData::OptionalBoolean has_all_urls =
105 ExtensionSyncData::BOOLEAN_UNSET;
106 return ExtensionSyncData(extension, enabled, disable_reasons,
107 incognito_enabled, remote_install, has_all_urls,
108 installed_by_custodian);
109 }
110
111 ExtensionSyncData GetEnableSyncData(const Extension& extension) {
112 bool enabled = true;
113 bool incognito_enabled = false;
114 bool remote_install = false;
115 bool installed_by_custodian = false;
116 ExtensionSyncData::OptionalBoolean has_all_urls =
117 ExtensionSyncData::BOOLEAN_UNSET;
118 return ExtensionSyncData(extension, enabled, Extension::DISABLE_NONE,
119 incognito_enabled, remote_install, has_all_urls,
120 installed_by_custodian);
121 }
122
97 SyncChangeList MakeSyncChangeList(const std::string& id, 123 SyncChangeList MakeSyncChangeList(const std::string& id,
98 const sync_pb::EntitySpecifics& specifics, 124 const sync_pb::EntitySpecifics& specifics,
99 SyncChange::SyncChangeType change_type) { 125 SyncChange::SyncChangeType change_type) {
100 syncer::SyncData sync_data = 126 syncer::SyncData sync_data =
101 syncer::SyncData::CreateLocalData(id, "Name", specifics); 127 syncer::SyncData::CreateLocalData(id, "Name", specifics);
102 return SyncChangeList(1, SyncChange(FROM_HERE, change_type, sync_data)); 128 return SyncChangeList(1, SyncChange(FROM_HERE, change_type, sync_data));
103 } 129 }
104 130
105 // This is a FakeSyncChangeProcessor specialization that maintains a store of 131 // This is a FakeSyncChangeProcessor specialization that maintains a store of
106 // SyncData items in the superclass' data_ member variable, treating it like a 132 // SyncData items in the superclass' data_ member variable, treating it like a
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 // Helper to call MergeDataAndStartSyncing with no server data and dummy 219 // Helper to call MergeDataAndStartSyncing with no server data and dummy
194 // change processor / error factory. 220 // change processor / error factory.
195 void StartSyncing(syncer::ModelType type) { 221 void StartSyncing(syncer::ModelType type) {
196 ASSERT_TRUE(type == syncer::EXTENSIONS || type == syncer::APPS); 222 ASSERT_TRUE(type == syncer::EXTENSIONS || type == syncer::APPS);
197 extension_sync_service()->MergeDataAndStartSyncing( 223 extension_sync_service()->MergeDataAndStartSyncing(
198 type, syncer::SyncDataList(), 224 type, syncer::SyncDataList(),
199 base::MakeUnique<syncer::FakeSyncChangeProcessor>(), 225 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
200 base::MakeUnique<syncer::SyncErrorFactoryMock>()); 226 base::MakeUnique<syncer::SyncErrorFactoryMock>());
201 } 227 }
202 228
229 void DisableExtensionFromSync(const Extension& extension,
230 int disable_reasons) {
231 ExtensionSyncData disable_extension =
232 GetDisableSyncData(extension, Extension::DISABLE_USER_ACTION);
233 SyncChangeList list(
234 1, disable_extension.GetSyncChange(SyncChange::ACTION_UPDATE));
235 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
236 }
237
238 void EnableExtensionFromSync(const Extension& extension) {
239 ExtensionSyncData enable_extension = GetEnableSyncData(extension);
240 SyncChangeList list(
241 1, enable_extension.GetSyncChange(SyncChange::ACTION_UPDATE));
242 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
243 }
244
203 protected: 245 protected:
204 // Paths to some of the fake extensions. 246 // Paths to some of the fake extensions.
205 base::FilePath good0_path() { 247 base::FilePath good0_path() {
206 return data_dir() 248 return data_dir()
207 .AppendASCII("good") 249 .AppendASCII("good")
208 .AppendASCII("Extensions") 250 .AppendASCII("Extensions")
209 .AppendASCII(good0) 251 .AppendASCII(good0)
210 .AppendASCII("1.0.0.0"); 252 .AppendASCII("1.0.0.0");
211 } 253 }
212 254
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 Extension::DISABLE_USER_ACTION, false, 375 Extension::DISABLE_USER_ACTION, false,
334 false, ExtensionSyncData::BOOLEAN_UNSET, 376 false, ExtensionSyncData::BOOLEAN_UNSET,
335 false); 377 false);
336 SyncChangeList list( 378 SyncChangeList list(
337 1, disable_good_crx.GetSyncChange(SyncChange::ACTION_UPDATE)); 379 1, disable_good_crx.GetSyncChange(SyncChange::ACTION_UPDATE));
338 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 380 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
339 381
340 ASSERT_FALSE(service()->IsExtensionEnabled(good0)); 382 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
341 } 383 }
342 384
385 // Test that sync can enable and disable installed extensions.
386 TEST_F(ExtensionServiceSyncTest, ReenableDisabledExtensionFromSync) {
387 InitializeEmptyExtensionService();
388
389 // Enable sync.
390 browser_sync::ProfileSyncService* sync_service =
391 ProfileSyncServiceFactory::GetForProfile(profile());
392 sync_service->SetFirstSetupComplete();
393
394 service()->Init();
395
396 // Load up a simple extension.
397 extensions::ChromeTestExtensionLoader extension_loader(profile());
398 extension_loader.set_pack_extension(true);
399 scoped_refptr<const Extension> extension = extension_loader.LoadExtension(
400 data_dir().AppendASCII("simple_with_file"));
401 ASSERT_TRUE(extension);
402 const std::string kExtensionId = extension->id();
403 ASSERT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
404
405 syncer::FakeSyncChangeProcessor* processor_raw = nullptr;
406 {
407 auto processor = base::MakeUnique<syncer::FakeSyncChangeProcessor>();
408 processor_raw = processor.get();
409 extension_sync_service()->MergeDataAndStartSyncing(
410 syncer::EXTENSIONS, syncer::SyncDataList(), std::move(processor),
411 base::MakeUnique<syncer::SyncErrorFactoryMock>());
412 }
413 processor_raw->changes().clear();
414
415 DisableExtensionFromSync(*extension, Extension::DISABLE_USER_ACTION);
416
417 // The extension should be disabled.
418 EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
419 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
420 ExtensionPrefs::Get(profile())->GetDisableReasons(kExtensionId));
421 EXPECT_TRUE(processor_raw->changes().empty());
422
423 // Enable the extension. Sync should push the new state.
424 service()->EnableExtension(kExtensionId);
425 {
426 ASSERT_EQ(1u, processor_raw->changes().size());
427 const SyncChange& change = processor_raw->changes()[0];
428 EXPECT_EQ(SyncChange::ACTION_UPDATE, change.change_type());
429 std::unique_ptr<ExtensionSyncData> data =
430 ExtensionSyncData::CreateFromSyncData(change.sync_data());
431 EXPECT_EQ(kExtensionId, data->id());
432 EXPECT_EQ(0, data->disable_reasons());
433 EXPECT_TRUE(data->enabled());
434 }
435
436 // Disable the extension again. Sync should push the new state.
437 processor_raw->changes().clear();
438 service()->DisableExtension(kExtensionId, Extension::DISABLE_USER_ACTION);
439 EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
440 {
441 ASSERT_EQ(1u, processor_raw->changes().size());
442 const SyncChange& change = processor_raw->changes()[0];
443 EXPECT_EQ(SyncChange::ACTION_UPDATE, change.change_type());
444 std::unique_ptr<ExtensionSyncData> data =
445 ExtensionSyncData::CreateFromSyncData(change.sync_data());
446 EXPECT_EQ(kExtensionId, data->id());
447 EXPECT_EQ(Extension::DISABLE_USER_ACTION, data->disable_reasons());
448 EXPECT_FALSE(data->enabled());
449 }
450 processor_raw->changes().clear();
451
452 // Enable the extension via sync.
453 EnableExtensionFromSync(*extension);
454
455 // The extension should be enabled.
456 EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
457 EXPECT_TRUE(processor_raw->changes().empty());
458 }
459
460 // Tests that default-installed extensions won't be affected by incoming sync
461 // data. (It's feasible to have a sync entry for an extension that could be
462 // default installed, since one installation may be default-installed while
463 // another may not be).
464 TEST_F(ExtensionServiceSyncTest,
465 DefaultInstalledExtensionsAreNotReenabledOrDisabledBySync) {
466 InitializeEmptyExtensionService();
467
468 // Enable sync.
469 browser_sync::ProfileSyncService* sync_service =
470 ProfileSyncServiceFactory::GetForProfile(profile());
471 sync_service->SetFirstSetupComplete();
472
473 service()->Init();
474
475 // Load up an extension that's considered default installed.
476 extensions::ChromeTestExtensionLoader extension_loader(profile());
477 extension_loader.set_pack_extension(true);
478 extension_loader.add_creation_flag(Extension::WAS_INSTALLED_BY_DEFAULT);
479 scoped_refptr<const Extension> extension = extension_loader.LoadExtension(
480 data_dir().AppendASCII("simple_with_file"));
481 ASSERT_TRUE(extension);
482
483 // The extension shouldn't sync.
484 EXPECT_FALSE(extensions::util::ShouldSync(extension.get(), profile()));
485 const std::string kExtensionId = extension->id();
486 ASSERT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
487
488 syncer::FakeSyncChangeProcessor* processor_raw = nullptr;
489 {
490 auto processor = base::MakeUnique<syncer::FakeSyncChangeProcessor>();
491 processor_raw = processor.get();
492 extension_sync_service()->MergeDataAndStartSyncing(
493 syncer::EXTENSIONS, syncer::SyncDataList(), std::move(processor),
494 base::MakeUnique<syncer::SyncErrorFactoryMock>());
495 }
496 processor_raw->changes().clear();
497
498 // Sync state says the extension is disabled (e.g. on another machine).
499 DisableExtensionFromSync(*extension, Extension::DISABLE_USER_ACTION);
500
501 // The extension should still be enabled, since it's default-installed.
502 EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
503 EXPECT_TRUE(processor_raw->changes().empty());
504
505 // Now disable the extension locally. Sync should *not* push new state.
506 service()->DisableExtension(kExtensionId, Extension::DISABLE_USER_ACTION);
507 EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
508 EXPECT_TRUE(processor_raw->changes().empty());
509
510 // Sync state says the extension is enabled.
511 EnableExtensionFromSync(*extension);
512
513 // As above, the extension should not have been affected by sync.
514 EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
515 EXPECT_TRUE(processor_raw->changes().empty());
516
517 // And re-enabling the extension should not push new state to sync.
518 service()->EnableExtension(kExtensionId);
519 EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
520 EXPECT_TRUE(processor_raw->changes().empty());
521 }
522
343 TEST_F(ExtensionServiceSyncTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) { 523 TEST_F(ExtensionServiceSyncTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) {
344 // Start the extension service with three extensions already installed. 524 // Start the extension service with three extensions already installed.
345 base::FilePath source_install_dir = 525 base::FilePath source_install_dir =
346 data_dir().AppendASCII("good").AppendASCII("Extensions"); 526 data_dir().AppendASCII("good").AppendASCII("Extensions");
347 base::FilePath pref_path = 527 base::FilePath pref_path =
348 source_install_dir.DirName().Append(chrome::kPreferencesFilename); 528 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
349 529
350 InitializeInstalledExtensionService(pref_path, source_install_dir); 530 InitializeInstalledExtensionService(pref_path, source_install_dir);
351 531
352 // The user has enabled sync. 532 // The user has enabled sync.
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id)); 1535 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
1356 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id)); 1536 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
1357 1537
1358 // Remove the extension again, so we can install it again for the next case. 1538 // Remove the extension again, so we can install it again for the next case.
1359 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED 1539 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
1360 : Extension::DISABLED); 1540 : Extension::DISABLED);
1361 } 1541 }
1362 } 1542 }
1363 1543
1364 TEST_F(ExtensionServiceSyncTest, ProcessSyncDataDeferredEnable) { 1544 TEST_F(ExtensionServiceSyncTest, ProcessSyncDataDeferredEnable) {
1545 // The permissions_increase test extension has a different update URL.
1546 // In order to make it syncable, we have to pretend it syncs from the
1547 // webstore.
1548 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1549 switches::kAppsGalleryUpdateURL,
1550 "http://localhost/autoupdate/updates.xml");
1551
1365 InitializeEmptyExtensionService(); 1552 InitializeEmptyExtensionService();
1366 extension_sync_service()->MergeDataAndStartSyncing( 1553 extension_sync_service()->MergeDataAndStartSyncing(
1367 syncer::EXTENSIONS, syncer::SyncDataList(), 1554 syncer::EXTENSIONS, syncer::SyncDataList(),
1368 base::MakeUnique<syncer::FakeSyncChangeProcessor>(), 1555 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
1369 base::MakeUnique<syncer::SyncErrorFactoryMock>()); 1556 base::MakeUnique<syncer::SyncErrorFactoryMock>());
1370 1557
1371 base::FilePath base_path = data_dir().AppendASCII("permissions_increase"); 1558 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
1372 base::FilePath pem_path = base_path.AppendASCII("permissions.pem"); 1559 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
1373 1560
1374 base::FilePath path = base_path.AppendASCII("v1"); 1561 base::FilePath path = base_path.AppendASCII("v1");
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 break; 2661 break;
2475 } 2662 }
2476 } 2663 }
2477 } 2664 }
2478 EXPECT_TRUE(found_delete); 2665 EXPECT_TRUE(found_delete);
2479 2666
2480 // Make sure there is one extension, and there are no more apps. 2667 // Make sure there is one extension, and there are no more apps.
2481 EXPECT_EQ(1u, extensions_processor.data().size()); 2668 EXPECT_EQ(1u, extensions_processor.data().size());
2482 EXPECT_TRUE(apps_processor.data().empty()); 2669 EXPECT_TRUE(apps_processor.data().empty());
2483 } 2670 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/chrome_test_extension_loader.cc ('k') | chrome/browser/extensions/extension_sync_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698