blob: 98f05e7c2f3e18b39eb6d45a489122b4d019d534 [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]ef413ca2010-05-25 21:09:1437#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0738#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3939#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2040#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0541#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5842#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2943#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1244#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5945#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2246#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0547#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4048#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1949#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1450#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4051#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5552#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1953#include "chrome/browser/extensions/extension_tabs_module.h"
54#include "chrome/browser/extensions/extension_toolbar_model.h"
55#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1656#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5857#include "chrome/browser/find_bar.h"
58#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2959#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0160#include "chrome/browser/host_content_settings_map.h"
[email protected]0ac83682010-01-22 17:46:2761#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0662#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0163#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5364#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2465#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0866#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0567#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1768#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0769#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2570#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0371#include "chrome/browser/ssl/ssl_manager.h"
72#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3473#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4574#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1775#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0576#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2977#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1978#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1779#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5580#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1481#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5782#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2583#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5684#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5785#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1786#include "net/proxy/proxy_service.h"
87#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2188#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3089#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2890#include "views/event.h"
[email protected]f7d48012010-05-06 08:17:0591#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2992
[email protected]de246f52009-02-25 18:25:4593#if defined(OS_WIN)
[email protected]de246f52009-02-25 18:25:4594#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4595#endif // defined(OS_WIN)
96
[email protected]e1acf6f2008-10-27 20:43:3397using base::Time;
98
[email protected]cbab76d2008-10-13 22:42:4799class AutomationInterstitialPage : public InterstitialPage {
100 public:
[email protected]57c6a652009-05-04 07:58:34101 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47102 const GURL& url,
103 const std::string& contents)
104 : InterstitialPage(tab, true, url),
105 contents_(contents) {
106 }
107
108 virtual std::string GetHTMLContents() { return contents_; }
109
110 private:
111 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29112
[email protected]cbab76d2008-10-13 22:42:47113 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
114};
115
[email protected]c2cb8542009-08-20 21:16:51116class ClickTask : public Task {
117 public:
[email protected]fc2e0872009-08-21 22:14:41118 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51119 virtual ~ClickTask() {}
120
121 virtual void Run() {
122 ui_controls::MouseButton button = ui_controls::LEFT;
123 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
124 views::Event::EF_LEFT_BUTTON_DOWN) {
125 button = ui_controls::LEFT;
126 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
127 views::Event::EF_RIGHT_BUTTON_DOWN) {
128 button = ui_controls::RIGHT;
129 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
130 views::Event::EF_MIDDLE_BUTTON_DOWN) {
131 button = ui_controls::MIDDLE;
132 } else {
133 NOTREACHED();
134 }
135
[email protected]fc2e0872009-08-21 22:14:41136 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51137 }
138
139 private:
[email protected]c2cb8542009-08-20 21:16:51140 int flags_;
141
142 DISALLOW_COPY_AND_ASSIGN(ClickTask);
143};
[email protected]c2cb8542009-08-20 21:16:51144
initial.commit09911bf2008-07-26 23:55:29145AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57146 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56147 profile_(profile),
[email protected]cc824372010-03-31 15:33:01148 reply_message_(NULL),
149 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29150 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19151 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29152 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20153 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29154 autocomplete_edit_tracker_.reset(
155 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29156 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
157 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44158 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19159 extension_test_result_observer_.reset(
160 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13161 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29162}
163
164AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50165 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
166 port_containers_.end());
167 port_containers_.clear();
168
[email protected]0da050b92008-08-19 19:29:47169 // Make sure that any outstanding NotificationObservers also get destroyed.
170 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31171 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47172 while ((observer = it.GetNext()) != NULL)
173 delete observer;
[email protected]528211a2010-01-14 15:25:13174
175 if (channel_.get()) {
176 channel_->Close();
177 }
178 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29179}
180
[email protected]9a3a293b2009-06-04 22:28:16181void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06182 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57183 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06184 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
185 automation_resource_message_filter_,
186 g_browser_process->io_thread()->message_loop(),
187 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43188 scoped_ptr<FileVersionInfo> version_info(
189 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40190 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43191 if (version_info != NULL) {
192 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40193 }
[email protected]c6cb1992009-04-13 16:45:29194
195 // Send a hello message with our current automation protocol version.
196 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29197}
198
199void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
200 if (expected_tabs == 0) {
201 Send(new AutomationMsg_InitialLoadsComplete(0));
202 } else {
203 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
204 }
205}
206
207NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58208 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01209 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29210 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58211 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01212 number_of_navigations,
213 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29214
[email protected]71f65dd2009-02-11 19:14:56215 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29216 return observer;
217}
218
[email protected]faf2ee42010-05-11 14:26:17219void AutomationProvider::RemoveNavigationStatusListener(
220 NotificationObserver* obs) {
221 notification_observer_list_.RemoveObserver(obs);
222}
223
initial.commit09911bf2008-07-26 23:55:29224NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14225 Browser* parent,
226 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56227 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14228 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29229 notification_observer_list_.AddObserver(observer);
230
231 return observer;
232}
233
[email protected]faf2ee42010-05-11 14:26:17234void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29235 notification_observer_list_.RemoveObserver(obs);
236}
237
238void AutomationProvider::AddLoginHandler(NavigationController* tab,
239 LoginHandler* handler) {
240 login_handler_map_[tab] = handler;
241}
242
243void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
244 DCHECK(login_handler_map_[tab]);
245 login_handler_map_.erase(tab);
246}
247
[email protected]f44265b2009-05-19 18:52:50248void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
249 int port_id = port->port_id();
250 DCHECK_NE(-1, port_id);
251 DCHECK(port_containers_.find(port_id) == port_containers_.end());
252
253 port_containers_[port_id] = port;
254}
255
256void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
257 int port_id = port->port_id();
258 DCHECK_NE(-1, port_id);
259
260 PortContainerMap::iterator it = port_containers_.find(port_id);
261 DCHECK(it != port_containers_.end());
262
263 if (it != port_containers_.end()) {
264 delete it->second;
265 port_containers_.erase(it);
266 }
267}
268
269ExtensionPortContainer* AutomationProvider::GetPortContainer(
270 int port_id) const {
271 PortContainerMap::const_iterator it = port_containers_.find(port_id);
272 if (it == port_containers_.end())
273 return NULL;
274
275 return it->second;
276}
277
initial.commit09911bf2008-07-26 23:55:29278int AutomationProvider::GetIndexForNavigationController(
279 const NavigationController* controller, const Browser* parent) const {
280 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12281 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29282}
283
[email protected]790788ac2010-04-06 17:52:19284int AutomationProvider::AddExtension(Extension* extension) {
285 DCHECK(extension);
286 return extension_tracker_->Add(extension);
287}
288
289Extension* AutomationProvider::GetExtension(int extension_handle) {
290 return extension_tracker_->GetResource(extension_handle);
291}
292
293Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
294 Extension* extension = extension_tracker_->GetResource(extension_handle);
295 ExtensionsService* service = profile_->GetExtensionsService();
296 if (extension && service &&
297 service->GetExtensionById(extension->id(), false))
298 return extension;
299 return NULL;
300}
301
302Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
303 Extension* extension = extension_tracker_->GetResource(extension_handle);
304 ExtensionsService* service = profile_->GetExtensionsService();
305 if (extension && service &&
306 service->GetExtensionById(extension->id(), true) &&
307 !service->GetExtensionById(extension->id(), false))
308 return extension;
309 return NULL;
310}
311
initial.commit09911bf2008-07-26 23:55:29312void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
313 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14314 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56315 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
316 CloseBrowserAsync)
317 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
318 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
319 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
320 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
321 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
322 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22323 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]1c58a5c2009-05-21 18:47:14324 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58325 IPC_MESSAGE_HANDLER_DELAY_REPLY(
326 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
327 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56328 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11329 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
330 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56331 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
332 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
333 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
334 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14335 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56336 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
337 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
338 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14339 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29340 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
341 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56342 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36343 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56344 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29345 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56346 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29347 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
348 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56349 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14350 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24351 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44352 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33353 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44354 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33355 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24356 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14357 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24358 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15359 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14360 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24361 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35362 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14363 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30364#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56365 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
366 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30367#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56368 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53369 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56370 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37371#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56372 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45373#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56374 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
375 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03376 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56377 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14378 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09379 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
380 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
381 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29382 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14383 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56384 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
385 ExecuteJavascript)
386 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29387 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14388 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
389 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56390 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
391 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14392 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17393 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14394 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14395 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53396 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
397 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14398 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56399 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14400 GetAutocompleteEditForBrowser)
401 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:45402#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29403 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:17404#endif
[email protected]71f65dd2009-02-11 19:14:56405 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:29406 NavigateInExternalTab)
[email protected]4150ef02009-08-19 23:14:26407 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
408 NavigateExternalTabAtIndex)
[email protected]71f65dd2009-02-11 19:14:56409 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14410 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56411 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14412 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:17413#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29414 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
415 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:17416#endif
[email protected]71f65dd2009-02-11 19:14:56417 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
418 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14419 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:17420#if defined(OS_WIN)
[email protected]5a9708432009-09-23 22:15:04421 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:39422 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
423 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:17424#endif
[email protected]1c58a5c2009-05-21 18:47:14425 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
426 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44427 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
428 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56429 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
430 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29431 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
432 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
433 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56434 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41435 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56436 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
437 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29438 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56439 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29440 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56441 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29442 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56443 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29444 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56445 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45446 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:45447 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
448 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:14449 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56450 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57451 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56452 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57453 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56454 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
455 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53456 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
457 GetBookmarksAsJSON)
458 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
459 WaitForBookmarkModelToLoad)
460 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
461 AddBookmarkGroup)
462 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
463 AddBookmarkURL)
464 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
465 ReparentBookmark)
466 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
467 SetBookmarkTitle)
468 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
469 SetBookmarkURL)
470 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
471 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04472 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
473 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18474 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
475 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
476 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56477 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42478 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56479 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
480 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14481 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56482 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44483 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56484 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20485 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14486 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56487 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16488 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56489 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16490 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56491 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16492 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14493 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20494 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
495 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14496 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]4cfc1d922009-11-08 14:02:58497#if defined(OS_WIN)
498 // Depends on ExternalTabContainer, so Windows-only
[email protected]b83e4602009-05-15 22:58:33499 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
500 SetEnableExtensionAutomation)
[email protected]4cfc1d922009-11-08 14:02:58501#endif
[email protected]59560e0b2009-06-04 03:30:22502 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13503 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19504 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
505 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
506 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
507 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
508 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
509 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52510 IPC_MESSAGE_HANDLER_DELAY_REPLY(
511 AutomationMsg_WaitForBrowserWindowCountToBecome,
512 WaitForBrowserWindowCountToBecome)
513 IPC_MESSAGE_HANDLER_DELAY_REPLY(
514 AutomationMsg_WaitForAppModalDialogToBeShown,
515 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26516 IPC_MESSAGE_HANDLER_DELAY_REPLY(
517 AutomationMsg_GoBackBlockUntilNavigationsComplete,
518 GoBackBlockUntilNavigationsComplete)
519 IPC_MESSAGE_HANDLER_DELAY_REPLY(
520 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
521 GoForwardBlockUntilNavigationsComplete)
[email protected]632fbb12009-09-06 15:27:14522#if defined(OS_WIN)
523 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
524#endif
[email protected]1bb5f892009-10-06 01:44:57525 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40526 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
527 InstallExtension)
528 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
529 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43530 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
531 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19532 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
533 WaitForExtensionTestResult)
534 IPC_MESSAGE_HANDLER_DELAY_REPLY(
535 AutomationMsg_InstallExtensionAndGetHandle,
536 InstallExtensionAndGetHandle)
537 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
538 UninstallExtension)
539 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
540 EnableExtension)
541 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
542 DisableExtension)
543 IPC_MESSAGE_HANDLER_DELAY_REPLY(
544 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
545 ExecuteExtensionActionInActiveTabAsync)
546 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
547 MoveExtensionBrowserAction)
548 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
549 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57550 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
551 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00552 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]2b19e2fe2010-02-16 02:24:18553#if defined(OS_WIN)
554 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
555#endif
[email protected]7dad3d5f2010-03-04 00:27:01556 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]566a0f762010-03-10 04:14:57557#if defined(OS_CHROMEOS)
558 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
559 LoginWithUserAndPass)
560#endif
[email protected]bc73b4e52010-03-26 04:16:20561 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]cc824372010-03-31 15:33:01562#if defined(TOOLKIT_VIEWS)
563 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
564 WaitForFocusedViewIDToChange)
565 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
566 StartTrackingPopupMenus)
567 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
568 WaitForPopupMenuToOpen)
569#endif
[email protected]d7e5525d2010-04-20 14:37:09570 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
initial.commit09911bf2008-07-26 23:55:29571 IPC_END_MESSAGE_MAP()
572}
573
[email protected]71f65dd2009-02-11 19:14:56574void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
575 *status = -1;
initial.commit09911bf2008-07-26 23:55:29576 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
577 Browser* browser = browser_tracker_->GetResource(handle);
578 if (at_index >= 0 && at_index < browser->tab_count()) {
579 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56580 *status = 0;
initial.commit09911bf2008-07-26 23:55:29581 }
582 }
initial.commit09911bf2008-07-26 23:55:29583}
584
[email protected]71f65dd2009-02-11 19:14:56585void AutomationProvider::AppendTab(int handle, const GURL& url,
586 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29587 int append_tab_response = -1; // -1 is the error code
588 NotificationObserver* observer = NULL;
589
590 if (browser_tracker_->ContainsHandle(handle)) {
591 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14592 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38593 TabContents* tab_contents = browser->AddTabWithURL(
594 url, GURL(), PageTransition::TYPED, -1, Browser::ADD_SELECTED, NULL,
595 std::string());
initial.commit09911bf2008-07-26 23:55:29596 if (tab_contents) {
597 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57598 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29599 }
600 }
601
602 if (append_tab_response < 0) {
603 // The append tab failed. Remove the TabStripObserver
604 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17605 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29606 delete observer;
607 }
608
[email protected]71f65dd2009-02-11 19:14:56609 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
610 append_tab_response);
611 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29612 }
613}
614
[email protected]71f65dd2009-02-11 19:14:56615void AutomationProvider::NavigateToURL(int handle, const GURL& url,
616 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58617 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
618}
619
620void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
621 int handle, const GURL& url, int number_of_navigations,
622 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29623 if (tab_tracker_->ContainsHandle(handle)) {
624 NavigationController* tab = tab_tracker_->GetResource(handle);
625
626 // Simulate what a user would do. Activate the tab and then navigate.
627 // We could allow navigating in a background tab in future.
628 Browser* browser = FindAndActivateTab(tab);
629
630 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01631 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
632 false);
[email protected]71f65dd2009-02-11 19:14:56633
initial.commit09911bf2008-07-26 23:55:29634 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50635 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29636 return;
637 }
638 }
[email protected]71f65dd2009-02-11 19:14:56639
640 AutomationMsg_NavigateToURL::WriteReplyParams(
641 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
642 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29643}
[email protected]2949e90d2009-08-21 15:32:52644
[email protected]c70f9b82010-04-21 07:31:11645void AutomationProvider::NavigationAsync(int handle,
646 const GURL& url,
647 bool* status) {
648 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
649}
650
651void AutomationProvider::NavigationAsyncWithDisposition(
652 int handle,
653 const GURL& url,
654 WindowOpenDisposition disposition,
655 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56656 *status = false;
initial.commit09911bf2008-07-26 23:55:29657
658 if (tab_tracker_->ContainsHandle(handle)) {
659 NavigationController* tab = tab_tracker_->GetResource(handle);
660
661 // Simulate what a user would do. Activate the tab and then navigate.
662 // We could allow navigating in a background tab in future.
663 Browser* browser = FindAndActivateTab(tab);
664
665 if (browser) {
666 // Don't add any listener unless a callback mechanism is desired.
667 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11668 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56669 *status = true;
initial.commit09911bf2008-07-26 23:55:29670 }
671 }
initial.commit09911bf2008-07-26 23:55:29672}
673
[email protected]71f65dd2009-02-11 19:14:56674void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29675 if (tab_tracker_->ContainsHandle(handle)) {
676 NavigationController* tab = tab_tracker_->GetResource(handle);
677 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14678 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01679 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29680 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29681 return;
682 }
683 }
[email protected]71f65dd2009-02-11 19:14:56684
685 AutomationMsg_GoBack::WriteReplyParams(
686 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
687 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29688}
689
[email protected]71f65dd2009-02-11 19:14:56690void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29691 if (tab_tracker_->ContainsHandle(handle)) {
692 NavigationController* tab = tab_tracker_->GetResource(handle);
693 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14694 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01695 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29696 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29697 return;
698 }
699 }
[email protected]71f65dd2009-02-11 19:14:56700
701 AutomationMsg_GoForward::WriteReplyParams(
702 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
703 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29704}
705
[email protected]71f65dd2009-02-11 19:14:56706void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29707 if (tab_tracker_->ContainsHandle(handle)) {
708 NavigationController* tab = tab_tracker_->GetResource(handle);
709 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14710 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01711 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28712 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29713 return;
714 }
715 }
[email protected]71f65dd2009-02-11 19:14:56716
717 AutomationMsg_Reload::WriteReplyParams(
718 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
719 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29720}
721
[email protected]71f65dd2009-02-11 19:14:56722void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29723 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56724 const std::wstring& password,
725 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29726 if (tab_tracker_->ContainsHandle(tab_handle)) {
727 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
728 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
729
730 if (iter != login_handler_map_.end()) {
731 // If auth is needed again after this, assume login has failed. This is
732 // not strictly correct, because a navigation can require both proxy and
733 // server auth, but it should be OK for now.
734 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01735 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29736 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52737 return;
initial.commit09911bf2008-07-26 23:55:29738 }
739 }
[email protected]de246f52009-02-25 18:25:45740
[email protected]457f5cf2009-08-18 16:37:52741 AutomationMsg_SetAuth::WriteReplyParams(
742 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
743 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29744}
745
[email protected]71f65dd2009-02-11 19:14:56746void AutomationProvider::CancelAuth(int tab_handle,
747 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29748 if (tab_tracker_->ContainsHandle(tab_handle)) {
749 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
750 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
751
752 if (iter != login_handler_map_.end()) {
753 // If auth is needed again after this, something is screwy.
754 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01755 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29756 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52757 return;
initial.commit09911bf2008-07-26 23:55:29758 }
759 }
[email protected]de246f52009-02-25 18:25:45760
[email protected]457f5cf2009-08-18 16:37:52761 AutomationMsg_CancelAuth::WriteReplyParams(
762 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
763 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29764}
765
[email protected]71f65dd2009-02-11 19:14:56766void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
767 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29768
769 if (tab_tracker_->ContainsHandle(tab_handle)) {
770 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
771 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
772
773 if (iter != login_handler_map_.end()) {
774 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56775 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29776 }
777 }
initial.commit09911bf2008-07-26 23:55:29778}
779
[email protected]71f65dd2009-02-11 19:14:56780void AutomationProvider::GetRedirectsFrom(int tab_handle,
781 const GURL& source_url,
782 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29783 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
784 if (tab_tracker_->ContainsHandle(tab_handle)) {
785 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
786 HistoryService* history_service =
787 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
788
789 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
790 "has no history service";
791 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56792 DCHECK(reply_message_ == NULL);
793 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29794 // Schedule a history query for redirects. The response will be sent
795 // asynchronously from the callback the history system uses to notify us
796 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29797 redirect_query_ = history_service->QueryRedirectsFrom(
798 source_url, &consumer_,
799 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
800 return; // Response will be sent when query completes.
801 }
802 }
803
804 // Send failure response.
[email protected]deb57402009-02-06 01:35:30805 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56806 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
807 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29808}
809
[email protected]71f65dd2009-02-11 19:14:56810void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
811 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29812 if (browser_tracker_->ContainsHandle(handle)) {
813 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56814 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29815 }
initial.commit09911bf2008-07-26 23:55:29816}
817
[email protected]202e7a72009-06-15 03:48:36818void AutomationProvider::GetBrowserLocale(string16* locale) {
819 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06820 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36821}
822
[email protected]71f65dd2009-02-11 19:14:56823void AutomationProvider::GetBrowserWindowCount(int* window_count) {
824 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29825}
826
[email protected]24497032009-05-01 17:00:29827void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
828 *window_count = static_cast<int>(
829 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
830}
831
[email protected]71f65dd2009-02-11 19:14:56832void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
833 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07834 AppModalDialog* dialog_delegate =
835 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50836 *showing_dialog = (dialog_delegate != NULL);
837 if (*showing_dialog)
838 *dialog_button = dialog_delegate->GetDialogButtons();
839 else
[email protected]478ff2ed2009-04-21 23:49:18840 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20841}
842
[email protected]71f65dd2009-02-11 19:14:56843void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
844 *success = false;
[email protected]fad84eab2008-12-05 00:37:20845
[email protected]1f460072009-05-28 17:02:07846 AppModalDialog* dialog_delegate =
847 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50848 if (dialog_delegate &&
849 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18850 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
851 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28852 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56853 *success = true;
[email protected]fad84eab2008-12-05 00:37:20854 }
[email protected]478ff2ed2009-04-21 23:49:18855 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
856 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56857 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28858 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56859 *success = true;
[email protected]fad84eab2008-12-05 00:37:20860 }
861 }
[email protected]c274acc2008-11-11 20:13:44862}
863
[email protected]fedaa7d2010-01-26 20:34:57864void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
865 if (browser_tracker_->ContainsHandle(handle)) {
866 Browser* browser = browser_tracker_->GetResource(handle);
867 browser->profile()->ShutdownSessionService();
868 *result = true;
869 } else {
870 *result = false;
871 }
872}
873
[email protected]71f65dd2009-02-11 19:14:56874void AutomationProvider::GetBrowserWindow(int index, int* handle) {
875 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29876 if (index >= 0) {
877 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:29878 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:29879 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56880 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29881 }
882 }
initial.commit09911bf2008-07-26 23:55:29883}
884
[email protected]24497032009-05-01 17:00:29885void AutomationProvider::FindNormalBrowserWindow(int* handle) {
886 *handle = 0;
887 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31888 Browser::TYPE_NORMAL,
889 false);
[email protected]24497032009-05-01 17:00:29890 if (browser)
891 *handle = browser_tracker_->Add(browser);
892}
893
[email protected]71f65dd2009-02-11 19:14:56894void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
895 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29896 Browser* browser = BrowserList::GetLastActive();
897 if (browser)
[email protected]71f65dd2009-02-11 19:14:56898 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29899}
900
[email protected]b2aa3ed72010-02-01 18:37:14901#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28902// TODO(estade): use this implementation for all platforms?
903void AutomationProvider::GetActiveWindow(int* handle) {
904 gfx::NativeWindow window =
905 BrowserList::GetLastActive()->window()->GetNativeHandle();
906 *handle = window_tracker_->Add(window);
907}
908#endif
909
[email protected]4f6381ee2009-04-16 02:46:33910void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
911 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56912 *success = false;
[email protected]4ae62752008-08-04 23:28:47913 if (browser_tracker_->ContainsHandle(handle)) {
914 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14915 if (browser->command_updater()->SupportsCommand(command) &&
916 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47917 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56918 *success = true;
[email protected]4ae62752008-08-04 23:28:47919 }
920 }
[email protected]4ae62752008-08-04 23:28:47921}
922
[email protected]4f6381ee2009-04-16 02:46:33923void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56924 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53925 // List of commands which just finish synchronously and don't require
926 // setting up an observer.
927 static const int kSynchronousCommands[] = {
928 IDC_HOME,
929 IDC_SELECT_NEXT_TAB,
930 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25931 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53932 };
[email protected]56e71b7c2009-03-27 03:05:56933 if (browser_tracker_->ContainsHandle(handle)) {
934 Browser* browser = browser_tracker_->GetResource(handle);
935 if (browser->command_updater()->SupportsCommand(command) &&
936 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53937 // First check if we can handle the command without using an observer.
938 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
939 if (command == kSynchronousCommands[i]) {
940 browser->ExecuteCommand(command);
941 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
942 true);
943 Send(reply_message);
944 return;
945 }
946 }
947
948 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42949 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
950 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27951 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42952 return;
953 }
[email protected]56e71b7c2009-03-27 03:05:56954 }
955 }
[email protected]49a14a82009-03-31 04:16:44956 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56957 Send(reply_message);
958}
959
[email protected]fc2e0872009-08-21 22:14:41960// This task just adds another task to the event queue. This is useful if
961// you want to ensure that any tasks added to the event queue after this one
962// have already been processed by the time |task| is run.
963class InvokeTaskLaterTask : public Task {
964 public:
965 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
966 virtual ~InvokeTaskLaterTask() {}
967
968 virtual void Run() {
969 MessageLoop::current()->PostTask(FROM_HERE, task_);
970 }
971
972 private:
973 Task* task_;
974
975 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
976};
977
initial.commit09911bf2008-07-26 23:55:29978void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
979 int handle,
[email protected]d1a5941e2009-08-13 23:34:24980 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29981 int flags) {
[email protected]b410bc32009-08-14 01:11:14982 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51983 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41984 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29985 }
986}
987
[email protected]60507b12009-11-02 23:51:35988void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
989 int handle,
990 const gfx::Point& location) {
991 if (window_tracker_->ContainsHandle(handle))
992 ui_controls::SendMouseMove(location.x(), location.y());
993}
994
initial.commit09911bf2008-07-26 23:55:29995void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
996 int handle,
[email protected]bc1407f2009-09-29 00:33:35997 int key,
initial.commit09911bf2008-07-26 23:55:29998 int flags) {
[email protected]b410bc32009-08-14 01:11:14999 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291000 return;
1001
[email protected]b410bc32009-08-14 01:11:141002 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291003 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351004 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381005 ((flags & views::Event::EF_CONTROL_DOWN) ==
1006 views::Event::EF_CONTROL_DOWN),
1007 ((flags & views::Event::EF_SHIFT_DOWN) ==
1008 views::Event::EF_SHIFT_DOWN),
1009 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301010 views::Event::EF_ALT_DOWN),
1011 ((flags & views::Event::EF_COMMAND_DOWN) ==
1012 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291013}
initial.commit09911bf2008-07-26 23:55:291014
[email protected]71f65dd2009-02-11 19:14:561015void AutomationProvider::IsWindowActive(int handle, bool* success,
1016 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291017 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171018 *is_active =
1019 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561020 *success = true;
initial.commit09911bf2008-07-26 23:55:291021 } else {
[email protected]71f65dd2009-02-11 19:14:561022 *success = false;
1023 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291024 }
1025}
1026
[email protected]71f65dd2009-02-11 19:14:561027void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1028 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291029
1030 if (browser_tracker_->ContainsHandle(handle)) {
1031 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561032 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291033 }
initial.commit09911bf2008-07-26 23:55:291034}
1035
[email protected]982921f12009-10-27 21:43:531036void AutomationProvider::GetType(int handle, int* type_as_int) {
1037 *type_as_int = -1; // -1 is the error code
1038
1039 if (browser_tracker_->ContainsHandle(handle)) {
1040 Browser* browser = browser_tracker_->GetResource(handle);
1041 *type_as_int = static_cast<int>(browser->type());
1042 }
1043}
1044
[email protected]71f65dd2009-02-11 19:14:561045void AutomationProvider::GetTab(int win_handle, int tab_index,
1046 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561047 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291048 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1049 Browser* browser = browser_tracker_->GetResource(win_handle);
1050 if (tab_index < browser->tab_count()) {
1051 TabContents* tab_contents =
1052 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571053 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291054 }
1055 }
initial.commit09911bf2008-07-26 23:55:291056}
1057
[email protected]71f65dd2009-02-11 19:14:561058void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1059 std::wstring* title) {
1060 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291061 if (tab_tracker_->ContainsHandle(handle)) {
1062 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361063 NavigationEntry* entry = tab->GetActiveEntry();
1064 if (entry != NULL) {
1065 *title = UTF16ToWideHack(entry->title());
1066 } else {
1067 *title = std::wstring();
1068 }
[email protected]71f65dd2009-02-11 19:14:561069 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291070 }
initial.commit09911bf2008-07-26 23:55:291071}
1072
[email protected]77bc6732009-04-20 22:01:031073void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1074 *tabstrip_index = -1; // -1 is the error code
1075
1076 if (tab_tracker_->ContainsHandle(handle)) {
1077 NavigationController* tab = tab_tracker_->GetResource(handle);
1078 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121079 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031080 }
1081}
1082
initial.commit09911bf2008-07-26 23:55:291083void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1084 if (window_tracker_->ContainsHandle(handle)) {
1085 window_tracker_->Remove(window_tracker_->GetResource(handle));
1086 }
1087}
1088
1089void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161090 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571091 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291092}
1093
1094// TODO(brettw) change this to accept GURLs when history supports it
1095void AutomationProvider::OnRedirectQueryComplete(
1096 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371097 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291098 bool success,
[email protected]379c2b12009-07-01 21:50:331099 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291100 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561101 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291102
[email protected]deb57402009-02-06 01:35:301103 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101104 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291105 if (success) {
initial.commit09911bf2008-07-26 23:55:291106 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301107 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291108 }
1109
[email protected]4f3dc372009-02-24 00:10:291110 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301111
[email protected]71f65dd2009-02-11 19:14:561112 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231113 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561114 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291115}
1116
1117bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571118 DCHECK(channel_.get());
1119 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291120}
1121
1122Browser* AutomationProvider::FindAndActivateTab(
1123 NavigationController* controller) {
1124 int tab_index;
1125 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1126 if (browser)
1127 browser->SelectTabContentsAt(tab_index, true);
1128
1129 return browser;
1130}
1131
[email protected]71f65dd2009-02-11 19:14:561132void AutomationProvider::GetCookies(const GURL& url, int handle,
1133 int* value_size,
1134 std::string* value) {
1135 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291136 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1137 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311138
1139 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001140 scoped_refptr<URLRequestContextGetter> request_context =
1141 tab->tab_contents()->request_context();
1142 if (!request_context.get())
1143 request_context = tab->profile()->GetRequestContext();
1144
1145 net::CookieStore* cookie_store = request_context->GetCookieStore();
[email protected]be180c802009-10-23 06:33:311146
1147 *value = cookie_store->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561148 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291149 }
initial.commit09911bf2008-07-26 23:55:291150}
1151
[email protected]71f65dd2009-02-11 19:14:561152void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291153 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561154 int handle,
1155 int* response_value) {
1156 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291157
1158 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1159 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311160
[email protected]dfa46e5f2009-11-17 18:48:431161 scoped_refptr<URLRequestContextGetter> request_context =
1162 tab->tab_contents()->request_context();
1163 if (!request_context.get())
1164 request_context = tab->profile()->GetRequestContext();
1165
[email protected]be180c802009-10-23 06:33:311166 // Since we are running on the UI thread don't call GetURLRequestContext().
1167 scoped_refptr<net::CookieStore> cookie_store =
[email protected]dfa46e5f2009-11-17 18:48:431168 request_context->GetCookieStore();
[email protected]be180c802009-10-23 06:33:311169
1170 if (cookie_store->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561171 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291172 }
initial.commit09911bf2008-07-26 23:55:291173}
1174
[email protected]5fa57942010-04-21 23:07:221175void AutomationProvider::DeleteCookie(const GURL& url,
1176 const std::string& cookie_name,
1177 int handle, bool* success) {
1178 *success = false;
1179 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1180 NavigationController* tab = tab_tracker_->GetResource(handle);
1181 net::CookieStore* cookie_store =
1182 tab->profile()->GetRequestContext()->GetCookieStore();
1183 cookie_store->DeleteCookie(url, cookie_name);
1184 *success = true;
1185 }
1186}
1187
[email protected]71f65dd2009-02-11 19:14:561188void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1189 *success = false;
initial.commit09911bf2008-07-26 23:55:291190 if (tab_tracker_->ContainsHandle(handle)) {
1191 NavigationController* tab = tab_tracker_->GetResource(handle);
1192 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541193 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561194 *success = true;
initial.commit09911bf2008-07-26 23:55:291195 }
initial.commit09911bf2008-07-26 23:55:291196}
1197
[email protected]71f65dd2009-02-11 19:14:561198void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1199 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291200
1201 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561202 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341203 TabContents* tab_contents =
1204 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161205 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1206 if (rph)
1207 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291208 }
initial.commit09911bf2008-07-26 23:55:291209}
1210
1211void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331212 NOTREACHED() << "This function has been deprecated. "
1213 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291214}
1215
[email protected]71f65dd2009-02-11 19:14:561216void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291217 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561218 const std::wstring& script,
1219 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291220 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341221 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1222 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571223 // Set the routing id of this message with the controller.
1224 // This routing id needs to be remembered for the reverse
1225 // communication while sending back the response of
1226 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331227 std::wstring set_automation_id;
1228 SStringPrintf(&set_automation_id,
1229 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561230 reply_message->routing_id());
1231
1232 DCHECK(reply_message_ == NULL);
1233 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291234
[email protected]57c6a652009-05-04 07:58:341235 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331236 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341237 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061238 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571239 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291240 }
1241
1242 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561243 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1244 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291245 }
1246}
1247
[email protected]71f65dd2009-02-11 19:14:561248void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1249 *visible = false;
[email protected]20e93d12008-08-28 16:31:571250
[email protected]59560e0b2009-06-04 03:30:221251 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251252#if defined(OS_CHROMEOS)
1253 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1254 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1255 for (BrowserList::const_iterator it = BrowserList::begin();
1256 it != BrowserList::end(); ++it) {
1257 if ((*it)->type() == Browser::TYPE_POPUP) {
1258 const GURL& url =
1259 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1260
1261 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1262 url.host() == chrome::kChromeUIFileBrowseHost) {
1263 *visible = true;
1264 break;
1265 }
1266 }
1267 }
1268#else
[email protected]59560e0b2009-06-04 03:30:221269 Browser* browser = browser_tracker_->GetResource(handle);
1270 if (browser) {
1271 *visible = browser->window()->IsDownloadShelfVisible();
1272 }
[email protected]f5bf8ccf2010-02-05 18:19:251273#endif
[email protected]59560e0b2009-06-04 03:30:221274 }
initial.commit09911bf2008-07-26 23:55:291275}
1276
[email protected]59560e0b2009-06-04 03:30:221277void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1278 if (browser_tracker_->ContainsHandle(handle)) {
1279 Browser* browser = browser_tracker_->GetResource(handle);
1280 if (browser) {
1281 if (visible)
1282 browser->window()->GetDownloadShelf()->Show();
1283 else
1284 browser->window()->GetDownloadShelf()->Close();
1285 }
1286 }
1287}
1288
[email protected]34930432009-11-09 00:12:091289void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1290 *visible = false;
1291
1292 if (browser_tracker_->ContainsHandle(handle)) {
1293 Browser* browser = browser_tracker_->GetResource(handle);
1294 if (browser)
1295 *visible = browser->window()->IsFullscreen();
1296 }
1297}
1298
1299void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1300 bool* visible) {
1301 *visible = false;
1302
1303 if (browser_tracker_->ContainsHandle(handle)) {
1304 Browser* browser = browser_tracker_->GetResource(handle);
1305 if (browser)
1306 *visible = browser->window()->IsFullscreenBubbleVisible();
1307 }
1308}
[email protected]59560e0b2009-06-04 03:30:221309
[email protected]71f65dd2009-02-11 19:14:561310void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1311 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291312 if (tab_tracker_->ContainsHandle(handle)) {
1313 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111314 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291315 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561316 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291317 }
1318 }
initial.commit09911bf2008-07-26 23:55:291319}
1320
initial.commit09911bf2008-07-26 23:55:291321void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561322 int handle, const std::wstring& find_request,
1323 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311324 NOTREACHED() << "This function has been deprecated."
1325 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561326 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311327 return;
1328}
1329
[email protected]4f999132009-03-31 18:08:401330void AutomationProvider::HandleFindRequest(
1331 int handle,
1332 const AutomationMsg_Find_Params& params,
1333 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291334 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561335 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1336 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291337 return;
1338 }
1339
1340 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111341 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291342
1343 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141344 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291345
[email protected]57c6a652009-05-04 07:58:341346 tab_contents->set_current_find_request_id(
1347 FindInPageNotificationObserver::kFindInPageRequestId);
1348 tab_contents->render_view_host()->StartFinding(
1349 FindInPageNotificationObserver::kFindInPageRequestId,
1350 params.search_string, params.forward, params.match_case,
1351 params.find_next);
initial.commit09911bf2008-07-26 23:55:291352}
1353
[email protected]5f8af2a2008-08-06 22:49:451354void AutomationProvider::HandleOpenFindInPageRequest(
1355 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291356 if (browser_tracker_->ContainsHandle(handle)) {
1357 Browser* browser = browser_tracker_->GetResource(handle);
1358 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451359 }
1360}
1361
[email protected]71f65dd2009-02-11 19:14:561362void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561363 *visible = false;
[email protected]855c0142009-09-28 22:35:241364 Browser* browser = browser_tracker_->GetResource(handle);
1365 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581366 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171367 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241368 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291369 }
[email protected]20e93d12008-08-28 16:31:571370}
1371
[email protected]71f65dd2009-02-11 19:14:561372void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1373 int* y) {
[email protected]9e0534b2008-10-21 15:03:011374 gfx::Point position(0, 0);
1375 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291376 if (browser_tracker_->ContainsHandle(handle)) {
1377 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581378 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171379 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581380 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291381 }
[email protected]20e93d12008-08-28 16:31:571382
[email protected]71f65dd2009-02-11 19:14:561383 *x = position.x();
1384 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571385}
1386
[email protected]4512cb52010-04-05 19:50:251387// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1388// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581389void AutomationProvider::GetBookmarkBarVisibility(int handle,
1390 bool* visible,
1391 bool* animating) {
1392 *visible = false;
1393 *animating = false;
1394
1395 if (browser_tracker_->ContainsHandle(handle)) {
1396 Browser* browser = browser_tracker_->GetResource(handle);
1397 if (browser) {
[email protected]472f099b2010-05-27 17:07:121398#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1399 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1400
[email protected]ab6ca392010-04-07 00:44:131401 // IsBookmarkBarVisible() line looks correct but is not
1402 // consistent across platforms. Specifically, on Mac/Linux, it
1403 // returns false if the bar is hidden in a pref (even if visible
1404 // on the NTP). On ChromeOS, it returned true if on NTP
1405 // independent of the pref. Making the code more consistent
1406 // caused a perf bot regression on Windows (which shares views).
1407 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251408 *visible = browser->profile()->GetPrefs()->GetBoolean(
1409 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401410#else
1411 *visible = browser->window()->IsBookmarkBarVisible();
1412#endif
[email protected]c3240722010-03-05 21:52:581413 *animating = browser->window()->IsBookmarkBarAnimating();
1414 }
1415 }
1416}
1417
[email protected]6d8ffc9f2010-03-12 18:27:531418void AutomationProvider::GetBookmarksAsJSON(int handle,
1419 std::string* bookmarks_as_json,
1420 bool *success) {
1421 *success = false;
1422 if (browser_tracker_->ContainsHandle(handle)) {
1423 Browser* browser = browser_tracker_->GetResource(handle);
1424 if (browser) {
1425 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1426 return;
1427 }
1428 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1429 browser->profile(),
1430 browser->profile()->GetBookmarkModel());
1431 *success = storage->SerializeData(bookmarks_as_json);
1432 }
1433 }
1434}
1435
1436void AutomationProvider::WaitForBookmarkModelToLoad(
1437 int handle,
1438 IPC::Message* reply_message) {
1439 if (browser_tracker_->ContainsHandle(handle)) {
1440 Browser* browser = browser_tracker_->GetResource(handle);
1441 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1442 if (model->IsLoaded()) {
1443 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1444 reply_message, true);
1445 Send(reply_message);
1446 } else {
1447 // The observer will delete itself when done.
1448 new AutomationProviderBookmarkModelObserver(this, reply_message,
1449 model);
1450 }
1451 }
1452}
1453
1454void AutomationProvider::AddBookmarkGroup(int handle,
1455 int64 parent_id, int index,
1456 std::wstring title,
1457 bool* success) {
1458 if (browser_tracker_->ContainsHandle(handle)) {
1459 Browser* browser = browser_tracker_->GetResource(handle);
1460 if (browser) {
1461 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1462 if (!model->IsLoaded()) {
1463 *success = false;
1464 return;
1465 }
1466 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1467 DCHECK(parent);
1468 if (parent) {
1469 const BookmarkNode* child = model->AddGroup(parent, index,
1470 WideToUTF16(title));
1471 DCHECK(child);
1472 if (child)
1473 *success = true;
1474 }
1475 }
1476 }
1477 *success = false;
1478}
1479
1480void AutomationProvider::AddBookmarkURL(int handle,
1481 int64 parent_id, int index,
1482 std::wstring title, const GURL& url,
1483 bool* success) {
1484 if (browser_tracker_->ContainsHandle(handle)) {
1485 Browser* browser = browser_tracker_->GetResource(handle);
1486 if (browser) {
1487 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1488 if (!model->IsLoaded()) {
1489 *success = false;
1490 return;
1491 }
1492 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1493 DCHECK(parent);
1494 if (parent) {
1495 const BookmarkNode* child = model->AddURL(parent, index,
1496 WideToUTF16(title), url);
1497 DCHECK(child);
1498 if (child)
1499 *success = true;
1500 }
1501 }
1502 }
1503 *success = false;
1504}
1505
1506void AutomationProvider::ReparentBookmark(int handle,
1507 int64 id, int64 new_parent_id,
1508 int index,
1509 bool* success) {
1510 if (browser_tracker_->ContainsHandle(handle)) {
1511 Browser* browser = browser_tracker_->GetResource(handle);
1512 if (browser) {
1513 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1514 if (!model->IsLoaded()) {
1515 *success = false;
1516 return;
1517 }
1518 const BookmarkNode* node = model->GetNodeByID(id);
1519 DCHECK(node);
1520 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1521 DCHECK(new_parent);
1522 if (node && new_parent) {
1523 model->Move(node, new_parent, index);
1524 *success = true;
1525 }
1526 }
1527 }
1528 *success = false;
1529}
1530
1531void AutomationProvider::SetBookmarkTitle(int handle,
1532 int64 id, std::wstring title,
1533 bool* success) {
1534 if (browser_tracker_->ContainsHandle(handle)) {
1535 Browser* browser = browser_tracker_->GetResource(handle);
1536 if (browser) {
1537 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1538 if (!model->IsLoaded()) {
1539 *success = false;
1540 return;
1541 }
1542 const BookmarkNode* node = model->GetNodeByID(id);
1543 DCHECK(node);
1544 if (node) {
1545 model->SetTitle(node, WideToUTF16(title));
1546 *success = true;
1547 }
1548 }
1549 }
1550 *success = false;
1551}
1552
1553void AutomationProvider::SetBookmarkURL(int handle,
1554 int64 id, const GURL& url,
1555 bool* success) {
1556 if (browser_tracker_->ContainsHandle(handle)) {
1557 Browser* browser = browser_tracker_->GetResource(handle);
1558 if (browser) {
1559 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1560 if (!model->IsLoaded()) {
1561 *success = false;
1562 return;
1563 }
1564 const BookmarkNode* node = model->GetNodeByID(id);
1565 DCHECK(node);
1566 if (node) {
1567 model->SetURL(node, url);
1568 *success = true;
1569 }
1570 }
1571 }
1572 *success = false;
1573}
1574
1575void AutomationProvider::RemoveBookmark(int handle,
1576 int64 id,
1577 bool* success) {
1578 if (browser_tracker_->ContainsHandle(handle)) {
1579 Browser* browser = browser_tracker_->GetResource(handle);
1580 if (browser) {
1581 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1582 if (!model->IsLoaded()) {
1583 *success = false;
1584 return;
1585 }
1586 const BookmarkNode* node = model->GetNodeByID(id);
1587 DCHECK(node);
1588 if (node) {
1589 const BookmarkNode* parent = node->GetParent();
1590 DCHECK(parent);
1591 model->Remove(parent, parent->IndexOfChild(node));
1592 *success = true;
1593 }
1594 }
1595 }
1596 *success = false;
1597}
1598
[email protected]ef413ca2010-05-25 21:09:141599// Sample json input: { "command": "SetWindowDimensions",
1600// "x": 20, # optional
1601// "y": 20, # optional
1602// "width": 800, # optional
1603// "height": 600 } # optional
1604void AutomationProvider::SetWindowDimensions(Browser* browser,
1605 DictionaryValue* args,
1606 IPC::Message* reply_message) {
1607 gfx::Rect rect = browser->window()->GetRestoredBounds();
1608 int x, y, width, height;
1609 if (args->GetInteger(L"x", &x))
1610 rect.set_x(x);
1611 if (args->GetInteger(L"y", &y))
1612 rect.set_y(y);
1613 if (args->GetInteger(L"width", &width))
1614 rect.set_width(width);
1615 if (args->GetInteger(L"height", &height))
1616 rect.set_height(height);
1617 browser->window()->SetBounds(rect);
1618 AutomationMsg_SendJSONRequest::WriteReplyParams(
1619 reply_message, std::string("{}"), true);
1620 Send(reply_message);
1621}
1622
[email protected]a9ff2c02010-05-13 17:33:051623// Sample json input: { "command": "GetBrowserInfo" }
1624// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1625// sample json output.
[email protected]53329582010-05-14 21:10:581626void AutomationProvider::GetBrowserInfo(Browser* browser,
1627 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051628 IPC::Message* reply_message) {
1629 std::string json_return;
1630 bool reply_return = true;
1631
1632 DictionaryValue* properties = new DictionaryValue;
1633 properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
1634 properties->SetString(L"BrowserProcessExecutableName",
1635 chrome::kBrowserProcessExecutableName);
1636 properties->SetString(L"HelperProcessExecutableName",
1637 chrome::kHelperProcessExecutableName);
1638 properties->SetString(L"BrowserProcessExecutablePath",
1639 chrome::kBrowserProcessExecutablePath);
1640 properties->SetString(L"HelperProcessExecutablePath",
1641 chrome::kHelperProcessExecutablePath);
1642#if defined(OS_WIN)
1643 properties->SetString(L"command_line_string",
1644 CommandLine::ForCurrentProcess()->command_line_string());
1645#elif defined(OS_POSIX)
[email protected]ef413ca2010-05-25 21:09:141646 properties->SetString(L"command_line_string",
1647 JoinString(CommandLine::ForCurrentProcess()->argv(), ' '));
[email protected]a9ff2c02010-05-13 17:33:051648#endif
1649
1650 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1651 return_value->Set(L"properties", properties);
1652
[email protected]ef413ca2010-05-25 21:09:141653 return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
1654 // Add info about all windows in a list of dictionaries, one dictionary
1655 // item per window.
1656 ListValue* windows = new ListValue;
1657 int windex = 0;
1658 for (BrowserList::const_iterator it = BrowserList::begin();
1659 it != BrowserList::end();
1660 ++it, ++windex) {
1661 DictionaryValue* browser_item = new DictionaryValue;
1662 browser = *it;
1663 browser_item->SetInteger(L"index", windex);
1664 // Window properties
1665 gfx::Rect rect = browser->window()->GetRestoredBounds();
1666 browser_item->SetInteger(L"x", rect.x());
1667 browser_item->SetInteger(L"y", rect.y());
1668 browser_item->SetInteger(L"width", rect.width());
1669 browser_item->SetInteger(L"height", rect.height());
1670 browser_item->SetBoolean(L"fullscreen",
1671 browser->window()->IsFullscreen());
1672 browser_item->SetInteger(L"selected_tab", browser->selected_index());
1673 browser_item->SetBoolean(L"incognito",
1674 browser->profile()->IsOffTheRecord());
1675 // For each window, add info about all tabs in a list of dictionaries,
1676 // one dictionary item per tab.
1677 ListValue* tabs = new ListValue;
1678 for (int i = 0; i < browser->tab_count(); ++i) {
1679 TabContents* tc = browser->GetTabContentsAt(i);
1680 DictionaryValue* tab = new DictionaryValue;
1681 tab->SetInteger(L"index", i);
1682 tab->SetString(L"url", tc->GetURL().spec());
1683 tab->SetInteger(L"renderer_pid",
1684 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
1685 tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
1686 tabs->Append(tab);
1687 }
1688 browser_item->Set(L"tabs", tabs);
1689
1690 windows->Append(browser_item);
1691 }
1692 return_value->Set(L"windows", windows);
1693
1694 return_value->SetString(L"child_process_path",
1695 ChildProcessHost::GetChildPath(true).value());
1696 // Child processes are the processes for plugins and other workers.
1697 // Add all child processes in a list of dictionaries, one dictionary item
1698 // per child process.
1699 ListValue* child_processes = new ListValue;
1700 for (ChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1701 // Only add processes which are already started, since we need their handle.
1702 if ((*iter)->handle() != base::kNullProcessHandle) {
1703 ChildProcessInfo* info = *iter;
1704 DictionaryValue* item = new DictionaryValue;
1705 item->SetString(L"name", info->name());
1706 item->SetString(L"type",
1707 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
1708 item->SetInteger(L"pid", base::GetProcId(info->handle()));
1709 child_processes->Append(item);
1710 }
1711 }
1712 return_value->Set(L"child_processes", child_processes);
1713
1714 // Add all extension processes in a list of dictionaries, one dictionary
1715 // item per extension process.
1716 ListValue* extension_processes = new ListValue;
1717 ProfileManager* profile_manager = g_browser_process->profile_manager();
1718 for (ProfileManager::const_iterator it = profile_manager->begin();
1719 it != profile_manager->end(); ++it) {
1720 ExtensionProcessManager* process_manager =
1721 (*it)->GetExtensionProcessManager();
1722 ExtensionProcessManager::const_iterator jt;
1723 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1724 ExtensionHost* ex_host = *jt;
1725 // Don't add dead extension processes.
1726 if (!ex_host->IsRenderViewLive())
1727 continue;
1728 DictionaryValue* item = new DictionaryValue;
1729 item->SetString(L"name", ex_host->extension()->name());
1730 item->SetInteger(
1731 L"pid",
1732 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1733 extension_processes->Append(item);
1734 }
1735 }
1736 return_value->Set(L"extension_processes", extension_processes);
1737
[email protected]a9ff2c02010-05-13 17:33:051738 base::JSONWriter::Write(return_value.get(), false, &json_return);
1739 AutomationMsg_SendJSONRequest::WriteReplyParams(
1740 reply_message, json_return, reply_return);
1741 Send(reply_message);
1742}
1743
[email protected]24e2b102010-04-29 17:56:471744// Sample json input: { "command": "GetHistoryInfo",
1745// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361746// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581747void AutomationProvider::GetHistoryInfo(Browser* browser,
1748 DictionaryValue* args,
1749 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361750 consumer_.CancelAllRequests();
1751
1752 std::wstring search_text;
1753 args->GetString(L"search_text", &search_text);
1754
1755 // Fetch history.
1756 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1757 history::QueryOptions options;
1758 // The observer owns itself. It deletes itself after it fetches history.
1759 AutomationProviderHistoryObserver* history_observer =
1760 new AutomationProviderHistoryObserver(this, reply_message);
1761 hs->QueryHistory(
1762 search_text,
1763 options,
1764 &consumer_,
1765 NewCallback(history_observer,
1766 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1767}
1768
[email protected]bbe6aa02010-05-07 17:27:291769// Sample json input: { "command": "AddHistoryItem",
1770// "item": { "URL": "http://www.google.com",
1771// "title": "Google", # optional
1772// "time": 12345 # optional (time_t)
1773// } }
1774// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581775void AutomationProvider::AddHistoryItem(Browser* browser,
1776 DictionaryValue* args,
1777 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:291778 bool reply_return = true;
1779 std::string json_return = "{}";
1780
1781 DictionaryValue* item = NULL;
1782 args->GetDictionary(L"item", &item);
1783 string16 url_text;
1784 std::wstring title;
1785 base::Time time = base::Time::Now();
1786
1787 if (item->GetString("url", &url_text)) {
1788 GURL gurl(url_text);
1789 item->GetString(L"title", &title); // Don't care if it fails.
1790 int it;
1791 double dt;
1792 if (item->GetInteger(L"time", &it))
1793 time = base::Time::FromTimeT(it);
1794 else if (item->GetReal(L"time", &dt))
1795 time = base::Time::FromDoubleT(dt);
1796
1797 // Ideas for "dummy" values (e.g. id_scope) came from
1798 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1799 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1800 const void* id_scope = reinterpret_cast<void*>(1);
1801 hs->AddPage(gurl, time,
1802 id_scope,
1803 0,
1804 GURL(),
1805 PageTransition::LINK,
1806 history::RedirectList(),
1807 false);
1808 if (title.length()) {
1809 // TODO(jrg): add a string16 interface for
1810 // HistoryService::SetPageTitle(), then use it.
1811 hs->SetPageTitle(gurl, title);
1812 }
1813 } else {
1814 json_return = "{\"error\": \"bad args (no URL in dict?).\"}";
1815 reply_return = false;
1816 }
1817
1818 AutomationMsg_SendJSONRequest::WriteReplyParams(
1819 reply_message, json_return, reply_return);
1820 Send(reply_message);
1821}
1822
[email protected]24e2b102010-04-29 17:56:471823// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361824// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581825void AutomationProvider::GetDownloadsInfo(Browser* browser,
1826 DictionaryValue* args,
1827 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:391828 std::string json_return;
1829 bool reply_return = true;
1830 AutomationProviderDownloadManagerObserver observer;
1831 std::vector<DownloadItem*> downloads;
1832 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1833
1834 if (!profile_->HasCreatedDownloadManager()) {
[email protected]24e2b102010-04-29 17:56:471835 json_return = "{\"error\": \"no download manager\"}";
[email protected]d4adc292010-04-15 18:06:391836 reply_return = false;
1837 } else {
1838 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1839 // since that would be transient; a download might enter and empty out
1840 // the current download queue too soon to be noticed.
1841 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1842 downloads = observer.Downloads();
1843 }
1844
1845 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1846 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1847 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1848 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1849 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1850
1851 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1852 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1853 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1854 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1855 std::string("DANGEROUS_BUT_VALIDATED");
1856
1857 ListValue* list_of_downloads = new ListValue;
1858 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1859 it != downloads.end();
1860 it++) { // Fill info about each download item.
1861 DictionaryValue* dl_item_value = new DictionaryValue;
1862 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1863 dl_item_value->SetString(L"url", (*it)->url().spec());
1864 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1865 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1866 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
1867 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
1868 dl_item_value->SetBoolean(L"open_when_complete",
1869 (*it)->open_when_complete());
1870 dl_item_value->SetBoolean(L"is_extension_install",
1871 (*it)->is_extension_install());
1872 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
1873 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
1874 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
1875 dl_item_value->SetString(L"safety_state",
1876 safety_state_to_string[(*it)->safety_state()]);
1877 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
1878 list_of_downloads->Append(dl_item_value);
1879 }
1880 return_value->Set(L"downloads", list_of_downloads);
1881 base::JSONWriter::Write(return_value.get(), false, &json_return);
1882
1883 AutomationMsg_SendJSONRequest::WriteReplyParams(
1884 reply_message, json_return, reply_return);
1885 Send(reply_message);
1886 // All value objects allocated above are owned by |return_value|
1887 // and get freed by it.
1888}
1889
[email protected]59a611242010-04-02 02:24:041890void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:581891 Browser* browser,
[email protected]59a611242010-04-02 02:24:041892 DictionaryValue* args,
1893 IPC::Message* reply_message) {
1894 std::string json_return;
1895 bool reply_return = true;
1896 AutomationProviderDownloadManagerObserver observer;
1897 std::vector<DownloadItem*> downloads;
1898
1899 // Look for a quick return.
1900 if (!profile_->HasCreatedDownloadManager()) {
[email protected]24e2b102010-04-29 17:56:471901 json_return = "{\"error\": \"no download manager\"}";
[email protected]59a611242010-04-02 02:24:041902 reply_return = false;
1903 } else {
1904 profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
1905 FilePath());
1906 downloads = observer.Downloads();
1907 if (downloads.size() == 0) {
1908 json_return = "{}";
1909 }
1910 }
1911 if (!json_return.empty()) {
1912 AutomationMsg_SendJSONRequest::WriteReplyParams(
1913 reply_message, json_return, reply_return);
1914 Send(reply_message);
1915 }
1916
1917 // The observer owns itself. When the last observed item pings, it
1918 // deletes itself.
1919 AutomationProviderDownloadItemObserver* item_observer =
1920 new AutomationProviderDownloadItemObserver(
1921 this, reply_message, downloads.size());
1922 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
1923 i != downloads.end();
1924 i++) {
1925 (*i)->AddObserver(item_observer);
1926 }
1927}
1928
[email protected]24e2b102010-04-29 17:56:471929// Sample json input: { "command": "GetPrefsInfo" }
1930// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581931void AutomationProvider::GetPrefsInfo(Browser* browser,
1932 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471933 IPC::Message* reply_message) {
1934 std::string json_return;
1935 bool reply_return = true;
1936
1937 const PrefService::PreferenceSet& prefs =
1938 profile_->GetPrefs()->preference_set();
1939 DictionaryValue* items = new DictionaryValue;
1940 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
1941 it != prefs.end(); ++it) {
1942 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
1943 }
1944 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1945 return_value->Set(L"prefs", items); // return_value owns items.
1946
1947 base::JSONWriter::Write(return_value.get(), false, &json_return);
1948 AutomationMsg_SendJSONRequest::WriteReplyParams(
1949 reply_message, json_return, reply_return);
1950 Send(reply_message);
1951}
1952
1953// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:581954void AutomationProvider::SetPrefs(Browser* browser,
1955 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471956 IPC::Message* reply_message) {
1957 bool reply_return = true;
1958 std::string json_return = "{}";
1959 std::wstring path;
1960 Value* val;
1961 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
1962 PrefService* pref_service = profile_->GetPrefs();
1963 const PrefService::Preference* pref =
1964 pref_service->FindPreference(path.c_str());
1965 if (!pref) { // Not a registered pref.
1966 json_return = "{\"error\": \"pref not registered.\"}";
1967 reply_return = false;
1968 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
1969 json_return = "{\"error\": \"pref is managed. cannot be changed.\"}";
1970 reply_return = false;
1971 } else { // Set the pref.
1972 pref_service->Set(path.c_str(), *val);
1973 }
1974 } else {
1975 json_return = "{\"error\": \"no pref path or value given.\"}";
1976 reply_return = false;
1977 }
1978
1979 AutomationMsg_SendJSONRequest::WriteReplyParams(
1980 reply_message, json_return, reply_return);
1981 Send(reply_message);
1982}
1983
[email protected]53329582010-05-14 21:10:581984// Sample json input: { "command": "GetOmniboxInfo" }
1985// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
1986void AutomationProvider::GetOmniboxInfo(Browser* browser,
1987 DictionaryValue* args,
1988 IPC::Message* reply_message) {
1989 std::string json_return;
1990 bool reply_return = true;
1991 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1992
1993 LocationBar* loc_bar = browser->window()->GetLocationBar();
1994 AutocompleteEditView* edit_view = loc_bar->location_entry();
1995 AutocompleteEditModel* model = edit_view->model();
1996
1997 // Fill up matches.
1998 ListValue* matches = new ListValue;
1999 const AutocompleteResult& result = model->result();
2000 for (AutocompleteResult::const_iterator i = result.begin();
2001 i != result.end(); ++i) {
2002 const AutocompleteMatch& match = *i;
2003 DictionaryValue* item = new DictionaryValue; // owned by return_value
2004 item->SetString(L"type", AutocompleteMatch::TypeToString(match.type));
2005 item->SetBoolean(L"starred", match.starred);
2006 item->SetString(L"destination_url", match.destination_url.spec());
2007 item->SetString(L"contents", match.contents);
2008 item->SetString(L"description", match.description);
2009 matches->Append(item);
2010 }
2011 return_value->Set(L"matches", matches);
2012
2013 // Fill up other properties.
2014 DictionaryValue* properties = new DictionaryValue; // owned by return_value
2015 properties->SetBoolean(L"has_focus", model->has_focus());
2016 properties->SetBoolean(L"query_in_progress", model->query_in_progress());
2017 properties->SetString(L"keyword", model->keyword());
2018 properties->SetString(L"text", edit_view->GetText());
2019 return_value->Set(L"properties", properties);
2020
2021 base::JSONWriter::Write(return_value.get(), false, &json_return);
2022 AutomationMsg_SendJSONRequest::WriteReplyParams(
2023 reply_message, json_return, reply_return);
2024 Send(reply_message);
2025}
2026
2027// Sample json input: { "command": "SetOmniboxText",
2028// "text": "goog" }
2029void AutomationProvider::SetOmniboxText(Browser* browser,
2030 DictionaryValue* args,
2031 IPC::Message* reply_message) {
2032 std::string json_return = "{}";
2033 bool reply_return = true;
2034 std::wstring text;
2035
2036 if (!args->GetString(L"text", &text)) {
2037 json_return = "{\"error\": \"text missing\"}";
2038 reply_return = false;
2039 } else {
2040 browser->FocusLocationBar();
2041 LocationBar* loc_bar = browser->window()->GetLocationBar();
2042 AutocompleteEditView* edit_view = loc_bar->location_entry();
2043 edit_view->model()->OnSetFocus(false);
2044 edit_view->SetUserText(text);
2045 }
2046
2047 AutomationMsg_SendJSONRequest::WriteReplyParams(
2048 reply_message, json_return, reply_return);
2049 Send(reply_message);
2050}
2051
2052// Sample json input: { "command": "OmniboxMovePopupSelection",
2053// "count": 1 }
2054// Negative count implies up, positive implies down. Count values will be
2055// capped by the size of the popup list.
2056void AutomationProvider::OmniboxMovePopupSelection(
2057 Browser* browser,
2058 DictionaryValue* args,
2059 IPC::Message* reply_message) {
2060 std::string json_return = "{}";
2061 bool reply_return = true;
2062 int count;
2063
2064 if (!args->GetInteger(L"count", &count)) {
2065 json_return = "{\"error\": \"count missing\"}";
2066 reply_return = false;
2067 } else {
2068 LocationBar* loc_bar = browser->window()->GetLocationBar();
2069 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2070 model->OnUpOrDownKeyPressed(count);
2071 }
2072
2073 AutomationMsg_SendJSONRequest::WriteReplyParams(
2074 reply_message, json_return, reply_return);
2075 Send(reply_message);
2076}
2077
2078// Sample json input: { "command": "OmniboxAcceptInput" }
2079void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2080 DictionaryValue* args,
2081 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282082 NavigationController& controller =
2083 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122084 // Setup observer to wait until the selected item loads.
2085 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282086 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122087 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582088
2089 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582090}
2091
[email protected]f7d48012010-05-06 08:17:052092// Sample json input: { "command": "GetPluginsInfo" }
2093// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582094void AutomationProvider::GetPluginsInfo(Browser* browser,
2095 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052096 IPC::Message* reply_message) {
2097 std::string json_return;
2098 bool reply_return = true;
2099
2100 std::vector<WebPluginInfo> plugins;
2101 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2102 ListValue* items = new ListValue;
2103 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2104 it != plugins.end();
2105 ++it) {
2106 DictionaryValue* item = new DictionaryValue;
2107 item->SetString(L"name", it->name);
2108 item->SetString(L"path", it->path.value());
2109 item->SetString(L"version", it->version);
2110 item->SetString(L"desc", it->desc);
2111 item->SetBoolean(L"enabled", it->enabled);
2112 // Add info about mime types.
2113 ListValue* mime_types = new ListValue();
2114 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2115 it->mime_types.begin();
2116 type_it != it->mime_types.end();
2117 ++type_it) {
2118 DictionaryValue* mime_type = new DictionaryValue();
2119 mime_type->SetString(L"mimeType", type_it->mime_type);
2120 mime_type->SetString(L"description", type_it->description);
2121
2122 ListValue* file_extensions = new ListValue();
2123 for (std::vector<std::string>::const_iterator ext_it =
2124 type_it->file_extensions.begin();
2125 ext_it != type_it->file_extensions.end();
2126 ++ext_it) {
2127 file_extensions->Append(new StringValue(*ext_it));
2128 }
2129 mime_type->Set(L"fileExtensions", file_extensions);
2130
2131 mime_types->Append(mime_type);
2132 }
2133 item->Set(L"mimeTypes", mime_types);
2134 items->Append(item);
2135 }
2136 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2137 return_value->Set(L"plugins", items); // return_value owns items.
2138
2139 base::JSONWriter::Write(return_value.get(), false, &json_return);
2140 AutomationMsg_SendJSONRequest::WriteReplyParams(
2141 reply_message, json_return, reply_return);
2142 Send(reply_message);
2143}
2144
2145// Sample json input:
2146// { "command": "EnablePlugin",
2147// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582148void AutomationProvider::EnablePlugin(Browser* browser,
2149 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052150 IPC::Message* reply_message) {
2151 std::string json_return = "{}";
2152 bool reply_return = true;
2153 FilePath::StringType path;
2154 if (!args->GetString(L"path", &path)) {
2155 json_return = "{\"error\": \"path not specified.\"}";
2156 reply_return = false;
2157 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
2158 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2159 " for path %s.\"}", path.c_str());
2160 reply_return = false;
2161 }
2162
2163 AutomationMsg_SendJSONRequest::WriteReplyParams(
2164 reply_message, json_return, reply_return);
2165 Send(reply_message);
2166}
2167
2168// Sample json input:
2169// { "command": "DisablePlugin",
2170// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582171void AutomationProvider::DisablePlugin(Browser* browser,
2172 DictionaryValue* args,
2173 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052174 std::string json_return = "{}";
2175 bool reply_return = true;
2176 FilePath::StringType path;
2177 if (!args->GetString(L"path", &path)) {
2178 json_return = "{\"error\": \"path not specified.\"}";
2179 reply_return = false;
2180 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
2181 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2182 " for path %s.\"}", path.c_str());
2183 reply_return = false;
2184 }
2185
2186 AutomationMsg_SendJSONRequest::WriteReplyParams(
2187 reply_message, json_return, reply_return);
2188 Send(reply_message);
2189}
2190
[email protected]53329582010-05-14 21:10:582191void AutomationProvider::SendJSONRequest(int handle,
2192 std::string json_request,
2193 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042194 Browser* browser = NULL;
2195 std::string error_string;
2196 scoped_ptr<Value> values;
2197
2198 // Basic error checking.
2199 if (browser_tracker_->ContainsHandle(handle)) {
2200 browser = browser_tracker_->GetResource(handle);
2201 }
2202 if (!browser) {
2203 error_string = "no browser object";
2204 } else {
2205 base::JSONReader reader;
2206 std::string error;
[email protected]ba399672010-04-06 15:42:392207 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
[email protected]59a611242010-04-02 02:24:042208 if (!error.empty()) {
2209 error_string = error;
2210 }
2211 }
2212
2213 // Make sure input is a dict with a string command.
2214 std::string command;
2215 DictionaryValue* dict_value = NULL;
2216 if (error_string.empty()) {
2217 if (values->GetType() != Value::TYPE_DICTIONARY) {
2218 error_string = "not a dict or no command key in dict";
2219 } else {
2220 // Ownership remains with "values" variable.
2221 dict_value = static_cast<DictionaryValue*>(values.get());
2222 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2223 error_string = "no command key in dict or not a string command";
2224 }
2225 }
2226 }
2227
[email protected]24e2b102010-04-29 17:56:472228 // Map json commands to their handlers.
2229 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052230 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2231 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2232 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2233
[email protected]a9ff2c02010-05-13 17:33:052234 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
2235
[email protected]24e2b102010-04-29 17:56:472236 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292237 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052238
[email protected]53329582010-05-14 21:10:582239 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2240 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2241 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2242 handler_map["OmniboxMovePopupSelection"] =
2243 &AutomationProvider::OmniboxMovePopupSelection;
2244
[email protected]24e2b102010-04-29 17:56:472245 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2246 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052247
[email protected]ef413ca2010-05-25 21:09:142248 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2249
[email protected]f7d48012010-05-06 08:17:052250 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472251 handler_map["WaitForAllDownloadsToComplete"] =
2252 &AutomationProvider::WaitForDownloadsToComplete;
2253
[email protected]59a611242010-04-02 02:24:042254 if (error_string.empty()) {
[email protected]24e2b102010-04-29 17:56:472255 if (handler_map.find(std::string(command)) != handler_map.end()) {
[email protected]53329582010-05-14 21:10:582256 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]59a611242010-04-02 02:24:042257 return;
2258 } else {
[email protected]24e2b102010-04-29 17:56:472259 error_string = "Unknown command. Options: ";
2260 for (std::map<std::string, JsonHandler>::const_iterator it =
2261 handler_map.begin(); it != handler_map.end(); ++it) {
2262 error_string += it->first + ", ";
2263 }
[email protected]59a611242010-04-02 02:24:042264 }
2265 }
2266
2267 // If we hit an error, return info.
[email protected]24e2b102010-04-29 17:56:472268 // Return a dict of {"error", "descriptive_string_for_error"}.
[email protected]59a611242010-04-02 02:24:042269 // Else return an empty dict.
2270 std::string json_string;
2271 bool success = true;
2272 if (!error_string.empty()) {
2273 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
2274 dict->SetString(L"error", error_string);
2275 base::JSONWriter::Write(dict.get(), false, &json_string);
2276 success = false;
2277 } else {
2278 json_string = "{}";
2279 }
2280 AutomationMsg_SendJSONRequest::WriteReplyParams(
2281 reply_message, json_string, success);
2282 Send(reply_message);
2283}
2284
initial.commit09911bf2008-07-26 23:55:292285void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562286 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342287 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2288 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562289 DCHECK(reply_message_ == NULL);
2290 reply_message_ = reply_message;
2291
[email protected]d9f9b792009-06-24 13:17:122292 DevToolsManager::GetInstance()->InspectElement(
2293 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292294 } else {
[email protected]71f65dd2009-02-11 19:14:562295 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2296 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292297 }
2298}
2299
2300void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092301 if (reply_message_) {
2302 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2303 num_resources);
2304 Send(reply_message_);
2305 reply_message_ = NULL;
2306 }
initial.commit09911bf2008-07-26 23:55:292307}
2308
[email protected]a7eee32f2009-05-22 18:08:172309class SetProxyConfigTask : public Task {
2310 public:
[email protected]be180c802009-10-23 06:33:312311 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2312 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252313 : request_context_getter_(request_context_getter),
2314 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172315 virtual void Run() {
2316 // First, deserialize the JSON string. If this fails, log and bail.
2317 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392318 std::string error_msg;
2319 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172320 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2321 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392322 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172323 return;
2324 }
2325
2326 scoped_ptr<DictionaryValue> dict(
2327 static_cast<DictionaryValue*>(root.release()));
2328 // Now put together a proxy configuration from the deserialized string.
2329 net::ProxyConfig pc;
2330 PopulateProxyConfig(*dict.get(), &pc);
2331
[email protected]be180c802009-10-23 06:33:312332 net::ProxyService* proxy_service =
2333 request_context_getter_->GetURLRequestContext()->proxy_service();
2334 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172335 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2336 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312337 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172338 }
2339
2340 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2341 DCHECK(pc);
2342 bool no_proxy = false;
2343 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2344 // Make no changes to the ProxyConfig.
2345 return;
2346 }
2347 bool auto_config;
2348 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482349 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172350 }
2351 std::string pac_url;
2352 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482353 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172354 }
2355 std::string proxy_bypass_list;
2356 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482357 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172358 }
2359 std::string proxy_server;
2360 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482361 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172362 }
2363 }
2364
2365 private:
[email protected]be180c802009-10-23 06:33:312366 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172367 std::string proxy_config_;
2368};
2369
2370
2371void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312372 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2373 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172374 FilePath user_data_dir;
2375 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2376 ProfileManager* profile_manager = g_browser_process->profile_manager();
2377 DCHECK(profile_manager);
2378 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2379 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312380 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172381 }
[email protected]be180c802009-10-23 06:33:312382 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172383
[email protected]fae20792009-10-28 20:31:582384 ChromeThread::PostTask(
2385 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312386 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172387}
2388
[email protected]4f3dc372009-02-24 00:10:292389void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332390 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292391 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292392 if (tab_tracker_->ContainsHandle(handle)) {
2393 NavigationController* tab = tab_tracker_->GetResource(handle);
2394 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2395 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332396 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292397 }
initial.commit09911bf2008-07-26 23:55:292398}
2399
[email protected]6a5670d22009-10-27 16:21:342400void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142401 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532402 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2403 reply_message);
2404}
2405
2406void AutomationProvider::OpenNewBrowserWindowOfType(
2407 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:142408 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292409 // We may have no current browser windows open so don't rely on
2410 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:532411 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
2412 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:052413 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152414 if (show)
[email protected]15952e462008-11-14 00:29:052415 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292416}
2417
[email protected]71f65dd2009-02-11 19:14:562418void AutomationProvider::GetWindowForBrowser(int browser_handle,
2419 bool* success,
2420 int* handle) {
2421 *success = false;
2422 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292423
2424 if (browser_tracker_->ContainsHandle(browser_handle)) {
2425 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202426 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292427 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202428 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562429 *success = true;
initial.commit09911bf2008-07-26 23:55:292430 }
initial.commit09911bf2008-07-26 23:55:292431}
2432
2433void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562434 int browser_handle,
2435 bool* success,
2436 int* autocomplete_edit_handle) {
2437 *success = false;
2438 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292439
2440 if (browser_tracker_->ContainsHandle(browser_handle)) {
2441 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062442 LocationBar* loc_bar = browser->window()->GetLocationBar();
2443 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292444 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562445 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2446 *success = true;
initial.commit09911bf2008-07-26 23:55:292447 }
initial.commit09911bf2008-07-26 23:55:292448}
initial.commit09911bf2008-07-26 23:55:292449
[email protected]71f65dd2009-02-11 19:14:562450void AutomationProvider::ShowInterstitialPage(int tab_handle,
2451 const std::string& html_text,
2452 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292453 if (tab_tracker_->ContainsHandle(tab_handle)) {
2454 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112455 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402456
[email protected]7dad3d5f2010-03-04 00:27:012457 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:402458 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342459 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402460 GURL("about:interstitial"),
2461 html_text);
2462 interstitial->Show();
2463 return;
initial.commit09911bf2008-07-26 23:55:292464 }
[email protected]71f65dd2009-02-11 19:14:562465
[email protected]457f5cf2009-08-18 16:37:522466 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2467 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562468 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292469}
2470
[email protected]71f65dd2009-02-11 19:14:562471void AutomationProvider::HideInterstitialPage(int tab_handle,
2472 bool* success) {
2473 *success = false;
[email protected]57c6a652009-05-04 07:58:342474 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2475 if (tab_contents && tab_contents->interstitial_page()) {
2476 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562477 *success = true;
initial.commit09911bf2008-07-26 23:55:292478 }
initial.commit09911bf2008-07-26 23:55:292479}
2480
[email protected]71f65dd2009-02-11 19:14:562481void AutomationProvider::CloseTab(int tab_handle,
2482 bool wait_until_closed,
2483 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292484 if (tab_tracker_->ContainsHandle(tab_handle)) {
2485 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2486 int index;
2487 Browser* browser = Browser::GetBrowserForController(controller, &index);
2488 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142489 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112490 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452491 return;
initial.commit09911bf2008-07-26 23:55:292492 }
[email protected]de246f52009-02-25 18:25:452493
2494 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:552495 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292496}
2497
[email protected]71f65dd2009-02-11 19:14:562498void AutomationProvider::CloseBrowser(int browser_handle,
2499 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292500 if (browser_tracker_->ContainsHandle(browser_handle)) {
2501 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562502 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562503 reply_message);
[email protected]f3e99e32008-07-30 04:48:392504 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292505 } else {
2506 NOTREACHED();
2507 }
2508}
2509
[email protected]71f65dd2009-02-11 19:14:562510void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2511 if (browser_tracker_->ContainsHandle(browser_handle)) {
2512 Browser* browser = browser_tracker_->GetResource(browser_handle);
2513 browser->window()->Close();
2514 } else {
2515 NOTREACHED();
2516 }
2517}
2518
[email protected]71f65dd2009-02-11 19:14:562519void AutomationProvider::NavigateInExternalTab(
[email protected]b36a9f92009-10-19 17:34:572520 int handle, const GURL& url, const GURL& referrer,
[email protected]71f65dd2009-02-11 19:14:562521 AutomationMsg_NavigationResponseValues* status) {
2522 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292523
2524 if (tab_tracker_->ContainsHandle(handle)) {
2525 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]b36a9f92009-10-19 17:34:572526 tab->LoadURL(url, referrer, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562527 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292528 }
initial.commit09911bf2008-07-26 23:55:292529}
2530
[email protected]4150ef02009-08-19 23:14:262531void AutomationProvider::NavigateExternalTabAtIndex(
2532 int handle, int navigation_index,
2533 AutomationMsg_NavigationResponseValues* status) {
2534 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
2535
2536 if (tab_tracker_->ContainsHandle(handle)) {
2537 NavigationController* tab = tab_tracker_->GetResource(handle);
2538 tab->GoToIndex(navigation_index);
2539 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
2540 }
2541}
2542
[email protected]71f65dd2009-02-11 19:14:562543void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2544 IPC::Message* reply_message) {
2545 if (tab_tracker_->ContainsHandle(tab_handle)) {
2546 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2547 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142548 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562549 }
2550}
2551
[email protected]71f65dd2009-02-11 19:14:562552void AutomationProvider::GetSecurityState(int handle, bool* success,
2553 SecurityStyle* security_style,
2554 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:482555 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:292556 if (tab_tracker_->ContainsHandle(handle)) {
2557 NavigationController* tab = tab_tracker_->GetResource(handle);
2558 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562559 *success = true;
2560 *security_style = entry->ssl().security_style();
2561 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:482562 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292563 } else {
[email protected]71f65dd2009-02-11 19:14:562564 *success = false;
2565 *security_style = SECURITY_STYLE_UNKNOWN;
2566 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:482567 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292568 }
2569}
2570
[email protected]71f65dd2009-02-11 19:14:562571void AutomationProvider::GetPageType(int handle, bool* success,
2572 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292573 if (tab_tracker_->ContainsHandle(handle)) {
2574 NavigationController* tab = tab_tracker_->GetResource(handle);
2575 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562576 *page_type = entry->page_type();
2577 *success = true;
initial.commit09911bf2008-07-26 23:55:292578 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342579 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562580 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342581 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562582 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292583 } else {
[email protected]71f65dd2009-02-11 19:14:562584 *success = false;
2585 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292586 }
2587}
2588
[email protected]84abba62009-10-07 17:01:442589void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
2590 int* duration_ms) {
2591 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
2592 event_name);
2593}
2594
[email protected]71f65dd2009-02-11 19:14:562595void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2596 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292597 if (tab_tracker_->ContainsHandle(handle)) {
2598 NavigationController* tab = tab_tracker_->GetResource(handle);
2599 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072600 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402601 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472602 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342603 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292604 if (ssl_blocking_page) {
2605 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:012606 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:562607 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292608 return;
2609 }
2610 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522611 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2612 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562613 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292614 return;
2615 }
2616 }
2617 }
2618 // We failed.
[email protected]457f5cf2009-08-18 16:37:522619 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2620 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562621 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292622}
2623
[email protected]71f65dd2009-02-11 19:14:562624void AutomationProvider::BringBrowserToFront(int browser_handle,
2625 bool* success) {
initial.commit09911bf2008-07-26 23:55:292626 if (browser_tracker_->ContainsHandle(browser_handle)) {
2627 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062628 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562629 *success = true;
initial.commit09911bf2008-07-26 23:55:292630 } else {
[email protected]71f65dd2009-02-11 19:14:562631 *success = false;
initial.commit09911bf2008-07-26 23:55:292632 }
2633}
2634
[email protected]71f65dd2009-02-11 19:14:562635void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2636 int message_num,
2637 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292638 if (browser_tracker_->ContainsHandle(browser_handle)) {
2639 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562640 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142641 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292642 } else {
[email protected]71f65dd2009-02-11 19:14:562643 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292644 }
2645}
2646
[email protected]71f65dd2009-02-11 19:14:562647void AutomationProvider::PrintNow(int tab_handle,
2648 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572649 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342650 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2651 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292652 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572653 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142654 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342655 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572656 return;
initial.commit09911bf2008-07-26 23:55:292657 }
[email protected]71f65dd2009-02-11 19:14:562658 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2659 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292660}
[email protected]d301c952009-07-13 15:02:412661
[email protected]71f65dd2009-02-11 19:14:562662void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:112663 const FilePath& file_name,
2664 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:562665 int type,
2666 bool* success) {
initial.commit09911bf2008-07-26 23:55:292667 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562668 *success = false;
initial.commit09911bf2008-07-26 23:55:292669 return;
2670 }
2671
2672 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2673 Browser* browser = FindAndActivateTab(nav);
2674 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142675 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562676 *success = false;
initial.commit09911bf2008-07-26 23:55:292677 return;
2678 }
2679
initial.commit09911bf2008-07-26 23:55:292680 SavePackage::SavePackageType save_type =
2681 static_cast<SavePackage::SavePackageType>(type);
2682 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2683 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342684 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292685
[email protected]71f65dd2009-02-11 19:14:562686 *success = true;
initial.commit09911bf2008-07-26 23:55:292687}
2688
[email protected]71f65dd2009-02-11 19:14:562689void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2690 bool* success,
2691 std::wstring* text) {
2692 *success = false;
initial.commit09911bf2008-07-26 23:55:292693 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562694 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522695 GetText();
[email protected]71f65dd2009-02-11 19:14:562696 *success = true;
initial.commit09911bf2008-07-26 23:55:292697 }
initial.commit09911bf2008-07-26 23:55:292698}
2699
[email protected]71f65dd2009-02-11 19:14:562700void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2701 const std::wstring& text,
2702 bool* success) {
2703 *success = false;
initial.commit09911bf2008-07-26 23:55:292704 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522705 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2706 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562707 *success = true;
initial.commit09911bf2008-07-26 23:55:292708 }
initial.commit09911bf2008-07-26 23:55:292709}
2710
2711void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562712 int autocomplete_edit_handle,
2713 bool* success,
2714 std::vector<AutocompleteMatchData>* matches) {
2715 *success = false;
initial.commit09911bf2008-07-26 23:55:292716 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272717 const AutocompleteResult& result = autocomplete_edit_tracker_->
2718 GetResource(autocomplete_edit_handle)->model()->result();
2719 for (AutocompleteResult::const_iterator i = result.begin();
2720 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562721 matches->push_back(AutocompleteMatchData(*i));
2722 *success = true;
initial.commit09911bf2008-07-26 23:55:292723 }
initial.commit09911bf2008-07-26 23:55:292724}
2725
2726void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562727 int autocomplete_edit_handle,
2728 bool* success,
2729 bool* query_in_progress) {
2730 *success = false;
2731 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292732 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562733 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522734 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562735 *success = true;
initial.commit09911bf2008-07-26 23:55:292736 }
initial.commit09911bf2008-07-26 23:55:292737}
2738
[email protected]63514af2010-03-30 17:17:232739#if !defined(OS_MACOSX)
[email protected]28790922009-03-09 19:48:372740void AutomationProvider::OnMessageFromExternalHost(int handle,
2741 const std::string& message,
2742 const std::string& origin,
2743 const std::string& target) {
[email protected]f7a68432009-07-29 23:18:192744 RenderViewHost* view_host = GetViewForTab(handle);
2745 if (!view_host) {
2746 return;
[email protected]fa83e762008-08-15 21:41:392747 }
[email protected]f7a68432009-07-29 23:18:192748
2749 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
2750 view_host, message, origin, target)) {
2751 // Message was diverted.
2752 return;
2753 }
2754
2755 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
2756 origin, target, this, view_host, handle)) {
2757 // Message was diverted.
2758 return;
2759 }
2760
2761 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
2762 // Message was diverted.
2763 return;
2764 }
2765
2766 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392767}
[email protected]a9024892009-06-16 23:13:552768
2769bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2770 const std::string& message, const std::string& origin,
2771 const std::string& target) {
2772 if (target !=
2773 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2774 return false;
2775
2776 if (origin != extension_automation_constants::kAutomationOrigin) {
2777 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2778 return false;
2779 }
2780
2781 // The message is a JSON-encoded array with two elements, both strings. The
2782 // first is the name of the event to dispatch. The second is a JSON-encoding
2783 // of the arguments specific to that event.
[email protected]93d49d72009-10-23 20:00:202784 scoped_ptr<Value> message_value(base::JSONReader::Read(message, false));
[email protected]a9024892009-06-16 23:13:552785 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2786 LOG(WARNING) << "Invalid browser event specified through automation";
2787 return false;
2788 }
2789
2790 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2791
2792 std::string event_name;
2793 if (!args->GetString(0, &event_name)) {
2794 LOG(WARNING) << "No browser event name specified through automation";
2795 return false;
2796 }
2797
2798 std::string json_args;
2799 if (!args->GetString(1, &json_args)) {
2800 LOG(WARNING) << "No browser event args specified through automation";
2801 return false;
2802 }
2803
[email protected]7120f132009-07-20 21:05:372804 if (profile()->GetExtensionMessageService()) {
[email protected]db7331a2010-02-25 22:10:502805 profile()->GetExtensionMessageService()->DispatchEventToRenderers(
[email protected]a807bbe2010-04-14 10:51:192806 event_name, json_args, profile()->IsOffTheRecord(), GURL());
[email protected]7120f132009-07-20 21:05:372807 }
[email protected]a9024892009-06-16 23:13:552808
2809 return true;
2810}
[email protected]5ae5bed2009-08-21 18:52:442811#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:392812
[email protected]57c6a652009-05-04 07:58:342813TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572814 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572815 if (tab_tracker_->ContainsHandle(handle)) {
2816 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342817 if (tab)
2818 *tab = nav_controller;
2819 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572820 }
[email protected]57c6a652009-05-04 07:58:342821 return NULL;
[email protected]20e93d12008-08-28 16:31:572822}
2823
initial.commit09911bf2008-07-26 23:55:292824TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2825 : AutomationProvider(profile) {
2826 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142827 registrar_.Add(this, NotificationType::SESSION_END,
2828 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292829}
2830
2831TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292832 BrowserList::RemoveObserver(this);
2833}
2834
2835void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:142836 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:292837 AutomationProvider::OnChannelError();
2838}
2839
2840void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2841 // For backwards compatibility with the testing automation interface, we
2842 // want the automation provider (and hence the process) to go away when the
2843 // last browser goes away.
2844 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292845 // If you change this, update Observer for NotificationType::SESSION_END
2846 // below.
[email protected]295039bd2008-08-15 04:32:572847 MessageLoop::current()->PostTask(FROM_HERE,
2848 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292849 }
2850}
2851
2852void TestingAutomationProvider::Observe(NotificationType type,
2853 const NotificationSource& source,
2854 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562855 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292856 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2857 // before the task runs resulting in this object not being deleted. This
2858 // Release balance out the Release scheduled by OnBrowserRemoving.
2859 Release();
2860}
[email protected]295039bd2008-08-15 04:32:572861
2862void TestingAutomationProvider::OnRemoveProvider() {
2863 AutomationProviderList::GetInstance()->RemoveProvider(this);
2864}
[email protected]8a3422c92008-09-24 17:42:422865
[email protected]816633a2009-11-11 21:48:182866void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:562867 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422868 if (tab_tracker_->ContainsHandle(handle)) {
2869 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342870 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112871 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422872 }
[email protected]8a3422c92008-09-24 17:42:422873}
2874
[email protected]816633a2009-11-11 21:48:182875void AutomationProvider::ClickInfoBarAccept(int handle,
2876 int info_bar_index,
2877 bool wait_for_navigation,
2878 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422879 bool success = false;
2880 if (tab_tracker_->ContainsHandle(handle)) {
2881 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2882 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112883 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422884 if (info_bar_index >= 0 && info_bar_index < count) {
2885 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:012886 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:422887 }
[email protected]eb9ba192008-12-02 02:41:342888 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112889 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342890 info_bar_index);
2891 if (delegate->AsConfirmInfoBarDelegate())
2892 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422893 success = true;
2894 }
2895 }
[email protected]4f3dc372009-02-24 00:10:292896 }
[email protected]58f622a62009-10-04 01:17:552897
2898 // This "!wait_for_navigation || !success condition" logic looks suspicious.
2899 // It will send a failure message when success is true but
2900 // |wait_for_navigation| is false.
2901 // TODO(phajdan.jr): investgate whether the reply param (currently
2902 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:422903 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:182904 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:522905 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422906}
2907
[email protected]71f65dd2009-02-11 19:14:562908void AutomationProvider::GetLastNavigationTime(int handle,
2909 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422910 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562911 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422912}
2913
[email protected]71f65dd2009-02-11 19:14:562914void AutomationProvider::WaitForNavigation(int handle,
2915 int64 last_navigation_time,
2916 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:252917 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:422918 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:252919
[email protected]8a3422c92008-09-24 17:42:422920 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562921 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522922 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
2923 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:552924 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:292925 return;
[email protected]8a3422c92008-09-24 17:42:422926 }
2927
[email protected]7dad3d5f2010-03-04 00:27:012928 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:422929}
2930
[email protected]71f65dd2009-02-11 19:14:562931void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162932 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562933 int value,
2934 bool* success) {
2935 *success = false;
[email protected]8a3422c92008-09-24 17:42:422936 if (browser_tracker_->ContainsHandle(handle)) {
2937 Browser* browser = browser_tracker_->GetResource(handle);
2938 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562939 *success = true;
[email protected]8a3422c92008-09-24 17:42:422940 }
[email protected]8a3422c92008-09-24 17:42:422941}
[email protected]97fa6ce32008-12-19 01:48:162942
[email protected]71f65dd2009-02-11 19:14:562943void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162944 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562945 const std::wstring& value,
2946 bool* success) {
2947 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162948 if (browser_tracker_->ContainsHandle(handle)) {
2949 Browser* browser = browser_tracker_->GetResource(handle);
2950 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562951 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162952 }
[email protected]97fa6ce32008-12-19 01:48:162953}
2954
[email protected]71f65dd2009-02-11 19:14:562955void AutomationProvider::GetBooleanPreference(int handle,
2956 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:362957 bool* success,
2958 bool* value) {
[email protected]71f65dd2009-02-11 19:14:562959 *success = false;
2960 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162961 if (browser_tracker_->ContainsHandle(handle)) {
2962 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562963 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2964 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162965 }
[email protected]97fa6ce32008-12-19 01:48:162966}
2967
[email protected]71f65dd2009-02-11 19:14:562968void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162969 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562970 bool value,
2971 bool* success) {
2972 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162973 if (browser_tracker_->ContainsHandle(handle)) {
2974 Browser* browser = browser_tracker_->GetResource(handle);
2975 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562976 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162977 }
[email protected]97fa6ce32008-12-19 01:48:162978}
2979
2980// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562981void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:402982 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162983 if (tab_tracker_->ContainsHandle(tab_handle)) {
2984 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2985 Browser* browser = FindAndActivateTab(nav);
2986 DCHECK(browser);
2987
[email protected]57c6a652009-05-04 07:58:342988 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2989 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162990 }
[email protected]97fa6ce32008-12-19 01:48:162991}
2992
[email protected]b8f48d12009-11-09 20:14:362993// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562994void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:402995 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:562996 bool* success) {
2997 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162998 if (tab_tracker_->ContainsHandle(tab_handle)) {
2999 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193000 if (!nav)
3001 return;
[email protected]97fa6ce32008-12-19 01:48:163002 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163003
[email protected]2f2afba2010-04-01 01:53:193004 // If the browser has UI, simulate what a user would do.
3005 // Activate the tab and then click the encoding menu.
3006 if (browser &&
3007 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163008 int selected_encoding_id =
3009 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3010 if (selected_encoding_id) {
3011 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563012 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163013 }
[email protected]2f2afba2010-04-01 01:53:193014 } else {
3015 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3016 // Try to get TabContents and call its override_encoding method.
3017 TabContents* contents = nav->tab_contents();
3018 if (!contents)
3019 return;
3020 const std::string selected_encoding =
3021 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
3022 if (selected_encoding.empty())
3023 return;
3024 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163025 }
3026 }
[email protected]97fa6ce32008-12-19 01:48:163027}
[email protected]5bcdb312009-01-07 21:43:203028
[email protected]4d434a1a2009-02-11 21:06:573029void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203030 SavePackage::SetShouldPromptUser(should_prompt);
3031}
[email protected]87eab222009-03-13 00:47:453032
[email protected]66ba4932009-06-04 19:22:133033void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3034 *count = -1; // -1 is the error code
3035 if (tab_tracker_->ContainsHandle(handle)) {
3036 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3037 TabContents* tab_contents = nav_controller->tab_contents();
3038 if (tab_contents) {
3039 BlockedPopupContainer* container =
3040 tab_contents->blocked_popup_container();
3041 if (container) {
3042 *count = static_cast<int>(container->GetBlockedPopupCount());
3043 } else {
3044 // If we don't have a container, we don't have any blocked popups to
3045 // contain!
3046 *count = 0;
3047 }
3048 }
3049 }
3050}
[email protected]f7a68432009-07-29 23:18:193051
3052void AutomationProvider::SelectAll(int tab_handle) {
3053 RenderViewHost* view = GetViewForTab(tab_handle);
3054 if (!view) {
3055 NOTREACHED();
3056 return;
3057 }
3058
3059 view->SelectAll();
3060}
3061
3062void AutomationProvider::Cut(int tab_handle) {
3063 RenderViewHost* view = GetViewForTab(tab_handle);
3064 if (!view) {
3065 NOTREACHED();
3066 return;
3067 }
3068
3069 view->Cut();
3070}
3071
3072void AutomationProvider::Copy(int tab_handle) {
3073 RenderViewHost* view = GetViewForTab(tab_handle);
3074 if (!view) {
3075 NOTREACHED();
3076 return;
3077 }
3078
3079 view->Copy();
3080}
3081
3082void AutomationProvider::Paste(int tab_handle) {
3083 RenderViewHost* view = GetViewForTab(tab_handle);
3084 if (!view) {
3085 NOTREACHED();
3086 return;
3087 }
3088
3089 view->Paste();
3090}
3091
3092void AutomationProvider::ReloadAsync(int tab_handle) {
3093 if (tab_tracker_->ContainsHandle(tab_handle)) {
3094 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3095 if (!tab) {
3096 NOTREACHED();
3097 return;
3098 }
3099
[email protected]106a0812010-03-18 00:15:123100 const bool check_for_repost = true;
3101 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193102 }
3103}
3104
3105void AutomationProvider::StopAsync(int tab_handle) {
3106 RenderViewHost* view = GetViewForTab(tab_handle);
3107 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363108 // We tolerate StopAsync being called even before a view has been created.
3109 // So just log a warning instead of a NOTREACHED().
3110 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193111 return;
3112 }
3113
3114 view->Stop();
3115}
3116
[email protected]1bb5f892009-10-06 01:44:573117void AutomationProvider::OnSetPageFontSize(int tab_handle,
3118 int font_size) {
3119 AutomationPageFontSize automation_font_size =
3120 static_cast<AutomationPageFontSize>(font_size);
3121
3122 if (automation_font_size < SMALLEST_FONT ||
3123 automation_font_size > LARGEST_FONT) {
3124 DLOG(ERROR) << "Invalid font size specified : "
3125 << font_size;
3126 return;
3127 }
3128
3129 if (tab_tracker_->ContainsHandle(tab_handle)) {
3130 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3131 DCHECK(tab != NULL);
3132 if (tab && tab->tab_contents()) {
3133 DCHECK(tab->tab_contents()->profile() != NULL);
3134 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3135 prefs::kWebKitDefaultFontSize, font_size);
3136 }
3137 }
3138}
3139
[email protected]bc73b4e52010-03-26 04:16:203140void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3141 BrowsingDataRemover* remover;
3142 remover = new BrowsingDataRemover(profile(),
3143 BrowsingDataRemover::EVERYTHING, // All time periods.
3144 base::Time());
3145 remover->Remove(remove_mask);
3146 // BrowsingDataRemover deletes itself.
3147}
[email protected]1bb5f892009-10-06 01:44:573148
[email protected]2949e90d2009-08-21 15:32:523149void AutomationProvider::WaitForBrowserWindowCountToBecome(
3150 int target_count, IPC::Message* reply_message) {
3151 if (static_cast<int>(BrowserList::size()) == target_count) {
3152 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3153 reply_message, true);
3154 Send(reply_message);
3155 return;
3156 }
3157
3158 // Set up an observer (it will delete itself).
3159 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3160}
3161
3162void AutomationProvider::WaitForAppModalDialogToBeShown(
3163 IPC::Message* reply_message) {
3164 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3165 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3166 reply_message, true);
3167 Send(reply_message);
3168 return;
3169 }
3170
3171 // Set up an observer (it will delete itself).
3172 new AppModalDialogShownObserver(this, reply_message);
3173}
3174
[email protected]1126a1d32009-08-26 15:39:263175void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3176 int handle, int number_of_navigations, IPC::Message* reply_message) {
3177 if (tab_tracker_->ContainsHandle(handle)) {
3178 NavigationController* tab = tab_tracker_->GetResource(handle);
3179 Browser* browser = FindAndActivateTab(tab);
3180 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013181 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3182 false);
[email protected]1126a1d32009-08-26 15:39:263183 browser->GoBack(CURRENT_TAB);
3184 return;
3185 }
3186 }
3187
3188 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3189 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3190 Send(reply_message);
3191}
3192
3193void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3194 int handle, int number_of_navigations, IPC::Message* reply_message) {
3195 if (tab_tracker_->ContainsHandle(handle)) {
3196 NavigationController* tab = tab_tracker_->GetResource(handle);
3197 Browser* browser = FindAndActivateTab(tab);
3198 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013199 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3200 false);
[email protected]1126a1d32009-08-26 15:39:263201 browser->GoForward(CURRENT_TAB);
3202 return;
3203 }
3204 }
3205
3206 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3207 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3208 Send(reply_message);
3209}
3210
[email protected]f7a68432009-07-29 23:18:193211RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3212 if (tab_tracker_->ContainsHandle(tab_handle)) {
3213 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3214 if (!tab) {
3215 NOTREACHED();
3216 return NULL;
3217 }
3218
3219 TabContents* tab_contents = tab->tab_contents();
3220 if (!tab_contents) {
3221 NOTREACHED();
3222 return NULL;
3223 }
3224
3225 RenderViewHost* view_host = tab_contents->render_view_host();
3226 return view_host;
3227 }
3228
3229 return NULL;
3230}
[email protected]675595f2009-08-26 22:32:043231
3232void AutomationProvider::GetBrowserForWindow(int window_handle,
3233 bool* success,
3234 int* browser_handle) {
3235 *success = false;
3236 *browser_handle = 0;
3237
3238 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3239 if (!window)
3240 return;
3241
3242 BrowserList::const_iterator iter = BrowserList::begin();
3243 for (;iter != BrowserList::end(); ++iter) {
3244 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3245 if (window == this_window) {
3246 // Add() returns the existing handle for the resource if any.
3247 *browser_handle = browser_tracker_->Add(*iter);
3248 *success = true;
3249 return;
3250 }
3251 }
3252}
[email protected]d11c8e92009-10-20 23:26:403253
3254void AutomationProvider::InstallExtension(const FilePath& crx_path,
3255 IPC::Message* reply_message) {
3256 ExtensionsService* service = profile_->GetExtensionsService();
3257 if (service) {
3258 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193259 new ExtensionInstallNotificationObserver(this,
3260 AutomationMsg_InstallExtension::ID,
3261 reply_message);
[email protected]d11c8e92009-10-20 23:26:403262
3263 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163264 scoped_refptr<CrxInstaller> installer(
3265 new CrxInstaller(install_dir,
3266 service,
3267 NULL)); // silent install, no UI
3268 installer->set_allow_privilege_increase(true);
3269 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403270 } else {
3271 AutomationMsg_InstallExtension::WriteReplyParams(
3272 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3273 Send(reply_message);
3274 }
3275}
3276
3277void AutomationProvider::LoadExpandedExtension(
3278 const FilePath& extension_dir,
3279 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383280 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403281 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193282 new ExtensionInstallNotificationObserver(
3283 this,
3284 AutomationMsg_LoadExpandedExtension::ID,
3285 reply_message);
[email protected]d11c8e92009-10-20 23:26:403286
3287 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403288 } else {
3289 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3290 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3291 Send(reply_message);
3292 }
3293}
[email protected]673fd2c02010-02-04 23:10:003294
[email protected]a1e62d12010-03-16 02:18:433295void AutomationProvider::GetEnabledExtensions(
3296 std::vector<FilePath>* result) {
3297 ExtensionsService* service = profile_->GetExtensionsService();
3298 DCHECK(service);
3299 if (service->extensions_enabled()) {
3300 const ExtensionList* extensions = service->extensions();
3301 DCHECK(extensions);
3302 for (size_t i = 0; i < extensions->size(); ++i) {
3303 Extension* extension = (*extensions)[i];
3304 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123305 if (extension->location() == Extension::INTERNAL ||
3306 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073307 result->push_back(extension->path());
3308 }
[email protected]a1e62d12010-03-16 02:18:433309 }
3310 }
3311}
3312
[email protected]790788ac2010-04-06 17:52:193313void AutomationProvider::WaitForExtensionTestResult(
3314 IPC::Message* reply_message) {
3315 DCHECK(reply_message_ == NULL);
3316 reply_message_ = reply_message;
3317 // Call MaybeSendResult, because the result might have come in before
3318 // we were waiting on it.
3319 extension_test_result_observer_->MaybeSendResult();
3320}
3321
3322void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093323 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193324 ExtensionsService* service = profile_->GetExtensionsService();
3325 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3326 if (service && manager) {
3327 // The observer will delete itself when done.
3328 new ExtensionReadyNotificationObserver(
3329 manager,
3330 this,
3331 AutomationMsg_InstallExtensionAndGetHandle::ID,
3332 reply_message);
3333
[email protected]d7e5525d2010-04-20 14:37:093334 ExtensionInstallUI* client =
3335 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193336 scoped_refptr<CrxInstaller> installer(
3337 new CrxInstaller(service->install_directory(),
3338 service,
[email protected]d7e5525d2010-04-20 14:37:093339 client));
[email protected]790788ac2010-04-06 17:52:193340 installer->set_allow_privilege_increase(true);
3341 installer->InstallCrx(crx_path);
3342 } else {
3343 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3344 reply_message, 0);
3345 Send(reply_message);
3346 }
3347}
3348
3349void AutomationProvider::UninstallExtension(int extension_handle,
3350 bool* success) {
3351 *success = false;
3352 Extension* extension = GetExtension(extension_handle);
3353 ExtensionsService* service = profile_->GetExtensionsService();
3354 if (extension && service) {
3355 ExtensionUnloadNotificationObserver observer;
3356 service->UninstallExtension(extension->id(), false);
3357 // The extension unload notification should have been sent synchronously
3358 // with the uninstall. Just to be safe, check that it was received.
3359 *success = observer.did_receive_unload_notification();
3360 }
3361}
3362
3363void AutomationProvider::EnableExtension(int extension_handle,
3364 IPC::Message* reply_message) {
3365 Extension* extension = GetDisabledExtension(extension_handle);
3366 ExtensionsService* service = profile_->GetExtensionsService();
3367 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3368 // Only enable if this extension is disabled.
3369 if (extension && service && manager) {
3370 // The observer will delete itself when done.
3371 new ExtensionReadyNotificationObserver(
3372 manager,
3373 this,
3374 AutomationMsg_EnableExtension::ID,
3375 reply_message);
3376 service->EnableExtension(extension->id());
3377 } else {
3378 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3379 Send(reply_message);
3380 }
3381}
3382
3383void AutomationProvider::DisableExtension(int extension_handle,
3384 bool* success) {
3385 *success = false;
3386 Extension* extension = GetEnabledExtension(extension_handle);
3387 ExtensionsService* service = profile_->GetExtensionsService();
3388 if (extension && service) {
3389 ExtensionUnloadNotificationObserver observer;
3390 service->DisableExtension(extension->id());
3391 // The extension unload notification should have been sent synchronously
3392 // with the disable. Just to be safe, check that it was received.
3393 *success = observer.did_receive_unload_notification();
3394 }
3395}
3396
3397void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3398 int extension_handle, int browser_handle,
3399 IPC::Message* reply_message) {
3400 bool success = false;
3401 Extension* extension = GetEnabledExtension(extension_handle);
3402 ExtensionsService* service = profile_->GetExtensionsService();
3403 ExtensionMessageService* message_service =
3404 profile_->GetExtensionMessageService();
3405 Browser* browser = browser_tracker_->GetResource(browser_handle);
3406 if (extension && service && message_service && browser) {
3407 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3408 if (extension->page_action()) {
3409 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3410 browser->profile(), extension->id(), "action", tab_id, "", 1);
3411 success = true;
3412 } else if (extension->browser_action()) {
3413 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3414 browser->profile(), extension->id(), browser);
3415 success = true;
3416 }
3417 }
3418 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3419 reply_message, success);
3420 Send(reply_message);
3421}
3422
3423void AutomationProvider::MoveExtensionBrowserAction(
3424 int extension_handle, int index, bool* success) {
3425 *success = false;
3426 Extension* extension = GetEnabledExtension(extension_handle);
3427 ExtensionsService* service = profile_->GetExtensionsService();
3428 if (extension && service) {
3429 ExtensionToolbarModel* toolbar = service->toolbar_model();
3430 if (toolbar) {
3431 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3432 toolbar->MoveBrowserAction(extension, index);
3433 *success = true;
3434 } else {
3435 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3436 }
3437 }
3438 }
3439}
3440
3441void AutomationProvider::GetExtensionProperty(
3442 int extension_handle,
3443 AutomationMsg_ExtensionProperty type,
3444 bool* success,
3445 std::string* value) {
3446 *success = false;
3447 Extension* extension = GetExtension(extension_handle);
3448 ExtensionsService* service = profile_->GetExtensionsService();
3449 if (extension && service) {
3450 ExtensionToolbarModel* toolbar = service->toolbar_model();
3451 int found_index = -1;
3452 int index = 0;
3453 switch (type) {
3454 case AUTOMATION_MSG_EXTENSION_ID:
3455 *value = extension->id();
3456 *success = true;
3457 break;
3458 case AUTOMATION_MSG_EXTENSION_NAME:
3459 *value = extension->name();
3460 *success = true;
3461 break;
3462 case AUTOMATION_MSG_EXTENSION_VERSION:
3463 *value = extension->VersionString();
3464 *success = true;
3465 break;
3466 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3467 if (toolbar) {
3468 for (ExtensionList::const_iterator iter = toolbar->begin();
3469 iter != toolbar->end(); iter++) {
3470 // Skip this extension if we are in incognito mode
3471 // and it is not incognito-enabled.
3472 if (profile_->IsOffTheRecord() &&
3473 !service->IsIncognitoEnabled(*iter))
3474 continue;
3475 if (*iter == extension) {
3476 found_index = index;
3477 break;
3478 }
3479 index++;
3480 }
3481 *value = IntToString(found_index);
3482 *success = true;
3483 }
3484 break;
3485 default:
3486 LOG(WARNING) << "Trying to get undefined extension property";
3487 break;
3488 }
3489 }
3490}
3491
[email protected]673fd2c02010-02-04 23:10:003492void AutomationProvider::SaveAsAsync(int tab_handle) {
3493 NavigationController* tab = NULL;
3494 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3495 if (tab_contents)
3496 tab_contents->OnSavePage();
3497}
[email protected]7dad3d5f2010-03-04 00:27:013498
3499void AutomationProvider::SetContentSetting(
3500 int handle,
3501 const std::string& host,
3502 ContentSettingsType content_type,
3503 ContentSetting setting,
3504 bool* success) {
3505 *success = false;
3506 if (browser_tracker_->ContainsHandle(handle)) {
3507 Browser* browser = browser_tracker_->GetResource(handle);
3508 HostContentSettingsMap* map =
3509 browser->profile()->GetHostContentSettingsMap();
3510 if (host.empty()) {
3511 map->SetDefaultContentSetting(content_type, setting);
3512 } else {
[email protected]0314ae02010-04-08 09:18:293513 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
3514 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:013515 }
3516 *success = true;
3517 }
3518}
[email protected]cc824372010-03-31 15:33:013519
3520#if !defined(TOOLKIT_VIEWS)
3521void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
3522 NOTIMPLEMENTED();
3523};
3524
3525void AutomationProvider::WaitForFocusedViewIDToChange(
3526 int handle, int previous_view_id, IPC::Message* reply_message) {
3527 NOTIMPLEMENTED();
3528}
3529
3530void AutomationProvider::StartTrackingPopupMenus(
3531 int browser_handle, bool* success) {
3532 NOTIMPLEMENTED();
3533}
3534
3535void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
3536 NOTIMPLEMENTED();
3537}
3538#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:093539
3540void AutomationProvider::ResetToDefaultTheme() {
3541 profile_->ClearTheme();
3542}