summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-28 00:02:08 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-28 00:02:08 +0000
commite12de87eca9b85c26152c32e349d84670c5dcb54 (patch)
tree20a5c62c9d6658a70a13c723d1f2c22c2b9eeb0d /chrome/browser
parent9b5d7374459f0deee6dbf7a5aa4dc43aec25e38c (diff)
downloadchromium_src-e12de87eca9b85c26152c32e349d84670c5dcb54.zip
chromium_src-e12de87eca9b85c26152c32e349d84670c5dcb54.tar.gz
chromium_src-e12de87eca9b85c26152c32e349d84670c5dcb54.tar.bz2
Move observers out of automation_provider.cc to declutter the file.
Also make sure they all use DISALLOW_COPY_AND_ASSIGN. TEST=none http://crbug.com/19874 Review URL: http://codereview.chromium.org/176004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24702 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc747
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc630
-rw-r--r--chrome/browser/automation/automation_provider_observers.h341
-rw-r--r--chrome/browser/views/find_bar_win_browsertest.cc4
4 files changed, 976 insertions, 746 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index a3c2c09..93aad4d 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/automation/automation_extension_function.h"
#include "chrome/browser/automation/automation_provider_list.h"
+#include "chrome/browser/automation/automation_provider_observers.h"
#include "chrome/browser/automation/extension_automation_constants.h"
#include "chrome/browser/automation/extension_port_container.h"
#include "chrome/browser/blocked_popup_container.h"
@@ -70,752 +71,6 @@
using base::Time;
-class InitialLoadObserver : public NotificationObserver {
- public:
- InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
- : automation_(automation),
- outstanding_tab_count_(tab_count) {
- if (outstanding_tab_count_ > 0) {
- registrar_.Add(this, NotificationType::LOAD_START,
- NotificationService::AllSources());
- registrar_.Add(this, NotificationType::LOAD_STOP,
- NotificationService::AllSources());
- }
- }
-
- ~InitialLoadObserver() {
- }
-
- void ConditionMet() {
- registrar_.RemoveAll();
- automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::LOAD_START) {
- if (outstanding_tab_count_ > loading_tabs_.size())
- loading_tabs_.insert(source.map_key());
- } else if (type == NotificationType::LOAD_STOP) {
- if (outstanding_tab_count_ > finished_tabs_.size()) {
- if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
- finished_tabs_.insert(source.map_key());
- if (outstanding_tab_count_ == finished_tabs_.size())
- ConditionMet();
- }
- } else {
- NOTREACHED();
- }
- }
-
- private:
- typedef std::set<uintptr_t> TabSet;
-
- NotificationRegistrar registrar_;
-
- AutomationProvider* automation_;
- size_t outstanding_tab_count_;
- TabSet loading_tabs_;
- TabSet finished_tabs_;
-};
-
-// Watches for NewTabUI page loads for performance timing purposes.
-class NewTabUILoadObserver : public NotificationObserver {
- public:
- explicit NewTabUILoadObserver(AutomationProvider* automation)
- : automation_(automation) {
- registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
- NotificationService::AllSources());
- }
-
- ~NewTabUILoadObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
- Details<int> load_time(details);
- automation_->Send(
- new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
- } else {
- NOTREACHED();
- }
- }
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
-};
-
-class NavigationControllerRestoredObserver : public NotificationObserver {
- public:
- NavigationControllerRestoredObserver(AutomationProvider* automation,
- NavigationController* controller,
- IPC::Message* reply_message)
- : automation_(automation),
- controller_(controller),
- reply_message_(reply_message) {
- if (FinishedRestoring()) {
- SendDone();
- } else {
- registrar_.Add(this, NotificationType::LOAD_STOP,
- NotificationService::AllSources());
- }
- }
-
- ~NavigationControllerRestoredObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (FinishedRestoring()) {
- SendDone();
- registrar_.RemoveAll();
- }
- }
-
- private:
- bool FinishedRestoring() {
- return (!controller_->needs_reload() && !controller_->pending_entry() &&
- !controller_->tab_contents()->is_loading());
- }
-
- void SendDone() {
- DCHECK(reply_message_ != NULL);
- automation_->Send(reply_message_);
- }
-
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- NavigationController* controller_;
- IPC::Message* reply_message_;
-
- DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
-};
-
-class NavigationNotificationObserver : public NotificationObserver {
- public:
- NavigationNotificationObserver(NavigationController* controller,
- AutomationProvider* automation,
- IPC::Message* reply_message,
- int number_of_navigations)
- : automation_(automation),
- reply_message_(reply_message),
- controller_(controller),
- navigations_remaining_(number_of_navigations),
- navigation_started_(false) {
- DCHECK_LT(0, navigations_remaining_);
- Source<NavigationController> source(controller_);
- registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
- registrar_.Add(this, NotificationType::LOAD_START, source);
- registrar_.Add(this, NotificationType::LOAD_STOP, source);
- registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
- registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
- }
-
- ~NavigationNotificationObserver() {
- if (reply_message_) {
- // This means we did not receive a notification for this navigation.
- // Send over a failed navigation status back to the caller to ensure that
- // the caller does not hang waiting for the response.
- IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
- reply_message_, AUTOMATION_MSG_NAVIGATION_ERROR);
- automation_->Send(reply_message_);
- reply_message_ = NULL;
- }
-
- automation_->RemoveNavigationStatusListener(this);
- }
-
- void ConditionMet(AutomationMsg_NavigationResponseValues navigation_result) {
- DCHECK(reply_message_ != NULL);
-
- IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
- reply_message_, navigation_result);
- automation_->Send(reply_message_);
- reply_message_ = NULL;
-
- delete this;
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- // We listen for 2 events to determine when the navigation started because:
- // - when this is used by the WaitForNavigation method, we might be invoked
- // afer the load has started (but not after the entry was committed, as
- // WaitForNavigation compares times of the last navigation).
- // - when this is used with a page requiring authentication, we will not get
- // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
- // we need the NotificationType::LOAD_START.
- if (type == NotificationType::NAV_ENTRY_COMMITTED ||
- type == NotificationType::LOAD_START) {
- navigation_started_ = true;
- } else if (type == NotificationType::LOAD_STOP) {
- if (navigation_started_) {
- navigation_started_ = false;
- if (--navigations_remaining_ == 0)
- ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
- }
- } else if (type == NotificationType::AUTH_SUPPLIED) {
- // The LoginHandler for this tab is no longer valid.
- automation_->RemoveLoginHandler(controller_);
-
- // Treat this as if navigation started again, since load start/stop don't
- // occur while authentication is ongoing.
- navigation_started_ = true;
- } else if (type == NotificationType::AUTH_NEEDED) {
-#if defined(OS_WIN)
- if (navigation_started_) {
- // Remember the login handler that wants authentication.
- LoginHandler* handler =
- Details<LoginNotificationDetails>(details)->handler();
- automation_->AddLoginHandler(controller_, handler);
-
- // Respond that authentication is needed.
- navigation_started_ = false;
- ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
- } else {
- NOTREACHED();
- }
-#else
- // TODO(port): Enable when we have LoginNotificationDetails etc.
- NOTIMPLEMENTED();
-#endif
- } else {
- NOTREACHED();
- }
- }
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- IPC::Message* reply_message_;
- NavigationController* controller_;
- int navigations_remaining_;
- bool navigation_started_;
-};
-
-class TabStripNotificationObserver : public NotificationObserver {
- public:
- TabStripNotificationObserver(NotificationType notification,
- AutomationProvider* automation)
- : automation_(automation),
- notification_(notification) {
- registrar_.Add(this, notification_, NotificationService::AllSources());
- }
-
- virtual ~TabStripNotificationObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == notification_) {
- ObserveTab(Source<NavigationController>(source).ptr());
-
- // If verified, no need to observe anymore
- automation_->RemoveTabStripObserver(this);
- delete this;
- } else {
- NOTREACHED();
- }
- }
-
- virtual void ObserveTab(NavigationController* controller) = 0;
-
- protected:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- NotificationType notification_;
-};
-
-class TabAppendedNotificationObserver : public TabStripNotificationObserver {
- public:
- TabAppendedNotificationObserver(Browser* parent,
- AutomationProvider* automation,
- IPC::Message* reply_message)
- : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
- automation),
- parent_(parent),
- reply_message_(reply_message) {
- }
-
- virtual void ObserveTab(NavigationController* controller) {
- if (automation_->GetIndexForNavigationController(controller, parent_) ==
- TabStripModel::kNoTab) {
- // This tab notification doesn't belong to the parent_.
- return;
- }
-
- automation_->AddNavigationStatusListener(controller, reply_message_, 1);
- }
-
- protected:
- Browser* parent_;
- IPC::Message* reply_message_;
-};
-
-class TabClosedNotificationObserver : public TabStripNotificationObserver {
- public:
- TabClosedNotificationObserver(AutomationProvider* automation,
- bool wait_until_closed,
- IPC::Message* reply_message)
- : TabStripNotificationObserver(wait_until_closed ?
- NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
- automation),
- reply_message_(reply_message),
- for_browser_command_(false) {
- }
-
- virtual void ObserveTab(NavigationController* controller) {
- if (for_browser_command_) {
- AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
- true);
- } else {
- AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
- }
- automation_->Send(reply_message_);
- }
-
- void set_for_browser_command(bool for_browser_command) {
- for_browser_command_ = for_browser_command;
- }
-
- protected:
- IPC::Message* reply_message_;
- bool for_browser_command_;
-};
-
-class BrowserOpenedNotificationObserver : public NotificationObserver {
- public:
- BrowserOpenedNotificationObserver(AutomationProvider* automation,
- IPC::Message* reply_message)
- : automation_(automation),
- reply_message_(reply_message),
- for_browser_command_(false) {
- registrar_.Add(this, NotificationType::BROWSER_OPENED,
- NotificationService::AllSources());
- }
-
- ~BrowserOpenedNotificationObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::BROWSER_OPENED) {
- if (for_browser_command_) {
- AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
- true);
- }
- automation_->Send(reply_message_);
- delete this;
- } else {
- NOTREACHED();
- }
- }
-
- void set_for_browser_command(bool for_browser_command) {
- for_browser_command_ = for_browser_command;
- }
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- IPC::Message* reply_message_;
- bool for_browser_command_;
-};
-
-class BrowserClosedNotificationObserver : public NotificationObserver {
- public:
- BrowserClosedNotificationObserver(Browser* browser,
- AutomationProvider* automation,
- IPC::Message* reply_message)
- : automation_(automation),
- reply_message_(reply_message),
- for_browser_command_(false) {
- registrar_.Add(this, NotificationType::BROWSER_CLOSED,
- Source<Browser>(browser));
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(type == NotificationType::BROWSER_CLOSED);
- Details<bool> close_app(details);
- DCHECK(reply_message_ != NULL);
- if (for_browser_command_) {
- AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
- true);
- } else {
- AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
- *(close_app.ptr()));
- }
- automation_->Send(reply_message_);
- reply_message_ = NULL;
- delete this;
- }
-
- void set_for_browser_command(bool for_browser_command) {
- for_browser_command_ = for_browser_command;
- }
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- IPC::Message* reply_message_;
- 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
-struct CommandNotification {
- int command;
- NotificationType::Type notification_type;
-};
-
-const struct CommandNotification command_notifications[] = {
- {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
- {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
- // Returns as soon as the restored tab is created. To further wait until
- // the content page is loaded, use WaitForTabToBeRestored.
- {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
-};
-
-} // namespace
-
-class ExecuteBrowserCommandObserver : public NotificationObserver {
- public:
- ~ExecuteBrowserCommandObserver() {
- }
-
- static bool CreateAndRegisterObserver(AutomationProvider* automation,
- Browser* browser,
- int command,
- IPC::Message* reply_message) {
- bool result = true;
- switch (command) {
- case IDC_NEW_WINDOW:
- case IDC_NEW_INCOGNITO_WINDOW: {
- BrowserOpenedNotificationObserver* observer =
- new BrowserOpenedNotificationObserver(automation, reply_message);
- observer->set_for_browser_command(true);
- break;
- }
- case IDC_CLOSE_WINDOW: {
- BrowserClosedNotificationObserver* observer =
- new BrowserClosedNotificationObserver(browser, automation,
- reply_message);
- observer->set_for_browser_command(true);
- break;
- }
- case IDC_CLOSE_TAB: {
- TabClosedNotificationObserver* observer =
- new TabClosedNotificationObserver(automation, true, reply_message);
- observer->set_for_browser_command(true);
- break;
- }
- case IDC_BACK:
- case IDC_FORWARD:
- case IDC_RELOAD: {
- automation->AddNavigationStatusListener(
- &browser->GetSelectedTabContents()->controller(),
- reply_message, 1);
- break;
- }
- default: {
- ExecuteBrowserCommandObserver* observer =
- new ExecuteBrowserCommandObserver(automation, reply_message);
- if (!observer->Register(command)) {
- delete observer;
- result = false;
- }
- break;
- }
- }
- return result;
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == notification_type_) {
- AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
- true);
- automation_->Send(reply_message_);
- delete this;
- } else {
- NOTREACHED();
- }
- }
-
- private:
- ExecuteBrowserCommandObserver(AutomationProvider* automation,
- IPC::Message* reply_message)
- : automation_(automation),
- reply_message_(reply_message) {
- }
-
- bool Register(int command) {
- if (!GetNotificationType(command, &notification_type_))
- return false;
- registrar_.Add(this, notification_type_, NotificationService::AllSources());
- return true;
- }
-
- bool GetNotificationType(int command, NotificationType::Type* type) {
- if (!type)
- return false;
- bool found = false;
- for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
- if (command_notifications[i].command == command) {
- *type = command_notifications[i].notification_type;
- found = true;
- break;
- }
- }
- return found;
- }
-
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- NotificationType::Type notification_type_;
- IPC::Message* reply_message_;
-};
-
-class FindInPageNotificationObserver : public NotificationObserver {
- public:
- FindInPageNotificationObserver(AutomationProvider* automation,
- TabContents* parent_tab,
- IPC::Message* reply_message)
- : automation_(automation),
- active_match_ordinal_(-1),
- reply_message_(reply_message) {
- registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
- Source<TabContents>(parent_tab));
- }
-
- ~FindInPageNotificationObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::FIND_RESULT_AVAILABLE) {
- Details<FindNotificationDetails> find_details(details);
- if (find_details->request_id() == kFindInPageRequestId) {
- // We get multiple responses and one of those will contain the ordinal.
- // This message comes to us before the final update is sent.
- if (find_details->active_match_ordinal() > -1)
- active_match_ordinal_ = find_details->active_match_ordinal();
- if (find_details->final_update()) {
- if (reply_message_ != NULL) {
- AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
- active_match_ordinal_, find_details->number_of_matches());
- automation_->Send(reply_message_);
- reply_message_ = NULL;
- } else {
- DLOG(WARNING) << "Multiple final Find messages observed.";
- }
- } else {
- DLOG(INFO) << "Ignoring, since we only care about the final message";
- }
- }
- } else {
- NOTREACHED();
- }
- }
-
- // The Find mechanism is over asynchronous IPC, so a search is kicked off and
- // we wait for notification to find out what the results are. As the user is
- // typing, new search requests can be issued and the Request ID helps us make
- // sense of whether this is the current request or an old one. The unit tests,
- // however, which uses this constant issues only one search at a time, so we
- // don't need a rolling id to identify each search. But, we still need to
- // specify one, so we just use a fixed one - its value does not matter.
- static const int kFindInPageRequestId;
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
- // We will at some point (before final update) be notified of the ordinal and
- // we need to preserve it so we can send it later.
- int active_match_ordinal_;
- IPC::Message* reply_message_;
-};
-
-const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
-
-class DomOperationNotificationObserver : public NotificationObserver {
- public:
- explicit DomOperationNotificationObserver(AutomationProvider* automation)
- : automation_(automation) {
- registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
- NotificationService::AllSources());
- }
-
- ~DomOperationNotificationObserver() {
- }
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (NotificationType::DOM_OPERATION_RESPONSE == type) {
- Details<DomOperationNotificationDetails> dom_op_details(details);
-
- IPC::Message* reply_message = automation_->reply_message_release();
- DCHECK(reply_message != NULL);
-
- AutomationMsg_DomOperation::WriteReplyParams(reply_message,
- dom_op_details->json());
- automation_->Send(reply_message);
- }
- }
-
- private:
- NotificationRegistrar registrar_;
- AutomationProvider* automation_;
-};
-
-#if defined(OS_WIN)
-// TODO(port): Enable when printing is ported.
-class DocumentPrintedNotificationObserver : public NotificationObserver {
- public:
- DocumentPrintedNotificationObserver(AutomationProvider* automation,
- IPC::Message* reply_message)
- : automation_(automation),
- success_(false),
- reply_message_(reply_message) {
- registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
- NotificationService::AllSources());
- }
-
- ~DocumentPrintedNotificationObserver() {
- DCHECK(reply_message_ != NULL);
- AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
- automation_->Send(reply_message_);
- automation_->RemoveNavigationStatusListener(this);
- }
-
- virtual void Observe(NotificationType type, const NotificationSource& source,
- const NotificationDetails& details) {
- using namespace printing;
- DCHECK(type == NotificationType::PRINT_JOB_EVENT);
- switch (Details<JobEventDetails>(details)->type()) {
- case JobEventDetails::JOB_DONE: {
- // Succeeded.
- success_ = true;
- delete this;
- break;
- }
- case JobEventDetails::USER_INIT_CANCELED:
- case JobEventDetails::FAILED: {
- // Failed.
- delete this;
- break;
- }
- case JobEventDetails::NEW_DOC:
- case JobEventDetails::USER_INIT_DONE:
- case JobEventDetails::DEFAULT_INIT_DONE:
- case JobEventDetails::NEW_PAGE:
- case JobEventDetails::PAGE_DONE:
- case JobEventDetails::DOC_DONE:
- case JobEventDetails::ALL_PAGES_REQUESTED: {
- // Don't care.
- break;
- }
- default: {
- NOTREACHED();
- break;
- }
- }
- }
-
- private:
- NotificationRegistrar registrar_;
- scoped_refptr<AutomationProvider> automation_;
- bool success_;
- IPC::Message* reply_message_;
-};
-#endif // defined(OS_WIN)
-
class AutomationInterstitialPage : public InterstitialPage {
public:
AutomationInterstitialPage(TabContents* tab,
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
new file mode 100644
index 0000000..fc427bb
--- /dev/null
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -0,0 +1,630 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/automation/automation_provider_observers.h"
+
+#include "base/basictypes.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/automation/automation_provider.h"
+#include "chrome/browser/dom_operation_notification_details.h"
+#include "chrome/browser/login_prompt.h"
+#if defined(OS_WIN)
+#include "chrome/browser/printing/print_job.h"
+#endif // defined(OS_WIN)
+#include "chrome/browser/tab_contents/navigation_controller.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/notification_service.h"
+
+InitialLoadObserver::InitialLoadObserver(size_t tab_count,
+ AutomationProvider* automation)
+ : automation_(automation),
+ outstanding_tab_count_(tab_count) {
+ if (outstanding_tab_count_ > 0) {
+ registrar_.Add(this, NotificationType::LOAD_START,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::LOAD_STOP,
+ NotificationService::AllSources());
+ }
+}
+
+InitialLoadObserver::~InitialLoadObserver() {
+}
+
+void InitialLoadObserver::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::LOAD_START) {
+ if (outstanding_tab_count_ > loading_tabs_.size())
+ loading_tabs_.insert(source.map_key());
+ } else if (type == NotificationType::LOAD_STOP) {
+ if (outstanding_tab_count_ > finished_tabs_.size()) {
+ if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
+ finished_tabs_.insert(source.map_key());
+ if (outstanding_tab_count_ == finished_tabs_.size())
+ ConditionMet();
+ }
+ } else {
+ NOTREACHED();
+ }
+}
+
+void InitialLoadObserver::ConditionMet() {
+ registrar_.RemoveAll();
+ automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
+}
+
+NewTabUILoadObserver::NewTabUILoadObserver(AutomationProvider* automation)
+ : automation_(automation) {
+ registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
+ NotificationService::AllSources());
+}
+
+NewTabUILoadObserver::~NewTabUILoadObserver() {
+}
+
+void NewTabUILoadObserver::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
+ Details<int> load_time(details);
+ automation_->Send(
+ new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
+ } else {
+ NOTREACHED();
+ }
+}
+
+NavigationControllerRestoredObserver::NavigationControllerRestoredObserver(
+ AutomationProvider* automation,
+ NavigationController* controller,
+ IPC::Message* reply_message)
+ : automation_(automation),
+ controller_(controller),
+ reply_message_(reply_message) {
+ if (FinishedRestoring()) {
+ SendDone();
+ } else {
+ registrar_.Add(this, NotificationType::LOAD_STOP,
+ NotificationService::AllSources());
+ }
+}
+
+NavigationControllerRestoredObserver::~NavigationControllerRestoredObserver() {
+}
+
+void NavigationControllerRestoredObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (FinishedRestoring()) {
+ SendDone();
+ registrar_.RemoveAll();
+ }
+}
+
+bool NavigationControllerRestoredObserver::FinishedRestoring() {
+ return (!controller_->needs_reload() && !controller_->pending_entry() &&
+ !controller_->tab_contents()->is_loading());
+}
+
+void NavigationControllerRestoredObserver::SendDone() {
+ DCHECK(reply_message_ != NULL);
+ automation_->Send(reply_message_);
+}
+
+NavigationNotificationObserver::NavigationNotificationObserver(
+ NavigationController* controller,
+ AutomationProvider* automation,
+ IPC::Message* reply_message,
+ int number_of_navigations)
+ : automation_(automation),
+ reply_message_(reply_message),
+ controller_(controller),
+ navigations_remaining_(number_of_navigations),
+ navigation_started_(false) {
+ DCHECK_LT(0, navigations_remaining_);
+ Source<NavigationController> source(controller_);
+ registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
+ registrar_.Add(this, NotificationType::LOAD_START, source);
+ registrar_.Add(this, NotificationType::LOAD_STOP, source);
+ registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
+ registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
+}
+
+NavigationNotificationObserver::~NavigationNotificationObserver() {
+ if (reply_message_) {
+ // This means we did not receive a notification for this navigation.
+ // Send over a failed navigation status back to the caller to ensure that
+ // the caller does not hang waiting for the response.
+ IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
+ reply_message_, AUTOMATION_MSG_NAVIGATION_ERROR);
+ automation_->Send(reply_message_);
+ reply_message_ = NULL;
+ }
+
+ automation_->RemoveNavigationStatusListener(this);
+}
+
+void NavigationNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ // We listen for 2 events to determine when the navigation started because:
+ // - when this is used by the WaitForNavigation method, we might be invoked
+ // afer the load has started (but not after the entry was committed, as
+ // WaitForNavigation compares times of the last navigation).
+ // - when this is used with a page requiring authentication, we will not get
+ // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
+ // we need the NotificationType::LOAD_START.
+ if (type == NotificationType::NAV_ENTRY_COMMITTED ||
+ type == NotificationType::LOAD_START) {
+ navigation_started_ = true;
+ } else if (type == NotificationType::LOAD_STOP) {
+ if (navigation_started_) {
+ navigation_started_ = false;
+ if (--navigations_remaining_ == 0)
+ ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
+ }
+ } else if (type == NotificationType::AUTH_SUPPLIED) {
+ // The LoginHandler for this tab is no longer valid.
+ automation_->RemoveLoginHandler(controller_);
+
+ // Treat this as if navigation started again, since load start/stop don't
+ // occur while authentication is ongoing.
+ navigation_started_ = true;
+ } else if (type == NotificationType::AUTH_NEEDED) {
+#if defined(OS_WIN)
+ if (navigation_started_) {
+ // Remember the login handler that wants authentication.
+ LoginHandler* handler =
+ Details<LoginNotificationDetails>(details)->handler();
+ automation_->AddLoginHandler(controller_, handler);
+
+ // Respond that authentication is needed.
+ navigation_started_ = false;
+ ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
+ } else {
+ NOTREACHED();
+ }
+#else
+ // TODO(port): Enable when we have LoginNotificationDetails etc.
+ NOTIMPLEMENTED();
+#endif
+ } else {
+ NOTREACHED();
+ }
+}
+
+void NavigationNotificationObserver::ConditionMet(
+ AutomationMsg_NavigationResponseValues navigation_result) {
+ DCHECK(reply_message_ != NULL);
+
+ IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
+ reply_message_, navigation_result);
+ automation_->Send(reply_message_);
+ reply_message_ = NULL;
+
+ delete this;
+}
+
+TabStripNotificationObserver::TabStripNotificationObserver(
+ NotificationType notification, AutomationProvider* automation)
+ : automation_(automation),
+ notification_(notification) {
+ registrar_.Add(this, notification_, NotificationService::AllSources());
+}
+
+TabStripNotificationObserver::~TabStripNotificationObserver() {
+}
+
+void TabStripNotificationObserver::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == notification_) {
+ ObserveTab(Source<NavigationController>(source).ptr());
+
+ // If verified, no need to observe anymore
+ automation_->RemoveTabStripObserver(this);
+ delete this;
+ } else {
+ NOTREACHED();
+ }
+}
+
+TabAppendedNotificationObserver::TabAppendedNotificationObserver(
+ Browser* parent, AutomationProvider* automation,
+ IPC::Message* reply_message)
+ : TabStripNotificationObserver(NotificationType::TAB_PARENTED, automation),
+ parent_(parent),
+ reply_message_(reply_message) {
+}
+
+void TabAppendedNotificationObserver::ObserveTab(
+ NavigationController* controller) {
+ if (automation_->GetIndexForNavigationController(controller, parent_) ==
+ TabStripModel::kNoTab) {
+ // This tab notification doesn't belong to the parent_.
+ return;
+ }
+
+ automation_->AddNavigationStatusListener(controller, reply_message_, 1);
+}
+
+TabClosedNotificationObserver::TabClosedNotificationObserver(
+ AutomationProvider* automation, bool wait_until_closed,
+ IPC::Message* reply_message)
+ : TabStripNotificationObserver(wait_until_closed ?
+ NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
+ automation),
+ reply_message_(reply_message),
+ for_browser_command_(false) {
+}
+
+void TabClosedNotificationObserver::ObserveTab(
+ NavigationController* controller) {
+ if (for_browser_command_) {
+ AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
+ true);
+ } else {
+ AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
+ }
+ automation_->Send(reply_message_);
+}
+
+void TabClosedNotificationObserver::set_for_browser_command(
+ bool for_browser_command) {
+ for_browser_command_ = for_browser_command;
+}
+
+BrowserOpenedNotificationObserver::BrowserOpenedNotificationObserver(
+ AutomationProvider* automation, IPC::Message* reply_message)
+ : automation_(automation),
+ reply_message_(reply_message),
+ for_browser_command_(false) {
+ registrar_.Add(this, NotificationType::BROWSER_OPENED,
+ NotificationService::AllSources());
+}
+
+BrowserOpenedNotificationObserver::~BrowserOpenedNotificationObserver() {
+}
+
+void BrowserOpenedNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::BROWSER_OPENED) {
+ if (for_browser_command_) {
+ AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
+ true);
+ }
+ automation_->Send(reply_message_);
+ delete this;
+ } else {
+ NOTREACHED();
+ }
+}
+
+void BrowserOpenedNotificationObserver::set_for_browser_command(
+ bool for_browser_command) {
+ for_browser_command_ = for_browser_command;
+}
+
+BrowserClosedNotificationObserver::BrowserClosedNotificationObserver(
+ Browser* browser,
+ AutomationProvider* automation,
+ IPC::Message* reply_message)
+ : automation_(automation),
+ reply_message_(reply_message),
+ for_browser_command_(false) {
+ registrar_.Add(this, NotificationType::BROWSER_CLOSED,
+ Source<Browser>(browser));
+}
+
+void BrowserClosedNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::BROWSER_CLOSED);
+ Details<bool> close_app(details);
+ DCHECK(reply_message_ != NULL);
+ if (for_browser_command_) {
+ AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
+ true);
+ } else {
+ AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
+ *(close_app.ptr()));
+ }
+ automation_->Send(reply_message_);
+ reply_message_ = NULL;
+ delete this;
+}
+
+void BrowserClosedNotificationObserver::set_for_browser_command(
+ bool for_browser_command) {
+ for_browser_command_ = for_browser_command;
+}
+
+BrowserCountChangeNotificationObserver::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());
+}
+
+void BrowserCountChangeNotificationObserver::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;
+ }
+}
+
+AppModalDialogShownObserver::AppModalDialogShownObserver(
+ AutomationProvider* automation, IPC::Message* reply_message)
+ : automation_(automation),
+ reply_message_(reply_message) {
+ registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN,
+ NotificationService::AllSources());
+}
+
+AppModalDialogShownObserver::~AppModalDialogShownObserver() {
+}
+
+void AppModalDialogShownObserver::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;
+}
+
+namespace {
+
+// Define mapping from command to notification
+struct CommandNotification {
+ int command;
+ NotificationType::Type notification_type;
+};
+
+const struct CommandNotification command_notifications[] = {
+ {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
+ {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
+ // Returns as soon as the restored tab is created. To further wait until
+ // the content page is loaded, use WaitForTabToBeRestored.
+ {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
+};
+
+} // namespace
+
+ExecuteBrowserCommandObserver::~ExecuteBrowserCommandObserver() {
+}
+
+// static
+bool ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
+ AutomationProvider* automation, Browser* browser, int command,
+ IPC::Message* reply_message) {
+ bool result = true;
+ switch (command) {
+ case IDC_NEW_WINDOW:
+ case IDC_NEW_INCOGNITO_WINDOW: {
+ BrowserOpenedNotificationObserver* observer =
+ new BrowserOpenedNotificationObserver(automation, reply_message);
+ observer->set_for_browser_command(true);
+ break;
+ }
+ case IDC_CLOSE_WINDOW: {
+ BrowserClosedNotificationObserver* observer =
+ new BrowserClosedNotificationObserver(browser, automation,
+ reply_message);
+ observer->set_for_browser_command(true);
+ break;
+ }
+ case IDC_CLOSE_TAB: {
+ TabClosedNotificationObserver* observer =
+ new TabClosedNotificationObserver(automation, true, reply_message);
+ observer->set_for_browser_command(true);
+ break;
+ }
+ case IDC_BACK:
+ case IDC_FORWARD:
+ case IDC_RELOAD: {
+ automation->AddNavigationStatusListener(
+ &browser->GetSelectedTabContents()->controller(),
+ reply_message, 1);
+ break;
+ }
+ default: {
+ ExecuteBrowserCommandObserver* observer =
+ new ExecuteBrowserCommandObserver(automation, reply_message);
+ if (!observer->Register(command)) {
+ delete observer;
+ result = false;
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+void ExecuteBrowserCommandObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == notification_type_) {
+ AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
+ true);
+ automation_->Send(reply_message_);
+ delete this;
+ } else {
+ NOTREACHED();
+ }
+}
+
+ExecuteBrowserCommandObserver::ExecuteBrowserCommandObserver(
+ AutomationProvider* automation, IPC::Message* reply_message)
+ : automation_(automation),
+ reply_message_(reply_message) {
+}
+
+bool ExecuteBrowserCommandObserver::Register(int command) {
+ if (!GetNotificationType(command, &notification_type_))
+ return false;
+ registrar_.Add(this, notification_type_, NotificationService::AllSources());
+ return true;
+}
+
+bool ExecuteBrowserCommandObserver::GetNotificationType(
+ int command, NotificationType::Type* type) {
+ if (!type)
+ return false;
+ bool found = false;
+ for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
+ if (command_notifications[i].command == command) {
+ *type = command_notifications[i].notification_type;
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+FindInPageNotificationObserver::FindInPageNotificationObserver(
+ AutomationProvider* automation, TabContents* parent_tab,
+ IPC::Message* reply_message)
+ : automation_(automation),
+ active_match_ordinal_(-1),
+ reply_message_(reply_message) {
+ registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(parent_tab));
+}
+
+FindInPageNotificationObserver::~FindInPageNotificationObserver() {
+}
+
+void FindInPageNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::FIND_RESULT_AVAILABLE) {
+ Details<FindNotificationDetails> find_details(details);
+ if (find_details->request_id() == kFindInPageRequestId) {
+ // We get multiple responses and one of those will contain the ordinal.
+ // This message comes to us before the final update is sent.
+ if (find_details->active_match_ordinal() > -1)
+ active_match_ordinal_ = find_details->active_match_ordinal();
+ if (find_details->final_update()) {
+ if (reply_message_ != NULL) {
+ AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
+ active_match_ordinal_, find_details->number_of_matches());
+ automation_->Send(reply_message_);
+ reply_message_ = NULL;
+ } else {
+ DLOG(WARNING) << "Multiple final Find messages observed.";
+ }
+ } else {
+ DLOG(INFO) << "Ignoring, since we only care about the final message";
+ }
+ }
+ } else {
+ NOTREACHED();
+ }
+}
+
+// static
+const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
+
+DomOperationNotificationObserver::DomOperationNotificationObserver(
+ AutomationProvider* automation)
+ : automation_(automation) {
+ registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
+ NotificationService::AllSources());
+}
+
+DomOperationNotificationObserver::~DomOperationNotificationObserver() {
+}
+
+void DomOperationNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (NotificationType::DOM_OPERATION_RESPONSE == type) {
+ Details<DomOperationNotificationDetails> dom_op_details(details);
+
+ IPC::Message* reply_message = automation_->reply_message_release();
+ DCHECK(reply_message != NULL);
+
+ AutomationMsg_DomOperation::WriteReplyParams(reply_message,
+ dom_op_details->json());
+ automation_->Send(reply_message);
+ }
+}
+
+#if defined(OS_WIN)
+// TODO(port): Enable when printing is ported.
+DocumentPrintedNotificationObserver::DocumentPrintedNotificationObserver(
+ AutomationProvider* automation, IPC::Message* reply_message)
+ : automation_(automation),
+ success_(false),
+ reply_message_(reply_message) {
+ registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
+ NotificationService::AllSources());
+}
+
+DocumentPrintedNotificationObserver::~DocumentPrintedNotificationObserver() {
+ DCHECK(reply_message_ != NULL);
+ AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
+ automation_->Send(reply_message_);
+ automation_->RemoveNavigationStatusListener(this);
+}
+
+void DocumentPrintedNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ using namespace printing;
+ DCHECK(type == NotificationType::PRINT_JOB_EVENT);
+ switch (Details<JobEventDetails>(details)->type()) {
+ case JobEventDetails::JOB_DONE: {
+ // Succeeded.
+ success_ = true;
+ delete this;
+ break;
+ }
+ case JobEventDetails::USER_INIT_CANCELED:
+ case JobEventDetails::FAILED: {
+ // Failed.
+ delete this;
+ break;
+ }
+ case JobEventDetails::NEW_DOC:
+ case JobEventDetails::USER_INIT_DONE:
+ case JobEventDetails::DEFAULT_INIT_DONE:
+ case JobEventDetails::NEW_PAGE:
+ case JobEventDetails::PAGE_DONE:
+ case JobEventDetails::DOC_DONE:
+ case JobEventDetails::ALL_PAGES_REQUESTED: {
+ // Don't care.
+ break;
+ }
+ default: {
+ NOTREACHED();
+ break;
+ }
+ }
+}
+#endif // defined(OS_WIN)
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
new file mode 100644
index 0000000..2dd596e
--- /dev/null
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -0,0 +1,341 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_
+#define CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_
+
+#include <set>
+
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/test/automation/automation_messages.h"
+
+class AutomationProvider;
+class Browser;
+class NavigationController;
+class TabContents;
+
+namespace IPC {
+class Message;
+}
+
+class InitialLoadObserver : public NotificationObserver {
+ public:
+ InitialLoadObserver(size_t tab_count, AutomationProvider* automation);
+ ~InitialLoadObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ typedef std::set<uintptr_t> TabSet;
+
+ void ConditionMet();
+
+ NotificationRegistrar registrar_;
+
+ AutomationProvider* automation_;
+ size_t outstanding_tab_count_;
+ TabSet loading_tabs_;
+ TabSet finished_tabs_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitialLoadObserver);
+};
+
+// Watches for NewTabUI page loads for performance timing purposes.
+class NewTabUILoadObserver : public NotificationObserver {
+ public:
+ explicit NewTabUILoadObserver(AutomationProvider* automation);
+ ~NewTabUILoadObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+
+ DISALLOW_COPY_AND_ASSIGN(NewTabUILoadObserver);
+};
+
+class NavigationControllerRestoredObserver : public NotificationObserver {
+ public:
+ NavigationControllerRestoredObserver(AutomationProvider* automation,
+ NavigationController* controller,
+ IPC::Message* reply_message);
+ ~NavigationControllerRestoredObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ bool FinishedRestoring();
+ void SendDone();
+
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ NavigationController* controller_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
+};
+
+class NavigationNotificationObserver : public NotificationObserver {
+ public:
+ NavigationNotificationObserver(NavigationController* controller,
+ AutomationProvider* automation,
+ IPC::Message* reply_message,
+ int number_of_navigations);
+ ~NavigationNotificationObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ void ConditionMet(AutomationMsg_NavigationResponseValues navigation_result);
+
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+ NavigationController* controller_;
+ int navigations_remaining_;
+ bool navigation_started_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationNotificationObserver);
+};
+
+class TabStripNotificationObserver : public NotificationObserver {
+ public:
+ TabStripNotificationObserver(NotificationType notification,
+ AutomationProvider* automation);
+ virtual ~TabStripNotificationObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ virtual void ObserveTab(NavigationController* controller) = 0;
+
+ protected:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ NotificationType notification_;
+};
+
+class TabAppendedNotificationObserver : public TabStripNotificationObserver {
+ public:
+ TabAppendedNotificationObserver(Browser* parent,
+ AutomationProvider* automation,
+ IPC::Message* reply_message);
+
+ virtual void ObserveTab(NavigationController* controller);
+
+ protected:
+ Browser* parent_;
+ IPC::Message* reply_message_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TabAppendedNotificationObserver);
+};
+
+class TabClosedNotificationObserver : public TabStripNotificationObserver {
+ public:
+ TabClosedNotificationObserver(AutomationProvider* automation,
+ bool wait_until_closed,
+ IPC::Message* reply_message);
+
+ virtual void ObserveTab(NavigationController* controller);
+
+ void set_for_browser_command(bool for_browser_command);
+
+ protected:
+ IPC::Message* reply_message_;
+ bool for_browser_command_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TabClosedNotificationObserver);
+};
+
+class BrowserOpenedNotificationObserver : public NotificationObserver {
+ public:
+ BrowserOpenedNotificationObserver(AutomationProvider* automation,
+ IPC::Message* reply_message);
+ ~BrowserOpenedNotificationObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ void set_for_browser_command(bool for_browser_command);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+ bool for_browser_command_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserOpenedNotificationObserver);
+};
+
+class BrowserClosedNotificationObserver : public NotificationObserver {
+ public:
+ BrowserClosedNotificationObserver(Browser* browser,
+ AutomationProvider* automation,
+ IPC::Message* reply_message);
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ void set_for_browser_command(bool for_browser_command);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+ bool for_browser_command_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserClosedNotificationObserver);
+};
+
+class BrowserCountChangeNotificationObserver : public NotificationObserver {
+ public:
+ BrowserCountChangeNotificationObserver(int target_count,
+ AutomationProvider* automation,
+ IPC::Message* reply_message);
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ int target_count_;
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserCountChangeNotificationObserver);
+};
+
+class AppModalDialogShownObserver : public NotificationObserver {
+ public:
+ AppModalDialogShownObserver(AutomationProvider* automation,
+ IPC::Message* reply_message);
+ ~AppModalDialogShownObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppModalDialogShownObserver);
+};
+
+class ExecuteBrowserCommandObserver : public NotificationObserver {
+ public:
+ ~ExecuteBrowserCommandObserver();
+
+ static bool CreateAndRegisterObserver(AutomationProvider* automation,
+ Browser* browser,
+ int command,
+ IPC::Message* reply_message);
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ ExecuteBrowserCommandObserver(AutomationProvider* automation,
+ IPC::Message* reply_message);
+
+ bool Register(int command);
+
+ bool GetNotificationType(int command, NotificationType::Type* type);
+
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ NotificationType::Type notification_type_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExecuteBrowserCommandObserver);
+};
+
+class FindInPageNotificationObserver : public NotificationObserver {
+ public:
+ FindInPageNotificationObserver(AutomationProvider* automation,
+ TabContents* parent_tab,
+ IPC::Message* reply_message);
+ ~FindInPageNotificationObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // The Find mechanism is over asynchronous IPC, so a search is kicked off and
+ // we wait for notification to find out what the results are. As the user is
+ // typing, new search requests can be issued and the Request ID helps us make
+ // sense of whether this is the current request or an old one. The unit tests,
+ // however, which uses this constant issues only one search at a time, so we
+ // don't need a rolling id to identify each search. But, we still need to
+ // specify one, so we just use a fixed one - its value does not matter.
+ static const int kFindInPageRequestId;
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ // We will at some point (before final update) be notified of the ordinal and
+ // we need to preserve it so we can send it later.
+ int active_match_ordinal_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver);
+};
+
+class DomOperationNotificationObserver : public NotificationObserver {
+ public:
+ explicit DomOperationNotificationObserver(AutomationProvider* automation);
+ ~DomOperationNotificationObserver();
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+
+ DISALLOW_COPY_AND_ASSIGN(DomOperationNotificationObserver);
+};
+
+#if defined(OS_WIN)
+// TODO(port): Enable when printing is ported.
+class DocumentPrintedNotificationObserver : public NotificationObserver {
+ public:
+ DocumentPrintedNotificationObserver(AutomationProvider* automation,
+ IPC::Message* reply_message);
+ ~DocumentPrintedNotificationObserver();
+
+ virtual void Observe(NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ NotificationRegistrar registrar_;
+ scoped_refptr<AutomationProvider> automation_;
+ bool success_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(DocumentPrintedNotificationObserver);
+};
+#endif // defined(OS_WIN)
+
+#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_
diff --git a/chrome/browser/views/find_bar_win_browsertest.cc b/chrome/browser/views/find_bar_win_browsertest.cc
index 3995293..63847fc 100644
--- a/chrome/browser/views/find_bar_win_browsertest.cc
+++ b/chrome/browser/views/find_bar_win_browsertest.cc
@@ -27,6 +27,8 @@ const std::wstring kPrematureEnd = L"files/find_in_page/premature_end.html";
const std::wstring kMoveIfOver = L"files/find_in_page/move_if_obscuring.html";
const std::wstring kBitstackCrash = L"files/find_in_page/crash_14491.html";
+namespace {
+
class FindInPageNotificationObserver : public NotificationObserver {
public:
explicit FindInPageNotificationObserver(TabContents* parent_tab)
@@ -76,6 +78,8 @@ class FindInPageNotificationObserver : public NotificationObserver {
int current_find_request_id_;
};
+} // namespace
+
typedef enum { BACK = 0, FWD = 1 } FindInPageDirection;
typedef enum { IGNORE_CASE = 0, CASE_SENSITIVE = 1 } FindInPageCase;