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

Side by Side Diff: chrome/browser/sync/glue/extension_change_processor.cc

Issue 3110008: Massive refactoring of extensions sync code (Closed) Base URL: 76.121.192.83:~/projects/chromium/src
Patch Set: Fixed compile error Created 10 years, 4 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 (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/sync/glue/extension_change_processor.h" 5 #include "chrome/browser/sync/glue/extension_change_processor.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 #include <string> 8 #include <string>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "chrome/browser/chrome_thread.h" 11 #include "chrome/browser/chrome_thread.h"
12 #include "chrome/browser/sync/engine/syncapi.h" 12 #include "chrome/browser/profile.h"
13 #include "chrome/browser/sync/glue/extension_model_associator.h" 13 #include "chrome/browser/extensions/extensions_service.h"
14 #include "chrome/browser/sync/glue/extension_sync.h"
14 #include "chrome/browser/sync/glue/extension_util.h" 15 #include "chrome/browser/sync/glue/extension_util.h"
16 #include "chrome/browser/sync/protocol/extension_specifics.pb.h"
15 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
16 #include "chrome/common/notification_details.h" 18 #include "chrome/common/notification_details.h"
17 #include "chrome/common/notification_source.h" 19 #include "chrome/common/notification_source.h"
18 20
19 namespace browser_sync { 21 namespace browser_sync {
20 22
21 ExtensionChangeProcessor::ExtensionChangeProcessor( 23 ExtensionChangeProcessor::ExtensionChangeProcessor(
22 UnrecoverableErrorHandler* error_handler, 24 UnrecoverableErrorHandler* error_handler)
23 ExtensionModelAssociator* extension_model_associator)
24 : ChangeProcessor(error_handler), 25 : ChangeProcessor(error_handler),
25 extension_model_associator_(extension_model_associator), 26 traits_(GetExtensionSyncTraits()),
26 profile_(NULL) { 27 profile_(NULL) {
27 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 28 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
28 DCHECK(error_handler); 29 DCHECK(error_handler);
29 DCHECK(extension_model_associator_);
30 } 30 }
31 31
32 ExtensionChangeProcessor::~ExtensionChangeProcessor() { 32 ExtensionChangeProcessor::~ExtensionChangeProcessor() {
33 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 33 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
34 } 34 }
35 35
36 // TODO(akalin): We need to make sure events we receive from either 36 // TODO(akalin): We need to make sure events we receive from either
37 // the browser or the syncapi are done in order; this is tricky since 37 // the browser or the syncapi are done in order; this is tricky since
38 // some events (e.g., extension installation) are done asynchronously. 38 // some events (e.g., extension installation) are done asynchronously.
39 39
40 void ExtensionChangeProcessor::Observe(NotificationType type, 40 void ExtensionChangeProcessor::Observe(NotificationType type,
41 const NotificationSource& source, 41 const NotificationSource& source,
42 const NotificationDetails& details) { 42 const NotificationDetails& details) {
43 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 43 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
44 DCHECK(running()); 44 DCHECK(running());
45 DCHECK(profile_); 45 DCHECK(profile_);
46 switch (type.value) { 46 if ((type != NotificationType::EXTENSION_LOADED) &&
47 case NotificationType::EXTENSION_LOADED: 47 (type != NotificationType::EXTENSION_UPDATE_DISABLED) &&
48 case NotificationType::EXTENSION_UPDATE_DISABLED: 48 (type != NotificationType::EXTENSION_UNLOADED) &&
49 case NotificationType::EXTENSION_UNLOADED: 49 (type != NotificationType::EXTENSION_UNLOADED_DISABLED)) {
50 case NotificationType::EXTENSION_UNLOADED_DISABLED: { 50 LOG(DFATAL) << "Received unexpected notification of type "
51 DCHECK_EQ(Source<Profile>(source).ptr(), profile_); 51 << type.value;
52 Extension* extension = Details<Extension>(details).ptr(); 52 return;
53 CHECK(extension); 53 }
54 // Ignore non-syncable extensions. 54 DCHECK_EQ(Source<Profile>(source).ptr(), profile_);
55 if (!IsExtensionSyncable(*extension)) { 55 const Extension* extension = Details<Extension>(details).ptr();
56 return; 56 CHECK(extension);
57 } 57 // Ignore non-syncable extensions.
58 const std::string& id = extension->id(); 58 if (!IsExtensionValidAndSyncable(
59 LOG(INFO) << "Got change notification of type " << type.value 59 *extension, traits_.allowed_extension_types)) {
60 << " for extension " << id; 60 return;
61 if (!extension_model_associator_->OnClientUpdate(id)) { 61 }
62 std::string error = std::string("Client update failed for ") + id; 62 const std::string& id = extension->id();
63 error_handler()->OnUnrecoverableError(FROM_HERE, error); 63 LOG(INFO) << "Got notification of type " << type.value
64 return; 64 << " for extension " << id;
65 } 65 ExtensionsService* extensions_service =
66 break; 66 GetExtensionsServiceFromProfile(profile_);
67 // Whether an extension is loaded or not isn't an indicator of
68 // whether it's installed or not; some extension actions unload and
69 // then reload an extension to force listeners to update.
70 bool extension_installed =
71 (extensions_service->GetExtensionById(id, true) != NULL);
72 if (extension_installed) {
73 LOG(INFO) << "Extension " << id
74 << " is installed; updating server data";
75 std::string error;
76 if (!UpdateServerData(traits_, *extension,
77 profile_->GetProfileSyncService(), &error)) {
78 error_handler()->OnUnrecoverableError(FROM_HERE, error);
67 } 79 }
68 default: 80 } else {
69 LOG(DFATAL) << "Received unexpected notification of type " 81 LOG(INFO) << "Extension " << id
70 << type.value; 82 << " is not installed; removing server data";
71 break; 83 RemoveServerData(traits_, *extension,
84 profile_->GetProfileSyncService());
72 } 85 }
73 } 86 }
74 87
75 void ExtensionChangeProcessor::ApplyChangesFromSyncModel( 88 void ExtensionChangeProcessor::ApplyChangesFromSyncModel(
76 const sync_api::BaseTransaction* trans, 89 const sync_api::BaseTransaction* trans,
77 const sync_api::SyncManager::ChangeRecord* changes, 90 const sync_api::SyncManager::ChangeRecord* changes,
78 int change_count) { 91 int change_count) {
79 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 92 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
80 if (!running()) { 93 if (!running()) {
81 return; 94 return;
82 } 95 }
96 ExtensionsService* extensions_service =
97 GetExtensionsServiceFromProfile(profile_);
83 for (int i = 0; i < change_count; ++i) { 98 for (int i = 0; i < change_count; ++i) {
84 const sync_api::SyncManager::ChangeRecord& change = changes[i]; 99 const sync_api::SyncManager::ChangeRecord& change = changes[i];
85 switch (change.action) { 100 switch (change.action) {
86 case sync_api::SyncManager::ChangeRecord::ACTION_ADD: 101 case sync_api::SyncManager::ChangeRecord::ACTION_ADD:
87 case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: { 102 case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
88 sync_api::ReadNode node(trans); 103 sync_api::ReadNode node(trans);
89 if (!node.InitByIdLookup(change.id)) { 104 if (!node.InitByIdLookup(change.id)) {
90 std::stringstream error; 105 std::stringstream error;
91 error << "Extension node lookup failed for change " << change.id 106 error << "Extension node lookup failed for change " << change.id
92 << " of action type " << change.action; 107 << " of action type " << change.action;
93 error_handler()->OnUnrecoverableError(FROM_HERE, error.str()); 108 error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
94 return; 109 return;
95 } 110 }
96 DCHECK_EQ(node.GetModelType(), syncable::EXTENSIONS); 111 DCHECK_EQ(node.GetModelType(), traits_.model_type);
97 const sync_pb::ExtensionSpecifics& specifics = 112 const sync_pb::ExtensionSpecifics& specifics =
98 node.GetExtensionSpecifics(); 113 (*traits_.extension_specifics_getter)(node);
99 if (!IsExtensionSpecificsValid(specifics)) { 114 if (!IsExtensionSpecificsValid(specifics)) {
100 std::string error = 115 std::string error =
101 std::string("Invalid server specifics: ") + 116 std::string("Invalid server specifics: ") +
102 ExtensionSpecificsToString(specifics); 117 ExtensionSpecificsToString(specifics);
103 error_handler()->OnUnrecoverableError(FROM_HERE, error); 118 error_handler()->OnUnrecoverableError(FROM_HERE, error);
104 return; 119 return;
105 } 120 }
106 StopObserving(); 121 StopObserving();
107 extension_model_associator_->OnServerUpdate(specifics); 122 UpdateClient(traits_, specifics, extensions_service);
108 StartObserving(); 123 StartObserving();
109 break; 124 break;
110 } 125 }
111 case sync_api::SyncManager::ChangeRecord::ACTION_DELETE: { 126 case sync_api::SyncManager::ChangeRecord::ACTION_DELETE: {
112 StopObserving(); 127 sync_pb::ExtensionSpecifics specifics;
113 if (change.specifics.HasExtension(sync_pb::extension)) { 128 if ((*traits_.extension_specifics_entity_getter)(
114 extension_model_associator_->OnServerRemove( 129 change.specifics, &specifics)) {
115 change.specifics.GetExtension(sync_pb::extension).id()); 130 StopObserving();
131 RemoveFromClient(traits_, specifics.id(), extensions_service);
132 StartObserving();
116 } else { 133 } else {
117 std::stringstream error; 134 std::stringstream error;
118 error << "Could not get extension ID for deleted node " 135 error << "Could not get extension ID for deleted node "
119 << change.id; 136 << change.id;
120 error_handler()->OnUnrecoverableError(FROM_HERE, error.str()); 137 error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
121 LOG(DFATAL) << error.str(); 138 LOG(DFATAL) << error.str();
122 } 139 }
123 StartObserving();
124 break; 140 break;
125 } 141 }
126 } 142 }
127 } 143 }
128 } 144 }
129 145
130 void ExtensionChangeProcessor::StartImpl(Profile* profile) { 146 void ExtensionChangeProcessor::StartImpl(Profile* profile) {
131 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 147 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
132 DCHECK(profile); 148 DCHECK(profile);
133 profile_ = profile; 149 profile_ = profile;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 181 }
166 182
167 void ExtensionChangeProcessor::StopObserving() { 183 void ExtensionChangeProcessor::StopObserving() {
168 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 184 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
169 DCHECK(profile_); 185 DCHECK(profile_);
170 LOG(INFO) << "Unobserving all notifications"; 186 LOG(INFO) << "Unobserving all notifications";
171 notification_registrar_.RemoveAll(); 187 notification_registrar_.RemoveAll();
172 } 188 }
173 189
174 } // namespace browser_sync 190 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/extension_change_processor.h ('k') | chrome/browser/sync/glue/extension_model_associator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698