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

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

Powered by Google App Engine
This is Rietveld 408576698