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

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

Powered by Google App Engine
This is Rietveld 408576698