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

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

Issue 8361027: Re-commit 106660 with the crashing test disabled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 9 years, 2 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 | 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"
10 #include "chrome/browser/extensions/extension_event_router.h"
11 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_settings_backend.h" 12 #include "chrome/browser/extensions/extension_settings_backend.h"
13 #include "chrome/browser/profiles/profile.h"
10 #include "content/browser/browser_thread.h" 14 #include "content/browser/browser_thread.h"
15 #include "content/public/browser/notification_service.h"
11 16
12 ExtensionSettingsFrontend::ExtensionSettingsFrontend( 17 class ExtensionSettingsFrontend::DefaultObserver
13 const FilePath& base_path) 18 : public ExtensionSettingsObserver {
14 : core_(new ExtensionSettingsFrontend::Core()) { 19 public:
20 explicit DefaultObserver(Profile* profile) : target_profile_(profile) {}
21 virtual ~DefaultObserver() {}
22
23 virtual void OnSettingsChanged(
24 const Profile* origin_profile,
25 const std::string& extension_id,
26 const ExtensionSettingChanges& changes) OVERRIDE {
27 if (origin_profile != target_profile_) {
28 target_profile_->GetExtensionEventRouter()->DispatchEventToExtension(
29 extension_id,
30 extension_event_names::kOnSettingsChanged,
31 // This is the list of function arguments to pass to the onChanged
32 // handler of extensions, a single argument with the list of changes.
33 std::string("[") + changes.ToJson() + "]",
34 target_profile_,
35 GURL());
36 }
37 }
38
39 private:
40 Profile* target_profile_;
41 };
42
43 class ExtensionSettingsFrontend::Core
44 : public base::RefCountedThreadSafe<Core> {
45 public:
46 explicit Core(
47 const scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >&
48 observers)
49 : observers_(observers), backend_(NULL) {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 }
52
53 // Does any FILE thread specific initialization, such as construction of
54 // |backend_|. Must be called before any call to
55 // RunWithBackendOnFileThread().
56 void InitOnFileThread(const FilePath& base_path) {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
58 DCHECK(!backend_);
59 backend_ = new ExtensionSettingsBackend(base_path, observers_);
60 }
61
62 // Runs |callback| with the extension backend.
63 void RunWithBackendOnFileThread(const BackendCallback& callback) {
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
65 DCHECK(backend_);
66 callback.Run(backend_);
67 }
68
69 private:
70 virtual ~Core() {
71 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
72 delete backend_;
73 } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
74 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backend_);
75 } else {
76 NOTREACHED();
77 }
78 }
79
80 friend class base::RefCountedThreadSafe<Core>;
81
82 // Observers to settings changes (thread safe).
83 scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >
84 observers_;
85
86 // Lives on the FILE thread.
87 ExtensionSettingsBackend* backend_;
88
89 DISALLOW_COPY_AND_ASSIGN(Core);
90 };
91
92 ExtensionSettingsFrontend::ExtensionSettingsFrontend(Profile* profile)
93 : profile_(profile),
94 observers_(new ObserverListThreadSafe<ExtensionSettingsObserver>()),
95 core_(new ExtensionSettingsFrontend::Core(observers_.get())) {
15 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 DCHECK(!profile->IsOffTheRecord());
98
99 // This class listens to all PROFILE_{CREATED,DESTROYED} events but we're
100 // only interested in those for the original Profile given on construction
101 // and its incognito version.
102 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
103 content::NotificationService::AllBrowserContextsAndSources());
104 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
105 content::NotificationService::AllBrowserContextsAndSources());
106 OnProfileCreated(profile);
107
16 BrowserThread::PostTask( 108 BrowserThread::PostTask(
17 BrowserThread::FILE, 109 BrowserThread::FILE,
18 FROM_HERE, 110 FROM_HERE,
19 base::Bind( 111 base::Bind(
20 &ExtensionSettingsFrontend::Core::InitOnFileThread, 112 &ExtensionSettingsFrontend::Core::InitOnFileThread,
21 core_.get(), 113 core_.get(),
22 base_path)); 114 profile->GetPath().AppendASCII(
115 ExtensionService::kSettingsDirectoryName)));
116 }
117
118 ExtensionSettingsFrontend::~ExtensionSettingsFrontend() {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
23 } 120 }
24 121
25 void ExtensionSettingsFrontend::RunWithBackend( 122 void ExtensionSettingsFrontend::RunWithBackend(
26 const BackendCallback& callback) { 123 const BackendCallback& callback) {
27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
28 BrowserThread::PostTask( 125 BrowserThread::PostTask(
29 BrowserThread::FILE, 126 BrowserThread::FILE,
30 FROM_HERE, 127 FROM_HERE,
31 base::Bind( 128 base::Bind(
32 &ExtensionSettingsFrontend::Core::RunWithBackendOnFileThread, 129 &ExtensionSettingsFrontend::Core::RunWithBackendOnFileThread,
33 core_.get(), 130 core_.get(),
34 callback)); 131 callback));
35 } 132 }
36 133
37 ExtensionSettingsFrontend::~ExtensionSettingsFrontend() { 134 void ExtensionSettingsFrontend::AddObserver(
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 135 ExtensionSettingsObserver* observer) {
136 observers_->AddObserver(observer);
39 } 137 }
40 138
41 ExtensionSettingsFrontend::Core::Core() : backend_(NULL) { 139 void ExtensionSettingsFrontend::RemoveObserver(
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 140 ExtensionSettingsObserver* observer) {
141 observers_->RemoveObserver(observer);
43 } 142 }
44 143
45 void ExtensionSettingsFrontend::Core::InitOnFileThread( 144 void ExtensionSettingsFrontend::Observe(
46 const FilePath& base_path) { 145 int type,
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 146 const content::NotificationSource& source,
48 DCHECK(!backend_); 147 const content::NotificationDetails& details) {
49 backend_ = new ExtensionSettingsBackend(base_path); 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 switch (type) {
150 case chrome::NOTIFICATION_PROFILE_CREATED:
151 OnProfileCreated(content::Source<Profile>(source).ptr());
152 break;
153 case chrome::NOTIFICATION_PROFILE_DESTROYED:
154 OnProfileDestroyed(content::Source<Profile>(source).ptr());
155 break;
156 default:
157 NOTREACHED();
158 }
50 } 159 }
51 160
52 void ExtensionSettingsFrontend::Core::RunWithBackendOnFileThread( 161 void ExtensionSettingsFrontend::OnProfileCreated(Profile* new_profile) {
53 const BackendCallback& callback) { 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 163 if (new_profile == profile_) {
55 DCHECK(backend_); 164 ClearDefaultObserver(&original_profile_observer);
56 callback.Run(backend_); 165 SetDefaultObserver(new_profile, &original_profile_observer);
166 } else if (new_profile->GetOriginalProfile() == profile_) {
167 DCHECK(new_profile->IsOffTheRecord());
168 ClearDefaultObserver(&incognito_profile_observer_);
169 SetDefaultObserver(new_profile, &incognito_profile_observer_);
170 }
57 } 171 }
58 172
59 ExtensionSettingsFrontend::Core::~Core() { 173 void ExtensionSettingsFrontend::OnProfileDestroyed(Profile* old_profile) {
60 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
61 delete backend_; 175 if (old_profile == profile_) {
62 } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 176 ClearDefaultObserver(&original_profile_observer);
63 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backend_); 177 } else if (old_profile->GetOriginalProfile() == profile_) {
64 } else { 178 DCHECK(old_profile->IsOffTheRecord());
65 NOTREACHED(); 179 ClearDefaultObserver(&incognito_profile_observer_);
66 } 180 }
67 } 181 }
182
183 void ExtensionSettingsFrontend::SetDefaultObserver(
184 Profile* profile, scoped_ptr<DefaultObserver>* observer) {
185 DCHECK(!observer->get());
186 observer->reset(new DefaultObserver(profile));
187 AddObserver(observer->get());
188 }
189
190 void ExtensionSettingsFrontend::ClearDefaultObserver(
191 scoped_ptr<DefaultObserver>* observer) {
192 if (observer->get()) {
193 RemoveObserver(observer->get());
194 observer->reset();
195 }
196 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698