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