summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation/testing_automation_provider_views.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/automation/testing_automation_provider_views.cc')
-rw-r--r--chrome/browser/automation/testing_automation_provider_views.cc158
1 files changed, 158 insertions, 0 deletions
diff --git a/chrome/browser/automation/testing_automation_provider_views.cc b/chrome/browser/automation/testing_automation_provider_views.cc
index cf6b4d7..6048cd8 100644
--- a/chrome/browser/automation/testing_automation_provider_views.cc
+++ b/chrome/browser/automation/testing_automation_provider_views.cc
@@ -4,13 +4,114 @@
#include "chrome/browser/automation/testing_automation_provider.h"
+#include "chrome/browser/automation/automation_browser_tracker.h"
#include "chrome/browser/automation/automation_window_tracker.h"
#include "chrome/browser/browser_window.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/toolbar_view.h"
+#include "chrome/test/automation/automation_messages.h"
#include "gfx/point.h"
+#include "views/controls/menu/menu_wrapper.h"
#include "views/view.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"
+namespace {
+
+// Helper class that waits until the focus has changed to a view other
+// than the one with the provided view id.
+class ViewFocusChangeWaiter : public views::FocusChangeListener {
+ public:
+ ViewFocusChangeWaiter(views::FocusManager* focus_manager,
+ int previous_view_id,
+ AutomationProvider* automation,
+ IPC::Message* reply_message)
+ : focus_manager_(focus_manager),
+ previous_view_id_(previous_view_id),
+ automation_(automation),
+ reply_message_(reply_message),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ focus_manager_->AddFocusChangeListener(this);
+ // Call the focus change notification once in case the focus has
+ // already changed.
+ FocusWillChange(NULL, focus_manager_->GetFocusedView());
+ }
+
+ ~ViewFocusChangeWaiter() {
+ focus_manager_->RemoveFocusChangeListener(this);
+ }
+
+ // Inherited from FocusChangeListener
+ virtual void FocusWillChange(views::View* focused_before,
+ views::View* focused_now) {
+ // This listener is called before focus actually changes. Post a task
+ // that will get run after focus changes.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &ViewFocusChangeWaiter::FocusChanged,
+ focused_before,
+ focused_now));
+ }
+
+ private:
+ void FocusChanged(views::View* focused_before,
+ views::View* focused_now) {
+ if (focused_now && focused_now->GetID() != previous_view_id_) {
+ AutomationMsg_WaitForFocusedViewIDToChange::WriteReplyParams(
+ reply_message_, true, focused_now->GetID());
+
+ automation_->Send(reply_message_);
+ delete this;
+ }
+ }
+
+ views::FocusManager* focus_manager_;
+ int previous_view_id_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+ ScopedRunnableMethodFactory<ViewFocusChangeWaiter> method_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewFocusChangeWaiter);
+};
+
+} // namespace
+
+class TestingAutomationProvider::PopupMenuWaiter : public views::MenuListener {
+ public:
+ PopupMenuWaiter(ToolbarView* toolbar_view,
+ TestingAutomationProvider* automation)
+ : toolbar_view_(toolbar_view),
+ automation_(automation),
+ reply_message_(NULL) {
+ toolbar_view_->AddMenuListener(this);
+ }
+
+ // Implementation of views::MenuListener
+ virtual void OnMenuOpened() {
+ toolbar_view_->RemoveMenuListener(this);
+ automation_->popup_menu_opened_ = true;
+ automation_->popup_menu_waiter_ = NULL;
+ if (reply_message_) {
+ AutomationMsg_WaitForPopupMenuToOpen::WriteReplyParams(
+ reply_message_, true);
+ automation_->Send(reply_message_);
+ }
+ delete this;
+ }
+
+ void set_reply_message(IPC::Message* reply_message) {
+ reply_message_ = reply_message;
+ }
+
+ private:
+ ToolbarView* toolbar_view_;
+ TestingAutomationProvider* automation_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(PopupMenuWaiter);
+};
+
void TestingAutomationProvider::WindowGetViewBounds(int handle,
int view_id,
bool screen_coordinates,
@@ -36,3 +137,60 @@ void TestingAutomationProvider::WindowGetViewBounds(int handle,
}
}
}
+
+void TestingAutomationProvider::GetFocusedViewID(int handle, int* view_id) {
+ *view_id = -1;
+ if (window_tracker_->ContainsHandle(handle)) {
+ gfx::NativeWindow window = window_tracker_->GetResource(handle);
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeWindow(window);
+ DCHECK(focus_manager);
+ views::View* focused_view = focus_manager->GetFocusedView();
+ if (focused_view)
+ *view_id = focused_view->GetID();
+ }
+}
+
+void TestingAutomationProvider::WaitForFocusedViewIDToChange(
+ int handle, int previous_view_id, IPC::Message* reply_message) {
+ if (!window_tracker_->ContainsHandle(handle))
+ return;
+ gfx::NativeWindow window = window_tracker_->GetResource(handle);
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeWindow(window);
+
+ // The waiter will respond to the IPC and delete itself when done.
+ new ViewFocusChangeWaiter(focus_manager,
+ previous_view_id,
+ this,
+ reply_message);
+}
+
+void TestingAutomationProvider::StartTrackingPopupMenus(
+ int browser_handle, bool* success) {
+ if (browser_tracker_->ContainsHandle(browser_handle)) {
+ Browser* browser = browser_tracker_->GetResource(browser_handle);
+ BrowserView* browser_view = reinterpret_cast<BrowserView*>(
+ browser->window());
+ ToolbarView* toolbar_view = browser_view->GetToolbarView();
+ popup_menu_opened_ = false;
+ popup_menu_waiter_ = new PopupMenuWaiter(toolbar_view, this);
+ *success = true;
+ }
+}
+
+void TestingAutomationProvider::WaitForPopupMenuToOpen(
+ IPC::Message* reply_message) {
+ // See if the menu already opened and return true if so.
+ if (popup_menu_opened_) {
+ AutomationMsg_WaitForPopupMenuToOpen::WriteReplyParams(
+ reply_message, true);
+ Send(reply_message);
+ return;
+ }
+
+ // Otherwise, register this reply message with the waiter,
+ // which will handle responding to this IPC when the popup
+ // menu opens.
+ popup_menu_waiter_->set_reply_message(reply_message);
+}