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