Chromium Code Reviews| Index: chrome/test/base/ui_test_utils.cc |
| diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc |
| index efb8a8dbdb8844216b7aa01078abcc029d0b446f..9462bab8439bff418846b2f668887851cc071265 100644 |
| --- a/chrome/test/base/ui_test_utils.cc |
| +++ b/chrome/test/base/ui_test_utils.cc |
| @@ -104,7 +104,7 @@ class DOMOperationObserver : public content::NotificationObserver, |
| did_respond_(false) { |
| registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, |
| content::Source<RenderViewHost>(render_view_host)); |
| - ui_test_utils::RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| } |
| virtual void Observe(int type, |
| @@ -114,12 +114,12 @@ class DOMOperationObserver : public content::NotificationObserver, |
| content::Details<DomOperationNotificationDetails> dom_op_details(details); |
| response_ = dom_op_details->json; |
| did_respond_ = true; |
| - MessageLoopForUI::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| } |
| // Overridden from content::WebContentsObserver: |
| virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE { |
| - MessageLoopForUI::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| } |
| bool GetResponse(std::string* response) WARN_UNUSED_RESULT { |
| @@ -131,6 +131,7 @@ class DOMOperationObserver : public content::NotificationObserver, |
| content::NotificationRegistrar registrar_; |
| std::string response_; |
| bool did_respond_; |
| + MessageLoopRunner message_loop_runner_; |
| DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver); |
| }; |
| @@ -145,7 +146,7 @@ class FindInPageNotificationObserver : public content::NotificationObserver { |
| parent_tab->find_tab_helper()->current_find_request_id(); |
| registrar_.Add(this, chrome::NOTIFICATION_FIND_RESULT_AVAILABLE, |
| content::Source<WebContents>(parent_tab_->web_contents())); |
| - ui_test_utils::RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| } |
| int active_match_ordinal() const { return active_match_ordinal_; } |
| @@ -163,7 +164,7 @@ class FindInPageNotificationObserver : public content::NotificationObserver { |
| active_match_ordinal_ = find_details->active_match_ordinal(); |
| if (find_details->final_update()) { |
| number_of_matches_ = find_details->number_of_matches(); |
| - MessageLoopForUI::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| } else { |
| DVLOG(1) << "Ignoring, since we only care about the final message"; |
| } |
| @@ -183,6 +184,7 @@ class FindInPageNotificationObserver : public content::NotificationObserver { |
| // The id of the current find request, obtained from WebContents. Allows us |
| // to monitor when the search completes. |
| int current_find_request_id_; |
| + MessageLoopRunner message_loop_runner_; |
| DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver); |
| }; |
| @@ -261,11 +263,13 @@ bool ExecuteJavaScriptHelper(RenderViewHost* render_view_host, |
| return true; |
| } |
| -void RunAllPendingMessageAndSendQuit(content::BrowserThread::ID thread_id) { |
| - MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| +void RunAllPendingMessageAndSendQuit(content::BrowserThread::ID thread_id, |
| + int message_loop_run_id) { |
| + MessageLoop::current()->PostTask(FROM_HERE, |
| + MessageLoop::QuitWhenIdleClosure()); |
| RunMessageLoop(); |
| content::BrowserThread::PostTask(thread_id, FROM_HERE, |
| - MessageLoop::QuitClosure()); |
| + MessageLoop::QuitNowByIDClosure(message_loop_run_id)); |
| } |
| } // namespace |
| @@ -293,7 +297,8 @@ void RunMessageLoop() { |
| } |
| void RunAllPendingInMessageLoop() { |
| - MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| + MessageLoop::current()->PostTask(FROM_HERE, |
| + MessageLoop::QuitWhenIdleClosure()); |
| ui_test_utils::RunMessageLoop(); |
| } |
| @@ -308,7 +313,8 @@ void RunAllPendingInMessageLoop(content::BrowserThread::ID thread_id) { |
| return; |
| } |
| content::BrowserThread::PostTask(thread_id, FROM_HERE, |
| - base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id)); |
| + base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id, |
| + MessageLoop::current()->next_run_id())); |
| ui_test_utils::RunMessageLoop(); |
| } |
| @@ -329,10 +335,10 @@ void WaitForNavigations(NavigationController* controller, |
| content::TestNavigationObserver observer( |
| content::Source<NavigationController>(controller), NULL, |
| number_of_navigations); |
| + int message_loop_run_id = MessageLoop::current()->next_run_id(); |
| observer.WaitForObservation( |
| base::Bind(&ui_test_utils::RunMessageLoop), |
| - base::Bind(&MessageLoop::Quit, |
| - base::Unretained(MessageLoopForUI::current()))); |
| + MessageLoop::QuitNowByIDClosure(message_loop_run_id)); |
| } |
| void WaitForNewTab(Browser* browser) { |
| @@ -389,11 +395,10 @@ void NavigateToURL(browser::NavigateParams* params) { |
| content::TestNavigationObserver observer( |
| content::NotificationService::AllSources(), NULL, 1); |
| browser::Navigate(params); |
| + int message_loop_run_id = MessageLoop::current()->next_run_id(); |
| observer.WaitForObservation( |
| base::Bind(&ui_test_utils::RunMessageLoop), |
| - base::Bind(&MessageLoop::Quit, |
| - base::Unretained(MessageLoopForUI::current()))); |
| - |
| + MessageLoop::QuitNowByIDClosure(message_loop_run_id)); |
| } |
| void NavigateToURL(Browser* browser, const GURL& url) { |
| @@ -463,10 +468,10 @@ static void NavigateToURLWithDispositionBlockUntilNavigationsComplete( |
| web_contents = browser->GetSelectedWebContents(); |
| } |
| if (disposition == CURRENT_TAB) { |
| + int message_loop_run_id = MessageLoop::current()->next_run_id(); |
| same_tab_observer.WaitForObservation( |
| base::Bind(&ui_test_utils::RunMessageLoop), |
| - base::Bind(&MessageLoop::Quit, |
| - base::Unretained(MessageLoopForUI::current()))); |
| + MessageLoop::QuitNowByIDClosure(message_loop_run_id)); |
| return; |
| } else if (web_contents) { |
| NavigationController* controller = &web_contents->GetController(); |
| @@ -770,14 +775,15 @@ bool SendKeyPressSync(const Browser* browser, |
| gfx::NativeWindow window = NULL; |
| if (!GetNativeWindow(browser, &window)) |
| return false; |
| - |
| + scoped_refptr<MessageLoopRunnerClosure> runner = |
| + new MessageLoopRunnerClosure; |
| bool result; |
| result = ui_controls::SendKeyPressNotifyWhenDone( |
| - window, key, control, shift, alt, command, MessageLoop::QuitClosure()); |
| + window, key, control, shift, alt, command, runner->QuitNowClosure()); |
| #if defined(OS_WIN) |
| if (!result && BringBrowserWindowToFront(browser)) { |
| result = ui_controls::SendKeyPressNotifyWhenDone( |
| - window, key, control, shift, alt, command, MessageLoop::QuitClosure()); |
| + window, key, control, shift, alt, command, runner->QuitNowClosure()); |
| } |
| #endif |
| if (!result) { |
| @@ -788,7 +794,7 @@ bool SendKeyPressSync(const Browser* browser, |
| // Run the message loop. It'll stop running when either the key was received |
| // or the test timed out (in which case testing::Test::HasFatalFailure should |
| // be set). |
| - RunMessageLoop(); |
| + runner->Run(); |
| return !testing::Test::HasFatalFailure(); |
| } |
| @@ -810,51 +816,69 @@ bool SendKeyPressAndWait(const Browser* browser, |
| } |
| bool SendMouseMoveSync(const gfx::Point& location) { |
| - if (!ui_controls::SendMouseMoveNotifyWhenDone(location.x(), location.y(), |
| - MessageLoop::QuitClosure())) { |
| + scoped_refptr<MessageLoopRunnerClosure> runner = |
| + new MessageLoopRunnerClosure; |
| + if (!ui_controls::SendMouseMoveNotifyWhenDone( |
| + location.x(), location.y(), runner->QuitNowClosure())) { |
| return false; |
| } |
| - RunMessageLoop(); |
| + runner->Run(); |
| return !testing::Test::HasFatalFailure(); |
| } |
| bool SendMouseEventsSync(ui_controls::MouseButton type, int state) { |
| + scoped_refptr<MessageLoopRunnerClosure> runner = |
| + new MessageLoopRunnerClosure; |
| if (!ui_controls::SendMouseEventsNotifyWhenDone( |
| - type, state, MessageLoop::QuitClosure())) { |
| + type, state, runner->QuitNowClosure())) { |
| return false; |
| } |
| - RunMessageLoop(); |
| + runner->Run(); |
| return !testing::Test::HasFatalFailure(); |
| } |
| -TimedMessageLoopRunner::TimedMessageLoopRunner() |
| - : loop_(new MessageLoopForUI()), |
| - owned_(true), |
| - quit_loop_invoked_(false) { |
| +void MessageLoopRunner::Run() { |
| + CHECK(message_loop_run_id_ == 0) << "Nested runs must use another instance"; |
|
jar (doing other things)
2012/06/14 04:50:29
I think you need to be explicit in the message loo
jbates
2012/06/15 02:20:38
Fixed by removing this code.
|
| + message_loop_run_id_ = MessageLoop::current()->next_run_id(); |
| + ui_test_utils::RunMessageLoop(); |
| } |
| -TimedMessageLoopRunner::~TimedMessageLoopRunner() { |
| - if (owned_) |
| - delete loop_; |
| +void MessageLoopRunner::QuitNow() { |
| + MessageLoopForUI::current()->PostTask( |
| + FROM_HERE, |
| + MessageLoop::QuitNowByIDClosure(message_loop_run_id_)); |
| + message_loop_run_id_ = 0; |
| } |
| -void TimedMessageLoopRunner::RunFor(int ms) { |
| - QuitAfter(ms); |
| - quit_loop_invoked_ = false; |
| - loop_->Run(); |
| +MessageLoopRunnerClosure::MessageLoopRunnerClosure() |
| + : run_called_(false), |
| + quit_received_(false), |
| + running_(false) { |
| } |
| -void TimedMessageLoopRunner::Quit() { |
| - quit_loop_invoked_ = true; |
| - loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| +MessageLoopRunnerClosure::~MessageLoopRunnerClosure() { |
| } |
| -void TimedMessageLoopRunner::QuitAfter(int ms) { |
| - quit_loop_invoked_ = true; |
| - loop_->PostDelayedTask( |
| - FROM_HERE, |
| - MessageLoop::QuitClosure(), |
| - base::TimeDelta::FromMilliseconds(ms)); |
| +void MessageLoopRunnerClosure::Run() { |
| + CHECK(!run_called_); |
| + run_called_ = true; |
| + |
| + if (quit_received_) |
| + return; |
| + |
| + running_ = true; |
| + message_loop_runner_.Run(); |
| + running_ = false; |
| +} |
| + |
| +base::Closure MessageLoopRunnerClosure::QuitNowClosure() { |
| + return base::Bind(&MessageLoopRunnerClosure::QuitNow, this); |
| +} |
| + |
| +void MessageLoopRunnerClosure::QuitNow() { |
| + quit_received_ = true; |
| + if (running_) |
| + message_loop_runner_.QuitNow(); |
| } |
| TestWebSocketServer::TestWebSocketServer() |
| @@ -1019,7 +1043,7 @@ void WindowedNotificationObserver::Wait() { |
| return; |
| running_ = true; |
| - ui_test_utils::RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| EXPECT_TRUE(seen_); |
| } |
| @@ -1033,7 +1057,7 @@ void WindowedNotificationObserver::Observe( |
| if (!running_) |
| return; |
| - MessageLoopForUI::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| running_ = false; |
| } |
| @@ -1084,7 +1108,7 @@ const string16& TitleWatcher::WaitAndGetTitle() { |
| if (expected_title_observed_) |
| return observed_title_; |
| quit_loop_on_observation_ = true; |
| - ui_test_utils::RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| return observed_title_; |
| } |
| @@ -1110,8 +1134,11 @@ void TitleWatcher::Observe(int type, |
| return; |
| observed_title_ = *it; |
| expected_title_observed_ = true; |
| - if (quit_loop_on_observation_) |
| - MessageLoopForUI::current()->Quit(); |
| + if (quit_loop_on_observation_) { |
| + // Only call Quit once, on first Observe: |
| + quit_loop_on_observation_ = false; |
| + message_loop_runner_.QuitNow(); |
| + } |
| } |
| BrowserAddedObserver::BrowserAddedObserver() |
| @@ -1146,7 +1173,7 @@ void DOMMessageQueue::Observe(int type, |
| message_queue_.push(dom_op_details->json); |
| if (waiting_for_message_) { |
| waiting_for_message_ = false; |
| - MessageLoopForUI::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| } |
| } |
| @@ -1158,7 +1185,7 @@ bool DOMMessageQueue::WaitForMessage(std::string* message) { |
| if (message_queue_.empty()) { |
| waiting_for_message_ = true; |
| // This will be quit when a new message comes in. |
| - RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| } |
| // The queue should not be empty, unless we were quit because of a timeout. |
| if (message_queue_.empty()) |
| @@ -1186,7 +1213,7 @@ class SnapshotTaker { |
| base::Bind(&SnapshotTaker::OnSnapshotTaken, base::Unretained(this)), |
| page_size, |
| desired_size); |
| - ui_test_utils::RunMessageLoop(); |
| + message_loop_runner_.Run(); |
| return snapshot_taken_; |
| } |
| @@ -1221,13 +1248,14 @@ class SnapshotTaker { |
| void OnSnapshotTaken(const SkBitmap& bitmap) { |
| *bitmap_ = bitmap; |
| snapshot_taken_ = true; |
| - MessageLoop::current()->Quit(); |
| + message_loop_runner_.QuitNow(); |
| } |
| SkBitmap* bitmap_; |
| // Whether the snapshot was actually taken and received by this SnapshotTaker. |
| // This will be false if the test times out. |
| bool snapshot_taken_; |
| + MessageLoopRunner message_loop_runner_; |
| DISALLOW_COPY_AND_ASSIGN(SnapshotTaker); |
| }; |
| @@ -1253,9 +1281,11 @@ void OverrideGeolocation(double latitude, double longitude) { |
| position.altitude = 0.; |
| position.accuracy = 0.; |
| position.timestamp = base::Time::Now(); |
| + scoped_refptr<MessageLoopRunnerClosure> runner = |
| + new MessageLoopRunnerClosure; |
| content::OverrideLocationForTesting(position, |
| - base::Bind(MessageLoop::QuitClosure())); |
| - RunMessageLoop(); |
| + runner->QuitNowClosure()); |
| + runner->Run(); |
| } |
| namespace internal { |