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

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, 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
« no previous file with comments | « no previous file | 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 "chrome/browser/extensions/extension_process_manager.h" 7 #include "chrome/browser/extensions/extension_process_manager.h"
8 #include "chrome/browser/extensions/extension_service.h" 8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_system.h" 9 #include "chrome/browser/extensions/extension_system.h"
10 #include "chrome/browser/profiles/profile_manager.h" 10 #include "chrome/browser/profiles/profile_manager.h"
11 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_window.h" 12 #include "chrome/browser/ui/browser_window.h"
13 #include "chrome/common/extensions/extension.h" 13 #include "chrome/common/extensions/extension.h"
14 #include "content/public/browser/notification_registrar.h" 14 #include "content/public/browser/notification_registrar.h"
15 #include "content/public/browser/notification_service.h" 15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_view_host.h" 16 #include "content/public/browser/render_view_host.h"
17 #include "content/public/test/test_utils.h" 17 #include "content/public/test/test_utils.h"
18 18
19 using extensions::Extension; 19 using extensions::Extension;
20 20
21 namespace { 21 namespace {
22 22
23 class ConditionRunLoop {
24 public:
25 typedef base::Callback<bool(void)> ConditionCallback;
26
27 explicit ConditionRunLoop(const ConditionCallback& callback);
28
29 void Wait();
30
31 void Check();
32
33 private:
34 base::RunLoop run_loop_;
35 ConditionCallback condition_callback_;
36 };
37
38 ConditionRunLoop::ConditionRunLoop(const ConditionCallback& callback)
39 : condition_callback_(callback) {}
40
41 void ConditionRunLoop::Wait() {
42 if (condition_callback_.Run())
43 return;
44
45 run_loop_.Run();
46 }
47
48 void ConditionRunLoop::Check() {
49 if (condition_callback_.Run())
50 run_loop_.Quit();
51 }
52
23 bool HasExtensionPageActionCountReachedTarget(LocationBarTesting* location_bar, 53 bool HasExtensionPageActionCountReachedTarget(LocationBarTesting* location_bar,
24 int target_page_action_count) { 54 int target_page_action_count) {
25 VLOG(1) << "Number of page actions: " << location_bar->PageActionCount(); 55 VLOG(1) << "Number of page actions: " << location_bar->PageActionCount();
26 return location_bar->PageActionCount() == target_page_action_count; 56 return location_bar->PageActionCount() == target_page_action_count;
27 } 57 }
28 58
29 bool HasExtensionPageActionVisibilityReachedTarget( 59 bool HasExtensionPageActionVisibilityReachedTarget(
30 LocationBarTesting* location_bar, 60 LocationBarTesting* location_bar,
31 int target_visible_page_action_count) { 61 int target_visible_page_action_count) {
32 VLOG(1) << "Number of visible page actions: " 62 VLOG(1) << "Number of visible page actions: "
33 << location_bar->PageActionVisibleCount(); 63 << location_bar->PageActionVisibleCount();
34 return location_bar->PageActionVisibleCount() == 64 return location_bar->PageActionVisibleCount() ==
35 target_visible_page_action_count; 65 target_visible_page_action_count;
36 } 66 }
37 67
68 bool HaveAllExtensionRenderViewHostsFinishedLoading(
69 ExtensionProcessManager* manager) {
70 ExtensionProcessManager::ViewSet all_views = manager->GetAllViews();
71 for (ExtensionProcessManager::ViewSet::const_iterator iter =
72 all_views.begin();
73 iter != all_views.end(); ++iter) {
74 if ((*iter)->IsLoading())
75 return false;
76 }
77 return true;
78 }
79
80 class NotificationCallbackRunner : public content::NotificationObserver {
Jeffrey Yasskin 2013/10/24 23:49:23 What if we had something like: class Notification
Bernhard Bauer 2013/10/29 16:37:02 Done. As an aside, the interface to CallbackList i
Jeffrey Yasskin 2013/11/06 03:33:59 :-/
81 public:
82 NotificationCallbackRunner(int type,
83 const content::NotificationSource& source,
84 const base::Closure& callback);
85
86 private:
87 // content::NotificationObserver
88 virtual void Observe(int type,
89 const content::NotificationSource& source,
90 const content::NotificationDetails& details) OVERRIDE;
91
92 content::NotificationRegistrar notification_registrar_;
93 base::Closure callback_;
94 };
95
96 NotificationCallbackRunner::NotificationCallbackRunner(
97 int type,
98 const content::NotificationSource& source,
99 const base::Closure& callback)
100 : callback_(callback) {
101 notification_registrar_.Add(this, type, source);
102 }
103
104 void NotificationCallbackRunner::Observe(
105 int type,
106 const content::NotificationSource& source,
107 const content::NotificationDetails& details) {
108 callback_.Run();
109 }
110
111 void WaitForConditionWithNotification(
112 const base::Callback<bool(void)>& condition,
113 int type,
114 const content::NotificationSource& source) {
115 ConditionRunLoop run_loop(condition);
116 NotificationCallbackRunner callback_runner(
117 type,
118 source,
119 base::Bind(&ConditionRunLoop::Check, base::Unretained(&run_loop)));
120 run_loop.Wait();
121 }
122
123 void WaitForConditionWithNotification(
124 const base::Callback<bool(void)>& condition,
125 int type) {
126 WaitForConditionWithNotification(
127 condition, type, content::NotificationService::AllSources());
128 }
129
38 } // namespace 130 } // namespace
39 131
40 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver( 132 ExtensionTestNotificationObserver::ExtensionTestNotificationObserver(
41 Browser* browser) 133 Browser* browser)
42 : browser_(browser), 134 : browser_(browser),
43 profile_(NULL), 135 profile_(NULL),
44 extension_installs_observed_(0), 136 extension_installs_observed_(0),
45 extension_load_errors_observed_(0), 137 extension_load_errors_observed_(0),
46 crx_installers_done_observed_(0) { 138 crx_installers_done_observed_(0) {
47 } 139 }
(...skipping 19 matching lines...) Expand all
67 registrar.Add( 159 registrar.Add(
68 this, notification_type, content::NotificationService::AllSources()); 160 this, notification_type, content::NotificationService::AllSources());
69 content::WindowedNotificationObserver( 161 content::WindowedNotificationObserver(
70 notification_type, content::NotificationService::AllSources()).Wait(); 162 notification_type, content::NotificationService::AllSources()).Wait();
71 } 163 }
72 164
73 bool ExtensionTestNotificationObserver::WaitForPageActionCountChangeTo( 165 bool ExtensionTestNotificationObserver::WaitForPageActionCountChangeTo(
74 int count) { 166 int count) {
75 LocationBarTesting* location_bar = 167 LocationBarTesting* location_bar =
76 browser_->window()->GetLocationBar()->GetLocationBarForTesting(); 168 browser_->window()->GetLocationBar()->GetLocationBarForTesting();
77 if (!HasExtensionPageActionCountReachedTarget(location_bar, count)) { 169 WaitForConditionWithNotification(
Jeffrey Yasskin 2013/10/24 23:49:23 I definitely like this since it removes the duplic
78 content::WindowedNotificationObserver( 170 base::Bind(
79 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED, 171 &HasExtensionPageActionCountReachedTarget, location_bar, count),
80 base::Bind( 172 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED);
81 &HasExtensionPageActionCountReachedTarget, location_bar, count)) 173 return true;
82 .Wait();
83 }
84 return HasExtensionPageActionCountReachedTarget(location_bar, count);
85 } 174 }
86 175
87 bool ExtensionTestNotificationObserver::WaitForPageActionVisibilityChangeTo( 176 bool ExtensionTestNotificationObserver::WaitForPageActionVisibilityChangeTo(
88 int count) { 177 int count) {
89 LocationBarTesting* location_bar = 178 LocationBarTesting* location_bar =
90 browser_->window()->GetLocationBar()->GetLocationBarForTesting(); 179 browser_->window()->GetLocationBar()->GetLocationBarForTesting();
91 if (!HasExtensionPageActionVisibilityReachedTarget(location_bar, count)) { 180 WaitForConditionWithNotification(
92 content::WindowedNotificationObserver( 181 base::Bind(
93 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED, 182 &HasExtensionPageActionVisibilityReachedTarget, location_bar, count),
94 base::Bind(&HasExtensionPageActionVisibilityReachedTarget, 183 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED);
95 location_bar, 184 return true;
96 count)).Wait();
97 }
98 return HasExtensionPageActionVisibilityReachedTarget(location_bar, count);
99 } 185 }
100 186
101 bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() { 187 bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() {
102 ExtensionProcessManager* manager = 188 ExtensionProcessManager* manager =
103 extensions::ExtensionSystem::Get(GetProfile())->process_manager(); 189 extensions::ExtensionSystem::Get(GetProfile())->process_manager();
104 ExtensionProcessManager::ViewSet all_views = manager->GetAllViews(); 190 ConditionRunLoop run_loop(
105 for (ExtensionProcessManager::ViewSet::const_iterator iter = 191 base::Bind(&HaveAllExtensionRenderViewHostsFinishedLoading, manager));
106 all_views.begin(); 192 NotificationCallbackRunner callback_runner(
Jeffrey Yasskin 2013/10/24 23:49:23 I don't really like using NotificationCallbackRunn
107 iter != all_views.end();) { 193 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
108 if (!(*iter)->IsLoading()) { 194 content::NotificationService::AllSources(),
109 ++iter; 195 base::Bind(&ConditionRunLoop::Check, base::Unretained(&run_loop)));
110 } else { 196 NotificationCallbackRunner callback_runner_2(
111 // Wait for all the extension render view hosts that exist to finish 197 content::NOTIFICATION_LOAD_STOP,
112 // loading. 198 content::NotificationService::AllSources(),
113 content::WindowedNotificationObserver observer( 199 base::Bind(&ConditionRunLoop::Check, base::Unretained(&run_loop)));
114 content::NOTIFICATION_LOAD_STOP, 200 run_loop.Wait();
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; 201 return true;
129 } 202 }
130 203
131 bool ExtensionTestNotificationObserver::WaitForExtensionInstall() { 204 bool ExtensionTestNotificationObserver::WaitForExtensionInstall() {
132 int before = extension_installs_observed_; 205 int before = extension_installs_observed_;
133 WaitForNotification(chrome::NOTIFICATION_EXTENSION_INSTALLED); 206 WaitForNotification(chrome::NOTIFICATION_EXTENSION_INSTALLED);
134 return extension_installs_observed_ == (before + 1); 207 return extension_installs_observed_ == (before + 1);
135 } 208 }
136 209
137 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() { 210 bool ExtensionTestNotificationObserver::WaitForExtensionInstallError() {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR: 298 case chrome::NOTIFICATION_EXTENSION_LOAD_ERROR:
226 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification."; 299 VLOG(1) << "Got EXTENSION_LOAD_ERROR notification.";
227 ++extension_load_errors_observed_; 300 ++extension_load_errors_observed_;
228 break; 301 break;
229 302
230 default: 303 default:
231 NOTREACHED(); 304 NOTREACHED();
232 break; 305 break;
233 } 306 }
234 } 307 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698