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