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

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

Issue 8375047: Separate the syncing of extension settings and app settings into separate data (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/extensions/extension_settings_frontend.h" 5 #include "chrome/browser/extensions/extension_settings_frontend.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "chrome/browser/extensions/extension_event_names.h" 9 #include "chrome/browser/extensions/extension_event_names.h"
10 #include "chrome/browser/extensions/extension_event_router.h" 10 #include "chrome/browser/extensions/extension_event_router.h"
11 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_settings_backend.h" 12 #include "chrome/browser/extensions/extension_settings_backend.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/notification_service.h" 15 #include "content/public/browser/notification_service.h"
16 16
17 namespace {
18
19 struct Backends {
20 Backends(
21 const FilePath& profile_path,
22 const scoped_refptr<ExtensionSettingsObserverList>& observers)
23 : extensions_backend_(
24 profile_path.AppendASCII(
25 ExtensionService::kExtensionSettingsDirectoryName),
26 observers),
27 apps_backend_(
28 profile_path.AppendASCII(
29 ExtensionService::kAppSettingsDirectoryName),
30 observers) {}
31
32 ExtensionSettingsBackend extensions_backend_;
33 ExtensionSettingsBackend apps_backend_;
34 };
35
36 static void CallbackWithExtensionsBackend(
37 const ExtensionSettingsFrontend::SyncableServiceCallback& callback,
38 Backends* backends) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
40 callback.Run(&backends->extensions_backend_);
41 }
42
43 void CallbackWithAppsBackend(
44 const ExtensionSettingsFrontend::SyncableServiceCallback& callback,
45 Backends* backends) {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
47 callback.Run(&backends->apps_backend_);
48 }
49
50 void CallbackWithExtensionsStorage(
51 const std::string& extension_id,
52 const ExtensionSettingsFrontend::StorageCallback& callback,
53 Backends* backends) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
55 callback.Run(backends->extensions_backend_.GetStorage(extension_id));
56 }
57
58 void CallbackWithAppsStorage(
59 const std::string& extension_id,
60 const ExtensionSettingsFrontend::StorageCallback& callback,
61 Backends* backends) {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
63 callback.Run(backends->apps_backend_.GetStorage(extension_id));
64 }
65
66 void CallbackWithNullStorage(
67 const ExtensionSettingsFrontend::StorageCallback& callback) {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
69 callback.Run(NULL);
70 }
71
72 void DeleteStorageOnFileThread(
73 const std::string& extension_id, Backends* backends) {
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
75 backends->extensions_backend_.DeleteStorage(extension_id);
76 backends->apps_backend_.DeleteStorage(extension_id);
77 }
78
79 } // namespace
80
17 class ExtensionSettingsFrontend::DefaultObserver 81 class ExtensionSettingsFrontend::DefaultObserver
18 : public ExtensionSettingsObserver { 82 : public ExtensionSettingsObserver {
19 public: 83 public:
20 explicit DefaultObserver(Profile* profile) : target_profile_(profile) {} 84 explicit DefaultObserver(Profile* profile) : target_profile_(profile) {}
21 virtual ~DefaultObserver() {} 85 virtual ~DefaultObserver() {}
22 86
23 virtual void OnSettingsChanged( 87 virtual void OnSettingsChanged(
24 const Profile* origin_profile, 88 const Profile* origin_profile,
25 const std::string& extension_id, 89 const std::string& extension_id,
26 const ExtensionSettingChanges& changes) OVERRIDE { 90 const ExtensionSettingChanges& changes) OVERRIDE {
(...skipping 10 matching lines...) Expand all
37 } 101 }
38 102
39 private: 103 private:
40 Profile* target_profile_; 104 Profile* target_profile_;
41 }; 105 };
42 106
43 class ExtensionSettingsFrontend::Core 107 class ExtensionSettingsFrontend::Core
44 : public base::RefCountedThreadSafe<Core> { 108 : public base::RefCountedThreadSafe<Core> {
45 public: 109 public:
46 explicit Core( 110 explicit Core(
47 const scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >& 111 const scoped_refptr<ExtensionSettingsObserverList>& observers)
48 observers) 112 : observers_(observers), backends_(NULL) {
49 : observers_(observers), backend_(NULL) {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 } 114 }
52 115
116 typedef base::Callback<void(Backends*)> BackendsCallback;
117
53 // Does any FILE thread specific initialization, such as construction of 118 // Does any FILE thread specific initialization, such as construction of
54 // |backend_|. Must be called before any call to 119 // |backend_|. Must be called before any call to
55 // RunWithBackendOnFileThread(). 120 // RunWithBackendOnFileThread().
56 void InitOnFileThread(const FilePath& base_path) { 121 void InitOnFileThread(const FilePath& profile_path) {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
58 DCHECK(!backend_); 123 DCHECK(!backends_);
59 backend_ = new ExtensionSettingsBackend(base_path, observers_); 124 backends_ = new Backends(profile_path, observers_);
60 } 125 }
61 126
62 // Runs |callback| with the extension backend. 127 // Runs |callback| with both the extensions and apps settings on the FILE
63 void RunWithBackendOnFileThread(const BackendCallback& callback) { 128 // thread.
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 129 void RunWithBackends(const BackendsCallback& callback) {
65 DCHECK(backend_); 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
66 callback.Run(backend_); 131 BrowserThread::PostTask(
132 BrowserThread::FILE,
133 FROM_HERE,
134 base::Bind(
135 &ExtensionSettingsFrontend::Core::RunWithBackendsOnFileThread,
136 this,
137 callback));
67 } 138 }
68 139
69 private: 140 private:
141 void RunWithBackendsOnFileThread(const BackendsCallback& callback) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
143 DCHECK(backends_);
144 callback.Run(backends_);
145 }
146
70 virtual ~Core() { 147 virtual ~Core() {
71 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 148 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
72 delete backend_; 149 delete backends_;
73 } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 150 } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
74 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backend_); 151 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backends_);
75 } else { 152 } else {
76 NOTREACHED(); 153 NOTREACHED();
77 } 154 }
78 } 155 }
79 156
80 friend class base::RefCountedThreadSafe<Core>; 157 friend class base::RefCountedThreadSafe<Core>;
81 158
82 // Observers to settings changes (thread safe). 159 // Observers to settings changes (thread safe).
83 scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> > 160 scoped_refptr<ExtensionSettingsObserverList> observers_;
84 observers_;
85 161
86 // Lives on the FILE thread. 162 // Backends for extensions and apps settings. Lives on FILE thread.
87 ExtensionSettingsBackend* backend_; 163 Backends* backends_;
88 164
89 DISALLOW_COPY_AND_ASSIGN(Core); 165 DISALLOW_COPY_AND_ASSIGN(Core);
90 }; 166 };
91 167
92 ExtensionSettingsFrontend::ExtensionSettingsFrontend(Profile* profile) 168 ExtensionSettingsFrontend::ExtensionSettingsFrontend(Profile* profile)
93 : profile_(profile), 169 : profile_(profile),
94 observers_(new ObserverListThreadSafe<ExtensionSettingsObserver>()), 170 observers_(new ExtensionSettingsObserverList()),
95 core_(new ExtensionSettingsFrontend::Core(observers_.get())) { 171 core_(new ExtensionSettingsFrontend::Core(observers_)) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 DCHECK(!profile->IsOffTheRecord()); 173 DCHECK(!profile->IsOffTheRecord());
98 174
99 // This class listens to all PROFILE_{CREATED,DESTROYED} events but we're 175 // This class listens to all PROFILE_{CREATED,DESTROYED} events but we're
100 // only interested in those for the original Profile given on construction 176 // only interested in those for the original Profile given on construction
101 // and its incognito version. 177 // and its incognito version.
102 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, 178 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
103 content::NotificationService::AllBrowserContextsAndSources()); 179 content::NotificationService::AllBrowserContextsAndSources());
104 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 180 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
105 content::NotificationService::AllBrowserContextsAndSources()); 181 content::NotificationService::AllBrowserContextsAndSources());
106 OnProfileCreated(profile); 182 OnProfileCreated(profile);
107 183
108 BrowserThread::PostTask( 184 BrowserThread::PostTask(
109 BrowserThread::FILE, 185 BrowserThread::FILE,
110 FROM_HERE, 186 FROM_HERE,
111 base::Bind( 187 base::Bind(
112 &ExtensionSettingsFrontend::Core::InitOnFileThread, 188 &ExtensionSettingsFrontend::Core::InitOnFileThread,
113 core_.get(), 189 core_.get(),
114 profile->GetPath().AppendASCII( 190 profile->GetPath()));
115 ExtensionService::kSettingsDirectoryName)));
116 } 191 }
117 192
118 ExtensionSettingsFrontend::~ExtensionSettingsFrontend() { 193 ExtensionSettingsFrontend::~ExtensionSettingsFrontend() {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120 } 195 }
121 196
122 void ExtensionSettingsFrontend::RunWithBackend( 197 void ExtensionSettingsFrontend::RunWithSyncableService(
123 const BackendCallback& callback) { 198 syncable::ModelType model_type, const SyncableServiceCallback& callback) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 BrowserThread::PostTask( 200 switch (model_type) {
126 BrowserThread::FILE, 201 case syncable::EXTENSION_SETTINGS:
127 FROM_HERE, 202 core_->RunWithBackends(
128 base::Bind( 203 base::Bind(&CallbackWithExtensionsBackend, callback));
129 &ExtensionSettingsFrontend::Core::RunWithBackendOnFileThread, 204 break;
130 core_.get(), 205 case syncable::APP_SETTINGS:
131 callback)); 206 core_->RunWithBackends(
207 base::Bind(&CallbackWithAppsBackend, callback));
208 break;
209 default:
210 NOTREACHED();
211 }
132 } 212 }
133 213
134 void ExtensionSettingsFrontend::AddObserver( 214 void ExtensionSettingsFrontend::RunWithStorage(
135 ExtensionSettingsObserver* observer) { 215 const std::string& extension_id,
136 observers_->AddObserver(observer); 216 const StorageCallback& callback) {
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
218
219 const Extension* extension =
220 profile_->GetExtensionService()->GetExtensionById(extension_id, true);
221 if (!extension) {
222 BrowserThread::PostTask(
223 BrowserThread::FILE,
224 FROM_HERE,
225 base::Bind(&CallbackWithNullStorage, callback));
226 return;
227 }
228
229 if (extension->is_app()) {
230 core_->RunWithBackends(
231 base::Bind(&CallbackWithAppsStorage, extension_id, callback));
232 } else {
233 core_->RunWithBackends(
234 base::Bind(&CallbackWithExtensionsStorage, extension_id, callback));
235 }
137 } 236 }
138 237
139 void ExtensionSettingsFrontend::RemoveObserver( 238 void ExtensionSettingsFrontend::DeleteStorageSoon(
140 ExtensionSettingsObserver* observer) { 239 const std::string& extension_id) {
141 observers_->RemoveObserver(observer); 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 core_->RunWithBackends(base::Bind(&DeleteStorageOnFileThread, extension_id));
242 }
243
244 scoped_refptr<ExtensionSettingsObserverList>
245 ExtensionSettingsFrontend::GetObservers() {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247 return observers_;
142 } 248 }
143 249
144 void ExtensionSettingsFrontend::Observe( 250 void ExtensionSettingsFrontend::Observe(
145 int type, 251 int type,
146 const content::NotificationSource& source, 252 const content::NotificationSource& source,
147 const content::NotificationDetails& details) { 253 const content::NotificationDetails& details) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 switch (type) { 255 switch (type) {
150 case chrome::NOTIFICATION_PROFILE_CREATED: 256 case chrome::NOTIFICATION_PROFILE_CREATED:
151 OnProfileCreated(content::Source<Profile>(source).ptr()); 257 OnProfileCreated(content::Source<Profile>(source).ptr());
(...skipping 25 matching lines...) Expand all
177 } else if (old_profile->GetOriginalProfile() == profile_) { 283 } else if (old_profile->GetOriginalProfile() == profile_) {
178 DCHECK(old_profile->IsOffTheRecord()); 284 DCHECK(old_profile->IsOffTheRecord());
179 ClearDefaultObserver(&incognito_profile_observer_); 285 ClearDefaultObserver(&incognito_profile_observer_);
180 } 286 }
181 } 287 }
182 288
183 void ExtensionSettingsFrontend::SetDefaultObserver( 289 void ExtensionSettingsFrontend::SetDefaultObserver(
184 Profile* profile, scoped_ptr<DefaultObserver>* observer) { 290 Profile* profile, scoped_ptr<DefaultObserver>* observer) {
185 DCHECK(!observer->get()); 291 DCHECK(!observer->get());
186 observer->reset(new DefaultObserver(profile)); 292 observer->reset(new DefaultObserver(profile));
187 AddObserver(observer->get()); 293 observers_->AddObserver(observer->get());
188 } 294 }
189 295
190 void ExtensionSettingsFrontend::ClearDefaultObserver( 296 void ExtensionSettingsFrontend::ClearDefaultObserver(
191 scoped_ptr<DefaultObserver>* observer) { 297 scoped_ptr<DefaultObserver>* observer) {
192 if (observer->get()) { 298 if (observer->get()) {
193 RemoveObserver(observer->get()); 299 observers_->RemoveObserver(observer->get());
194 observer->reset(); 300 observer->reset();
195 } 301 }
196 } 302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698