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