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

Side by Side Diff: extensions/test/extension_test_notification_observer.cc

Issue 2393343002: Split ExtensionTestObserver and move to //extensions. (Closed)
Patch Set: fix bug in ActivityLogApiTest.TriggerEvent Created 4 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
« no previous file with comments | « extensions/test/extension_test_notification_observer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_test_notification_observer.h" 5 #include "extensions/test/extension_test_notification_observer.h"
6 6
7 #include <stddef.h> 7 #include "content/public/browser/browser_context.h"
8 8 #include "content/public/browser/notification_details.h"
9 #include "base/callback_list.h"
10 #include "base/scoped_observer.h"
11 #include "chrome/browser/extensions/extension_action_test_util.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/extension_util.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "content/public/browser/notification_registrar.h" 9 #include "content/public/browser/notification_registrar.h"
19 #include "content/public/browser/notification_service.h" 10 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/render_frame_host.h"
21 #include "content/public/test/test_utils.h" 12 #include "content/public/test/test_utils.h"
22 #include "extensions/browser/extension_system.h" 13 #include "extensions/browser/extension_registry.h"
14 #include "extensions/browser/notification_types.h"
23 #include "extensions/browser/process_manager.h" 15 #include "extensions/browser/process_manager.h"
24 #include "extensions/browser/process_manager_observer.h"
25 #include "extensions/common/extension.h" 16 #include "extensions/common/extension.h"
26 17
27 using extensions::Extension; 18 using extensions::Extension;
28 19
29 namespace { 20 namespace {
30 21
31 // A callback that returns true if the condition has been met and takes no 22 // A callback that returns true if the condition has been met and takes no
32 // arguments. 23 // arguments.
33 typedef base::Callback<bool(void)> ConditionCallback; 24 using ConditionCallback = base::Callback<bool(void)>;
34 25
35 bool HasPageActionVisibilityReachedTarget( 26 const Extension* GetNonTerminatedExtensions(const std::string& id,
36 Browser* browser, size_t target_visible_page_action_count) { 27 content::BrowserContext* context) {
37 return extensions::extension_action_test_util::GetVisiblePageActionCount( 28 return extensions::ExtensionRegistry::Get(context)->GetExtensionById(
38 browser->tab_strip_model()->GetActiveWebContents()) == 29 id, extensions::ExtensionRegistry::EVERYTHING &
39 target_visible_page_action_count; 30 ~extensions::ExtensionRegistry::TERMINATED);
40 }
41
42 bool HaveAllExtensionRenderFrameHostsFinishedLoading(
43 extensions::ProcessManager* manager) {
44 extensions::ProcessManager::FrameSet all_views = manager->GetAllFrames();
45 for (content::RenderFrameHost* host : manager->GetAllFrames()) {
46 if (content::WebContents::FromRenderFrameHost(host)->IsLoading())
47 return false;
48 }
49 return true;
50 }
51
52 bool IsExtensionNotIdle(const std::string& extension_id,
53 content::BrowserContext* context) {
54 return !extensions::util::IsExtensionIdle(extension_id, context);
55 } 31 }
56 32
57 } // namespace 33 } // namespace
58 34
59 //////////////////////////////////////////////////////////////////////////////// 35 ////////////////////////////////////////////////////////////////////////////////
60 // ExtensionTestNotificationObserver::NotificationSet 36 // ExtensionTestNotificationObserver::NotificationSet
61 37
62 class ExtensionTestNotificationObserver::NotificationSet 38 ExtensionTestNotificationObserver::NotificationSet::NotificationSet()
63 : public content::NotificationObserver, 39 : process_manager_observer_(this) {}
64 public extensions::ProcessManagerObserver { 40 ExtensionTestNotificationObserver::NotificationSet::~NotificationSet() {}
65 public:
66 NotificationSet() : process_manager_observer_(this) {}
67 ~NotificationSet() override {}
68
69 void Add(int type, const content::NotificationSource& source);
70 void Add(int type);
71 void AddExtensionFrameUnregistration(extensions::ProcessManager* manager);
72
73 // Notified any time an Add()ed notification is received.
74 // The details of the notification are dropped.
75 base::CallbackList<void()>& callback_list() {
76 return callback_list_;
77 }
78
79 private:
80 // content::NotificationObserver:
81 void Observe(int type,
82 const content::NotificationSource& source,
83 const content::NotificationDetails& details) override;
84
85 // extensions::ProcessManagerObserver:
86 void OnExtensionFrameUnregistered(
87 const std::string& extension_id,
88 content::RenderFrameHost* render_frame_host) override;
89
90 content::NotificationRegistrar notification_registrar_;
91 base::CallbackList<void()> callback_list_;
92 ScopedObserver<extensions::ProcessManager, extensions::ProcessManagerObserver>
93 process_manager_observer_;
94 };
95 41
96 void ExtensionTestNotificationObserver::NotificationSet::Add( 42 void ExtensionTestNotificationObserver::NotificationSet::Add(
97 int type, 43 int type,
98 const content::NotificationSource& source) { 44 const content::NotificationSource& source) {
99 notification_registrar_.Add(this, type, source); 45 notification_registrar_.Add(this, type, source);
100 } 46 }
101 47
102 void ExtensionTestNotificationObserver::NotificationSet::Add(int type) { 48 void ExtensionTestNotificationObserver::NotificationSet::Add(int type) {
103 Add(type, content::NotificationService::AllSources()); 49 Add(type, content::NotificationService::AllSources());
104 } 50 }
(...skipping 13 matching lines...) Expand all
118 void ExtensionTestNotificationObserver::NotificationSet:: 64 void ExtensionTestNotificationObserver::NotificationSet::
119 OnExtensionFrameUnregistered(const std::string& extension_id, 65 OnExtensionFrameUnregistered(const std::string& extension_id,
120 content::RenderFrameHost* render_frame_host) { 66 content::RenderFrameHost* render_frame_host) {
121 callback_list_.Notify(); 67 callback_list_.Notify();
122 } 68 }
123 69
124 //////////////////////////////////////////////////////////////////////////////// 70 ////////////////////////////////////////////////////////////////////////////////
125 // ExtensionTestNotificationObserver 71 // ExtensionTestNotificationObserver
126 72
127 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver( 73 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver(
128 Browser* browser) 74 content::BrowserContext* context)
129 : browser_(browser), 75 : context_(context),
130 profile_(NULL),
131 extension_installs_observed_(0), 76 extension_installs_observed_(0),
132 extension_load_errors_observed_(0), 77 extension_load_errors_observed_(0),
133 crx_installers_done_observed_(0) { 78 crx_installers_done_observed_(0) {}
134 }
135 79
136 ExtensionTestNotificationObserver::~ExtensionTestNotificationObserver() {} 80 ExtensionTestNotificationObserver::~ExtensionTestNotificationObserver() {}
137 81
138 Profile* ExtensionTestNotificationObserver::GetProfile() {
139 if (!profile_) {
140 if (browser_)
141 profile_ = browser_->profile();
142 else
143 profile_ = ProfileManager::GetActiveUserProfile();
144 }
145 return profile_;
146 }
147
148 void ExtensionTestNotificationObserver::WaitForNotification( 82 void ExtensionTestNotificationObserver::WaitForNotification(
149 int notification_type) { 83 int notification_type) {
150 // TODO(bauerb): Using a WindowedNotificationObserver like this can break 84 // TODO(bauerb): Using a WindowedNotificationObserver like this can break
151 // easily, if the notification we're waiting for is sent before this method. 85 // easily, if the notification we're waiting for is sent before this method.
152 // Change it so that the WindowedNotificationObserver is constructed earlier. 86 // Change it so that the WindowedNotificationObserver is constructed earlier.
153 content::NotificationRegistrar registrar; 87 content::NotificationRegistrar registrar;
154 registrar.Add( 88 registrar.Add(this, notification_type,
155 this, notification_type, content::NotificationService::AllSources()); 89 content::NotificationService::AllSources());
156 content::WindowedNotificationObserver( 90 content::WindowedNotificationObserver(
157 notification_type, content::NotificationService::AllSources()).Wait(); 91 notification_type, content::NotificationService::AllSources())
158 } 92 .Wait();
159
160 bool ExtensionTestNotificationObserver::WaitForPageActionVisibilityChangeTo(
161 int count) {
162 extensions::ExtensionActionAPI::Get(GetProfile())->AddObserver(this);
163 WaitForCondition(
164 base::Bind(&HasPageActionVisibilityReachedTarget, browser_, count),
165 NULL);
166 extensions::ExtensionActionAPI::Get(GetProfile())->
167 RemoveObserver(this);
168 return true;
169 }
170
171 bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() {
172 extensions::ProcessManager* manager =
173 extensions::ProcessManager::Get(GetProfile());
174 NotificationSet notification_set;
175 notification_set.Add(content::NOTIFICATION_WEB_CONTENTS_DESTROYED);
176 notification_set.Add(content::NOTIFICATION_LOAD_STOP);
177 notification_set.AddExtensionFrameUnregistration(manager);
178 WaitForCondition(
179 base::Bind(&HaveAllExtensionRenderFrameHostsFinishedLoading, manager),
180 &notification_set);
181 return true;
182 }
183
184 bool ExtensionTestNotificationObserver::WaitForExtensionIdle(
185 const std::string& extension_id) {
186 NotificationSet notification_set;
187 notification_set.Add(content::NOTIFICATION_RENDERER_PROCESS_TERMINATED);
188 WaitForCondition(base::Bind(&extensions::util::IsExtensionIdle, extension_id,
189 GetProfile()),
190 &notification_set);
191 return true;
192 }
193
194 bool ExtensionTestNotificationObserver::WaitForExtensionNotIdle(
195 const std::string& extension_id) {
196 NotificationSet notification_set;
197 notification_set.Add(content::NOTIFICATION_LOAD_STOP);
198 WaitForCondition(base::Bind(&IsExtensionNotIdle, extension_id, GetProfile()),
199 &notification_set);
200 return true;
201 } 93 }
202 94
203 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() { 95 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() {
204 int before = extension_installs_observed_; 96 int before = extension_installs_observed_;
205 content::WindowedNotificationObserver( 97 content::WindowedNotificationObserver(
206 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, 98 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
207 content::NotificationService::AllSources()).Wait(); 99 content::NotificationService::AllSources())
100 .Wait();
208 return extension_installs_observed_ == before; 101 return extension_installs_observed_ == before;
209 } 102 }
210 103
211 void ExtensionTestNotificationObserver::WaitForExtensionLoad() { 104 void ExtensionTestNotificationObserver::WaitForExtensionLoad() {
212 WaitForNotification(extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED); 105 WaitForNotification(extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED);
213 } 106 }
214 107
215 void ExtensionTestNotificationObserver::WaitForExtensionAndViewLoad() {
216 this->WaitForExtensionLoad();
217 WaitForExtensionViewsToLoad();
218 }
219
220 bool ExtensionTestNotificationObserver::WaitForExtensionLoadError() { 108 bool ExtensionTestNotificationObserver::WaitForExtensionLoadError() {
221 int before = extension_load_errors_observed_; 109 int before = extension_load_errors_observed_;
222 WaitForNotification(extensions::NOTIFICATION_EXTENSION_LOAD_ERROR); 110 WaitForNotification(extensions::NOTIFICATION_EXTENSION_LOAD_ERROR);
223 return extension_load_errors_observed_ != before; 111 return extension_load_errors_observed_ != before;
224 } 112 }
225 113
226 bool ExtensionTestNotificationObserver::WaitForExtensionCrash( 114 bool ExtensionTestNotificationObserver::WaitForExtensionCrash(
227 const std::string& extension_id) { 115 const std::string& extension_id) {
228 ExtensionService* service = extensions::ExtensionSystem::Get( 116 if (!GetNonTerminatedExtensions(extension_id, context_)) {
229 GetProfile())->extension_service();
230
231 if (!service->GetExtensionById(extension_id, true)) {
232 // The extension is already unloaded, presumably due to a crash. 117 // The extension is already unloaded, presumably due to a crash.
233 return true; 118 return true;
234 } 119 }
120
235 content::WindowedNotificationObserver( 121 content::WindowedNotificationObserver(
236 extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 122 extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
237 content::NotificationService::AllSources()).Wait(); 123 content::NotificationService::AllSources())
238 return (service->GetExtensionById(extension_id, true) == NULL); 124 .Wait();
125 return (GetNonTerminatedExtensions(extension_id, context_) == NULL);
239 } 126 }
240 127
241 bool ExtensionTestNotificationObserver::WaitForCrxInstallerDone() { 128 bool ExtensionTestNotificationObserver::WaitForCrxInstallerDone() {
242 int before = crx_installers_done_observed_; 129 int before = crx_installers_done_observed_;
243 WaitForNotification(extensions::NOTIFICATION_CRX_INSTALLER_DONE); 130 WaitForNotification(extensions::NOTIFICATION_CRX_INSTALLER_DONE);
244 return crx_installers_done_observed_ == (before + 1); 131 return crx_installers_done_observed_ == before + 1;
245 } 132 }
246 133
247 void ExtensionTestNotificationObserver::Watch( 134 void ExtensionTestNotificationObserver::Watch(
248 int type, 135 int type,
249 const content::NotificationSource& source) { 136 const content::NotificationSource& source) {
250 CHECK(!observer_); 137 CHECK(!observer_);
251 observer_.reset(new content::WindowedNotificationObserver(type, source)); 138 observer_.reset(new content::WindowedNotificationObserver(type, source));
252 registrar_.Add(this, type, source); 139 registrar_.Add(this, type, source);
253 } 140 }
254 141
255 void ExtensionTestNotificationObserver::Wait() { 142 void ExtensionTestNotificationObserver::Wait() {
256 observer_->Wait(); 143 observer_->Wait();
257 144
258 registrar_.RemoveAll(); 145 registrar_.RemoveAll();
259 observer_.reset(); 146 observer_.reset();
260 } 147 }
261 148
262 void ExtensionTestNotificationObserver::Observe( 149 void ExtensionTestNotificationObserver::Observe(
263 int type, 150 int type,
264 const content::NotificationSource& source, 151 const content::NotificationSource& source,
265 const content::NotificationDetails& details) { 152 const content::NotificationDetails& details) {
266 switch (type) { 153 switch (type) {
267 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: 154 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
268 last_loaded_extension_id_ = 155 last_loaded_extension_id_ =
269 content::Details<const Extension>(details).ptr()->id(); 156 content::Details<const Extension>(details).ptr()->id();
270 VLOG(1) << "Got EXTENSION_LOADED notification."; 157 VLOG(1) << "Got EXTENSION_LOADED notification.";
271 break; 158 break;
272 159
273 case extensions::NOTIFICATION_CRX_INSTALLER_DONE: 160 case extensions::NOTIFICATION_CRX_INSTALLER_DONE:
274 VLOG(1) << "Got CRX_INSTALLER_DONE notification."; 161 VLOG(1) << "Got CRX_INSTALLER_DONE notification.";
275 { 162 {
276 const Extension* extension = 163 const Extension* extension =
277 content::Details<const Extension>(details).ptr(); 164 content::Details<const Extension>(details).ptr();
278 if (extension) 165 if (extension)
279 last_loaded_extension_id_ = extension->id(); 166 last_loaded_extension_id_ = extension->id();
280 else 167 else
281 last_loaded_extension_id_.clear(); 168 last_loaded_extension_id_.clear();
282 } 169 }
283 ++crx_installers_done_observed_; 170 ++crx_installers_done_observed_;
284 break; 171 break;
285 172
286 case extensions::NOTIFICATION_EXTENSION_LOAD_ERROR: 173 case extensions::NOTIFICATION_EXTENSION_LOAD_ERROR:
287 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification."; 174 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification.";
288 ++extension_load_errors_observed_; 175 ++extension_load_errors_observed_;
289 break; 176 break;
290 177
291 default: 178 default:
292 NOTREACHED(); 179 NOTREACHED();
293 break; 180 break;
294 } 181 }
295 } 182 }
296 183
297 void ExtensionTestNotificationObserver::OnPageActionsUpdated(
298 content::WebContents* web_contents) {
299 MaybeQuit();
300 }
301
302 void ExtensionTestNotificationObserver::WaitForCondition( 184 void ExtensionTestNotificationObserver::WaitForCondition(
303 const ConditionCallback& condition, 185 const ConditionCallback& condition,
304 NotificationSet* notification_set) { 186 NotificationSet* notification_set) {
305 if (condition.Run()) 187 if (condition.Run())
306 return; 188 return;
307 condition_ = condition; 189 condition_ = condition;
308 190
309 scoped_refptr<content::MessageLoopRunner> runner( 191 scoped_refptr<content::MessageLoopRunner> runner(
310 new content::MessageLoopRunner); 192 new content::MessageLoopRunner);
311 quit_closure_ = runner->QuitClosure(); 193 quit_closure_ = runner->QuitClosure();
312 194
313 std::unique_ptr<base::CallbackList<void()>::Subscription> subscription; 195 std::unique_ptr<base::CallbackList<void()>::Subscription> subscription;
314 if (notification_set) { 196 if (notification_set) {
315 subscription = notification_set->callback_list().Add( 197 subscription = notification_set->callback_list().Add(base::Bind(
316 base::Bind(&ExtensionTestNotificationObserver::MaybeQuit, 198 &ExtensionTestNotificationObserver::MaybeQuit, base::Unretained(this)));
317 base::Unretained(this)));
318 } 199 }
319 runner->Run(); 200 runner->Run();
320 201
321 condition_.Reset(); 202 condition_.Reset();
322 quit_closure_.Reset(); 203 quit_closure_.Reset();
323 } 204 }
324 205
325 void ExtensionTestNotificationObserver::MaybeQuit() { 206 void ExtensionTestNotificationObserver::MaybeQuit() {
326 if (condition_.Run()) 207 if (condition_.Run())
327 quit_closure_.Run(); 208 quit_closure_.Run();
328 } 209 }
OLDNEW
« no previous file with comments | « extensions/test/extension_test_notification_observer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698