blob: 93ad3d53bcd152eaf215117a50e6f4864272df9e [file] [log] [blame]
[email protected]3b5f7022010-03-25 20:37:401// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]202e7a72009-06-15 03:48:369#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3110#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]c6cb1992009-04-13 16:45:2912#include "base/file_version_info.h"
[email protected]93d49d72009-10-23 20:00:2013#include "base/json/json_reader.h"
[email protected]59a611242010-04-02 02:24:0414#include "base/json/json_writer.h"
[email protected]bc1407f2009-09-29 00:33:3515#include "base/keyboard_codes.h"
[email protected]5fac9622009-02-04 21:49:3816#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2917#include "base/path_service.h"
[email protected]201b2732009-11-13 18:57:4618#include "base/process_util.h"
[email protected]f44265b2009-05-19 18:52:5019#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2720#include "base/string_util.h"
[email protected]5fac9622009-02-04 21:49:3821#include "base/thread.h"
[email protected]6d8ffc9f2010-03-12 18:27:5322#include "base/utf_string_conversions.h"
[email protected]a7eee32f2009-05-22 18:08:1723#include "base/values.h"
[email protected]4f3dc372009-02-24 00:10:2924#include "chrome/app/chrome_dll_resource.h"
[email protected]bcff05a2010-04-14 01:46:4325#include "chrome/app/chrome_version_info.h"
[email protected]0bfa713f2009-04-07 20:18:2826#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0927#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]b83e4602009-05-15 22:58:3328#include "chrome/browser/automation/automation_extension_function.h"
[email protected]790788ac2010-04-06 17:52:1929#include "chrome/browser/automation/automation_extension_tracker.h"
initial.commit09911bf2008-07-26 23:55:2930#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0831#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]a9024892009-06-16 23:13:5532#include "chrome/browser/automation/extension_automation_constants.h"
[email protected]f44265b2009-05-19 18:52:5033#include "chrome/browser/automation/extension_port_container.h"
[email protected]66ba4932009-06-04 19:22:1334#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5335#include "chrome/browser/bookmarks/bookmark_model.h"
36#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]5c238752009-06-13 10:29:0737#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3938#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2039#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0540#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5841#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2942#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1243#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5944#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2245#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0546#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4047#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1948#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]d11c8e92009-10-20 23:26:4049#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5550#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1951#include "chrome/browser/extensions/extension_tabs_module.h"
52#include "chrome/browser/extensions/extension_toolbar_model.h"
53#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1654#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5855#include "chrome/browser/find_bar.h"
56#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2957#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0158#include "chrome/browser/host_content_settings_map.h"
[email protected]0ac83682010-01-22 17:46:2759#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0660#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0161#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5362#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2463#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0864#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0565#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1766#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0767#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2568#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0369#include "chrome/browser/ssl/ssl_manager.h"
70#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3471#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4572#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1773#include "chrome/common/automation_constants.h"
initial.commit09911bf2008-07-26 23:55:2974#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1975#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1776#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5577#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1478#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5779#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2580#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5681#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5782#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1783#include "net/proxy/proxy_service.h"
84#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2185#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3086#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2887#include "views/event.h"
[email protected]f7d48012010-05-06 08:17:0588#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2989
[email protected]de246f52009-02-25 18:25:4590#if defined(OS_WIN)
[email protected]de246f52009-02-25 18:25:4591#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4592#endif // defined(OS_WIN)
93
[email protected]e1acf6f2008-10-27 20:43:3394using base::Time;
95
[email protected]cbab76d2008-10-13 22:42:4796class AutomationInterstitialPage : public InterstitialPage {
97 public:
[email protected]57c6a652009-05-04 07:58:3498 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:4799 const GURL& url,
100 const std::string& contents)
101 : InterstitialPage(tab, true, url),
102 contents_(contents) {
103 }
104
105 virtual std::string GetHTMLContents() { return contents_; }
106
107 private:
108 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29109
[email protected]cbab76d2008-10-13 22:42:47110 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
111};
112
[email protected]c2cb8542009-08-20 21:16:51113class ClickTask : public Task {
114 public:
[email protected]fc2e0872009-08-21 22:14:41115 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51116 virtual ~ClickTask() {}
117
118 virtual void Run() {
119 ui_controls::MouseButton button = ui_controls::LEFT;
120 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
121 views::Event::EF_LEFT_BUTTON_DOWN) {
122 button = ui_controls::LEFT;
123 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
124 views::Event::EF_RIGHT_BUTTON_DOWN) {
125 button = ui_controls::RIGHT;
126 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
127 views::Event::EF_MIDDLE_BUTTON_DOWN) {
128 button = ui_controls::MIDDLE;
129 } else {
130 NOTREACHED();
131 }
132
[email protected]fc2e0872009-08-21 22:14:41133 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51134 }
135
136 private:
[email protected]c2cb8542009-08-20 21:16:51137 int flags_;
138
139 DISALLOW_COPY_AND_ASSIGN(ClickTask);
140};
[email protected]c2cb8542009-08-20 21:16:51141
initial.commit09911bf2008-07-26 23:55:29142AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57143 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56144 profile_(profile),
[email protected]cc824372010-03-31 15:33:01145 reply_message_(NULL),
146 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29147 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19148 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29149 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20150 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29151 autocomplete_edit_tracker_.reset(
152 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29153 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
154 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44155 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19156 extension_test_result_observer_.reset(
157 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13158 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29159}
160
161AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50162 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
163 port_containers_.end());
164 port_containers_.clear();
165
[email protected]0da050b92008-08-19 19:29:47166 // Make sure that any outstanding NotificationObservers also get destroyed.
167 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31168 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47169 while ((observer = it.GetNext()) != NULL)
170 delete observer;
[email protected]528211a2010-01-14 15:25:13171
172 if (channel_.get()) {
173 channel_->Close();
174 }
175 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29176}
177
[email protected]9a3a293b2009-06-04 22:28:16178void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06179 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57180 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06181 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
182 automation_resource_message_filter_,
183 g_browser_process->io_thread()->message_loop(),
184 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43185 scoped_ptr<FileVersionInfo> version_info(
186 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40187 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43188 if (version_info != NULL) {
189 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40190 }
[email protected]c6cb1992009-04-13 16:45:29191
192 // Send a hello message with our current automation protocol version.
193 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29194}
195
196void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
197 if (expected_tabs == 0) {
198 Send(new AutomationMsg_InitialLoadsComplete(0));
199 } else {
200 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
201 }
202}
203
204NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58205 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01206 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29207 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58208 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01209 number_of_navigations,
210 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29211
[email protected]71f65dd2009-02-11 19:14:56212 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29213 return observer;
214}
215
[email protected]faf2ee42010-05-11 14:26:17216void AutomationProvider::RemoveNavigationStatusListener(
217 NotificationObserver* obs) {
218 notification_observer_list_.RemoveObserver(obs);
219}
220
initial.commit09911bf2008-07-26 23:55:29221NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14222 Browser* parent,
223 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56224 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14225 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29226 notification_observer_list_.AddObserver(observer);
227
228 return observer;
229}
230
[email protected]faf2ee42010-05-11 14:26:17231void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29232 notification_observer_list_.RemoveObserver(obs);
233}
234
235void AutomationProvider::AddLoginHandler(NavigationController* tab,
236 LoginHandler* handler) {
237 login_handler_map_[tab] = handler;
238}
239
240void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
241 DCHECK(login_handler_map_[tab]);
242 login_handler_map_.erase(tab);
243}
244
[email protected]f44265b2009-05-19 18:52:50245void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
246 int port_id = port->port_id();
247 DCHECK_NE(-1, port_id);
248 DCHECK(port_containers_.find(port_id) == port_containers_.end());
249
250 port_containers_[port_id] = port;
251}
252
253void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
254 int port_id = port->port_id();
255 DCHECK_NE(-1, port_id);
256
257 PortContainerMap::iterator it = port_containers_.find(port_id);
258 DCHECK(it != port_containers_.end());
259
260 if (it != port_containers_.end()) {
261 delete it->second;
262 port_containers_.erase(it);
263 }
264}
265
266ExtensionPortContainer* AutomationProvider::GetPortContainer(
267 int port_id) const {
268 PortContainerMap::const_iterator it = port_containers_.find(port_id);
269 if (it == port_containers_.end())
270 return NULL;
271
272 return it->second;
273}
274
initial.commit09911bf2008-07-26 23:55:29275int AutomationProvider::GetIndexForNavigationController(
276 const NavigationController* controller, const Browser* parent) const {
277 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12278 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29279}
280
[email protected]790788ac2010-04-06 17:52:19281int AutomationProvider::AddExtension(Extension* extension) {
282 DCHECK(extension);
283 return extension_tracker_->Add(extension);
284}
285
286Extension* AutomationProvider::GetExtension(int extension_handle) {
287 return extension_tracker_->GetResource(extension_handle);
288}
289
290Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
291 Extension* extension = extension_tracker_->GetResource(extension_handle);
292 ExtensionsService* service = profile_->GetExtensionsService();
293 if (extension && service &&
294 service->GetExtensionById(extension->id(), false))
295 return extension;
296 return NULL;
297}
298
299Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
300 Extension* extension = extension_tracker_->GetResource(extension_handle);
301 ExtensionsService* service = profile_->GetExtensionsService();
302 if (extension && service &&
303 service->GetExtensionById(extension->id(), true) &&
304 !service->GetExtensionById(extension->id(), false))
305 return extension;
306 return NULL;
307}
308
initial.commit09911bf2008-07-26 23:55:29309void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
310 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14311 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56312 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
313 CloseBrowserAsync)
314 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
315 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
316 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
317 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
318 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
319 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22320 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]1c58a5c2009-05-21 18:47:14321 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58322 IPC_MESSAGE_HANDLER_DELAY_REPLY(
323 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
324 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56325 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11326 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
327 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56328 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
329 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
330 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
331 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14332 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56333 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
334 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
335 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14336 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29337 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
338 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56339 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36340 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56341 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29342 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56343 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29344 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
345 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56346 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14347 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24348 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44349 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33350 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44351 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33352 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24353 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14354 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24355 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15356 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14357 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24358 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35359 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14360 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30361#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56362 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
363 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30364#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56365 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53366 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56367 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37368#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56369 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45370#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56371 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
372 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03373 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56374 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14375 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09376 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
377 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
378 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29379 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14380 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56381 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
382 ExecuteJavascript)
383 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29384 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14385 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
386 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56387 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
388 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14389 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17390 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14391 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14392 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53393 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
394 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14395 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56396 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14397 GetAutocompleteEditForBrowser)
398 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:45399#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29400 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:17401#endif
[email protected]71f65dd2009-02-11 19:14:56402 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:29403 NavigateInExternalTab)
[email protected]4150ef02009-08-19 23:14:26404 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
405 NavigateExternalTabAtIndex)
[email protected]71f65dd2009-02-11 19:14:56406 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14407 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56408 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14409 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:17410#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29411 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
412 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:17413#endif
[email protected]71f65dd2009-02-11 19:14:56414 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
415 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14416 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:17417#if defined(OS_WIN)
[email protected]5a9708432009-09-23 22:15:04418 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:39419 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
420 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:17421#endif
[email protected]1c58a5c2009-05-21 18:47:14422 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
423 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44424 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
425 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56426 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
427 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29428 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
429 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
430 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56431 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41432 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56433 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
434 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29435 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56436 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29437 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56438 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29439 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56440 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29441 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56442 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45443 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:45444 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
445 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:14446 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56447 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57448 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56449 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57450 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56451 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
452 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53453 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
454 GetBookmarksAsJSON)
455 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
456 WaitForBookmarkModelToLoad)
457 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
458 AddBookmarkGroup)
459 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
460 AddBookmarkURL)
461 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
462 ReparentBookmark)
463 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
464 SetBookmarkTitle)
465 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
466 SetBookmarkURL)
467 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
468 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04469 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
470 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18471 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
472 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
473 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56474 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42475 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56476 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
477 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14478 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56479 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44480 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56481 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20482 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14483 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56484 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16485 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56486 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16487 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56488 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16489 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14490 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20491 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
492 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14493 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]4cfc1d922009-11-08 14:02:58494#if defined(OS_WIN)
495 // Depends on ExternalTabContainer, so Windows-only
[email protected]b83e4602009-05-15 22:58:33496 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
497 SetEnableExtensionAutomation)
[email protected]4cfc1d922009-11-08 14:02:58498#endif
[email protected]59560e0b2009-06-04 03:30:22499 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13500 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19501 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
502 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
503 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
504 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
505 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
506 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52507 IPC_MESSAGE_HANDLER_DELAY_REPLY(
508 AutomationMsg_WaitForBrowserWindowCountToBecome,
509 WaitForBrowserWindowCountToBecome)
510 IPC_MESSAGE_HANDLER_DELAY_REPLY(
511 AutomationMsg_WaitForAppModalDialogToBeShown,
512 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26513 IPC_MESSAGE_HANDLER_DELAY_REPLY(
514 AutomationMsg_GoBackBlockUntilNavigationsComplete,
515 GoBackBlockUntilNavigationsComplete)
516 IPC_MESSAGE_HANDLER_DELAY_REPLY(
517 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
518 GoForwardBlockUntilNavigationsComplete)
[email protected]632fbb12009-09-06 15:27:14519#if defined(OS_WIN)
520 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
521#endif
[email protected]1bb5f892009-10-06 01:44:57522 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40523 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
524 InstallExtension)
525 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
526 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43527 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
528 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19529 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
530 WaitForExtensionTestResult)
531 IPC_MESSAGE_HANDLER_DELAY_REPLY(
532 AutomationMsg_InstallExtensionAndGetHandle,
533 InstallExtensionAndGetHandle)
534 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
535 UninstallExtension)
536 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
537 EnableExtension)
538 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
539 DisableExtension)
540 IPC_MESSAGE_HANDLER_DELAY_REPLY(
541 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
542 ExecuteExtensionActionInActiveTabAsync)
543 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
544 MoveExtensionBrowserAction)
545 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
546 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57547 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
548 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00549 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]2b19e2fe2010-02-16 02:24:18550#if defined(OS_WIN)
551 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
552#endif
[email protected]7dad3d5f2010-03-04 00:27:01553 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]566a0f762010-03-10 04:14:57554#if defined(OS_CHROMEOS)
555 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
556 LoginWithUserAndPass)
557#endif
[email protected]bc73b4e52010-03-26 04:16:20558 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]cc824372010-03-31 15:33:01559#if defined(TOOLKIT_VIEWS)
560 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
561 WaitForFocusedViewIDToChange)
562 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
563 StartTrackingPopupMenus)
564 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
565 WaitForPopupMenuToOpen)
566#endif
[email protected]d7e5525d2010-04-20 14:37:09567 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
initial.commit09911bf2008-07-26 23:55:29568 IPC_END_MESSAGE_MAP()
569}
570
[email protected]71f65dd2009-02-11 19:14:56571void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
572 *status = -1;
initial.commit09911bf2008-07-26 23:55:29573 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
574 Browser* browser = browser_tracker_->GetResource(handle);
575 if (at_index >= 0 && at_index < browser->tab_count()) {
576 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56577 *status = 0;
initial.commit09911bf2008-07-26 23:55:29578 }
579 }
initial.commit09911bf2008-07-26 23:55:29580}
581
[email protected]71f65dd2009-02-11 19:14:56582void AutomationProvider::AppendTab(int handle, const GURL& url,
583 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29584 int append_tab_response = -1; // -1 is the error code
585 NotificationObserver* observer = NULL;
586
587 if (browser_tracker_->ContainsHandle(handle)) {
588 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14589 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38590 TabContents* tab_contents = browser->AddTabWithURL(
591 url, GURL(), PageTransition::TYPED, -1, Browser::ADD_SELECTED, NULL,
592 std::string());
initial.commit09911bf2008-07-26 23:55:29593 if (tab_contents) {
594 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57595 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29596 }
597 }
598
599 if (append_tab_response < 0) {
600 // The append tab failed. Remove the TabStripObserver
601 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17602 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29603 delete observer;
604 }
605
[email protected]71f65dd2009-02-11 19:14:56606 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
607 append_tab_response);
608 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29609 }
610}
611
[email protected]71f65dd2009-02-11 19:14:56612void AutomationProvider::NavigateToURL(int handle, const GURL& url,
613 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58614 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
615}
616
617void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
618 int handle, const GURL& url, int number_of_navigations,
619 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29620 if (tab_tracker_->ContainsHandle(handle)) {
621 NavigationController* tab = tab_tracker_->GetResource(handle);
622
623 // Simulate what a user would do. Activate the tab and then navigate.
624 // We could allow navigating in a background tab in future.
625 Browser* browser = FindAndActivateTab(tab);
626
627 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01628 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
629 false);
[email protected]71f65dd2009-02-11 19:14:56630
initial.commit09911bf2008-07-26 23:55:29631 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50632 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29633 return;
634 }
635 }
[email protected]71f65dd2009-02-11 19:14:56636
637 AutomationMsg_NavigateToURL::WriteReplyParams(
638 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
639 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29640}
[email protected]2949e90d2009-08-21 15:32:52641
[email protected]c70f9b82010-04-21 07:31:11642void AutomationProvider::NavigationAsync(int handle,
643 const GURL& url,
644 bool* status) {
645 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
646}
647
648void AutomationProvider::NavigationAsyncWithDisposition(
649 int handle,
650 const GURL& url,
651 WindowOpenDisposition disposition,
652 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56653 *status = false;
initial.commit09911bf2008-07-26 23:55:29654
655 if (tab_tracker_->ContainsHandle(handle)) {
656 NavigationController* tab = tab_tracker_->GetResource(handle);
657
658 // Simulate what a user would do. Activate the tab and then navigate.
659 // We could allow navigating in a background tab in future.
660 Browser* browser = FindAndActivateTab(tab);
661
662 if (browser) {
663 // Don't add any listener unless a callback mechanism is desired.
664 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11665 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56666 *status = true;
initial.commit09911bf2008-07-26 23:55:29667 }
668 }
initial.commit09911bf2008-07-26 23:55:29669}
670
[email protected]71f65dd2009-02-11 19:14:56671void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29672 if (tab_tracker_->ContainsHandle(handle)) {
673 NavigationController* tab = tab_tracker_->GetResource(handle);
674 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14675 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01676 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29677 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29678 return;
679 }
680 }
[email protected]71f65dd2009-02-11 19:14:56681
682 AutomationMsg_GoBack::WriteReplyParams(
683 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
684 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29685}
686
[email protected]71f65dd2009-02-11 19:14:56687void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29688 if (tab_tracker_->ContainsHandle(handle)) {
689 NavigationController* tab = tab_tracker_->GetResource(handle);
690 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14691 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01692 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29693 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29694 return;
695 }
696 }
[email protected]71f65dd2009-02-11 19:14:56697
698 AutomationMsg_GoForward::WriteReplyParams(
699 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
700 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29701}
702
[email protected]71f65dd2009-02-11 19:14:56703void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29704 if (tab_tracker_->ContainsHandle(handle)) {
705 NavigationController* tab = tab_tracker_->GetResource(handle);
706 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14707 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01708 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29709 browser->Reload();
710 return;
711 }
712 }
[email protected]71f65dd2009-02-11 19:14:56713
714 AutomationMsg_Reload::WriteReplyParams(
715 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
716 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29717}
718
[email protected]71f65dd2009-02-11 19:14:56719void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29720 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56721 const std::wstring& password,
722 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29723 if (tab_tracker_->ContainsHandle(tab_handle)) {
724 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
725 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
726
727 if (iter != login_handler_map_.end()) {
728 // If auth is needed again after this, assume login has failed. This is
729 // not strictly correct, because a navigation can require both proxy and
730 // server auth, but it should be OK for now.
731 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01732 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29733 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52734 return;
initial.commit09911bf2008-07-26 23:55:29735 }
736 }
[email protected]de246f52009-02-25 18:25:45737
[email protected]457f5cf2009-08-18 16:37:52738 AutomationMsg_SetAuth::WriteReplyParams(
739 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
740 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29741}
742
[email protected]71f65dd2009-02-11 19:14:56743void AutomationProvider::CancelAuth(int tab_handle,
744 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29745 if (tab_tracker_->ContainsHandle(tab_handle)) {
746 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
747 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
748
749 if (iter != login_handler_map_.end()) {
750 // If auth is needed again after this, something is screwy.
751 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01752 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29753 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52754 return;
initial.commit09911bf2008-07-26 23:55:29755 }
756 }
[email protected]de246f52009-02-25 18:25:45757
[email protected]457f5cf2009-08-18 16:37:52758 AutomationMsg_CancelAuth::WriteReplyParams(
759 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
760 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29761}
762
[email protected]71f65dd2009-02-11 19:14:56763void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
764 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29765
766 if (tab_tracker_->ContainsHandle(tab_handle)) {
767 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
768 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
769
770 if (iter != login_handler_map_.end()) {
771 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56772 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29773 }
774 }
initial.commit09911bf2008-07-26 23:55:29775}
776
[email protected]71f65dd2009-02-11 19:14:56777void AutomationProvider::GetRedirectsFrom(int tab_handle,
778 const GURL& source_url,
779 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29780 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
781 if (tab_tracker_->ContainsHandle(tab_handle)) {
782 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
783 HistoryService* history_service =
784 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
785
786 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
787 "has no history service";
788 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56789 DCHECK(reply_message_ == NULL);
790 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29791 // Schedule a history query for redirects. The response will be sent
792 // asynchronously from the callback the history system uses to notify us
793 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29794 redirect_query_ = history_service->QueryRedirectsFrom(
795 source_url, &consumer_,
796 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
797 return; // Response will be sent when query completes.
798 }
799 }
800
801 // Send failure response.
[email protected]deb57402009-02-06 01:35:30802 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56803 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
804 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29805}
806
[email protected]71f65dd2009-02-11 19:14:56807void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
808 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29809 if (browser_tracker_->ContainsHandle(handle)) {
810 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56811 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29812 }
initial.commit09911bf2008-07-26 23:55:29813}
814
[email protected]202e7a72009-06-15 03:48:36815void AutomationProvider::GetBrowserLocale(string16* locale) {
816 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06817 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36818}
819
[email protected]71f65dd2009-02-11 19:14:56820void AutomationProvider::GetBrowserWindowCount(int* window_count) {
821 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29822}
823
[email protected]24497032009-05-01 17:00:29824void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
825 *window_count = static_cast<int>(
826 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
827}
828
[email protected]71f65dd2009-02-11 19:14:56829void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
830 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07831 AppModalDialog* dialog_delegate =
832 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50833 *showing_dialog = (dialog_delegate != NULL);
834 if (*showing_dialog)
835 *dialog_button = dialog_delegate->GetDialogButtons();
836 else
[email protected]478ff2ed2009-04-21 23:49:18837 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20838}
839
[email protected]71f65dd2009-02-11 19:14:56840void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
841 *success = false;
[email protected]fad84eab2008-12-05 00:37:20842
[email protected]1f460072009-05-28 17:02:07843 AppModalDialog* dialog_delegate =
844 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50845 if (dialog_delegate &&
846 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18847 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
848 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28849 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56850 *success = true;
[email protected]fad84eab2008-12-05 00:37:20851 }
[email protected]478ff2ed2009-04-21 23:49:18852 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
853 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56854 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28855 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56856 *success = true;
[email protected]fad84eab2008-12-05 00:37:20857 }
858 }
[email protected]c274acc2008-11-11 20:13:44859}
860
[email protected]fedaa7d2010-01-26 20:34:57861void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
862 if (browser_tracker_->ContainsHandle(handle)) {
863 Browser* browser = browser_tracker_->GetResource(handle);
864 browser->profile()->ShutdownSessionService();
865 *result = true;
866 } else {
867 *result = false;
868 }
869}
870
[email protected]71f65dd2009-02-11 19:14:56871void AutomationProvider::GetBrowserWindow(int index, int* handle) {
872 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29873 if (index >= 0) {
874 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:29875 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:29876 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56877 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29878 }
879 }
initial.commit09911bf2008-07-26 23:55:29880}
881
[email protected]24497032009-05-01 17:00:29882void AutomationProvider::FindNormalBrowserWindow(int* handle) {
883 *handle = 0;
884 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31885 Browser::TYPE_NORMAL,
886 false);
[email protected]24497032009-05-01 17:00:29887 if (browser)
888 *handle = browser_tracker_->Add(browser);
889}
890
[email protected]71f65dd2009-02-11 19:14:56891void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
892 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29893 Browser* browser = BrowserList::GetLastActive();
894 if (browser)
[email protected]71f65dd2009-02-11 19:14:56895 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29896}
897
[email protected]b2aa3ed72010-02-01 18:37:14898#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28899// TODO(estade): use this implementation for all platforms?
900void AutomationProvider::GetActiveWindow(int* handle) {
901 gfx::NativeWindow window =
902 BrowserList::GetLastActive()->window()->GetNativeHandle();
903 *handle = window_tracker_->Add(window);
904}
905#endif
906
[email protected]4f6381ee2009-04-16 02:46:33907void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
908 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56909 *success = false;
[email protected]4ae62752008-08-04 23:28:47910 if (browser_tracker_->ContainsHandle(handle)) {
911 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14912 if (browser->command_updater()->SupportsCommand(command) &&
913 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47914 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56915 *success = true;
[email protected]4ae62752008-08-04 23:28:47916 }
917 }
[email protected]4ae62752008-08-04 23:28:47918}
919
[email protected]4f6381ee2009-04-16 02:46:33920void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56921 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53922 // List of commands which just finish synchronously and don't require
923 // setting up an observer.
924 static const int kSynchronousCommands[] = {
925 IDC_HOME,
926 IDC_SELECT_NEXT_TAB,
927 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25928 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53929 };
[email protected]56e71b7c2009-03-27 03:05:56930 if (browser_tracker_->ContainsHandle(handle)) {
931 Browser* browser = browser_tracker_->GetResource(handle);
932 if (browser->command_updater()->SupportsCommand(command) &&
933 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53934 // First check if we can handle the command without using an observer.
935 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
936 if (command == kSynchronousCommands[i]) {
937 browser->ExecuteCommand(command);
938 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
939 true);
940 Send(reply_message);
941 return;
942 }
943 }
944
945 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42946 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
947 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27948 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42949 return;
950 }
[email protected]56e71b7c2009-03-27 03:05:56951 }
952 }
[email protected]49a14a82009-03-31 04:16:44953 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56954 Send(reply_message);
955}
956
[email protected]fc2e0872009-08-21 22:14:41957// This task just adds another task to the event queue. This is useful if
958// you want to ensure that any tasks added to the event queue after this one
959// have already been processed by the time |task| is run.
960class InvokeTaskLaterTask : public Task {
961 public:
962 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
963 virtual ~InvokeTaskLaterTask() {}
964
965 virtual void Run() {
966 MessageLoop::current()->PostTask(FROM_HERE, task_);
967 }
968
969 private:
970 Task* task_;
971
972 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
973};
974
initial.commit09911bf2008-07-26 23:55:29975void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
976 int handle,
[email protected]d1a5941e2009-08-13 23:34:24977 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29978 int flags) {
[email protected]b410bc32009-08-14 01:11:14979 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51980 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41981 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29982 }
983}
984
[email protected]60507b12009-11-02 23:51:35985void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
986 int handle,
987 const gfx::Point& location) {
988 if (window_tracker_->ContainsHandle(handle))
989 ui_controls::SendMouseMove(location.x(), location.y());
990}
991
initial.commit09911bf2008-07-26 23:55:29992void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
993 int handle,
[email protected]bc1407f2009-09-29 00:33:35994 int key,
initial.commit09911bf2008-07-26 23:55:29995 int flags) {
[email protected]b410bc32009-08-14 01:11:14996 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:29997 return;
998
[email protected]b410bc32009-08-14 01:11:14999 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291000 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351001 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381002 ((flags & views::Event::EF_CONTROL_DOWN) ==
1003 views::Event::EF_CONTROL_DOWN),
1004 ((flags & views::Event::EF_SHIFT_DOWN) ==
1005 views::Event::EF_SHIFT_DOWN),
1006 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301007 views::Event::EF_ALT_DOWN),
1008 ((flags & views::Event::EF_COMMAND_DOWN) ==
1009 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291010}
initial.commit09911bf2008-07-26 23:55:291011
[email protected]71f65dd2009-02-11 19:14:561012void AutomationProvider::IsWindowActive(int handle, bool* success,
1013 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291014 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171015 *is_active =
1016 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561017 *success = true;
initial.commit09911bf2008-07-26 23:55:291018 } else {
[email protected]71f65dd2009-02-11 19:14:561019 *success = false;
1020 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291021 }
1022}
1023
[email protected]71f65dd2009-02-11 19:14:561024void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1025 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291026
1027 if (browser_tracker_->ContainsHandle(handle)) {
1028 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561029 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291030 }
initial.commit09911bf2008-07-26 23:55:291031}
1032
[email protected]982921f12009-10-27 21:43:531033void AutomationProvider::GetType(int handle, int* type_as_int) {
1034 *type_as_int = -1; // -1 is the error code
1035
1036 if (browser_tracker_->ContainsHandle(handle)) {
1037 Browser* browser = browser_tracker_->GetResource(handle);
1038 *type_as_int = static_cast<int>(browser->type());
1039 }
1040}
1041
[email protected]71f65dd2009-02-11 19:14:561042void AutomationProvider::GetTab(int win_handle, int tab_index,
1043 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561044 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291045 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1046 Browser* browser = browser_tracker_->GetResource(win_handle);
1047 if (tab_index < browser->tab_count()) {
1048 TabContents* tab_contents =
1049 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571050 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291051 }
1052 }
initial.commit09911bf2008-07-26 23:55:291053}
1054
[email protected]71f65dd2009-02-11 19:14:561055void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1056 std::wstring* title) {
1057 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291058 if (tab_tracker_->ContainsHandle(handle)) {
1059 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361060 NavigationEntry* entry = tab->GetActiveEntry();
1061 if (entry != NULL) {
1062 *title = UTF16ToWideHack(entry->title());
1063 } else {
1064 *title = std::wstring();
1065 }
[email protected]71f65dd2009-02-11 19:14:561066 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291067 }
initial.commit09911bf2008-07-26 23:55:291068}
1069
[email protected]77bc6732009-04-20 22:01:031070void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1071 *tabstrip_index = -1; // -1 is the error code
1072
1073 if (tab_tracker_->ContainsHandle(handle)) {
1074 NavigationController* tab = tab_tracker_->GetResource(handle);
1075 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121076 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031077 }
1078}
1079
initial.commit09911bf2008-07-26 23:55:291080void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1081 if (window_tracker_->ContainsHandle(handle)) {
1082 window_tracker_->Remove(window_tracker_->GetResource(handle));
1083 }
1084}
1085
1086void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161087 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571088 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291089}
1090
1091// TODO(brettw) change this to accept GURLs when history supports it
1092void AutomationProvider::OnRedirectQueryComplete(
1093 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371094 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291095 bool success,
[email protected]379c2b12009-07-01 21:50:331096 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291097 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561098 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291099
[email protected]deb57402009-02-06 01:35:301100 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101101 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291102 if (success) {
initial.commit09911bf2008-07-26 23:55:291103 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301104 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291105 }
1106
[email protected]4f3dc372009-02-24 00:10:291107 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301108
[email protected]71f65dd2009-02-11 19:14:561109 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231110 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561111 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291112}
1113
1114bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571115 DCHECK(channel_.get());
1116 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291117}
1118
1119Browser* AutomationProvider::FindAndActivateTab(
1120 NavigationController* controller) {
1121 int tab_index;
1122 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1123 if (browser)
1124 browser->SelectTabContentsAt(tab_index, true);
1125
1126 return browser;
1127}
1128
[email protected]71f65dd2009-02-11 19:14:561129void AutomationProvider::GetCookies(const GURL& url, int handle,
1130 int* value_size,
1131 std::string* value) {
1132 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291133 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1134 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311135
1136 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001137 scoped_refptr<URLRequestContextGetter> request_context =
1138 tab->tab_contents()->request_context();
1139 if (!request_context.get())
1140 request_context = tab->profile()->GetRequestContext();
1141
1142 net::CookieStore* cookie_store = request_context->GetCookieStore();
[email protected]be180c802009-10-23 06:33:311143
1144 *value = cookie_store->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561145 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291146 }
initial.commit09911bf2008-07-26 23:55:291147}
1148
[email protected]71f65dd2009-02-11 19:14:561149void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291150 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561151 int handle,
1152 int* response_value) {
1153 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291154
1155 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1156 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311157
[email protected]dfa46e5f2009-11-17 18:48:431158 scoped_refptr<URLRequestContextGetter> request_context =
1159 tab->tab_contents()->request_context();
1160 if (!request_context.get())
1161 request_context = tab->profile()->GetRequestContext();
1162
[email protected]be180c802009-10-23 06:33:311163 // Since we are running on the UI thread don't call GetURLRequestContext().
1164 scoped_refptr<net::CookieStore> cookie_store =
[email protected]dfa46e5f2009-11-17 18:48:431165 request_context->GetCookieStore();
[email protected]be180c802009-10-23 06:33:311166
1167 if (cookie_store->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561168 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291169 }
initial.commit09911bf2008-07-26 23:55:291170}
1171
[email protected]5fa57942010-04-21 23:07:221172void AutomationProvider::DeleteCookie(const GURL& url,
1173 const std::string& cookie_name,
1174 int handle, bool* success) {
1175 *success = false;
1176 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1177 NavigationController* tab = tab_tracker_->GetResource(handle);
1178 net::CookieStore* cookie_store =
1179 tab->profile()->GetRequestContext()->GetCookieStore();
1180 cookie_store->DeleteCookie(url, cookie_name);
1181 *success = true;
1182 }
1183}
1184
[email protected]71f65dd2009-02-11 19:14:561185void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1186 *success = false;
initial.commit09911bf2008-07-26 23:55:291187 if (tab_tracker_->ContainsHandle(handle)) {
1188 NavigationController* tab = tab_tracker_->GetResource(handle);
1189 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541190 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561191 *success = true;
initial.commit09911bf2008-07-26 23:55:291192 }
initial.commit09911bf2008-07-26 23:55:291193}
1194
[email protected]71f65dd2009-02-11 19:14:561195void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1196 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291197
1198 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561199 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341200 TabContents* tab_contents =
1201 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161202 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1203 if (rph)
1204 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291205 }
initial.commit09911bf2008-07-26 23:55:291206}
1207
1208void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331209 NOTREACHED() << "This function has been deprecated. "
1210 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291211}
1212
[email protected]71f65dd2009-02-11 19:14:561213void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291214 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561215 const std::wstring& script,
1216 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291217 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341218 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1219 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571220 // Set the routing id of this message with the controller.
1221 // This routing id needs to be remembered for the reverse
1222 // communication while sending back the response of
1223 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331224 std::wstring set_automation_id;
1225 SStringPrintf(&set_automation_id,
1226 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561227 reply_message->routing_id());
1228
1229 DCHECK(reply_message_ == NULL);
1230 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291231
[email protected]57c6a652009-05-04 07:58:341232 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331233 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341234 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061235 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571236 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291237 }
1238
1239 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561240 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1241 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291242 }
1243}
1244
[email protected]71f65dd2009-02-11 19:14:561245void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1246 *visible = false;
[email protected]20e93d12008-08-28 16:31:571247
[email protected]59560e0b2009-06-04 03:30:221248 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251249#if defined(OS_CHROMEOS)
1250 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1251 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1252 for (BrowserList::const_iterator it = BrowserList::begin();
1253 it != BrowserList::end(); ++it) {
1254 if ((*it)->type() == Browser::TYPE_POPUP) {
1255 const GURL& url =
1256 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1257
1258 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1259 url.host() == chrome::kChromeUIFileBrowseHost) {
1260 *visible = true;
1261 break;
1262 }
1263 }
1264 }
1265#else
[email protected]59560e0b2009-06-04 03:30:221266 Browser* browser = browser_tracker_->GetResource(handle);
1267 if (browser) {
1268 *visible = browser->window()->IsDownloadShelfVisible();
1269 }
[email protected]f5bf8ccf2010-02-05 18:19:251270#endif
[email protected]59560e0b2009-06-04 03:30:221271 }
initial.commit09911bf2008-07-26 23:55:291272}
1273
[email protected]59560e0b2009-06-04 03:30:221274void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1275 if (browser_tracker_->ContainsHandle(handle)) {
1276 Browser* browser = browser_tracker_->GetResource(handle);
1277 if (browser) {
1278 if (visible)
1279 browser->window()->GetDownloadShelf()->Show();
1280 else
1281 browser->window()->GetDownloadShelf()->Close();
1282 }
1283 }
1284}
1285
[email protected]34930432009-11-09 00:12:091286void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1287 *visible = false;
1288
1289 if (browser_tracker_->ContainsHandle(handle)) {
1290 Browser* browser = browser_tracker_->GetResource(handle);
1291 if (browser)
1292 *visible = browser->window()->IsFullscreen();
1293 }
1294}
1295
1296void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1297 bool* visible) {
1298 *visible = false;
1299
1300 if (browser_tracker_->ContainsHandle(handle)) {
1301 Browser* browser = browser_tracker_->GetResource(handle);
1302 if (browser)
1303 *visible = browser->window()->IsFullscreenBubbleVisible();
1304 }
1305}
[email protected]59560e0b2009-06-04 03:30:221306
[email protected]71f65dd2009-02-11 19:14:561307void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1308 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291309 if (tab_tracker_->ContainsHandle(handle)) {
1310 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111311 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291312 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561313 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291314 }
1315 }
initial.commit09911bf2008-07-26 23:55:291316}
1317
initial.commit09911bf2008-07-26 23:55:291318void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561319 int handle, const std::wstring& find_request,
1320 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311321 NOTREACHED() << "This function has been deprecated."
1322 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561323 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311324 return;
1325}
1326
[email protected]4f999132009-03-31 18:08:401327void AutomationProvider::HandleFindRequest(
1328 int handle,
1329 const AutomationMsg_Find_Params& params,
1330 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291331 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561332 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1333 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291334 return;
1335 }
1336
1337 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111338 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291339
1340 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141341 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291342
[email protected]57c6a652009-05-04 07:58:341343 tab_contents->set_current_find_request_id(
1344 FindInPageNotificationObserver::kFindInPageRequestId);
1345 tab_contents->render_view_host()->StartFinding(
1346 FindInPageNotificationObserver::kFindInPageRequestId,
1347 params.search_string, params.forward, params.match_case,
1348 params.find_next);
initial.commit09911bf2008-07-26 23:55:291349}
1350
[email protected]5f8af2a2008-08-06 22:49:451351void AutomationProvider::HandleOpenFindInPageRequest(
1352 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291353 if (browser_tracker_->ContainsHandle(handle)) {
1354 Browser* browser = browser_tracker_->GetResource(handle);
1355 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451356 }
1357}
1358
[email protected]71f65dd2009-02-11 19:14:561359void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561360 *visible = false;
[email protected]855c0142009-09-28 22:35:241361 Browser* browser = browser_tracker_->GetResource(handle);
1362 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581363 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171364 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241365 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291366 }
[email protected]20e93d12008-08-28 16:31:571367}
1368
[email protected]71f65dd2009-02-11 19:14:561369void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1370 int* y) {
[email protected]9e0534b2008-10-21 15:03:011371 gfx::Point position(0, 0);
1372 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291373 if (browser_tracker_->ContainsHandle(handle)) {
1374 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581375 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171376 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581377 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291378 }
[email protected]20e93d12008-08-28 16:31:571379
[email protected]71f65dd2009-02-11 19:14:561380 *x = position.x();
1381 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571382}
1383
[email protected]4512cb52010-04-05 19:50:251384// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1385// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581386void AutomationProvider::GetBookmarkBarVisibility(int handle,
1387 bool* visible,
1388 bool* animating) {
1389 *visible = false;
1390 *animating = false;
1391
1392 if (browser_tracker_->ContainsHandle(handle)) {
1393 Browser* browser = browser_tracker_->GetResource(handle);
1394 if (browser) {
[email protected]ab6ca392010-04-07 00:44:131395#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1396 // IsBookmarkBarVisible() line looks correct but is not
1397 // consistent across platforms. Specifically, on Mac/Linux, it
1398 // returns false if the bar is hidden in a pref (even if visible
1399 // on the NTP). On ChromeOS, it returned true if on NTP
1400 // independent of the pref. Making the code more consistent
1401 // caused a perf bot regression on Windows (which shares views).
1402 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251403 *visible = browser->profile()->GetPrefs()->GetBoolean(
1404 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401405#else
1406 *visible = browser->window()->IsBookmarkBarVisible();
1407#endif
[email protected]c3240722010-03-05 21:52:581408 *animating = browser->window()->IsBookmarkBarAnimating();
1409 }
1410 }
1411}
1412
[email protected]6d8ffc9f2010-03-12 18:27:531413void AutomationProvider::GetBookmarksAsJSON(int handle,
1414 std::string* bookmarks_as_json,
1415 bool *success) {
1416 *success = false;
1417 if (browser_tracker_->ContainsHandle(handle)) {
1418 Browser* browser = browser_tracker_->GetResource(handle);
1419 if (browser) {
1420 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1421 return;
1422 }
1423 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1424 browser->profile(),
1425 browser->profile()->GetBookmarkModel());
1426 *success = storage->SerializeData(bookmarks_as_json);
1427 }
1428 }
1429}
1430
1431void AutomationProvider::WaitForBookmarkModelToLoad(
1432 int handle,
1433 IPC::Message* reply_message) {
1434 if (browser_tracker_->ContainsHandle(handle)) {
1435 Browser* browser = browser_tracker_->GetResource(handle);
1436 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1437 if (model->IsLoaded()) {
1438 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1439 reply_message, true);
1440 Send(reply_message);
1441 } else {
1442 // The observer will delete itself when done.
1443 new AutomationProviderBookmarkModelObserver(this, reply_message,
1444 model);
1445 }
1446 }
1447}
1448
1449void AutomationProvider::AddBookmarkGroup(int handle,
1450 int64 parent_id, int index,
1451 std::wstring title,
1452 bool* success) {
1453 if (browser_tracker_->ContainsHandle(handle)) {
1454 Browser* browser = browser_tracker_->GetResource(handle);
1455 if (browser) {
1456 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1457 if (!model->IsLoaded()) {
1458 *success = false;
1459 return;
1460 }
1461 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1462 DCHECK(parent);
1463 if (parent) {
1464 const BookmarkNode* child = model->AddGroup(parent, index,
1465 WideToUTF16(title));
1466 DCHECK(child);
1467 if (child)
1468 *success = true;
1469 }
1470 }
1471 }
1472 *success = false;
1473}
1474
1475void AutomationProvider::AddBookmarkURL(int handle,
1476 int64 parent_id, int index,
1477 std::wstring title, const GURL& url,
1478 bool* success) {
1479 if (browser_tracker_->ContainsHandle(handle)) {
1480 Browser* browser = browser_tracker_->GetResource(handle);
1481 if (browser) {
1482 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1483 if (!model->IsLoaded()) {
1484 *success = false;
1485 return;
1486 }
1487 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1488 DCHECK(parent);
1489 if (parent) {
1490 const BookmarkNode* child = model->AddURL(parent, index,
1491 WideToUTF16(title), url);
1492 DCHECK(child);
1493 if (child)
1494 *success = true;
1495 }
1496 }
1497 }
1498 *success = false;
1499}
1500
1501void AutomationProvider::ReparentBookmark(int handle,
1502 int64 id, int64 new_parent_id,
1503 int index,
1504 bool* success) {
1505 if (browser_tracker_->ContainsHandle(handle)) {
1506 Browser* browser = browser_tracker_->GetResource(handle);
1507 if (browser) {
1508 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1509 if (!model->IsLoaded()) {
1510 *success = false;
1511 return;
1512 }
1513 const BookmarkNode* node = model->GetNodeByID(id);
1514 DCHECK(node);
1515 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1516 DCHECK(new_parent);
1517 if (node && new_parent) {
1518 model->Move(node, new_parent, index);
1519 *success = true;
1520 }
1521 }
1522 }
1523 *success = false;
1524}
1525
1526void AutomationProvider::SetBookmarkTitle(int handle,
1527 int64 id, std::wstring title,
1528 bool* success) {
1529 if (browser_tracker_->ContainsHandle(handle)) {
1530 Browser* browser = browser_tracker_->GetResource(handle);
1531 if (browser) {
1532 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1533 if (!model->IsLoaded()) {
1534 *success = false;
1535 return;
1536 }
1537 const BookmarkNode* node = model->GetNodeByID(id);
1538 DCHECK(node);
1539 if (node) {
1540 model->SetTitle(node, WideToUTF16(title));
1541 *success = true;
1542 }
1543 }
1544 }
1545 *success = false;
1546}
1547
1548void AutomationProvider::SetBookmarkURL(int handle,
1549 int64 id, const GURL& url,
1550 bool* success) {
1551 if (browser_tracker_->ContainsHandle(handle)) {
1552 Browser* browser = browser_tracker_->GetResource(handle);
1553 if (browser) {
1554 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1555 if (!model->IsLoaded()) {
1556 *success = false;
1557 return;
1558 }
1559 const BookmarkNode* node = model->GetNodeByID(id);
1560 DCHECK(node);
1561 if (node) {
1562 model->SetURL(node, url);
1563 *success = true;
1564 }
1565 }
1566 }
1567 *success = false;
1568}
1569
1570void AutomationProvider::RemoveBookmark(int handle,
1571 int64 id,
1572 bool* success) {
1573 if (browser_tracker_->ContainsHandle(handle)) {
1574 Browser* browser = browser_tracker_->GetResource(handle);
1575 if (browser) {
1576 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1577 if (!model->IsLoaded()) {
1578 *success = false;
1579 return;
1580 }
1581 const BookmarkNode* node = model->GetNodeByID(id);
1582 DCHECK(node);
1583 if (node) {
1584 const BookmarkNode* parent = node->GetParent();
1585 DCHECK(parent);
1586 model->Remove(parent, parent->IndexOfChild(node));
1587 *success = true;
1588 }
1589 }
1590 }
1591 *success = false;
1592}
1593
[email protected]24e2b102010-04-29 17:56:471594// Sample json input: { "command": "GetHistoryInfo",
1595// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361596// Refer chrome/test/pyautolib/history_info.py for sample json output.
1597void AutomationProvider::GetHistoryInfo(
1598 DictionaryValue* args,
1599 IPC::Message* reply_message) {
1600 consumer_.CancelAllRequests();
1601
1602 std::wstring search_text;
1603 args->GetString(L"search_text", &search_text);
1604
1605 // Fetch history.
1606 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1607 history::QueryOptions options;
1608 // The observer owns itself. It deletes itself after it fetches history.
1609 AutomationProviderHistoryObserver* history_observer =
1610 new AutomationProviderHistoryObserver(this, reply_message);
1611 hs->QueryHistory(
1612 search_text,
1613 options,
1614 &consumer_,
1615 NewCallback(history_observer,
1616 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1617}
1618
[email protected]bbe6aa02010-05-07 17:27:291619// Sample json input: { "command": "AddHistoryItem",
1620// "item": { "URL": "http://www.google.com",
1621// "title": "Google", # optional
1622// "time": 12345 # optional (time_t)
1623// } }
1624// Refer chrome/test/pyautolib/pyauto.py for details on input.
1625void AutomationProvider::AddHistoryItem(
1626 DictionaryValue* args,
1627 IPC::Message* reply_message) {
1628 bool reply_return = true;
1629 std::string json_return = "{}";
1630
1631 DictionaryValue* item = NULL;
1632 args->GetDictionary(L"item", &item);
1633 string16 url_text;
1634 std::wstring title;
1635 base::Time time = base::Time::Now();
1636
1637 if (item->GetString("url", &url_text)) {
1638 GURL gurl(url_text);
1639 item->GetString(L"title", &title); // Don't care if it fails.
1640 int it;
1641 double dt;
1642 if (item->GetInteger(L"time", &it))
1643 time = base::Time::FromTimeT(it);
1644 else if (item->GetReal(L"time", &dt))
1645 time = base::Time::FromDoubleT(dt);
1646
1647 // Ideas for "dummy" values (e.g. id_scope) came from
1648 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1649 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1650 const void* id_scope = reinterpret_cast<void*>(1);
1651 hs->AddPage(gurl, time,
1652 id_scope,
1653 0,
1654 GURL(),
1655 PageTransition::LINK,
1656 history::RedirectList(),
1657 false);
1658 if (title.length()) {
1659 // TODO(jrg): add a string16 interface for
1660 // HistoryService::SetPageTitle(), then use it.
1661 hs->SetPageTitle(gurl, title);
1662 }
1663 } else {
1664 json_return = "{\"error\": \"bad args (no URL in dict?).\"}";
1665 reply_return = false;
1666 }
1667
1668 AutomationMsg_SendJSONRequest::WriteReplyParams(
1669 reply_message, json_return, reply_return);
1670 Send(reply_message);
1671}
1672
[email protected]24e2b102010-04-29 17:56:471673// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361674// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]d4adc292010-04-15 18:06:391675void AutomationProvider::GetDownloadsInfo(
1676 DictionaryValue* args,
1677 IPC::Message* reply_message) {
1678 std::string json_return;
1679 bool reply_return = true;
1680 AutomationProviderDownloadManagerObserver observer;
1681 std::vector<DownloadItem*> downloads;
1682 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1683
1684 if (!profile_->HasCreatedDownloadManager()) {
[email protected]24e2b102010-04-29 17:56:471685 json_return = "{\"error\": \"no download manager\"}";
[email protected]d4adc292010-04-15 18:06:391686 reply_return = false;
1687 } else {
1688 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1689 // since that would be transient; a download might enter and empty out
1690 // the current download queue too soon to be noticed.
1691 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1692 downloads = observer.Downloads();
1693 }
1694
1695 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1696 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1697 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1698 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1699 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1700
1701 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1702 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1703 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1704 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1705 std::string("DANGEROUS_BUT_VALIDATED");
1706
1707 ListValue* list_of_downloads = new ListValue;
1708 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1709 it != downloads.end();
1710 it++) { // Fill info about each download item.
1711 DictionaryValue* dl_item_value = new DictionaryValue;
1712 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1713 dl_item_value->SetString(L"url", (*it)->url().spec());
1714 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1715 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1716 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
1717 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
1718 dl_item_value->SetBoolean(L"open_when_complete",
1719 (*it)->open_when_complete());
1720 dl_item_value->SetBoolean(L"is_extension_install",
1721 (*it)->is_extension_install());
1722 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
1723 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
1724 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
1725 dl_item_value->SetString(L"safety_state",
1726 safety_state_to_string[(*it)->safety_state()]);
1727 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
1728 list_of_downloads->Append(dl_item_value);
1729 }
1730 return_value->Set(L"downloads", list_of_downloads);
1731 base::JSONWriter::Write(return_value.get(), false, &json_return);
1732
1733 AutomationMsg_SendJSONRequest::WriteReplyParams(
1734 reply_message, json_return, reply_return);
1735 Send(reply_message);
1736 // All value objects allocated above are owned by |return_value|
1737 // and get freed by it.
1738}
1739
[email protected]59a611242010-04-02 02:24:041740void AutomationProvider::WaitForDownloadsToComplete(
1741 DictionaryValue* args,
1742 IPC::Message* reply_message) {
1743 std::string json_return;
1744 bool reply_return = true;
1745 AutomationProviderDownloadManagerObserver observer;
1746 std::vector<DownloadItem*> downloads;
1747
1748 // Look for a quick return.
1749 if (!profile_->HasCreatedDownloadManager()) {
[email protected]24e2b102010-04-29 17:56:471750 json_return = "{\"error\": \"no download manager\"}";
[email protected]59a611242010-04-02 02:24:041751 reply_return = false;
1752 } else {
1753 profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
1754 FilePath());
1755 downloads = observer.Downloads();
1756 if (downloads.size() == 0) {
1757 json_return = "{}";
1758 }
1759 }
1760 if (!json_return.empty()) {
1761 AutomationMsg_SendJSONRequest::WriteReplyParams(
1762 reply_message, json_return, reply_return);
1763 Send(reply_message);
1764 }
1765
1766 // The observer owns itself. When the last observed item pings, it
1767 // deletes itself.
1768 AutomationProviderDownloadItemObserver* item_observer =
1769 new AutomationProviderDownloadItemObserver(
1770 this, reply_message, downloads.size());
1771 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
1772 i != downloads.end();
1773 i++) {
1774 (*i)->AddObserver(item_observer);
1775 }
1776}
1777
[email protected]24e2b102010-04-29 17:56:471778// Sample json input: { "command": "GetPrefsInfo" }
1779// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
1780void AutomationProvider::GetPrefsInfo(DictionaryValue* args,
1781 IPC::Message* reply_message) {
1782 std::string json_return;
1783 bool reply_return = true;
1784
1785 const PrefService::PreferenceSet& prefs =
1786 profile_->GetPrefs()->preference_set();
1787 DictionaryValue* items = new DictionaryValue;
1788 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
1789 it != prefs.end(); ++it) {
1790 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
1791 }
1792 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1793 return_value->Set(L"prefs", items); // return_value owns items.
1794
1795 base::JSONWriter::Write(return_value.get(), false, &json_return);
1796 AutomationMsg_SendJSONRequest::WriteReplyParams(
1797 reply_message, json_return, reply_return);
1798 Send(reply_message);
1799}
1800
1801// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
1802void AutomationProvider::SetPrefs(DictionaryValue* args,
1803 IPC::Message* reply_message) {
1804 bool reply_return = true;
1805 std::string json_return = "{}";
1806 std::wstring path;
1807 Value* val;
1808 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
1809 PrefService* pref_service = profile_->GetPrefs();
1810 const PrefService::Preference* pref =
1811 pref_service->FindPreference(path.c_str());
1812 if (!pref) { // Not a registered pref.
1813 json_return = "{\"error\": \"pref not registered.\"}";
1814 reply_return = false;
1815 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
1816 json_return = "{\"error\": \"pref is managed. cannot be changed.\"}";
1817 reply_return = false;
1818 } else { // Set the pref.
1819 pref_service->Set(path.c_str(), *val);
1820 }
1821 } else {
1822 json_return = "{\"error\": \"no pref path or value given.\"}";
1823 reply_return = false;
1824 }
1825
1826 AutomationMsg_SendJSONRequest::WriteReplyParams(
1827 reply_message, json_return, reply_return);
1828 Send(reply_message);
1829}
1830
[email protected]f7d48012010-05-06 08:17:051831// Sample json input: { "command": "GetPluginsInfo" }
1832// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
1833void AutomationProvider::GetPluginsInfo(DictionaryValue* args,
1834 IPC::Message* reply_message) {
1835 std::string json_return;
1836 bool reply_return = true;
1837
1838 std::vector<WebPluginInfo> plugins;
1839 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
1840 ListValue* items = new ListValue;
1841 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
1842 it != plugins.end();
1843 ++it) {
1844 DictionaryValue* item = new DictionaryValue;
1845 item->SetString(L"name", it->name);
1846 item->SetString(L"path", it->path.value());
1847 item->SetString(L"version", it->version);
1848 item->SetString(L"desc", it->desc);
1849 item->SetBoolean(L"enabled", it->enabled);
1850 // Add info about mime types.
1851 ListValue* mime_types = new ListValue();
1852 for (std::vector<WebPluginMimeType>::const_iterator type_it =
1853 it->mime_types.begin();
1854 type_it != it->mime_types.end();
1855 ++type_it) {
1856 DictionaryValue* mime_type = new DictionaryValue();
1857 mime_type->SetString(L"mimeType", type_it->mime_type);
1858 mime_type->SetString(L"description", type_it->description);
1859
1860 ListValue* file_extensions = new ListValue();
1861 for (std::vector<std::string>::const_iterator ext_it =
1862 type_it->file_extensions.begin();
1863 ext_it != type_it->file_extensions.end();
1864 ++ext_it) {
1865 file_extensions->Append(new StringValue(*ext_it));
1866 }
1867 mime_type->Set(L"fileExtensions", file_extensions);
1868
1869 mime_types->Append(mime_type);
1870 }
1871 item->Set(L"mimeTypes", mime_types);
1872 items->Append(item);
1873 }
1874 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1875 return_value->Set(L"plugins", items); // return_value owns items.
1876
1877 base::JSONWriter::Write(return_value.get(), false, &json_return);
1878 AutomationMsg_SendJSONRequest::WriteReplyParams(
1879 reply_message, json_return, reply_return);
1880 Send(reply_message);
1881}
1882
1883// Sample json input:
1884// { "command": "EnablePlugin",
1885// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
1886void AutomationProvider::EnablePlugin(DictionaryValue* args,
1887 IPC::Message* reply_message) {
1888 std::string json_return = "{}";
1889 bool reply_return = true;
1890 FilePath::StringType path;
1891 if (!args->GetString(L"path", &path)) {
1892 json_return = "{\"error\": \"path not specified.\"}";
1893 reply_return = false;
1894 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
1895 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
1896 " for path %s.\"}", path.c_str());
1897 reply_return = false;
1898 }
1899
1900 AutomationMsg_SendJSONRequest::WriteReplyParams(
1901 reply_message, json_return, reply_return);
1902 Send(reply_message);
1903}
1904
1905// Sample json input:
1906// { "command": "DisablePlugin",
1907// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
1908void AutomationProvider::DisablePlugin(DictionaryValue* args,
1909 IPC::Message* reply_message) {
1910 std::string json_return = "{}";
1911 bool reply_return = true;
1912 FilePath::StringType path;
1913 if (!args->GetString(L"path", &path)) {
1914 json_return = "{\"error\": \"path not specified.\"}";
1915 reply_return = false;
1916 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
1917 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
1918 " for path %s.\"}", path.c_str());
1919 reply_return = false;
1920 }
1921
1922 AutomationMsg_SendJSONRequest::WriteReplyParams(
1923 reply_message, json_return, reply_return);
1924 Send(reply_message);
1925}
1926
[email protected]59a611242010-04-02 02:24:041927void AutomationProvider::SendJSONRequest(
1928 int handle,
1929 std::string json_request,
1930 IPC::Message* reply_message) {
1931 Browser* browser = NULL;
1932 std::string error_string;
1933 scoped_ptr<Value> values;
1934
1935 // Basic error checking.
1936 if (browser_tracker_->ContainsHandle(handle)) {
1937 browser = browser_tracker_->GetResource(handle);
1938 }
1939 if (!browser) {
1940 error_string = "no browser object";
1941 } else {
1942 base::JSONReader reader;
1943 std::string error;
[email protected]ba399672010-04-06 15:42:391944 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
[email protected]59a611242010-04-02 02:24:041945 if (!error.empty()) {
1946 error_string = error;
1947 }
1948 }
1949
1950 // Make sure input is a dict with a string command.
1951 std::string command;
1952 DictionaryValue* dict_value = NULL;
1953 if (error_string.empty()) {
1954 if (values->GetType() != Value::TYPE_DICTIONARY) {
1955 error_string = "not a dict or no command key in dict";
1956 } else {
1957 // Ownership remains with "values" variable.
1958 dict_value = static_cast<DictionaryValue*>(values.get());
1959 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
1960 error_string = "no command key in dict or not a string command";
1961 }
1962 }
1963 }
1964
[email protected]24e2b102010-04-29 17:56:471965 // Map json commands to their handlers.
1966 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:051967 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
1968 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
1969 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
1970
[email protected]24e2b102010-04-29 17:56:471971 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:291972 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:051973
[email protected]24e2b102010-04-29 17:56:471974 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
1975 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:051976
1977 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:471978 handler_map["WaitForAllDownloadsToComplete"] =
1979 &AutomationProvider::WaitForDownloadsToComplete;
1980
[email protected]59a611242010-04-02 02:24:041981 if (error_string.empty()) {
[email protected]24e2b102010-04-29 17:56:471982 if (handler_map.find(std::string(command)) != handler_map.end()) {
1983 (this->*handler_map[command])(dict_value, reply_message);
[email protected]59a611242010-04-02 02:24:041984 return;
1985 } else {
[email protected]24e2b102010-04-29 17:56:471986 error_string = "Unknown command. Options: ";
1987 for (std::map<std::string, JsonHandler>::const_iterator it =
1988 handler_map.begin(); it != handler_map.end(); ++it) {
1989 error_string += it->first + ", ";
1990 }
[email protected]59a611242010-04-02 02:24:041991 }
1992 }
1993
1994 // If we hit an error, return info.
[email protected]24e2b102010-04-29 17:56:471995 // Return a dict of {"error", "descriptive_string_for_error"}.
[email protected]59a611242010-04-02 02:24:041996 // Else return an empty dict.
1997 std::string json_string;
1998 bool success = true;
1999 if (!error_string.empty()) {
2000 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
2001 dict->SetString(L"error", error_string);
2002 base::JSONWriter::Write(dict.get(), false, &json_string);
2003 success = false;
2004 } else {
2005 json_string = "{}";
2006 }
2007 AutomationMsg_SendJSONRequest::WriteReplyParams(
2008 reply_message, json_string, success);
2009 Send(reply_message);
2010}
2011
initial.commit09911bf2008-07-26 23:55:292012void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562013 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342014 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2015 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562016 DCHECK(reply_message_ == NULL);
2017 reply_message_ = reply_message;
2018
[email protected]d9f9b792009-06-24 13:17:122019 DevToolsManager::GetInstance()->InspectElement(
2020 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292021 } else {
[email protected]71f65dd2009-02-11 19:14:562022 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2023 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292024 }
2025}
2026
2027void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092028 if (reply_message_) {
2029 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2030 num_resources);
2031 Send(reply_message_);
2032 reply_message_ = NULL;
2033 }
initial.commit09911bf2008-07-26 23:55:292034}
2035
[email protected]a7eee32f2009-05-22 18:08:172036class SetProxyConfigTask : public Task {
2037 public:
[email protected]be180c802009-10-23 06:33:312038 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2039 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252040 : request_context_getter_(request_context_getter),
2041 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172042 virtual void Run() {
2043 // First, deserialize the JSON string. If this fails, log and bail.
2044 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392045 std::string error_msg;
2046 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172047 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2048 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392049 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172050 return;
2051 }
2052
2053 scoped_ptr<DictionaryValue> dict(
2054 static_cast<DictionaryValue*>(root.release()));
2055 // Now put together a proxy configuration from the deserialized string.
2056 net::ProxyConfig pc;
2057 PopulateProxyConfig(*dict.get(), &pc);
2058
[email protected]be180c802009-10-23 06:33:312059 net::ProxyService* proxy_service =
2060 request_context_getter_->GetURLRequestContext()->proxy_service();
2061 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172062 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2063 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312064 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172065 }
2066
2067 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2068 DCHECK(pc);
2069 bool no_proxy = false;
2070 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2071 // Make no changes to the ProxyConfig.
2072 return;
2073 }
2074 bool auto_config;
2075 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482076 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172077 }
2078 std::string pac_url;
2079 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482080 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172081 }
2082 std::string proxy_bypass_list;
2083 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482084 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172085 }
2086 std::string proxy_server;
2087 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482088 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172089 }
2090 }
2091
2092 private:
[email protected]be180c802009-10-23 06:33:312093 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172094 std::string proxy_config_;
2095};
2096
2097
2098void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312099 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2100 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172101 FilePath user_data_dir;
2102 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2103 ProfileManager* profile_manager = g_browser_process->profile_manager();
2104 DCHECK(profile_manager);
2105 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2106 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312107 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172108 }
[email protected]be180c802009-10-23 06:33:312109 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172110
[email protected]fae20792009-10-28 20:31:582111 ChromeThread::PostTask(
2112 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312113 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172114}
2115
[email protected]4f3dc372009-02-24 00:10:292116void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332117 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292118 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292119 if (tab_tracker_->ContainsHandle(handle)) {
2120 NavigationController* tab = tab_tracker_->GetResource(handle);
2121 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2122 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332123 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292124 }
initial.commit09911bf2008-07-26 23:55:292125}
2126
[email protected]6a5670d22009-10-27 16:21:342127void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142128 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532129 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2130 reply_message);
2131}
2132
2133void AutomationProvider::OpenNewBrowserWindowOfType(
2134 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:142135 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292136 // We may have no current browser windows open so don't rely on
2137 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:532138 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
2139 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:052140 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152141 if (show)
[email protected]15952e462008-11-14 00:29:052142 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292143}
2144
[email protected]71f65dd2009-02-11 19:14:562145void AutomationProvider::GetWindowForBrowser(int browser_handle,
2146 bool* success,
2147 int* handle) {
2148 *success = false;
2149 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292150
2151 if (browser_tracker_->ContainsHandle(browser_handle)) {
2152 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202153 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292154 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202155 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562156 *success = true;
initial.commit09911bf2008-07-26 23:55:292157 }
initial.commit09911bf2008-07-26 23:55:292158}
2159
2160void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562161 int browser_handle,
2162 bool* success,
2163 int* autocomplete_edit_handle) {
2164 *success = false;
2165 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292166
2167 if (browser_tracker_->ContainsHandle(browser_handle)) {
2168 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062169 LocationBar* loc_bar = browser->window()->GetLocationBar();
2170 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292171 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562172 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2173 *success = true;
initial.commit09911bf2008-07-26 23:55:292174 }
initial.commit09911bf2008-07-26 23:55:292175}
initial.commit09911bf2008-07-26 23:55:292176
[email protected]71f65dd2009-02-11 19:14:562177void AutomationProvider::ShowInterstitialPage(int tab_handle,
2178 const std::string& html_text,
2179 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292180 if (tab_tracker_->ContainsHandle(tab_handle)) {
2181 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112182 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402183
[email protected]7dad3d5f2010-03-04 00:27:012184 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:402185 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342186 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402187 GURL("about:interstitial"),
2188 html_text);
2189 interstitial->Show();
2190 return;
initial.commit09911bf2008-07-26 23:55:292191 }
[email protected]71f65dd2009-02-11 19:14:562192
[email protected]457f5cf2009-08-18 16:37:522193 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2194 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562195 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292196}
2197
[email protected]71f65dd2009-02-11 19:14:562198void AutomationProvider::HideInterstitialPage(int tab_handle,
2199 bool* success) {
2200 *success = false;
[email protected]57c6a652009-05-04 07:58:342201 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2202 if (tab_contents && tab_contents->interstitial_page()) {
2203 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562204 *success = true;
initial.commit09911bf2008-07-26 23:55:292205 }
initial.commit09911bf2008-07-26 23:55:292206}
2207
[email protected]71f65dd2009-02-11 19:14:562208void AutomationProvider::CloseTab(int tab_handle,
2209 bool wait_until_closed,
2210 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292211 if (tab_tracker_->ContainsHandle(tab_handle)) {
2212 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2213 int index;
2214 Browser* browser = Browser::GetBrowserForController(controller, &index);
2215 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142216 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112217 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452218 return;
initial.commit09911bf2008-07-26 23:55:292219 }
[email protected]de246f52009-02-25 18:25:452220
2221 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:552222 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292223}
2224
[email protected]71f65dd2009-02-11 19:14:562225void AutomationProvider::CloseBrowser(int browser_handle,
2226 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292227 if (browser_tracker_->ContainsHandle(browser_handle)) {
2228 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562229 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562230 reply_message);
[email protected]f3e99e32008-07-30 04:48:392231 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292232 } else {
2233 NOTREACHED();
2234 }
2235}
2236
[email protected]71f65dd2009-02-11 19:14:562237void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2238 if (browser_tracker_->ContainsHandle(browser_handle)) {
2239 Browser* browser = browser_tracker_->GetResource(browser_handle);
2240 browser->window()->Close();
2241 } else {
2242 NOTREACHED();
2243 }
2244}
2245
[email protected]71f65dd2009-02-11 19:14:562246void AutomationProvider::NavigateInExternalTab(
[email protected]b36a9f92009-10-19 17:34:572247 int handle, const GURL& url, const GURL& referrer,
[email protected]71f65dd2009-02-11 19:14:562248 AutomationMsg_NavigationResponseValues* status) {
2249 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292250
2251 if (tab_tracker_->ContainsHandle(handle)) {
2252 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]b36a9f92009-10-19 17:34:572253 tab->LoadURL(url, referrer, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562254 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292255 }
initial.commit09911bf2008-07-26 23:55:292256}
2257
[email protected]4150ef02009-08-19 23:14:262258void AutomationProvider::NavigateExternalTabAtIndex(
2259 int handle, int navigation_index,
2260 AutomationMsg_NavigationResponseValues* status) {
2261 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
2262
2263 if (tab_tracker_->ContainsHandle(handle)) {
2264 NavigationController* tab = tab_tracker_->GetResource(handle);
2265 tab->GoToIndex(navigation_index);
2266 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
2267 }
2268}
2269
[email protected]71f65dd2009-02-11 19:14:562270void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2271 IPC::Message* reply_message) {
2272 if (tab_tracker_->ContainsHandle(tab_handle)) {
2273 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2274 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142275 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562276 }
2277}
2278
[email protected]71f65dd2009-02-11 19:14:562279void AutomationProvider::GetSecurityState(int handle, bool* success,
2280 SecurityStyle* security_style,
2281 int* ssl_cert_status,
2282 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292283 if (tab_tracker_->ContainsHandle(handle)) {
2284 NavigationController* tab = tab_tracker_->GetResource(handle);
2285 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562286 *success = true;
2287 *security_style = entry->ssl().security_style();
2288 *ssl_cert_status = entry->ssl().cert_status();
2289 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292290 } else {
[email protected]71f65dd2009-02-11 19:14:562291 *success = false;
2292 *security_style = SECURITY_STYLE_UNKNOWN;
2293 *ssl_cert_status = 0;
2294 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292295 }
2296}
2297
[email protected]71f65dd2009-02-11 19:14:562298void AutomationProvider::GetPageType(int handle, bool* success,
2299 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292300 if (tab_tracker_->ContainsHandle(handle)) {
2301 NavigationController* tab = tab_tracker_->GetResource(handle);
2302 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562303 *page_type = entry->page_type();
2304 *success = true;
initial.commit09911bf2008-07-26 23:55:292305 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342306 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562307 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342308 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562309 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292310 } else {
[email protected]71f65dd2009-02-11 19:14:562311 *success = false;
2312 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292313 }
2314}
2315
[email protected]84abba62009-10-07 17:01:442316void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
2317 int* duration_ms) {
2318 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
2319 event_name);
2320}
2321
[email protected]71f65dd2009-02-11 19:14:562322void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2323 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292324 if (tab_tracker_->ContainsHandle(handle)) {
2325 NavigationController* tab = tab_tracker_->GetResource(handle);
2326 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072327 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402328 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472329 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342330 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292331 if (ssl_blocking_page) {
2332 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:012333 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:562334 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292335 return;
2336 }
2337 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522338 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2339 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562340 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292341 return;
2342 }
2343 }
2344 }
2345 // We failed.
[email protected]457f5cf2009-08-18 16:37:522346 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2347 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562348 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292349}
2350
[email protected]71f65dd2009-02-11 19:14:562351void AutomationProvider::BringBrowserToFront(int browser_handle,
2352 bool* success) {
initial.commit09911bf2008-07-26 23:55:292353 if (browser_tracker_->ContainsHandle(browser_handle)) {
2354 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062355 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562356 *success = true;
initial.commit09911bf2008-07-26 23:55:292357 } else {
[email protected]71f65dd2009-02-11 19:14:562358 *success = false;
initial.commit09911bf2008-07-26 23:55:292359 }
2360}
2361
[email protected]71f65dd2009-02-11 19:14:562362void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2363 int message_num,
2364 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292365 if (browser_tracker_->ContainsHandle(browser_handle)) {
2366 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562367 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142368 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292369 } else {
[email protected]71f65dd2009-02-11 19:14:562370 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292371 }
2372}
2373
[email protected]71f65dd2009-02-11 19:14:562374void AutomationProvider::PrintNow(int tab_handle,
2375 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572376 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342377 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2378 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292379 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572380 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142381 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342382 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572383 return;
initial.commit09911bf2008-07-26 23:55:292384 }
[email protected]71f65dd2009-02-11 19:14:562385 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2386 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292387}
[email protected]d301c952009-07-13 15:02:412388
[email protected]71f65dd2009-02-11 19:14:562389void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:112390 const FilePath& file_name,
2391 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:562392 int type,
2393 bool* success) {
initial.commit09911bf2008-07-26 23:55:292394 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562395 *success = false;
initial.commit09911bf2008-07-26 23:55:292396 return;
2397 }
2398
2399 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2400 Browser* browser = FindAndActivateTab(nav);
2401 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142402 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562403 *success = false;
initial.commit09911bf2008-07-26 23:55:292404 return;
2405 }
2406
initial.commit09911bf2008-07-26 23:55:292407 SavePackage::SavePackageType save_type =
2408 static_cast<SavePackage::SavePackageType>(type);
2409 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2410 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342411 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292412
[email protected]71f65dd2009-02-11 19:14:562413 *success = true;
initial.commit09911bf2008-07-26 23:55:292414}
2415
[email protected]71f65dd2009-02-11 19:14:562416void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2417 bool* success,
2418 std::wstring* text) {
2419 *success = false;
initial.commit09911bf2008-07-26 23:55:292420 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562421 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522422 GetText();
[email protected]71f65dd2009-02-11 19:14:562423 *success = true;
initial.commit09911bf2008-07-26 23:55:292424 }
initial.commit09911bf2008-07-26 23:55:292425}
2426
[email protected]71f65dd2009-02-11 19:14:562427void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2428 const std::wstring& text,
2429 bool* success) {
2430 *success = false;
initial.commit09911bf2008-07-26 23:55:292431 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522432 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2433 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562434 *success = true;
initial.commit09911bf2008-07-26 23:55:292435 }
initial.commit09911bf2008-07-26 23:55:292436}
2437
2438void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562439 int autocomplete_edit_handle,
2440 bool* success,
2441 std::vector<AutocompleteMatchData>* matches) {
2442 *success = false;
initial.commit09911bf2008-07-26 23:55:292443 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272444 const AutocompleteResult& result = autocomplete_edit_tracker_->
2445 GetResource(autocomplete_edit_handle)->model()->result();
2446 for (AutocompleteResult::const_iterator i = result.begin();
2447 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562448 matches->push_back(AutocompleteMatchData(*i));
2449 *success = true;
initial.commit09911bf2008-07-26 23:55:292450 }
initial.commit09911bf2008-07-26 23:55:292451}
2452
2453void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562454 int autocomplete_edit_handle,
2455 bool* success,
2456 bool* query_in_progress) {
2457 *success = false;
2458 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292459 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562460 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522461 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562462 *success = true;
initial.commit09911bf2008-07-26 23:55:292463 }
initial.commit09911bf2008-07-26 23:55:292464}
2465
[email protected]63514af2010-03-30 17:17:232466#if !defined(OS_MACOSX)
[email protected]28790922009-03-09 19:48:372467void AutomationProvider::OnMessageFromExternalHost(int handle,
2468 const std::string& message,
2469 const std::string& origin,
2470 const std::string& target) {
[email protected]f7a68432009-07-29 23:18:192471 RenderViewHost* view_host = GetViewForTab(handle);
2472 if (!view_host) {
2473 return;
[email protected]fa83e762008-08-15 21:41:392474 }
[email protected]f7a68432009-07-29 23:18:192475
2476 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
2477 view_host, message, origin, target)) {
2478 // Message was diverted.
2479 return;
2480 }
2481
2482 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
2483 origin, target, this, view_host, handle)) {
2484 // Message was diverted.
2485 return;
2486 }
2487
2488 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
2489 // Message was diverted.
2490 return;
2491 }
2492
2493 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392494}
[email protected]a9024892009-06-16 23:13:552495
2496bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2497 const std::string& message, const std::string& origin,
2498 const std::string& target) {
2499 if (target !=
2500 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2501 return false;
2502
2503 if (origin != extension_automation_constants::kAutomationOrigin) {
2504 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2505 return false;
2506 }
2507
2508 // The message is a JSON-encoded array with two elements, both strings. The
2509 // first is the name of the event to dispatch. The second is a JSON-encoding
2510 // of the arguments specific to that event.
[email protected]93d49d72009-10-23 20:00:202511 scoped_ptr<Value> message_value(base::JSONReader::Read(message, false));
[email protected]a9024892009-06-16 23:13:552512 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2513 LOG(WARNING) << "Invalid browser event specified through automation";
2514 return false;
2515 }
2516
2517 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2518
2519 std::string event_name;
2520 if (!args->GetString(0, &event_name)) {
2521 LOG(WARNING) << "No browser event name specified through automation";
2522 return false;
2523 }
2524
2525 std::string json_args;
2526 if (!args->GetString(1, &json_args)) {
2527 LOG(WARNING) << "No browser event args specified through automation";
2528 return false;
2529 }
2530
[email protected]7120f132009-07-20 21:05:372531 if (profile()->GetExtensionMessageService()) {
[email protected]db7331a2010-02-25 22:10:502532 profile()->GetExtensionMessageService()->DispatchEventToRenderers(
[email protected]a807bbe2010-04-14 10:51:192533 event_name, json_args, profile()->IsOffTheRecord(), GURL());
[email protected]7120f132009-07-20 21:05:372534 }
[email protected]a9024892009-06-16 23:13:552535
2536 return true;
2537}
[email protected]5ae5bed2009-08-21 18:52:442538#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:392539
[email protected]57c6a652009-05-04 07:58:342540TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572541 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572542 if (tab_tracker_->ContainsHandle(handle)) {
2543 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342544 if (tab)
2545 *tab = nav_controller;
2546 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572547 }
[email protected]57c6a652009-05-04 07:58:342548 return NULL;
[email protected]20e93d12008-08-28 16:31:572549}
2550
initial.commit09911bf2008-07-26 23:55:292551TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2552 : AutomationProvider(profile) {
2553 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142554 registrar_.Add(this, NotificationType::SESSION_END,
2555 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292556}
2557
2558TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292559 BrowserList::RemoveObserver(this);
2560}
2561
2562void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:142563 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:292564 AutomationProvider::OnChannelError();
2565}
2566
2567void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2568 // For backwards compatibility with the testing automation interface, we
2569 // want the automation provider (and hence the process) to go away when the
2570 // last browser goes away.
2571 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292572 // If you change this, update Observer for NotificationType::SESSION_END
2573 // below.
[email protected]295039bd2008-08-15 04:32:572574 MessageLoop::current()->PostTask(FROM_HERE,
2575 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292576 }
2577}
2578
2579void TestingAutomationProvider::Observe(NotificationType type,
2580 const NotificationSource& source,
2581 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562582 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292583 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2584 // before the task runs resulting in this object not being deleted. This
2585 // Release balance out the Release scheduled by OnBrowserRemoving.
2586 Release();
2587}
[email protected]295039bd2008-08-15 04:32:572588
2589void TestingAutomationProvider::OnRemoveProvider() {
2590 AutomationProviderList::GetInstance()->RemoveProvider(this);
2591}
[email protected]8a3422c92008-09-24 17:42:422592
[email protected]816633a2009-11-11 21:48:182593void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:562594 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422595 if (tab_tracker_->ContainsHandle(handle)) {
2596 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342597 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112598 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422599 }
[email protected]8a3422c92008-09-24 17:42:422600}
2601
[email protected]816633a2009-11-11 21:48:182602void AutomationProvider::ClickInfoBarAccept(int handle,
2603 int info_bar_index,
2604 bool wait_for_navigation,
2605 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422606 bool success = false;
2607 if (tab_tracker_->ContainsHandle(handle)) {
2608 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2609 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112610 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422611 if (info_bar_index >= 0 && info_bar_index < count) {
2612 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:012613 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:422614 }
[email protected]eb9ba192008-12-02 02:41:342615 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112616 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342617 info_bar_index);
2618 if (delegate->AsConfirmInfoBarDelegate())
2619 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422620 success = true;
2621 }
2622 }
[email protected]4f3dc372009-02-24 00:10:292623 }
[email protected]58f622a62009-10-04 01:17:552624
2625 // This "!wait_for_navigation || !success condition" logic looks suspicious.
2626 // It will send a failure message when success is true but
2627 // |wait_for_navigation| is false.
2628 // TODO(phajdan.jr): investgate whether the reply param (currently
2629 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:422630 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:182631 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:522632 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422633}
2634
[email protected]71f65dd2009-02-11 19:14:562635void AutomationProvider::GetLastNavigationTime(int handle,
2636 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422637 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562638 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422639}
2640
[email protected]71f65dd2009-02-11 19:14:562641void AutomationProvider::WaitForNavigation(int handle,
2642 int64 last_navigation_time,
2643 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:252644 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:422645 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:252646
[email protected]8a3422c92008-09-24 17:42:422647 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562648 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522649 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
2650 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:552651 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:292652 return;
[email protected]8a3422c92008-09-24 17:42:422653 }
2654
[email protected]7dad3d5f2010-03-04 00:27:012655 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:422656}
2657
[email protected]71f65dd2009-02-11 19:14:562658void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162659 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562660 int value,
2661 bool* success) {
2662 *success = false;
[email protected]8a3422c92008-09-24 17:42:422663 if (browser_tracker_->ContainsHandle(handle)) {
2664 Browser* browser = browser_tracker_->GetResource(handle);
2665 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562666 *success = true;
[email protected]8a3422c92008-09-24 17:42:422667 }
[email protected]8a3422c92008-09-24 17:42:422668}
[email protected]97fa6ce32008-12-19 01:48:162669
[email protected]71f65dd2009-02-11 19:14:562670void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162671 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562672 const std::wstring& value,
2673 bool* success) {
2674 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162675 if (browser_tracker_->ContainsHandle(handle)) {
2676 Browser* browser = browser_tracker_->GetResource(handle);
2677 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562678 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162679 }
[email protected]97fa6ce32008-12-19 01:48:162680}
2681
[email protected]71f65dd2009-02-11 19:14:562682void AutomationProvider::GetBooleanPreference(int handle,
2683 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:362684 bool* success,
2685 bool* value) {
[email protected]71f65dd2009-02-11 19:14:562686 *success = false;
2687 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162688 if (browser_tracker_->ContainsHandle(handle)) {
2689 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562690 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2691 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162692 }
[email protected]97fa6ce32008-12-19 01:48:162693}
2694
[email protected]71f65dd2009-02-11 19:14:562695void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162696 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562697 bool value,
2698 bool* success) {
2699 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162700 if (browser_tracker_->ContainsHandle(handle)) {
2701 Browser* browser = browser_tracker_->GetResource(handle);
2702 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562703 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162704 }
[email protected]97fa6ce32008-12-19 01:48:162705}
2706
2707// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562708void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:402709 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162710 if (tab_tracker_->ContainsHandle(tab_handle)) {
2711 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2712 Browser* browser = FindAndActivateTab(nav);
2713 DCHECK(browser);
2714
[email protected]57c6a652009-05-04 07:58:342715 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2716 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162717 }
[email protected]97fa6ce32008-12-19 01:48:162718}
2719
[email protected]b8f48d12009-11-09 20:14:362720// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562721void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:402722 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:562723 bool* success) {
2724 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162725 if (tab_tracker_->ContainsHandle(tab_handle)) {
2726 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:192727 if (!nav)
2728 return;
[email protected]97fa6ce32008-12-19 01:48:162729 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:162730
[email protected]2f2afba2010-04-01 01:53:192731 // If the browser has UI, simulate what a user would do.
2732 // Activate the tab and then click the encoding menu.
2733 if (browser &&
2734 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162735 int selected_encoding_id =
2736 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2737 if (selected_encoding_id) {
2738 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562739 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162740 }
[email protected]2f2afba2010-04-01 01:53:192741 } else {
2742 // There is no UI, Chrome probably runs as Chrome-Frame mode.
2743 // Try to get TabContents and call its override_encoding method.
2744 TabContents* contents = nav->tab_contents();
2745 if (!contents)
2746 return;
2747 const std::string selected_encoding =
2748 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
2749 if (selected_encoding.empty())
2750 return;
2751 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:162752 }
2753 }
[email protected]97fa6ce32008-12-19 01:48:162754}
[email protected]5bcdb312009-01-07 21:43:202755
[email protected]4d434a1a2009-02-11 21:06:572756void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:202757 SavePackage::SetShouldPromptUser(should_prompt);
2758}
[email protected]87eab222009-03-13 00:47:452759
[email protected]66ba4932009-06-04 19:22:132760void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
2761 *count = -1; // -1 is the error code
2762 if (tab_tracker_->ContainsHandle(handle)) {
2763 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2764 TabContents* tab_contents = nav_controller->tab_contents();
2765 if (tab_contents) {
2766 BlockedPopupContainer* container =
2767 tab_contents->blocked_popup_container();
2768 if (container) {
2769 *count = static_cast<int>(container->GetBlockedPopupCount());
2770 } else {
2771 // If we don't have a container, we don't have any blocked popups to
2772 // contain!
2773 *count = 0;
2774 }
2775 }
2776 }
2777}
[email protected]f7a68432009-07-29 23:18:192778
2779void AutomationProvider::SelectAll(int tab_handle) {
2780 RenderViewHost* view = GetViewForTab(tab_handle);
2781 if (!view) {
2782 NOTREACHED();
2783 return;
2784 }
2785
2786 view->SelectAll();
2787}
2788
2789void AutomationProvider::Cut(int tab_handle) {
2790 RenderViewHost* view = GetViewForTab(tab_handle);
2791 if (!view) {
2792 NOTREACHED();
2793 return;
2794 }
2795
2796 view->Cut();
2797}
2798
2799void AutomationProvider::Copy(int tab_handle) {
2800 RenderViewHost* view = GetViewForTab(tab_handle);
2801 if (!view) {
2802 NOTREACHED();
2803 return;
2804 }
2805
2806 view->Copy();
2807}
2808
2809void AutomationProvider::Paste(int tab_handle) {
2810 RenderViewHost* view = GetViewForTab(tab_handle);
2811 if (!view) {
2812 NOTREACHED();
2813 return;
2814 }
2815
2816 view->Paste();
2817}
2818
2819void AutomationProvider::ReloadAsync(int tab_handle) {
2820 if (tab_tracker_->ContainsHandle(tab_handle)) {
2821 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2822 if (!tab) {
2823 NOTREACHED();
2824 return;
2825 }
2826
[email protected]106a0812010-03-18 00:15:122827 const bool check_for_repost = true;
2828 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:192829 }
2830}
2831
2832void AutomationProvider::StopAsync(int tab_handle) {
2833 RenderViewHost* view = GetViewForTab(tab_handle);
2834 if (!view) {
[email protected]8b2b3312009-09-14 18:38:362835 // We tolerate StopAsync being called even before a view has been created.
2836 // So just log a warning instead of a NOTREACHED().
2837 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:192838 return;
2839 }
2840
2841 view->Stop();
2842}
2843
[email protected]1bb5f892009-10-06 01:44:572844void AutomationProvider::OnSetPageFontSize(int tab_handle,
2845 int font_size) {
2846 AutomationPageFontSize automation_font_size =
2847 static_cast<AutomationPageFontSize>(font_size);
2848
2849 if (automation_font_size < SMALLEST_FONT ||
2850 automation_font_size > LARGEST_FONT) {
2851 DLOG(ERROR) << "Invalid font size specified : "
2852 << font_size;
2853 return;
2854 }
2855
2856 if (tab_tracker_->ContainsHandle(tab_handle)) {
2857 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2858 DCHECK(tab != NULL);
2859 if (tab && tab->tab_contents()) {
2860 DCHECK(tab->tab_contents()->profile() != NULL);
2861 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
2862 prefs::kWebKitDefaultFontSize, font_size);
2863 }
2864 }
2865}
2866
[email protected]bc73b4e52010-03-26 04:16:202867void AutomationProvider::RemoveBrowsingData(int remove_mask) {
2868 BrowsingDataRemover* remover;
2869 remover = new BrowsingDataRemover(profile(),
2870 BrowsingDataRemover::EVERYTHING, // All time periods.
2871 base::Time());
2872 remover->Remove(remove_mask);
2873 // BrowsingDataRemover deletes itself.
2874}
[email protected]1bb5f892009-10-06 01:44:572875
[email protected]2949e90d2009-08-21 15:32:522876void AutomationProvider::WaitForBrowserWindowCountToBecome(
2877 int target_count, IPC::Message* reply_message) {
2878 if (static_cast<int>(BrowserList::size()) == target_count) {
2879 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
2880 reply_message, true);
2881 Send(reply_message);
2882 return;
2883 }
2884
2885 // Set up an observer (it will delete itself).
2886 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
2887}
2888
2889void AutomationProvider::WaitForAppModalDialogToBeShown(
2890 IPC::Message* reply_message) {
2891 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
2892 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
2893 reply_message, true);
2894 Send(reply_message);
2895 return;
2896 }
2897
2898 // Set up an observer (it will delete itself).
2899 new AppModalDialogShownObserver(this, reply_message);
2900}
2901
[email protected]1126a1d32009-08-26 15:39:262902void AutomationProvider::GoBackBlockUntilNavigationsComplete(
2903 int handle, int number_of_navigations, IPC::Message* reply_message) {
2904 if (tab_tracker_->ContainsHandle(handle)) {
2905 NavigationController* tab = tab_tracker_->GetResource(handle);
2906 Browser* browser = FindAndActivateTab(tab);
2907 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:012908 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
2909 false);
[email protected]1126a1d32009-08-26 15:39:262910 browser->GoBack(CURRENT_TAB);
2911 return;
2912 }
2913 }
2914
2915 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
2916 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
2917 Send(reply_message);
2918}
2919
2920void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
2921 int handle, int number_of_navigations, IPC::Message* reply_message) {
2922 if (tab_tracker_->ContainsHandle(handle)) {
2923 NavigationController* tab = tab_tracker_->GetResource(handle);
2924 Browser* browser = FindAndActivateTab(tab);
2925 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:012926 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
2927 false);
[email protected]1126a1d32009-08-26 15:39:262928 browser->GoForward(CURRENT_TAB);
2929 return;
2930 }
2931 }
2932
2933 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
2934 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
2935 Send(reply_message);
2936}
2937
[email protected]f7a68432009-07-29 23:18:192938RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
2939 if (tab_tracker_->ContainsHandle(tab_handle)) {
2940 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2941 if (!tab) {
2942 NOTREACHED();
2943 return NULL;
2944 }
2945
2946 TabContents* tab_contents = tab->tab_contents();
2947 if (!tab_contents) {
2948 NOTREACHED();
2949 return NULL;
2950 }
2951
2952 RenderViewHost* view_host = tab_contents->render_view_host();
2953 return view_host;
2954 }
2955
2956 return NULL;
2957}
[email protected]675595f2009-08-26 22:32:042958
2959void AutomationProvider::GetBrowserForWindow(int window_handle,
2960 bool* success,
2961 int* browser_handle) {
2962 *success = false;
2963 *browser_handle = 0;
2964
2965 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
2966 if (!window)
2967 return;
2968
2969 BrowserList::const_iterator iter = BrowserList::begin();
2970 for (;iter != BrowserList::end(); ++iter) {
2971 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
2972 if (window == this_window) {
2973 // Add() returns the existing handle for the resource if any.
2974 *browser_handle = browser_tracker_->Add(*iter);
2975 *success = true;
2976 return;
2977 }
2978 }
2979}
[email protected]d11c8e92009-10-20 23:26:402980
2981void AutomationProvider::InstallExtension(const FilePath& crx_path,
2982 IPC::Message* reply_message) {
2983 ExtensionsService* service = profile_->GetExtensionsService();
2984 if (service) {
2985 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:192986 new ExtensionInstallNotificationObserver(this,
2987 AutomationMsg_InstallExtension::ID,
2988 reply_message);
[email protected]d11c8e92009-10-20 23:26:402989
2990 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:162991 scoped_refptr<CrxInstaller> installer(
2992 new CrxInstaller(install_dir,
2993 service,
2994 NULL)); // silent install, no UI
2995 installer->set_allow_privilege_increase(true);
2996 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:402997 } else {
2998 AutomationMsg_InstallExtension::WriteReplyParams(
2999 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3000 Send(reply_message);
3001 }
3002}
3003
3004void AutomationProvider::LoadExpandedExtension(
3005 const FilePath& extension_dir,
3006 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383007 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403008 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193009 new ExtensionInstallNotificationObserver(
3010 this,
3011 AutomationMsg_LoadExpandedExtension::ID,
3012 reply_message);
[email protected]d11c8e92009-10-20 23:26:403013
3014 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403015 } else {
3016 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3017 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3018 Send(reply_message);
3019 }
3020}
[email protected]673fd2c02010-02-04 23:10:003021
[email protected]a1e62d12010-03-16 02:18:433022void AutomationProvider::GetEnabledExtensions(
3023 std::vector<FilePath>* result) {
3024 ExtensionsService* service = profile_->GetExtensionsService();
3025 DCHECK(service);
3026 if (service->extensions_enabled()) {
3027 const ExtensionList* extensions = service->extensions();
3028 DCHECK(extensions);
3029 for (size_t i = 0; i < extensions->size(); ++i) {
3030 Extension* extension = (*extensions)[i];
3031 DCHECK(extension);
[email protected]237f281672010-03-20 12:37:073032 if (extension->location() == Extension::INTERNAL) {
3033 result->push_back(extension->path());
3034 }
[email protected]a1e62d12010-03-16 02:18:433035 }
3036 }
3037}
3038
[email protected]790788ac2010-04-06 17:52:193039void AutomationProvider::WaitForExtensionTestResult(
3040 IPC::Message* reply_message) {
3041 DCHECK(reply_message_ == NULL);
3042 reply_message_ = reply_message;
3043 // Call MaybeSendResult, because the result might have come in before
3044 // we were waiting on it.
3045 extension_test_result_observer_->MaybeSendResult();
3046}
3047
3048void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093049 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193050 ExtensionsService* service = profile_->GetExtensionsService();
3051 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3052 if (service && manager) {
3053 // The observer will delete itself when done.
3054 new ExtensionReadyNotificationObserver(
3055 manager,
3056 this,
3057 AutomationMsg_InstallExtensionAndGetHandle::ID,
3058 reply_message);
3059
[email protected]d7e5525d2010-04-20 14:37:093060 ExtensionInstallUI* client =
3061 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193062 scoped_refptr<CrxInstaller> installer(
3063 new CrxInstaller(service->install_directory(),
3064 service,
[email protected]d7e5525d2010-04-20 14:37:093065 client));
[email protected]790788ac2010-04-06 17:52:193066 installer->set_allow_privilege_increase(true);
3067 installer->InstallCrx(crx_path);
3068 } else {
3069 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3070 reply_message, 0);
3071 Send(reply_message);
3072 }
3073}
3074
3075void AutomationProvider::UninstallExtension(int extension_handle,
3076 bool* success) {
3077 *success = false;
3078 Extension* extension = GetExtension(extension_handle);
3079 ExtensionsService* service = profile_->GetExtensionsService();
3080 if (extension && service) {
3081 ExtensionUnloadNotificationObserver observer;
3082 service->UninstallExtension(extension->id(), false);
3083 // The extension unload notification should have been sent synchronously
3084 // with the uninstall. Just to be safe, check that it was received.
3085 *success = observer.did_receive_unload_notification();
3086 }
3087}
3088
3089void AutomationProvider::EnableExtension(int extension_handle,
3090 IPC::Message* reply_message) {
3091 Extension* extension = GetDisabledExtension(extension_handle);
3092 ExtensionsService* service = profile_->GetExtensionsService();
3093 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3094 // Only enable if this extension is disabled.
3095 if (extension && service && manager) {
3096 // The observer will delete itself when done.
3097 new ExtensionReadyNotificationObserver(
3098 manager,
3099 this,
3100 AutomationMsg_EnableExtension::ID,
3101 reply_message);
3102 service->EnableExtension(extension->id());
3103 } else {
3104 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3105 Send(reply_message);
3106 }
3107}
3108
3109void AutomationProvider::DisableExtension(int extension_handle,
3110 bool* success) {
3111 *success = false;
3112 Extension* extension = GetEnabledExtension(extension_handle);
3113 ExtensionsService* service = profile_->GetExtensionsService();
3114 if (extension && service) {
3115 ExtensionUnloadNotificationObserver observer;
3116 service->DisableExtension(extension->id());
3117 // The extension unload notification should have been sent synchronously
3118 // with the disable. Just to be safe, check that it was received.
3119 *success = observer.did_receive_unload_notification();
3120 }
3121}
3122
3123void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3124 int extension_handle, int browser_handle,
3125 IPC::Message* reply_message) {
3126 bool success = false;
3127 Extension* extension = GetEnabledExtension(extension_handle);
3128 ExtensionsService* service = profile_->GetExtensionsService();
3129 ExtensionMessageService* message_service =
3130 profile_->GetExtensionMessageService();
3131 Browser* browser = browser_tracker_->GetResource(browser_handle);
3132 if (extension && service && message_service && browser) {
3133 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3134 if (extension->page_action()) {
3135 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3136 browser->profile(), extension->id(), "action", tab_id, "", 1);
3137 success = true;
3138 } else if (extension->browser_action()) {
3139 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3140 browser->profile(), extension->id(), browser);
3141 success = true;
3142 }
3143 }
3144 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3145 reply_message, success);
3146 Send(reply_message);
3147}
3148
3149void AutomationProvider::MoveExtensionBrowserAction(
3150 int extension_handle, int index, bool* success) {
3151 *success = false;
3152 Extension* extension = GetEnabledExtension(extension_handle);
3153 ExtensionsService* service = profile_->GetExtensionsService();
3154 if (extension && service) {
3155 ExtensionToolbarModel* toolbar = service->toolbar_model();
3156 if (toolbar) {
3157 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3158 toolbar->MoveBrowserAction(extension, index);
3159 *success = true;
3160 } else {
3161 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3162 }
3163 }
3164 }
3165}
3166
3167void AutomationProvider::GetExtensionProperty(
3168 int extension_handle,
3169 AutomationMsg_ExtensionProperty type,
3170 bool* success,
3171 std::string* value) {
3172 *success = false;
3173 Extension* extension = GetExtension(extension_handle);
3174 ExtensionsService* service = profile_->GetExtensionsService();
3175 if (extension && service) {
3176 ExtensionToolbarModel* toolbar = service->toolbar_model();
3177 int found_index = -1;
3178 int index = 0;
3179 switch (type) {
3180 case AUTOMATION_MSG_EXTENSION_ID:
3181 *value = extension->id();
3182 *success = true;
3183 break;
3184 case AUTOMATION_MSG_EXTENSION_NAME:
3185 *value = extension->name();
3186 *success = true;
3187 break;
3188 case AUTOMATION_MSG_EXTENSION_VERSION:
3189 *value = extension->VersionString();
3190 *success = true;
3191 break;
3192 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3193 if (toolbar) {
3194 for (ExtensionList::const_iterator iter = toolbar->begin();
3195 iter != toolbar->end(); iter++) {
3196 // Skip this extension if we are in incognito mode
3197 // and it is not incognito-enabled.
3198 if (profile_->IsOffTheRecord() &&
3199 !service->IsIncognitoEnabled(*iter))
3200 continue;
3201 if (*iter == extension) {
3202 found_index = index;
3203 break;
3204 }
3205 index++;
3206 }
3207 *value = IntToString(found_index);
3208 *success = true;
3209 }
3210 break;
3211 default:
3212 LOG(WARNING) << "Trying to get undefined extension property";
3213 break;
3214 }
3215 }
3216}
3217
[email protected]673fd2c02010-02-04 23:10:003218void AutomationProvider::SaveAsAsync(int tab_handle) {
3219 NavigationController* tab = NULL;
3220 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3221 if (tab_contents)
3222 tab_contents->OnSavePage();
3223}
[email protected]7dad3d5f2010-03-04 00:27:013224
3225void AutomationProvider::SetContentSetting(
3226 int handle,
3227 const std::string& host,
3228 ContentSettingsType content_type,
3229 ContentSetting setting,
3230 bool* success) {
3231 *success = false;
3232 if (browser_tracker_->ContainsHandle(handle)) {
3233 Browser* browser = browser_tracker_->GetResource(handle);
3234 HostContentSettingsMap* map =
3235 browser->profile()->GetHostContentSettingsMap();
3236 if (host.empty()) {
3237 map->SetDefaultContentSetting(content_type, setting);
3238 } else {
[email protected]0314ae02010-04-08 09:18:293239 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
3240 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:013241 }
3242 *success = true;
3243 }
3244}
[email protected]cc824372010-03-31 15:33:013245
3246#if !defined(TOOLKIT_VIEWS)
3247void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
3248 NOTIMPLEMENTED();
3249};
3250
3251void AutomationProvider::WaitForFocusedViewIDToChange(
3252 int handle, int previous_view_id, IPC::Message* reply_message) {
3253 NOTIMPLEMENTED();
3254}
3255
3256void AutomationProvider::StartTrackingPopupMenus(
3257 int browser_handle, bool* success) {
3258 NOTIMPLEMENTED();
3259}
3260
3261void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
3262 NOTIMPLEMENTED();
3263}
3264#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:093265
3266void AutomationProvider::ResetToDefaultTheme() {
3267 profile_->ClearTheme();
3268}