Home | History | Annotate | Download | only in automation
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This implements a browser-side endpoint for UI automation activity.
      6 // The client-side endpoint is implemented by AutomationProxy.
      7 // The entire lifetime of this object should be contained within that of
      8 // the BrowserProcess, and in particular the NotificationService that's
      9 // hung off of it.
     10 
     11 #ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_
     12 #define CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_
     13 #pragma once
     14 
     15 #include <map>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "base/basictypes.h"
     20 #include "base/compiler_specific.h"
     21 #include "base/memory/scoped_ptr.h"
     22 #include "base/memory/weak_ptr.h"
     23 #include "base/observer_list.h"
     24 #include "base/string16.h"
     25 #include "chrome/browser/autofill/field_types.h"
     26 #include "chrome/common/automation_constants.h"
     27 #include "chrome/common/content_settings.h"
     28 #include "content/browser/browser_thread.h"
     29 #include "content/browser/cancelable_request.h"
     30 #include "content/browser/tab_contents/navigation_entry.h"
     31 #include "content/common/notification_observer.h"
     32 #include "ipc/ipc_channel.h"
     33 
     34 #if defined(OS_WIN)
     35 #include "ui/gfx/native_widget_types.h"
     36 #include "views/events/event.h"
     37 #endif  // defined(OS_WIN)
     38 
     39 class PopupMenuWaiter;
     40 class TabContents;
     41 struct AutomationMsg_Find_Params;
     42 struct Reposition_Params;
     43 struct ExternalTabSettings;
     44 
     45 namespace IPC {
     46 class ChannelProxy;
     47 }
     48 
     49 class AutofillProfile;
     50 class AutomationAutocompleteEditTracker;
     51 class AutomationBrowserTracker;
     52 class AutomationExtensionTracker;
     53 class AutomationResourceMessageFilter;
     54 class AutomationTabTracker;
     55 class AutomationWindowTracker;
     56 class Browser;
     57 class CreditCard;
     58 class DictionaryValue;
     59 class DownloadItem;
     60 class Extension;
     61 class ExtensionPortContainer;
     62 class ExtensionTestResultNotificationObserver;
     63 class ExternalTabContainer;
     64 class FilePath;
     65 class InitialLoadObserver;
     66 class ListValue;
     67 class LoginHandler;
     68 class MetricEventDurationObserver;
     69 class NavigationController;
     70 class NavigationControllerRestoredObserver;
     71 class Profile;
     72 class RenderViewHost;
     73 class TabContents;
     74 struct AutocompleteMatchData;
     75 
     76 namespace gfx {
     77 class Point;
     78 }
     79 
     80 class AutomationProvider
     81     : public IPC::Channel::Listener,
     82       public IPC::Message::Sender,
     83       public base::SupportsWeakPtr<AutomationProvider>,
     84       public base::RefCountedThreadSafe<AutomationProvider,
     85                                         BrowserThread::DeleteOnUIThread> {
     86  public:
     87   explicit AutomationProvider(Profile* profile);
     88 
     89   Profile* profile() const { return profile_; }
     90 
     91   // Initializes a channel for a connection to an AutomationProxy.
     92   // If channel_id starts with kNamedInterfacePrefix, it will act
     93   // as a server, create a named IPC socket with channel_id as its
     94   // path, and will listen on the socket for incoming connections.
     95   // If channel_id does not, it will act as a client and establish
     96   // a connection on its primary IPC channel. See ipc/ipc_channel_posix.cc
     97   // for more information about kPrimaryIPCChannel.
     98   bool InitializeChannel(const std::string& channel_id) WARN_UNUSED_RESULT;
     99 
    100   // Sets the number of tabs that we expect; when this number of tabs has
    101   // loaded, an AutomationMsg_InitialLoadsComplete message is sent.
    102   void SetExpectedTabCount(size_t expected_tabs);
    103 
    104   // Called when the inital set of tabs has finished loading.
    105   // Call SetExpectedTabCount(0) to set this to true immediately.
    106   void OnInitialTabLoadsComplete();
    107 
    108   // Called when the ChromeOS network library has finished its first update.
    109   void OnNetworkLibraryInit();
    110 
    111   // Get the index of a particular NavigationController object
    112   // in the given parent window.  This method uses
    113   // TabStrip::GetIndexForNavigationController to get the index.
    114   int GetIndexForNavigationController(const NavigationController* controller,
    115                                       const Browser* parent) const;
    116 
    117   // Add or remove a non-owning reference to a tab's LoginHandler.  This is for
    118   // when a login prompt is shown for HTTP/FTP authentication.
    119   // TODO(mpcomplete): The login handling is a fairly special purpose feature.
    120   // Eventually we'll probably want ways to interact with the ChromeView of the
    121   // login window in a generic manner, such that it can be used for anything,
    122   // not just logins.
    123   void AddLoginHandler(NavigationController* tab, LoginHandler* handler);
    124   void RemoveLoginHandler(NavigationController* tab);
    125 
    126   // IPC implementations
    127   virtual bool Send(IPC::Message* msg);
    128   virtual void OnChannelConnected(int pid);
    129   virtual bool OnMessageReceived(const IPC::Message& msg);
    130   virtual void OnChannelError();
    131 
    132   IPC::Message* reply_message_release() {
    133     IPC::Message* reply_message = reply_message_;
    134     reply_message_ = NULL;
    135     return reply_message;
    136   }
    137 
    138   // Adds the extension passed in to the extension tracker, and returns
    139   // the associated handle. If the tracker already contains the extension,
    140   // the handle is simply returned.
    141   int AddExtension(const Extension* extension);
    142 
    143 #if defined(OS_WIN)
    144   // Adds the external tab passed in to the tab tracker.
    145   bool AddExternalTab(ExternalTabContainer* external_tab);
    146 #endif
    147 
    148   // Get the DictionaryValue equivalent for a download item. Caller owns the
    149   // DictionaryValue.
    150   DictionaryValue* GetDictionaryFromDownloadItem(const DownloadItem* download);
    151 
    152  protected:
    153   friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
    154   friend class DeleteTask<AutomationProvider>;
    155   virtual ~AutomationProvider();
    156 
    157   // Helper function to find the browser window that contains a given
    158   // NavigationController and activate that tab.
    159   // Returns the Browser if found.
    160   Browser* FindAndActivateTab(NavigationController* contents);
    161 
    162   // Convert a tab handle into a TabContents. If |tab| is non-NULL a pointer
    163   // to the tab is also returned. Returns NULL in case of failure or if the tab
    164   // is not of the TabContents type.
    165   TabContents* GetTabContentsForHandle(int handle, NavigationController** tab);
    166 
    167   // Returns the protocol version which typically is the module version.
    168   virtual std::string GetProtocolVersion();
    169 
    170   // Returns the associated view for the tab handle passed in.
    171   // Returns NULL on failure.
    172   RenderViewHost* GetViewForTab(int tab_handle);
    173 
    174   // Called on IPC message deserialization failure. Prints an error message
    175   // and closes the IPC channel.
    176   void OnMessageDeserializationFailure();
    177 
    178   scoped_ptr<AutomationAutocompleteEditTracker> autocomplete_edit_tracker_;
    179   scoped_ptr<AutomationBrowserTracker> browser_tracker_;
    180   scoped_ptr<InitialLoadObserver> initial_load_observer_;
    181   scoped_ptr<MetricEventDurationObserver> metric_event_duration_observer_;
    182   scoped_ptr<NavigationControllerRestoredObserver> restore_tracker_;
    183   scoped_ptr<AutomationTabTracker> tab_tracker_;
    184   scoped_ptr<AutomationWindowTracker> window_tracker_;
    185 
    186   typedef std::map<NavigationController*, LoginHandler*> LoginHandlerMap;
    187   LoginHandlerMap login_handler_map_;
    188 
    189   Profile* profile_;
    190 
    191   // A pointer to reply message used when we do asynchronous processing in the
    192   // message handler.
    193   // TODO(phajdan.jr): Remove |reply_message_|, it is error-prone.
    194   IPC::Message* reply_message_;
    195 
    196   // Consumer for asynchronous history queries.
    197   CancelableRequestConsumer consumer_;
    198 
    199   // Sends a find request for a given query.
    200   void SendFindRequest(
    201       TabContents* tab_contents,
    202       bool with_json,
    203       const string16& search_string,
    204       bool forward,
    205       bool match_case,
    206       bool find_next,
    207       IPC::Message* reply_message);
    208 
    209   scoped_refptr<AutomationResourceMessageFilter>
    210       automation_resource_message_filter_;
    211 
    212   // True iff we should open a new automation IPC channel if it closes.
    213   bool reinitialize_on_channel_error_;
    214 
    215  private:
    216   void OnUnhandledMessage();
    217 
    218   // Clear and reinitialize the automation IPC channel.
    219   bool ReinitializeChannel();
    220 
    221   // IPC Message callbacks.
    222   void WindowSimulateDrag(int handle,
    223                           const std::vector<gfx::Point>& drag_path,
    224                           int flags,
    225                           bool press_escape_en_route,
    226                           IPC::Message* reply_message);
    227   void HandleUnused(const IPC::Message& message, int handle);
    228   void SetFilteredInet(const IPC::Message& message, bool enabled);
    229   void GetFilteredInetHitCount(int* hit_count);
    230   void SetProxyConfig(const std::string& new_proxy_config);
    231 
    232   // Responds to the FindInPage request, retrieves the search query parameters,
    233   // launches an observer to listen for results and issues a StartFind request.
    234   void HandleFindRequest(int handle,
    235                          const AutomationMsg_Find_Params& params,
    236                          IPC::Message* reply_message);
    237 
    238   void OnSetPageFontSize(int tab_handle, int font_size);
    239 
    240   // See browsing_data_remover.h for explanation of bitmap fields.
    241   void RemoveBrowsingData(int remove_mask);
    242 
    243   // Notify the JavaScript engine in the render to change its parameters
    244   // while performing stress testing. See
    245   // |ViewHostMsg_JavaScriptStressTestControl_Commands| in render_messages.h
    246   // for information on the arguments.
    247   void JavaScriptStressTestControl(int handle, int cmd, int param);
    248 
    249   void InstallExtension(const FilePath& crx_path,
    250                         IPC::Message* reply_message);
    251 
    252   void WaitForExtensionTestResult(IPC::Message* reply_message);
    253 
    254   void InstallExtensionAndGetHandle(const FilePath& crx_path,
    255                                     bool with_ui,
    256                                     IPC::Message* reply_message);
    257 
    258   void UninstallExtension(int extension_handle,
    259                           bool* success);
    260 
    261   void ReloadExtension(int extension_handle,
    262                        IPC::Message* reply_message);
    263 
    264   void EnableExtension(int extension_handle,
    265                        IPC::Message* reply_message);
    266 
    267   void DisableExtension(int extension_handle,
    268                         bool* success);
    269 
    270   void ExecuteExtensionActionInActiveTabAsync(int extension_handle,
    271                                               int browser_handle,
    272                                               IPC::Message* reply_message);
    273 
    274   void MoveExtensionBrowserAction(int extension_handle, int index,
    275                                   bool* success);
    276 
    277   void GetExtensionProperty(int extension_handle,
    278                             AutomationMsg_ExtensionProperty type,
    279                             bool* success,
    280                             std::string* value);
    281 
    282   // Asynchronous request for printing the current tab.
    283   void PrintAsync(int tab_handle);
    284 
    285   // Uses the specified encoding to override the encoding of the page in the
    286   // specified tab.
    287   void OverrideEncoding(int tab_handle,
    288                         const std::string& encoding_name,
    289                         bool* success);
    290 
    291   // Selects all contents on the page.
    292   void SelectAll(int tab_handle);
    293 
    294   // Edit operations on the page.
    295   void Cut(int tab_handle);
    296   void Copy(int tab_handle);
    297   void Paste(int tab_handle);
    298 
    299   void ReloadAsync(int tab_handle);
    300   void StopAsync(int tab_handle);
    301   void SaveAsAsync(int tab_handle);
    302 
    303   // Returns the extension for the given handle. Returns NULL if there is
    304   // no extension for the handle.
    305   const Extension* GetExtension(int extension_handle);
    306 
    307   // Returns the extension for the given handle, if the handle is valid and
    308   // the associated extension is enabled. Returns NULL otherwise.
    309   const Extension* GetEnabledExtension(int extension_handle);
    310 
    311   // Returns the extension for the given handle, if the handle is valid and
    312   // the associated extension is disabled. Returns NULL otherwise.
    313   const Extension* GetDisabledExtension(int extension_handle);
    314 
    315   // Method called by the popup menu tracker when a popup menu is opened.
    316   void NotifyPopupMenuOpened();
    317 
    318 #if defined(OS_WIN)
    319   // The functions in this block are for use with external tabs, so they are
    320   // Windows only.
    321 
    322   // The container of an externally hosted tab calls this to reflect any
    323   // accelerator keys that it did not process. This gives the tab a chance
    324   // to handle the keys
    325   void ProcessUnhandledAccelerator(const IPC::Message& message, int handle,
    326                                    const MSG& msg);
    327 
    328   void SetInitialFocus(const IPC::Message& message, int handle, bool reverse,
    329                        bool restore_focus_to_view);
    330 
    331   void OnTabReposition(int tab_handle,
    332                        const Reposition_Params& params);
    333 
    334   void OnForwardContextMenuCommandToChrome(int tab_handle, int command);
    335 
    336   void CreateExternalTab(const ExternalTabSettings& settings,
    337                          gfx::NativeWindow* tab_container_window,
    338                          gfx::NativeWindow* tab_window,
    339                          int* tab_handle,
    340                          int* session_id);
    341 
    342   void ConnectExternalTab(uint64 cookie,
    343                           bool allow,
    344                           gfx::NativeWindow parent_window,
    345                           gfx::NativeWindow* tab_container_window,
    346                           gfx::NativeWindow* tab_window,
    347                           int* tab_handle,
    348                           int* session_id);
    349 
    350   void NavigateInExternalTab(
    351       int handle, const GURL& url, const GURL& referrer,
    352       AutomationMsg_NavigationResponseValues* status);
    353   void NavigateExternalTabAtIndex(
    354       int handle, int index, AutomationMsg_NavigationResponseValues* status);
    355 
    356   // Handler for a message sent by the automation client.
    357   void OnMessageFromExternalHost(int handle, const std::string& message,
    358                                  const std::string& origin,
    359                                  const std::string& target);
    360 
    361   void OnBrowserMoved(int handle);
    362 
    363   void OnRunUnloadHandlers(int handle, IPC::Message* reply_message);
    364 
    365   void OnSetZoomLevel(int handle, int zoom_level);
    366 
    367   ExternalTabContainer* GetExternalTabForHandle(int handle);
    368 #endif  // defined(OS_WIN)
    369 
    370   scoped_ptr<IPC::ChannelProxy> channel_;
    371   scoped_ptr<NotificationObserver> new_tab_ui_load_observer_;
    372   scoped_ptr<NotificationObserver> find_in_page_observer_;
    373   scoped_ptr<ExtensionTestResultNotificationObserver>
    374       extension_test_result_observer_;
    375   scoped_ptr<AutomationExtensionTracker> extension_tracker_;
    376 
    377   // True iff connected to an AutomationProxy.
    378   bool is_connected_;
    379 
    380   // True iff browser finished loading initial set of tabs.
    381   bool initial_tab_loads_complete_;
    382 
    383   // True iff the Chrome OS network library finished initialization.
    384   bool network_library_initialized_;
    385 
    386   // ID of automation channel.
    387   std::string channel_id_;
    388 
    389   DISALLOW_COPY_AND_ASSIGN(AutomationProvider);
    390 };
    391 
    392 #endif  // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_
    393