Home | History | Annotate | Download | only in automation
      1 // Copyright (c) 2012 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 
     14 #include <list>
     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/sequenced_task_runner_helpers.h"
     25 #include "base/strings/string16.h"
     26 #include "chrome/browser/common/cancelable_request.h"
     27 #include "chrome/common/automation_constants.h"
     28 #include "chrome/common/content_settings.h"
     29 #include "components/autofill/core/browser/field_types.h"
     30 #include "content/public/browser/browser_thread.h"
     31 #include "content/public/browser/notification_observer.h"
     32 #include "ipc/ipc_channel.h"
     33 #include "ipc/ipc_listener.h"
     34 #include "ipc/ipc_sender.h"
     35 
     36 #if defined(OS_WIN) && !defined(USE_AURA)
     37 #include "ui/gfx/native_widget_types.h"
     38 #endif  // defined(OS_WIN) && !defined(USE_AURA)
     39 
     40 class AutomationBrowserTracker;
     41 class AutomationResourceMessageFilter;
     42 class AutomationTabTracker;
     43 class AutomationWindowTracker;
     44 class Browser;
     45 class ExternalTabContainer;
     46 class FindInPageNotificationObserver;
     47 class InitialLoadObserver;
     48 class LoginHandler;
     49 class MetricEventDurationObserver;
     50 class NavigationControllerRestoredObserver;
     51 class NewTabUILoadObserver;
     52 class Profile;
     53 struct AutomationMsg_Find_Params;
     54 struct Reposition_Params;
     55 struct ExternalTabSettings;
     56 
     57 namespace IPC {
     58 class ChannelProxy;
     59 }
     60 
     61 namespace content {
     62 class NavigationController;
     63 class RenderViewHost;
     64 }
     65 
     66 namespace base {
     67 class DictionaryValue;
     68 }
     69 
     70 namespace content {
     71 class DownloadItem;
     72 class WebContents;
     73 }
     74 
     75 namespace gfx {
     76 class Point;
     77 }
     78 
     79 class AutomationProvider
     80     : public IPC::Listener,
     81       public IPC::Sender,
     82       public base::SupportsWeakPtr<AutomationProvider>,
     83       public base::RefCountedThreadSafe<
     84           AutomationProvider, content::BrowserThread::DeleteOnUIThread> {
     85  public:
     86   explicit AutomationProvider(Profile* profile);
     87 
     88   Profile* profile() const { return profile_; }
     89 
     90   void set_profile(Profile* profile);
     91 
     92   // Initializes a channel for a connection to an AutomationProxy.
     93   // If channel_id starts with kNamedInterfacePrefix, it will act
     94   // as a server, create a named IPC socket with channel_id as its
     95   // path, and will listen on the socket for incoming connections.
     96   // If channel_id does not, it will act as a client and establish
     97   // a connection on its primary IPC channel. See ipc/ipc_channel_posix.cc
     98   // for more information about kPrimaryIPCChannel.
     99   bool InitializeChannel(const std::string& channel_id) WARN_UNUSED_RESULT;
    100 
    101   virtual IPC::Channel::Mode GetChannelMode(bool use_named_interface);
    102 
    103   // Sets the number of tabs that we expect; when this number of tabs has
    104   // loaded, an AutomationMsg_InitialLoadsComplete message is sent.
    105   void SetExpectedTabCount(size_t expected_tabs);
    106 
    107   // Called when the inital set of tabs has finished loading.
    108   // Call SetExpectedTabCount(0) to set this to true immediately.
    109   void OnInitialTabLoadsComplete();
    110 
    111   // Called when the chromeos WebUI OOBE/Login is ready.
    112   void OnOOBEWebuiReady();
    113 
    114   // Checks all of the initial load conditions, then sends the
    115   // InitialLoadsComplete message over the automation channel.
    116   void SendInitialLoadMessage();
    117 
    118   // Call this before calling InitializeChannel. If called, send the
    119   // InitialLoadsComplete message immediately when the automation channel is
    120   // connected, without waiting for the initial load conditions to be met.
    121   void DisableInitialLoadObservers();
    122 
    123   // Get the index of a particular NavigationController object
    124   // in the given parent window.  This method uses
    125   // TabStrip::GetIndexForNavigationController to get the index.
    126   int GetIndexForNavigationController(
    127       const content::NavigationController* controller,
    128       const Browser* parent) const;
    129 
    130   // IPC::Sender implementation.
    131   virtual bool Send(IPC::Message* msg) OVERRIDE;
    132 
    133   // IPC::Listener implementation.
    134   virtual void OnChannelConnected(int pid) OVERRIDE;
    135   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
    136   virtual void OnChannelError() OVERRIDE;
    137 
    138   IPC::Message* reply_message_release() {
    139     IPC::Message* reply_message = reply_message_;
    140     reply_message_ = NULL;
    141     return reply_message;
    142   }
    143 
    144 #if defined(OS_WIN)
    145   // Adds the external tab passed in to the tab tracker.
    146   bool AddExternalTab(ExternalTabContainer* external_tab);
    147 #endif
    148 
    149   // Get the DictionaryValue equivalent for a download item. Caller owns the
    150   // DictionaryValue.
    151   base::DictionaryValue* GetDictionaryFromDownloadItem(
    152       const content::DownloadItem* download,
    153       bool incognito);
    154 
    155  protected:
    156   friend struct content::BrowserThread::DeleteOnThread<
    157       content::BrowserThread::UI>;
    158   friend class base::DeleteHelper<AutomationProvider>;
    159   virtual ~AutomationProvider();
    160 
    161   // Helper function to find the browser window that contains a given
    162   // NavigationController and activate that tab.
    163   // Returns the Browser if found.
    164   Browser* FindAndActivateTab(content::NavigationController* contents);
    165 
    166   // Convert a tab handle into a WebContents. If |tab| is non-NULL a pointer
    167   // to the tab is also returned. Returns NULL in case of failure or if the tab
    168   // is not of the WebContents type.
    169   content::WebContents* GetWebContentsForHandle(
    170       int handle, content::NavigationController** tab);
    171 
    172   // Returns the protocol version which typically is the module version.
    173   virtual std::string GetProtocolVersion();
    174 
    175   // Returns the associated view for the tab handle passed in.
    176   // Returns NULL on failure.
    177   content::RenderViewHost* GetViewForTab(int tab_handle);
    178 
    179   // Called on IPC message deserialization failure. Prints an error message
    180   // and closes the IPC channel.
    181   void OnMessageDeserializationFailure();
    182 
    183   scoped_ptr<AutomationBrowserTracker> browser_tracker_;
    184   scoped_ptr<InitialLoadObserver> initial_load_observer_;
    185   scoped_ptr<MetricEventDurationObserver> metric_event_duration_observer_;
    186   scoped_ptr<AutomationTabTracker> tab_tracker_;
    187   scoped_ptr<AutomationWindowTracker> window_tracker_;
    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       content::WebContents* web_contents,
    202       bool with_json,
    203       const base::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(const IPC::Message& message);
    217 
    218   // Clear and reinitialize the automation IPC channel.
    219   bool ReinitializeChannel();
    220 
    221   void HandleUnused(const IPC::Message& message, int handle);
    222   void GetFilteredInetHitCount(int* hit_count);
    223   void SetProxyConfig(const std::string& new_proxy_config);
    224 
    225   // Responds to the FindInPage request, retrieves the search query parameters,
    226   // launches an observer to listen for results and issues a StartFind request.
    227   void HandleFindRequest(int handle,
    228                          const AutomationMsg_Find_Params& params,
    229                          IPC::Message* reply_message);
    230 
    231   void OnSetPageFontSize(int tab_handle, int font_size);
    232 
    233   // See browsing_data_remover.h for explanation of bitmap fields.
    234   void RemoveBrowsingData(int remove_mask);
    235 
    236   // Notify the JavaScript engine in the render to change its parameters
    237   // while performing stress testing. See
    238   // |ViewHostMsg_JavaScriptStressTestControl_Commands| in render_messages.h
    239   // for information on the arguments.
    240   void JavaScriptStressTestControl(int handle, int cmd, int param);
    241 
    242   void BeginTracing(const std::string& category_patterns, bool* success);
    243   void EndTracing(IPC::Message* reply_message);
    244   void OnTraceDataCollected(IPC::Message* reply_message,
    245                             const base::FilePath& path);
    246 
    247   // Asynchronous request for printing the current tab.
    248   void PrintAsync(int tab_handle);
    249 
    250   // Uses the specified encoding to override the encoding of the page in the
    251   // specified tab.
    252   void OverrideEncoding(int tab_handle,
    253                         const std::string& encoding_name,
    254                         bool* success);
    255 
    256   // Selects all contents on the page.
    257   void SelectAll(int tab_handle);
    258 
    259   // Edit operations on the page.
    260   void Cut(int tab_handle);
    261   void Copy(int tab_handle);
    262   void Paste(int tab_handle);
    263 
    264   void ReloadAsync(int tab_handle);
    265   void StopAsync(int tab_handle);
    266   void SaveAsAsync(int tab_handle);
    267 
    268   // Method called by the popup menu tracker when a popup menu is opened.
    269   void NotifyPopupMenuOpened();
    270 
    271 #if defined(OS_WIN)
    272   // The functions in this block are for use with external tabs, so they are
    273   // Windows only.
    274 
    275   // The container of an externally hosted tab calls this to reflect any
    276   // accelerator keys that it did not process. This gives the tab a chance
    277   // to handle the keys
    278   void ProcessUnhandledAccelerator(const IPC::Message& message, int handle,
    279                                    const MSG& msg);
    280 
    281   void SetInitialFocus(const IPC::Message& message, int handle, bool reverse,
    282                        bool restore_focus_to_view);
    283 
    284   void OnTabReposition(int tab_handle,
    285                        const Reposition_Params& params);
    286 
    287   void OnForwardContextMenuCommandToChrome(int tab_handle, int command);
    288 
    289   void CreateExternalTab(const ExternalTabSettings& settings,
    290                          HWND* tab_container_window,
    291                          HWND* tab_window,
    292                          int* tab_handle,
    293                          int* session_id);
    294 
    295   void ConnectExternalTab(uint64 cookie,
    296                           bool allow,
    297                           HWND parent_window,
    298                           HWND* tab_container_window,
    299                           HWND* tab_window,
    300                           int* tab_handle,
    301                           int* session_id);
    302 
    303   void NavigateInExternalTab(
    304       int handle, const GURL& url, const GURL& referrer,
    305       AutomationMsg_NavigationResponseValues* status);
    306   void NavigateExternalTabAtIndex(
    307       int handle, int index, AutomationMsg_NavigationResponseValues* status);
    308 
    309   // Handler for a message sent by the automation client.
    310   void OnMessageFromExternalHost(int handle, const std::string& message,
    311                                  const std::string& origin,
    312                                  const std::string& target);
    313 
    314   void OnBrowserMoved(int handle);
    315 
    316   void OnRunUnloadHandlers(int handle, IPC::Message* reply_message);
    317 
    318   void OnSetZoomLevel(int handle, int zoom_level);
    319 
    320   ExternalTabContainer* GetExternalTabForHandle(int handle);
    321 #endif  // defined(OS_WIN)
    322 
    323   scoped_ptr<IPC::ChannelProxy> channel_;
    324   scoped_ptr<NewTabUILoadObserver> new_tab_ui_load_observer_;
    325   scoped_ptr<FindInPageNotificationObserver> find_in_page_observer_;
    326 
    327   // True iff we should enable observers that check for initial load conditions.
    328   bool use_initial_load_observers_;
    329 
    330   // True iff connected to an AutomationProxy.
    331   bool is_connected_;
    332 
    333   // True iff browser finished loading initial set of tabs.
    334   bool initial_tab_loads_complete_;
    335 
    336   // True iff ChromeOS webui login ui is ready.
    337   bool login_webui_ready_;
    338 
    339   // ID of automation channel.
    340   std::string channel_id_;
    341 
    342   DISALLOW_COPY_AND_ASSIGN(AutomationProvider);
    343 };
    344 
    345 #endif  // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_H_
    346