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 39class PopupMenuWaiter; 40class TabContents; 41struct AutomationMsg_Find_Params; 42struct Reposition_Params; 43struct ExternalTabSettings; 44 45namespace IPC { 46class ChannelProxy; 47} 48 49class AutofillProfile; 50class AutomationAutocompleteEditTracker; 51class AutomationBrowserTracker; 52class AutomationExtensionTracker; 53class AutomationResourceMessageFilter; 54class AutomationTabTracker; 55class AutomationWindowTracker; 56class Browser; 57class CreditCard; 58class DictionaryValue; 59class DownloadItem; 60class Extension; 61class ExtensionPortContainer; 62class ExtensionTestResultNotificationObserver; 63class ExternalTabContainer; 64class FilePath; 65class InitialLoadObserver; 66class ListValue; 67class LoginHandler; 68class MetricEventDurationObserver; 69class NavigationController; 70class NavigationControllerRestoredObserver; 71class Profile; 72class RenderViewHost; 73class TabContents; 74struct AutocompleteMatchData; 75 76namespace gfx { 77class Point; 78} 79 80class 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