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

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

Issue 30943005: Add WaitForCondition() and use it in ExtensionTestNotificationObserver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 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
« no previous file with comments | « base/callback_list.h.pump ('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 2013 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 "chrome/browser/extensions/extension_test_notification_observer.h"
6 6
7 #include "base/callback_list.h"
7 #include "chrome/browser/extensions/extension_process_manager.h" 8 #include "chrome/browser/extensions/extension_process_manager.h"
8 #include "chrome/browser/extensions/extension_service.h" 9 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_system.h" 10 #include "chrome/browser/extensions/extension_system.h"
10 #include "chrome/browser/profiles/profile_manager.h" 11 #include "chrome/browser/profiles/profile_manager.h"
11 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_window.h" 13 #include "chrome/browser/ui/browser_window.h"
13 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension.h"
14 #include "content/public/browser/notification_registrar.h" 15 #include "content/public/browser/notification_registrar.h"
15 #include "content/public/browser/notification_service.h" 16 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/render_view_host.h"
17 #include "content/public/test/test_utils.h" 18 #include "content/public/test/test_utils.h"
18 19
19 using extensions::Extension; 20 using extensions::Extension;
20 21
21 namespace { 22 namespace {
22 23
24 class ConditionRunLoop {
25 public:
26 typedef base::Callback<bool(void)> ConditionCallback;
27
28 explicit ConditionRunLoop(const ConditionCallback& callback);
29
30 void Wait();
31
32 void Check();
33
34 private:
35 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
36 ConditionCallback condition_callback_;
37 };
38
39 ConditionRunLoop::ConditionRunLoop(const ConditionCallback& callback)
40 : message_loop_runner_(new content::MessageLoopRunner),
41 condition_callback_(callback) {}
42
43 void ConditionRunLoop::Wait() {
44 if (condition_callback_.Run())
45 return;
46
47 message_loop_runner_->Run();
48 }
49
50 void ConditionRunLoop::Check() {
51 if (condition_callback_.Run())
52 message_loop_runner_->Quit();
53 }
54
23 bool HasExtensionPageActionCountReachedTarget(LocationBarTesting* location_bar, 55 bool HasExtensionPageActionCountReachedTarget(LocationBarTesting* location_bar,
24 int target_page_action_count) { 56 int target_page_action_count) {
25 VLOG(1) << "Number of page actions: " << location_bar->PageActionCount(); 57 VLOG(1) << "Number of page actions: " << location_bar->PageActionCount();
26 return location_bar->PageActionCount() == target_page_action_count; 58 return location_bar->PageActionCount() == target_page_action_count;
27 } 59 }
28 60
29 bool HasExtensionPageActionVisibilityReachedTarget( 61 bool HasExtensionPageActionVisibilityReachedTarget(
30 LocationBarTesting* location_bar, 62 LocationBarTesting* location_bar,
31 int target_visible_page_action_count) { 63 int target_visible_page_action_count) {
32 VLOG(1) << "Number of visible page actions: " 64 VLOG(1) << "Number of visible page actions: "
33 << location_bar->PageActionVisibleCount(); 65 << location_bar->PageActionVisibleCount();
34 return location_bar->PageActionVisibleCount() == 66 return location_bar->PageActionVisibleCount() ==
35 target_visible_page_action_count; 67 target_visible_page_action_count;
36 } 68 }
37 69
70 bool HaveAllExtensionRenderViewHostsFinishedLoading(
71 ExtensionProcessManager* manager) {
72 ExtensionProcessManager::ViewSet all_views = manager->GetAllViews();
73 for (ExtensionProcessManager::ViewSet::const_iterator iter =
74 all_views.begin();
75 iter != all_views.end(); ++iter) {
76 if ((*iter)->IsLoading())
77 return false;
78 }
79 return true;
80 }
81
82 class NotificationSet : public content::NotificationObserver {
83 public:
84 void Add(int type, const content::NotificationSource& source);
85 void Add(int type);
86
87 // Notified any time an Add()ed notification is received.
88 // The details of the notification are dropped.
89 base::CallbackList<void()>& callback_list() {
90 return callback_list_;
91 }
92
93 private:
94 // content::NotificationObserver:
95 virtual void Observe(int type,
96 const content::NotificationSource& source,
97 const content::NotificationDetails& details) OVERRIDE;
98
99 content::NotificationRegistrar notification_registrar_;
100 base::CallbackList<void()> callback_list_;
101 };
102
103 void NotificationSet::Add(
104 int type,
105 const content::NotificationSource& source) {
106 notification_registrar_.Add(this, type, source);
107 }
108
109 void NotificationSet::Add(int type) {
110 Add(type, content::NotificationService::AllSources());
111 }
112
113 void NotificationSet::Observe(
114 int type,
115 const content::NotificationSource& source,
116 const content::NotificationDetails& details) {
117 callback_list_.Notify();
118 }
119
120 void WaitForCondition(
121 const base::Callback<bool(void)>& condition,
122 NotificationSet* notification_set) {
123 ConditionRunLoop run_loop(condition);
Jeffrey Yasskin 2013/11/06 03:33:59 Since this is now the only use of ConditionRunLoop
Bernhard Bauer 2013/11/11 14:37:44 Done!
124 scoped_ptr<base::CallbackList<void()>::Subscription> subscription =
125 notification_set->callback_list().Add(
126 base::Bind(&ConditionRunLoop::Check, base::Unretained(&run_loop)));
127 run_loop.Wait();
128 }
129
130 void WaitForCondition(
131 const base::Callback<bool(void)>& condition,
132 int type) {
133 NotificationSet notification_set;
Jeffrey Yasskin 2013/11/06 03:33:59 I think I'd weakly prefer duplicating these two li
Bernhard Bauer 2013/11/11 14:37:44 Hm... I kind of like having the short cut.
134 notification_set.Add(type);
135 WaitForCondition(condition, &notification_set);
136 }
137
38 } // namespace 138 } // namespace
39 139
40 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver( 140 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver(
41 Browser* browser) 141 Browser* browser)
42 : browser_(browser), 142 : browser_(browser),
43 profile_(NULL), 143 profile_(NULL),
44 extension_installs_observed_(0), 144 extension_installs_observed_(0),
45 extension_load_errors_observed_(0), 145 extension_load_errors_observed_(0),
46 crx_installers_done_observed_(0) { 146 crx_installers_done_observed_(0) {
47 } 147 }
(...skipping 19 matching lines...) Expand all
67 registrar.Add( 167 registrar.Add(
68 this, notification_type, content::NotificationService::AllSources()); 168 this, notification_type, content::NotificationService::AllSources());
69 content::WindowedNotificationObserver( 169 content::WindowedNotificationObserver(
70 notification_type, content::NotificationService::AllSources()).Wait(); 170 notification_type, content::NotificationService::AllSources()).Wait();
71 } 171 }
72 172
73 bool ExtensionTestNotificationObserver::WaitForPageActionCountChangeTo( 173 bool ExtensionTestNotificationObserver::WaitForPageActionCountChangeTo(
74 int count) { 174 int count) {
75 LocationBarTesting* location_bar = 175 LocationBarTesting* location_bar =
76 browser_->window()->GetLocationBar()->GetLocationBarForTesting(); 176 browser_->window()->GetLocationBar()->GetLocationBarForTesting();
77 if (!HasExtensionPageActionCountReachedTarget(location_bar, count)) { 177 WaitForCondition(
78 content::WindowedNotificationObserver( 178 base::Bind(
79 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED, 179 &HasExtensionPageActionCountReachedTarget, location_bar, count),
80 base::Bind( 180 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED);
81 &HasExtensionPageActionCountReachedTarget, location_bar, count)) 181 return true;
82 .Wait();
83 }
84 return HasExtensionPageActionCountReachedTarget(location_bar, count);
85 } 182 }
86 183
87 bool ExtensionTestNotificationObserver::WaitForPageActionVisibilityChangeTo( 184 bool ExtensionTestNotificationObserver::WaitForPageActionVisibilityChangeTo(
88 int count) { 185 int count) {
89 LocationBarTesting* location_bar = 186 LocationBarTesting* location_bar =
90 browser_->window()->GetLocationBar()->GetLocationBarForTesting(); 187 browser_->window()->GetLocationBar()->GetLocationBarForTesting();
91 if (!HasExtensionPageActionVisibilityReachedTarget(location_bar, count)) { 188 WaitForCondition(
92 content::WindowedNotificationObserver( 189 base::Bind(
93 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED, 190 &HasExtensionPageActionVisibilityReachedTarget, location_bar, count),
94 base::Bind(&HasExtensionPageActionVisibilityReachedTarget, 191 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED);
95 location_bar, 192 return true;
96 count)).Wait();
97 }
98 return HasExtensionPageActionVisibilityReachedTarget(location_bar, count);
99 } 193 }
100 194
101 bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() { 195 bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() {
102 ExtensionProcessManager* manager = 196 ExtensionProcessManager* manager =
103 extensions::ExtensionSystem::Get(GetProfile())->process_manager(); 197 extensions::ExtensionSystem::Get(GetProfile())->process_manager();
104 ExtensionProcessManager::ViewSet all_views = manager->GetAllViews(); 198 NotificationSet notification_set;
105 for (ExtensionProcessManager::ViewSet::const_iterator iter = 199 notification_set.Add(content::NOTIFICATION_WEB_CONTENTS_DESTROYED);
106 all_views.begin(); 200 notification_set.Add(content::NOTIFICATION_LOAD_STOP);
107 iter != all_views.end();) { 201 WaitForCondition(
108 if (!(*iter)->IsLoading()) { 202 base::Bind(&HaveAllExtensionRenderViewHostsFinishedLoading, manager),
109 ++iter; 203 &notification_set);
110 } else {
111 // Wait for all the extension render view hosts that exist to finish
112 // loading.
113 content::WindowedNotificationObserver observer(
114 content::NOTIFICATION_LOAD_STOP,
115 content::NotificationService::AllSources());
116 observer.AddNotificationType(
117 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
118 content::NotificationService::AllSources());
119 observer.Wait();
120
121 // Test activity may have modified the set of extension processes during
122 // message processing, so re-start the iteration to catch added/removed
123 // processes.
124 all_views = manager->GetAllViews();
125 iter = all_views.begin();
126 }
127 }
128 return true; 204 return true;
129 } 205 }
130 206
131 bool ExtensionTestNotificationObserver::WaitForExtensionInstall() { 207 bool ExtensionTestNotificationObserver::WaitForExtensionInstall() {
132 int before = extension_installs_observed_; 208 int before = extension_installs_observed_;
133 WaitForNotification(chrome::NOTIFICATION_EXTENSION_INSTALLED); 209 WaitForNotification(chrome::NOTIFICATION_EXTENSION_INSTALLED);
134 return extension_installs_observed_ == (before + 1); 210 return extension_installs_observed_ == (before + 1);
135 } 211 }
136 212
137 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() { 213 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: 301 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR:
226 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification."; 302 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification.";
227 ++extension_load_errors_observed_; 303 ++extension_load_errors_observed_;
228 break; 304 break;
229 305
230 default: 306 default:
231 NOTREACHED(); 307 NOTREACHED();
232 break; 308 break;
233 } 309 }
234 } 310 }
OLDNEW
« no previous file with comments | « base/callback_list.h.pump ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698