diff options
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 105 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 5 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 15 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.cc | 42 |
4 files changed, 136 insertions, 31 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index be26975..86ccbb9 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -499,6 +499,78 @@ class BrowserClosedNotificationObserver : public NotificationObserver { bool for_browser_command_; }; +class BrowserCountChangeNotificationObserver : public NotificationObserver { + public: + BrowserCountChangeNotificationObserver(int target_count, + AutomationProvider* automation, + IPC::Message* reply_message) + : target_count_(target_count), + automation_(automation), + reply_message_(reply_message) { + registrar_.Add(this, NotificationType::BROWSER_OPENED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::BROWSER_CLOSED, + NotificationService::AllSources()); + } + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::BROWSER_OPENED || + type == NotificationType::BROWSER_CLOSED); + int current_count = static_cast<int>(BrowserList::size()); + if (type == NotificationType::BROWSER_CLOSED) { + // At the time of the notification the browser being closed is not removed + // from the list. The real count is one less than the reported count. + DCHECK_LT(0, current_count); + current_count--; + } + if (current_count == target_count_) { + AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams( + reply_message_, true); + automation_->Send(reply_message_); + reply_message_ = NULL; + delete this; + } + } + + private: + int target_count_; + NotificationRegistrar registrar_; + AutomationProvider* automation_; + IPC::Message* reply_message_; +}; + +class AppModalDialogShownObserver : public NotificationObserver { + public: + AppModalDialogShownObserver(AutomationProvider* automation, + IPC::Message* reply_message) + : automation_(automation), + reply_message_(reply_message) { + registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN, + NotificationService::AllSources()); + } + + ~AppModalDialogShownObserver() { + } + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::APP_MODAL_DIALOG_SHOWN); + AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams( + reply_message_, true); + automation_->Send(reply_message_); + reply_message_ = NULL; + delete this; + } + + private: + NotificationRegistrar registrar_; + AutomationProvider* automation_; + IPC::Message* reply_message_; +}; + namespace { // Define mapping from command to notification @@ -1115,6 +1187,12 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste) IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync) IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync) + IPC_MESSAGE_HANDLER_DELAY_REPLY( + AutomationMsg_WaitForBrowserWindowCountToBecome, + WaitForBrowserWindowCountToBecome) + IPC_MESSAGE_HANDLER_DELAY_REPLY( + AutomationMsg_WaitForAppModalDialogToBeShown, + WaitForAppModalDialogToBeShown) IPC_END_MESSAGE_MAP() } @@ -1187,6 +1265,7 @@ void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete( reply_message, AUTOMATION_MSG_NAVIGATION_ERROR); Send(reply_message); } + void AutomationProvider::NavigationAsync(int handle, const GURL& url, bool* status) { *status = false; @@ -3121,6 +3200,32 @@ void AutomationProvider::StopAsync(int tab_handle) { view->Stop(); } +void AutomationProvider::WaitForBrowserWindowCountToBecome( + int target_count, IPC::Message* reply_message) { + if (static_cast<int>(BrowserList::size()) == target_count) { + AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams( + reply_message, true); + Send(reply_message); + return; + } + + // Set up an observer (it will delete itself). + new BrowserCountChangeNotificationObserver(target_count, this, reply_message); +} + +void AutomationProvider::WaitForAppModalDialogToBeShown( + IPC::Message* reply_message) { + if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) { + AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams( + reply_message, true); + Send(reply_message); + return; + } + + // Set up an observer (it will delete itself). + new AppModalDialogShownObserver(this, reply_message); +} + RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) { if (tab_tracker_->ContainsHandle(tab_handle)) { NavigationController* tab = tab_tracker_->GetResource(tab_handle); diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index 6344661..510a91d 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -461,6 +461,11 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, void ReloadAsync(int tab_handle); void StopAsync(int tab_handle); + void WaitForBrowserWindowCountToBecome(int target_count, + IPC::Message* reply_message); + + void WaitForAppModalDialogToBeShown(IPC::Message* reply_message); + // Convert a tab handle into a TabContents. If |tab| is non-NULL a pointer // to the tab is also returned. Returns NULL in case of failure or if the tab // is not of the TabContents type. diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h index 93ad554..52eeb41 100644 --- a/chrome/test/automation/automation_messages_internal.h +++ b/chrome/test/automation/automation_messages_internal.h @@ -1025,4 +1025,19 @@ IPC_BEGIN_MESSAGES(Automation) IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_NavigateExternalTabAtIndex, int, int, AutomationMsg_NavigationResponseValues) + // This message requests the provider to wait until the window count + // reached the specified value. + // Request: + // - int: target browser window count + // Response: + // - bool: whether the operation was successful. + IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_WaitForBrowserWindowCountToBecome, + int, bool) + + // This message requests the provider to wait until an application modal + // dialog is shown. + // Response: + // - bool: whether the operation was successful + IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_WaitForAppModalDialogToBeShown, bool) + IPC_END_MESSAGES(Automation) diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index 70e4b33..7a42fb8 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -259,21 +259,12 @@ bool AutomationProxy::GetNormalBrowserWindowCount(int* num_windows) { bool AutomationProxy::WaitForWindowCountToBecome(int count, int wait_timeout) { - const TimeTicks start = TimeTicks::Now(); - const TimeDelta timeout = TimeDelta::FromMilliseconds(wait_timeout); - while (TimeTicks::Now() - start < timeout) { - int new_count; - bool succeeded = GetBrowserWindowCount(&new_count); - if (!succeeded) { - // Try again next round, but log it. - DLOG(ERROR) << "GetBrowserWindowCount returned false"; - } else if (count == new_count) { - return true; - } - PlatformThread::Sleep(automation::kSleepTime); - } - // Window count never reached the value we sought. - return false; + bool wait_success = false; + bool send_success = SendWithTimeout( + new AutomationMsg_WaitForBrowserWindowCountToBecome(0, count, + &wait_success), + wait_timeout, NULL); + return wait_success && send_success; } bool AutomationProxy::GetShowingAppModalDialog( @@ -313,22 +304,11 @@ bool AutomationProxy::ClickAppModalDialogButton( } bool AutomationProxy::WaitForAppModalDialog(int wait_timeout) { - const TimeTicks start = TimeTicks::Now(); - const TimeDelta timeout = TimeDelta::FromMilliseconds(wait_timeout); - while (TimeTicks::Now() - start < timeout) { - bool dialog_shown = false; - MessageBoxFlags::DialogButton button = MessageBoxFlags::DIALOGBUTTON_NONE; - bool succeeded = GetShowingAppModalDialog(&dialog_shown, &button); - if (!succeeded) { - // Try again next round, but log it. - DLOG(ERROR) << "GetShowingAppModalDialog returned false"; - } else if (dialog_shown) { - return true; - } - PlatformThread::Sleep(automation::kSleepTime); - } - // Dialog never shown. - return false; + bool wait_success = false; + bool send_success = SendWithTimeout( + new AutomationMsg_WaitForAppModalDialogToBeShown(0, &wait_success), + wait_timeout, NULL); + return wait_success && send_success; } bool AutomationProxy::WaitForURLDisplayed(GURL url, int wait_timeout) { |