blob: ed37ea400594efbc61a2876658dbdf824663b1b2 [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]37126212009-05-06 02:23:319#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5910#include "base/callback.h"
[email protected]7060bb292010-06-24 00:52:4911#include "base/file_path.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]93364da2010-06-29 18:03:4415#include "base/json/string_escape.h"
[email protected]bc1407f2009-09-29 00:33:3516#include "base/keyboard_codes.h"
[email protected]5fac9622009-02-04 21:49:3817#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/path_service.h"
[email protected]201b2732009-11-13 18:57:4619#include "base/process_util.h"
[email protected]f44265b2009-05-19 18:52:5020#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2721#include "base/string_util.h"
[email protected]9eaa18e2010-06-29 20:51:0122#include "base/task.h"
[email protected]5fac9622009-02-04 21:49:3823#include "base/thread.h"
[email protected]a872ea1f2010-08-11 04:45:3324#include "base/trace_event.h"
[email protected]528c56d2010-07-30 19:28:4425#include "base/string_number_conversions.h"
[email protected]6d8ffc9f2010-03-12 18:27:5326#include "base/utf_string_conversions.h"
[email protected]a7eee32f2009-05-22 18:08:1727#include "base/values.h"
[email protected]9eaa18e2010-06-29 20:51:0128#include "base/waitable_event.h"
[email protected]4f3dc372009-02-24 00:10:2929#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2830#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0931#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]55846ad842010-07-09 18:22:5632#include "chrome/browser/autofill/autofill_manager.h"
[email protected]679082052010-07-21 21:30:1333#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
34#include "chrome/browser/automation/automation_browser_tracker.h"
[email protected]790788ac2010-04-06 17:52:1935#include "chrome/browser/automation/automation_extension_tracker.h"
[email protected]7c983cc2010-07-16 11:33:3436#include "chrome/browser/automation/automation_provider_json.h"
initial.commit09911bf2008-07-26 23:55:2937#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0838#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]679082052010-07-21 21:30:1339#include "chrome/browser/automation/automation_resource_message_filter.h"
40#include "chrome/browser/automation/automation_tab_tracker.h"
41#include "chrome/browser/automation/automation_window_tracker.h"
[email protected]f44265b2009-05-19 18:52:5042#include "chrome/browser/automation/extension_port_container.h"
[email protected]12802702010-07-09 19:43:0943#include "chrome/browser/autocomplete/autocomplete_edit.h"
[email protected]66ba4932009-06-04 19:22:1344#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5345#include "chrome/browser/bookmarks/bookmark_model.h"
46#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1447#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0748#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3949#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2050#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0551#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5852#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2953#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1254#include "chrome/browser/debugger/devtools_manager.h"
[email protected]6c69796d2010-07-16 21:41:1655#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2256#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0557#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4058#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1959#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1460#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4061#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5562#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1963#include "chrome/browser/extensions/extension_tabs_module.h"
64#include "chrome/browser/extensions/extension_toolbar_model.h"
65#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1666#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5867#include "chrome/browser/find_bar.h"
68#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2969#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0170#include "chrome/browser/host_content_settings_map.h"
[email protected]c5aa5322010-07-15 19:00:0771#include "chrome/browser/importer/importer.h"
72#include "chrome/browser/importer/importer_data_types.h"
[email protected]0ac83682010-01-22 17:46:2773#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0674#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0175#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5376#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2477#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0878#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0579#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1780#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0781#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2582#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0383#include "chrome/browser/ssl/ssl_manager.h"
84#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]b5558cf22010-07-12 17:30:0685#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]57c6a652009-05-04 07:58:3486#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4587#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]38b5a3852010-07-21 06:49:5288#include "chrome/browser/translate/translate_infobar_delegate.h"
[email protected]a7eee32f2009-05-22 18:08:1789#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0590#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2991#include "chrome/common/chrome_paths.h"
[email protected]c984d9f2010-07-20 20:52:2092#include "chrome/common/chrome_switches.h"
[email protected]1eeb5e02010-07-20 23:02:1193#include "chrome/common/chrome_version_info.h"
[email protected]790788ac2010-04-06 17:52:1994#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1795#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5596#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1497#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5798#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2599#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:56100#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:57101#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:17102#include "net/proxy/proxy_service.h"
103#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:21104#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:30105#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:28106#include "views/event.h"
[email protected]5bcfe1672010-07-16 20:51:57107#include "webkit/glue/password_form.h"
[email protected]f7d48012010-05-06 08:17:05108#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:29109
[email protected]de246f52009-02-25 18:25:45110#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:35111#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:45112#endif // defined(OS_WIN)
113
[email protected]e1acf6f2008-10-27 20:43:33114using base::Time;
115
[email protected]cbab76d2008-10-13 22:42:47116class AutomationInterstitialPage : public InterstitialPage {
117 public:
[email protected]57c6a652009-05-04 07:58:34118 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47119 const GURL& url,
120 const std::string& contents)
121 : InterstitialPage(tab, true, url),
122 contents_(contents) {
123 }
124
125 virtual std::string GetHTMLContents() { return contents_; }
126
127 private:
128 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29129
[email protected]cbab76d2008-10-13 22:42:47130 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
131};
132
[email protected]c2cb8542009-08-20 21:16:51133class ClickTask : public Task {
134 public:
[email protected]fc2e0872009-08-21 22:14:41135 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51136 virtual ~ClickTask() {}
137
138 virtual void Run() {
139 ui_controls::MouseButton button = ui_controls::LEFT;
140 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
141 views::Event::EF_LEFT_BUTTON_DOWN) {
142 button = ui_controls::LEFT;
143 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
144 views::Event::EF_RIGHT_BUTTON_DOWN) {
145 button = ui_controls::RIGHT;
146 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
147 views::Event::EF_MIDDLE_BUTTON_DOWN) {
148 button = ui_controls::MIDDLE;
149 } else {
150 NOTREACHED();
151 }
152
[email protected]fc2e0872009-08-21 22:14:41153 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51154 }
155
156 private:
[email protected]c2cb8542009-08-20 21:16:51157 int flags_;
158
159 DISALLOW_COPY_AND_ASSIGN(ClickTask);
160};
[email protected]c2cb8542009-08-20 21:16:51161
initial.commit09911bf2008-07-26 23:55:29162AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57163 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56164 profile_(profile),
[email protected]cc824372010-03-31 15:33:01165 reply_message_(NULL),
166 popup_menu_waiter_(NULL) {
[email protected]a872ea1f2010-08-11 04:45:33167 TRACE_EVENT_BEGIN("AutomationProvider::AutomationProvider", 0, "");
168
initial.commit09911bf2008-07-26 23:55:29169 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19170 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29171 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20172 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29173 autocomplete_edit_tracker_.reset(
174 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29175 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
176 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44177 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19178 extension_test_result_observer_.reset(
179 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13180 g_browser_process->AddRefModule();
[email protected]a872ea1f2010-08-11 04:45:33181
182 TRACE_EVENT_END("AutomationProvider::AutomationProvider", 0, "");
initial.commit09911bf2008-07-26 23:55:29183}
184
185AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50186 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
187 port_containers_.end());
188 port_containers_.clear();
189
[email protected]0da050b92008-08-19 19:29:47190 // Make sure that any outstanding NotificationObservers also get destroyed.
191 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31192 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47193 while ((observer = it.GetNext()) != NULL)
194 delete observer;
[email protected]528211a2010-01-14 15:25:13195
196 if (channel_.get()) {
197 channel_->Close();
198 }
199 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29200}
201
[email protected]9a3a293b2009-06-04 22:28:16202void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]a872ea1f2010-08-11 04:45:33203 TRACE_EVENT_BEGIN("AutomationProvider::ConnectToChannel", 0, "");
204
[email protected]2e4633c2009-07-09 16:58:06205 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57206 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06207 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
208 automation_resource_message_filter_,
209 g_browser_process->io_thread()->message_loop(),
210 true, g_browser_process->shutdown_event()));
[email protected]1eeb5e02010-07-20 23:02:11211 scoped_ptr<FileVersionInfo> version_info(chrome::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40212 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43213 if (version_info != NULL) {
214 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40215 }
[email protected]c6cb1992009-04-13 16:45:29216
217 // Send a hello message with our current automation protocol version.
218 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
[email protected]a872ea1f2010-08-11 04:45:33219
220 TRACE_EVENT_END("AutomationProvider::ConnectToChannel", 0, "");
initial.commit09911bf2008-07-26 23:55:29221}
222
223void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
224 if (expected_tabs == 0) {
225 Send(new AutomationMsg_InitialLoadsComplete(0));
226 } else {
227 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
228 }
229}
230
231NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58232 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01233 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29234 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58235 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01236 number_of_navigations,
237 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29238
[email protected]71f65dd2009-02-11 19:14:56239 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29240 return observer;
241}
242
[email protected]faf2ee42010-05-11 14:26:17243void AutomationProvider::RemoveNavigationStatusListener(
244 NotificationObserver* obs) {
245 notification_observer_list_.RemoveObserver(obs);
246}
247
initial.commit09911bf2008-07-26 23:55:29248NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14249 Browser* parent,
250 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56251 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14252 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29253 notification_observer_list_.AddObserver(observer);
254
255 return observer;
256}
257
[email protected]faf2ee42010-05-11 14:26:17258void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29259 notification_observer_list_.RemoveObserver(obs);
260}
261
262void AutomationProvider::AddLoginHandler(NavigationController* tab,
263 LoginHandler* handler) {
264 login_handler_map_[tab] = handler;
265}
266
267void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
268 DCHECK(login_handler_map_[tab]);
269 login_handler_map_.erase(tab);
270}
271
[email protected]f44265b2009-05-19 18:52:50272void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
273 int port_id = port->port_id();
274 DCHECK_NE(-1, port_id);
275 DCHECK(port_containers_.find(port_id) == port_containers_.end());
276
277 port_containers_[port_id] = port;
278}
279
280void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
281 int port_id = port->port_id();
282 DCHECK_NE(-1, port_id);
283
284 PortContainerMap::iterator it = port_containers_.find(port_id);
285 DCHECK(it != port_containers_.end());
286
287 if (it != port_containers_.end()) {
288 delete it->second;
289 port_containers_.erase(it);
290 }
291}
292
293ExtensionPortContainer* AutomationProvider::GetPortContainer(
294 int port_id) const {
295 PortContainerMap::const_iterator it = port_containers_.find(port_id);
296 if (it == port_containers_.end())
297 return NULL;
298
299 return it->second;
300}
301
initial.commit09911bf2008-07-26 23:55:29302int AutomationProvider::GetIndexForNavigationController(
303 const NavigationController* controller, const Browser* parent) const {
304 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12305 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29306}
307
[email protected]790788ac2010-04-06 17:52:19308int AutomationProvider::AddExtension(Extension* extension) {
309 DCHECK(extension);
310 return extension_tracker_->Add(extension);
311}
312
313Extension* AutomationProvider::GetExtension(int extension_handle) {
314 return extension_tracker_->GetResource(extension_handle);
315}
316
317Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
318 Extension* extension = extension_tracker_->GetResource(extension_handle);
319 ExtensionsService* service = profile_->GetExtensionsService();
320 if (extension && service &&
321 service->GetExtensionById(extension->id(), false))
322 return extension;
323 return NULL;
324}
325
326Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
327 Extension* extension = extension_tracker_->GetResource(extension_handle);
328 ExtensionsService* service = profile_->GetExtensionsService();
329 if (extension && service &&
330 service->GetExtensionById(extension->id(), true) &&
331 !service->GetExtensionById(extension->id(), false))
332 return extension;
333 return NULL;
334}
335
initial.commit09911bf2008-07-26 23:55:29336void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
337 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14338 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56339 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
340 CloseBrowserAsync)
341 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
342 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
343 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
344 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
345 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
346 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22347 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]a503c97c2010-07-16 13:05:48348 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog,
349 ShowCollectedCookiesDialog)
[email protected]1c58a5c2009-05-21 18:47:14350 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58351 IPC_MESSAGE_HANDLER_DELAY_REPLY(
352 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
353 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56354 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11355 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
356 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56357 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
358 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
359 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
360 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14361 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56362 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
363 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
364 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14365 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29366 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
367 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56368 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36369 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56370 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29371 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56372 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29373 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
374 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56375 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14376 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24377 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44378 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33379 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44380 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33381 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24382 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14383 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24384 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15385 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14386 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24387 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35388 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14389 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30390#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56391 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
392 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30393#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56394 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53395 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56396 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37397#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56398 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45399#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56400 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
401 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03402 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56403 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14404 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09405 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
406 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
407 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29408 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14409 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56410 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
411 ExecuteJavascript)
412 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29413 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14414 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
415 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56416 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
417 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14418 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17419 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14420 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14421 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53422 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
423 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14424 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56425 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14426 GetAutocompleteEditForBrowser)
427 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56428 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14429 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56430 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14431 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56432 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
433 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14434 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
435 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44436 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
437 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56438 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
439 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29440 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
[email protected]bdb7ff62010-07-20 01:56:52441 IPC_MESSAGE_HANDLER(AutomationMsg_IsMenuCommandEnabled,
442 IsMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56443 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41444 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56445 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
446 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29447 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56448 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29449 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56450 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29451 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56452 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29453 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56454 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45455 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14456 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56457 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57458 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56459 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57460 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56461 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
462 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53463 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
464 GetBookmarksAsJSON)
465 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
466 WaitForBookmarkModelToLoad)
467 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
468 AddBookmarkGroup)
469 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
470 AddBookmarkURL)
471 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
472 ReparentBookmark)
473 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
474 SetBookmarkTitle)
475 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
476 SetBookmarkURL)
477 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
478 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04479 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
480 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18481 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
482 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
483 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56484 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42485 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56486 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
487 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14488 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56489 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44490 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56491 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20492 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14493 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56494 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16495 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56496 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16497 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56498 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16499 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14500 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20501 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
502 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14503 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22504 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13505 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19506 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
507 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
508 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
509 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
510 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
511 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52512 IPC_MESSAGE_HANDLER_DELAY_REPLY(
513 AutomationMsg_WaitForBrowserWindowCountToBecome,
514 WaitForBrowserWindowCountToBecome)
515 IPC_MESSAGE_HANDLER_DELAY_REPLY(
516 AutomationMsg_WaitForAppModalDialogToBeShown,
517 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26518 IPC_MESSAGE_HANDLER_DELAY_REPLY(
519 AutomationMsg_GoBackBlockUntilNavigationsComplete,
520 GoBackBlockUntilNavigationsComplete)
521 IPC_MESSAGE_HANDLER_DELAY_REPLY(
522 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
523 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57524 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40525 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
526 InstallExtension)
527 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
528 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43529 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
530 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19531 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
532 WaitForExtensionTestResult)
533 IPC_MESSAGE_HANDLER_DELAY_REPLY(
534 AutomationMsg_InstallExtensionAndGetHandle,
535 InstallExtensionAndGetHandle)
536 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
537 UninstallExtension)
538 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
539 EnableExtension)
540 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
541 DisableExtension)
542 IPC_MESSAGE_HANDLER_DELAY_REPLY(
543 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
544 ExecuteExtensionActionInActiveTabAsync)
545 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
546 MoveExtensionBrowserAction)
547 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
548 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57549 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
550 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00551 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01552 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20553 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00554 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01555#if defined(TOOLKIT_VIEWS)
556 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
557 WaitForFocusedViewIDToChange)
558 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
559 StartTrackingPopupMenus)
560 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
561 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00562#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52563#if defined(OS_WIN)
564 // These are for use with external tabs.
565 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
566 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
567 ProcessUnhandledAccelerator)
568 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
569 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
570 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
571 OnForwardContextMenuCommandToChrome)
572 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
573 NavigateInExternalTab)
574 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
575 NavigateExternalTabAtIndex)
576 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
577 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
578 SetEnableExtensionAutomation)
579 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
580 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00581 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
[email protected]1f71d5882010-07-15 20:39:07582 IPC_MESSAGE_HANDLER(AutomationMsg_RunUnloadHandlers, OnRunUnloadHandlers)
[email protected]7f860dd82010-08-09 23:18:05583 IPC_MESSAGE_HANDLER(AutomationMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]bdd5a9c92010-06-14 18:21:00584#endif // defined(OS_WIN)
585#if defined(OS_CHROMEOS)
586 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
587 LoginWithUserAndPass)
588#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29589 IPC_END_MESSAGE_MAP()
590}
591
[email protected]71f65dd2009-02-11 19:14:56592void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
593 *status = -1;
initial.commit09911bf2008-07-26 23:55:29594 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
595 Browser* browser = browser_tracker_->GetResource(handle);
596 if (at_index >= 0 && at_index < browser->tab_count()) {
597 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56598 *status = 0;
initial.commit09911bf2008-07-26 23:55:29599 }
600 }
initial.commit09911bf2008-07-26 23:55:29601}
602
[email protected]71f65dd2009-02-11 19:14:56603void AutomationProvider::AppendTab(int handle, const GURL& url,
604 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29605 int append_tab_response = -1; // -1 is the error code
606 NotificationObserver* observer = NULL;
607
608 if (browser_tracker_->ContainsHandle(handle)) {
609 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14610 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38611 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39612 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
[email protected]b283a7532010-08-12 21:24:59613 NULL, std::string(), &browser);
initial.commit09911bf2008-07-26 23:55:29614 if (tab_contents) {
615 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57616 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29617 }
618 }
619
620 if (append_tab_response < 0) {
621 // The append tab failed. Remove the TabStripObserver
622 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17623 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29624 delete observer;
625 }
626
[email protected]71f65dd2009-02-11 19:14:56627 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
628 append_tab_response);
629 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29630 }
631}
632
[email protected]71f65dd2009-02-11 19:14:56633void AutomationProvider::NavigateToURL(int handle, const GURL& url,
634 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58635 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
636}
637
638void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
639 int handle, const GURL& url, int number_of_navigations,
640 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29641 if (tab_tracker_->ContainsHandle(handle)) {
642 NavigationController* tab = tab_tracker_->GetResource(handle);
643
644 // Simulate what a user would do. Activate the tab and then navigate.
645 // We could allow navigating in a background tab in future.
646 Browser* browser = FindAndActivateTab(tab);
647
648 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01649 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
650 false);
[email protected]71f65dd2009-02-11 19:14:56651
initial.commit09911bf2008-07-26 23:55:29652 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50653 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29654 return;
655 }
656 }
[email protected]71f65dd2009-02-11 19:14:56657
658 AutomationMsg_NavigateToURL::WriteReplyParams(
659 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
660 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29661}
[email protected]2949e90d2009-08-21 15:32:52662
[email protected]c70f9b82010-04-21 07:31:11663void AutomationProvider::NavigationAsync(int handle,
664 const GURL& url,
665 bool* status) {
666 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
667}
668
669void AutomationProvider::NavigationAsyncWithDisposition(
670 int handle,
671 const GURL& url,
672 WindowOpenDisposition disposition,
673 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56674 *status = false;
initial.commit09911bf2008-07-26 23:55:29675
676 if (tab_tracker_->ContainsHandle(handle)) {
677 NavigationController* tab = tab_tracker_->GetResource(handle);
678
679 // Simulate what a user would do. Activate the tab and then navigate.
680 // We could allow navigating in a background tab in future.
681 Browser* browser = FindAndActivateTab(tab);
682
683 if (browser) {
684 // Don't add any listener unless a callback mechanism is desired.
685 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11686 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56687 *status = true;
initial.commit09911bf2008-07-26 23:55:29688 }
689 }
initial.commit09911bf2008-07-26 23:55:29690}
691
[email protected]71f65dd2009-02-11 19:14:56692void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29693 if (tab_tracker_->ContainsHandle(handle)) {
694 NavigationController* tab = tab_tracker_->GetResource(handle);
695 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14696 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01697 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29698 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29699 return;
700 }
701 }
[email protected]71f65dd2009-02-11 19:14:56702
703 AutomationMsg_GoBack::WriteReplyParams(
704 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
705 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29706}
707
[email protected]71f65dd2009-02-11 19:14:56708void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29709 if (tab_tracker_->ContainsHandle(handle)) {
710 NavigationController* tab = tab_tracker_->GetResource(handle);
711 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14712 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01713 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29714 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29715 return;
716 }
717 }
[email protected]71f65dd2009-02-11 19:14:56718
719 AutomationMsg_GoForward::WriteReplyParams(
720 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
721 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29722}
723
[email protected]71f65dd2009-02-11 19:14:56724void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29725 if (tab_tracker_->ContainsHandle(handle)) {
726 NavigationController* tab = tab_tracker_->GetResource(handle);
727 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14728 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01729 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28730 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29731 return;
732 }
733 }
[email protected]71f65dd2009-02-11 19:14:56734
735 AutomationMsg_Reload::WriteReplyParams(
736 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
737 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29738}
739
[email protected]71f65dd2009-02-11 19:14:56740void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29741 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56742 const std::wstring& password,
743 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29744 if (tab_tracker_->ContainsHandle(tab_handle)) {
745 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
746 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
747
748 if (iter != login_handler_map_.end()) {
749 // If auth is needed again after this, assume login has failed. This is
750 // not strictly correct, because a navigation can require both proxy and
751 // server auth, but it should be OK for now.
752 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01753 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29754 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52755 return;
initial.commit09911bf2008-07-26 23:55:29756 }
757 }
[email protected]de246f52009-02-25 18:25:45758
[email protected]457f5cf2009-08-18 16:37:52759 AutomationMsg_SetAuth::WriteReplyParams(
760 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
761 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29762}
763
[email protected]71f65dd2009-02-11 19:14:56764void AutomationProvider::CancelAuth(int tab_handle,
765 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29766 if (tab_tracker_->ContainsHandle(tab_handle)) {
767 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
768 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
769
770 if (iter != login_handler_map_.end()) {
771 // If auth is needed again after this, something is screwy.
772 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01773 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29774 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52775 return;
initial.commit09911bf2008-07-26 23:55:29776 }
777 }
[email protected]de246f52009-02-25 18:25:45778
[email protected]457f5cf2009-08-18 16:37:52779 AutomationMsg_CancelAuth::WriteReplyParams(
780 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
781 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29782}
783
[email protected]71f65dd2009-02-11 19:14:56784void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
785 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29786
787 if (tab_tracker_->ContainsHandle(tab_handle)) {
788 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
789 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
790
791 if (iter != login_handler_map_.end()) {
792 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56793 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29794 }
795 }
initial.commit09911bf2008-07-26 23:55:29796}
797
[email protected]71f65dd2009-02-11 19:14:56798void AutomationProvider::GetRedirectsFrom(int tab_handle,
799 const GURL& source_url,
800 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29801 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
802 if (tab_tracker_->ContainsHandle(tab_handle)) {
803 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
804 HistoryService* history_service =
805 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
806
807 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
808 "has no history service";
809 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56810 DCHECK(reply_message_ == NULL);
811 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29812 // Schedule a history query for redirects. The response will be sent
813 // asynchronously from the callback the history system uses to notify us
814 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29815 redirect_query_ = history_service->QueryRedirectsFrom(
816 source_url, &consumer_,
817 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
818 return; // Response will be sent when query completes.
819 }
820 }
821
822 // Send failure response.
[email protected]deb57402009-02-06 01:35:30823 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56824 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
825 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29826}
827
[email protected]71f65dd2009-02-11 19:14:56828void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
829 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29830 if (browser_tracker_->ContainsHandle(handle)) {
831 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56832 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29833 }
initial.commit09911bf2008-07-26 23:55:29834}
835
[email protected]202e7a72009-06-15 03:48:36836void AutomationProvider::GetBrowserLocale(string16* locale) {
837 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06838 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36839}
840
[email protected]71f65dd2009-02-11 19:14:56841void AutomationProvider::GetBrowserWindowCount(int* window_count) {
842 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29843}
844
[email protected]24497032009-05-01 17:00:29845void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
846 *window_count = static_cast<int>(
847 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
848}
849
[email protected]71f65dd2009-02-11 19:14:56850void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
851 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07852 AppModalDialog* dialog_delegate =
853 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50854 *showing_dialog = (dialog_delegate != NULL);
855 if (*showing_dialog)
856 *dialog_button = dialog_delegate->GetDialogButtons();
857 else
[email protected]478ff2ed2009-04-21 23:49:18858 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20859}
860
[email protected]71f65dd2009-02-11 19:14:56861void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
862 *success = false;
[email protected]fad84eab2008-12-05 00:37:20863
[email protected]1f460072009-05-28 17:02:07864 AppModalDialog* dialog_delegate =
865 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50866 if (dialog_delegate &&
867 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18868 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
869 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28870 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56871 *success = true;
[email protected]fad84eab2008-12-05 00:37:20872 }
[email protected]478ff2ed2009-04-21 23:49:18873 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
874 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56875 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28876 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56877 *success = true;
[email protected]fad84eab2008-12-05 00:37:20878 }
879 }
[email protected]c274acc2008-11-11 20:13:44880}
881
[email protected]fedaa7d2010-01-26 20:34:57882void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
883 if (browser_tracker_->ContainsHandle(handle)) {
884 Browser* browser = browser_tracker_->GetResource(handle);
885 browser->profile()->ShutdownSessionService();
886 *result = true;
887 } else {
888 *result = false;
889 }
890}
891
[email protected]71f65dd2009-02-11 19:14:56892void AutomationProvider::GetBrowserWindow(int index, int* handle) {
893 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29894 if (index >= 0) {
895 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30896 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29897 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56898 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29899 }
900 }
initial.commit09911bf2008-07-26 23:55:29901}
902
[email protected]24497032009-05-01 17:00:29903void AutomationProvider::FindNormalBrowserWindow(int* handle) {
904 *handle = 0;
905 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31906 Browser::TYPE_NORMAL,
907 false);
[email protected]24497032009-05-01 17:00:29908 if (browser)
909 *handle = browser_tracker_->Add(browser);
910}
911
[email protected]71f65dd2009-02-11 19:14:56912void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
913 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29914 Browser* browser = BrowserList::GetLastActive();
915 if (browser)
[email protected]71f65dd2009-02-11 19:14:56916 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29917}
918
[email protected]b2aa3ed72010-02-01 18:37:14919#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28920// TODO(estade): use this implementation for all platforms?
921void AutomationProvider::GetActiveWindow(int* handle) {
922 gfx::NativeWindow window =
923 BrowserList::GetLastActive()->window()->GetNativeHandle();
924 *handle = window_tracker_->Add(window);
925}
926#endif
927
[email protected]4f6381ee2009-04-16 02:46:33928void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
929 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56930 *success = false;
[email protected]4ae62752008-08-04 23:28:47931 if (browser_tracker_->ContainsHandle(handle)) {
932 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14933 if (browser->command_updater()->SupportsCommand(command) &&
934 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47935 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56936 *success = true;
[email protected]4ae62752008-08-04 23:28:47937 }
938 }
[email protected]4ae62752008-08-04 23:28:47939}
940
[email protected]4f6381ee2009-04-16 02:46:33941void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56942 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53943 // List of commands which just finish synchronously and don't require
944 // setting up an observer.
945 static const int kSynchronousCommands[] = {
946 IDC_HOME,
947 IDC_SELECT_NEXT_TAB,
948 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25949 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53950 };
[email protected]56e71b7c2009-03-27 03:05:56951 if (browser_tracker_->ContainsHandle(handle)) {
952 Browser* browser = browser_tracker_->GetResource(handle);
953 if (browser->command_updater()->SupportsCommand(command) &&
954 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53955 // First check if we can handle the command without using an observer.
956 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
957 if (command == kSynchronousCommands[i]) {
958 browser->ExecuteCommand(command);
959 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
960 true);
961 Send(reply_message);
962 return;
963 }
964 }
965
966 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42967 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
968 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27969 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42970 return;
971 }
[email protected]56e71b7c2009-03-27 03:05:56972 }
973 }
[email protected]49a14a82009-03-31 04:16:44974 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56975 Send(reply_message);
976}
977
[email protected]fc2e0872009-08-21 22:14:41978// This task just adds another task to the event queue. This is useful if
979// you want to ensure that any tasks added to the event queue after this one
980// have already been processed by the time |task| is run.
981class InvokeTaskLaterTask : public Task {
982 public:
983 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
984 virtual ~InvokeTaskLaterTask() {}
985
986 virtual void Run() {
987 MessageLoop::current()->PostTask(FROM_HERE, task_);
988 }
989
990 private:
991 Task* task_;
992
993 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
994};
995
initial.commit09911bf2008-07-26 23:55:29996void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
997 int handle,
[email protected]d1a5941e2009-08-13 23:34:24998 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29999 int flags) {
[email protected]b410bc32009-08-14 01:11:141000 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:511001 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:411002 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:291003 }
1004}
1005
[email protected]60507b12009-11-02 23:51:351006void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
1007 int handle,
1008 const gfx::Point& location) {
1009 if (window_tracker_->ContainsHandle(handle))
1010 ui_controls::SendMouseMove(location.x(), location.y());
1011}
1012
initial.commit09911bf2008-07-26 23:55:291013void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1014 int handle,
[email protected]bc1407f2009-09-29 00:33:351015 int key,
initial.commit09911bf2008-07-26 23:55:291016 int flags) {
[email protected]b410bc32009-08-14 01:11:141017 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291018 return;
1019
[email protected]b410bc32009-08-14 01:11:141020 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291021 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351022 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381023 ((flags & views::Event::EF_CONTROL_DOWN) ==
1024 views::Event::EF_CONTROL_DOWN),
1025 ((flags & views::Event::EF_SHIFT_DOWN) ==
1026 views::Event::EF_SHIFT_DOWN),
1027 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301028 views::Event::EF_ALT_DOWN),
1029 ((flags & views::Event::EF_COMMAND_DOWN) ==
1030 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291031}
initial.commit09911bf2008-07-26 23:55:291032
[email protected]71f65dd2009-02-11 19:14:561033void AutomationProvider::IsWindowActive(int handle, bool* success,
1034 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291035 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171036 *is_active =
1037 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561038 *success = true;
initial.commit09911bf2008-07-26 23:55:291039 } else {
[email protected]71f65dd2009-02-11 19:14:561040 *success = false;
1041 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291042 }
1043}
1044
[email protected]71f65dd2009-02-11 19:14:561045void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1046 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291047
1048 if (browser_tracker_->ContainsHandle(handle)) {
1049 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561050 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291051 }
initial.commit09911bf2008-07-26 23:55:291052}
1053
[email protected]982921f12009-10-27 21:43:531054void AutomationProvider::GetType(int handle, int* type_as_int) {
1055 *type_as_int = -1; // -1 is the error code
1056
1057 if (browser_tracker_->ContainsHandle(handle)) {
1058 Browser* browser = browser_tracker_->GetResource(handle);
1059 *type_as_int = static_cast<int>(browser->type());
1060 }
1061}
1062
[email protected]71f65dd2009-02-11 19:14:561063void AutomationProvider::GetTab(int win_handle, int tab_index,
1064 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561065 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291066 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1067 Browser* browser = browser_tracker_->GetResource(win_handle);
1068 if (tab_index < browser->tab_count()) {
1069 TabContents* tab_contents =
1070 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571071 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291072 }
1073 }
initial.commit09911bf2008-07-26 23:55:291074}
1075
[email protected]71f65dd2009-02-11 19:14:561076void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1077 std::wstring* title) {
1078 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291079 if (tab_tracker_->ContainsHandle(handle)) {
1080 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361081 NavigationEntry* entry = tab->GetActiveEntry();
1082 if (entry != NULL) {
1083 *title = UTF16ToWideHack(entry->title());
1084 } else {
1085 *title = std::wstring();
1086 }
[email protected]71f65dd2009-02-11 19:14:561087 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291088 }
initial.commit09911bf2008-07-26 23:55:291089}
1090
[email protected]77bc6732009-04-20 22:01:031091void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1092 *tabstrip_index = -1; // -1 is the error code
1093
1094 if (tab_tracker_->ContainsHandle(handle)) {
1095 NavigationController* tab = tab_tracker_->GetResource(handle);
1096 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121097 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031098 }
1099}
1100
initial.commit09911bf2008-07-26 23:55:291101void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1102 if (window_tracker_->ContainsHandle(handle)) {
1103 window_tracker_->Remove(window_tracker_->GetResource(handle));
1104 }
1105}
1106
1107void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161108 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571109 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291110}
1111
1112// TODO(brettw) change this to accept GURLs when history supports it
1113void AutomationProvider::OnRedirectQueryComplete(
1114 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371115 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291116 bool success,
[email protected]379c2b12009-07-01 21:50:331117 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291118 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561119 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291120
[email protected]deb57402009-02-06 01:35:301121 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101122 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291123 if (success) {
initial.commit09911bf2008-07-26 23:55:291124 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301125 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291126 }
1127
[email protected]4f3dc372009-02-24 00:10:291128 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301129
[email protected]71f65dd2009-02-11 19:14:561130 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231131 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561132 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291133}
1134
1135bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571136 DCHECK(channel_.get());
1137 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291138}
1139
1140Browser* AutomationProvider::FindAndActivateTab(
1141 NavigationController* controller) {
1142 int tab_index;
1143 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1144 if (browser)
1145 browser->SelectTabContentsAt(tab_index, true);
1146
1147 return browser;
1148}
1149
[email protected]9eaa18e2010-06-29 20:51:011150namespace {
1151
1152class GetCookiesTask : public Task {
1153 public:
1154 GetCookiesTask(const GURL& url,
1155 URLRequestContextGetter* context_getter,
1156 base::WaitableEvent* event,
1157 std::string* cookies)
1158 : url_(url),
1159 context_getter_(context_getter),
1160 event_(event),
1161 cookies_(cookies) {}
1162
1163 virtual void Run() {
1164 *cookies_ = context_getter_->GetCookieStore()->GetCookies(url_);
1165 event_->Signal();
1166 }
1167
1168 private:
1169 const GURL& url_;
1170 URLRequestContextGetter* const context_getter_;
1171 base::WaitableEvent* const event_;
1172 std::string* const cookies_;
1173
1174 DISALLOW_COPY_AND_ASSIGN(GetCookiesTask);
1175};
1176
1177std::string GetCookiesForURL(
1178 const GURL& url,
1179 URLRequestContextGetter* context_getter) {
1180 std::string cookies;
1181 base::WaitableEvent event(true /* manual reset */,
1182 false /* not initially signaled */);
1183 CHECK(ChromeThread::PostTask(
1184 ChromeThread::IO, FROM_HERE,
1185 new GetCookiesTask(url, context_getter, &event, &cookies)));
1186 event.Wait();
1187 return cookies;
1188}
1189
1190class SetCookieTask : public Task {
1191 public:
1192 SetCookieTask(const GURL& url,
1193 const std::string& value,
1194 URLRequestContextGetter* context_getter,
1195 base::WaitableEvent* event,
1196 bool* rv)
1197 : url_(url),
1198 value_(value),
1199 context_getter_(context_getter),
1200 event_(event),
1201 rv_(rv) {}
1202
1203 virtual void Run() {
1204 *rv_ = context_getter_->GetCookieStore()->SetCookie(url_, value_);
1205 event_->Signal();
1206 }
1207
1208 private:
1209 const GURL& url_;
1210 const std::string& value_;
1211 URLRequestContextGetter* const context_getter_;
1212 base::WaitableEvent* const event_;
1213 bool* const rv_;
1214
1215 DISALLOW_COPY_AND_ASSIGN(SetCookieTask);
1216};
1217
1218bool SetCookieForURL(
1219 const GURL& url,
1220 const std::string& value,
1221 URLRequestContextGetter* context_getter) {
1222 base::WaitableEvent event(true /* manual reset */,
1223 false /* not initially signaled */);
1224 bool rv = false;
1225 CHECK(ChromeThread::PostTask(
1226 ChromeThread::IO, FROM_HERE,
1227 new SetCookieTask(url, value, context_getter, &event, &rv)));
1228 event.Wait();
1229 return rv;
1230}
1231
1232class DeleteCookieTask : public Task {
1233 public:
1234 DeleteCookieTask(const GURL& url,
1235 const std::string& name,
1236 const scoped_refptr<URLRequestContextGetter>& context_getter)
1237 : url_(url),
1238 name_(name),
1239 context_getter_(context_getter) {}
1240
1241 virtual void Run() {
1242 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
1243 cookie_store->DeleteCookie(url_, name_);
1244 }
1245
1246 private:
1247 const GURL url_;
1248 const std::string name_;
1249 const scoped_refptr<URLRequestContextGetter> context_getter_;
1250
1251 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
1252};
1253
1254} // namespace
1255
[email protected]71f65dd2009-02-11 19:14:561256void AutomationProvider::GetCookies(const GURL& url, int handle,
1257 int* value_size,
1258 std::string* value) {
1259 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291260 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1261 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311262
1263 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]674b3822010-08-04 04:02:511264 *value = GetCookiesForURL(url, tab->profile()->GetRequestContext());
[email protected]71f65dd2009-02-11 19:14:561265 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291266 }
initial.commit09911bf2008-07-26 23:55:291267}
1268
[email protected]71f65dd2009-02-11 19:14:561269void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291270 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561271 int handle,
1272 int* response_value) {
1273 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291274
1275 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1276 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311277
[email protected]674b3822010-08-04 04:02:511278 if (SetCookieForURL(url, value, tab->profile()->GetRequestContext()))
[email protected]71f65dd2009-02-11 19:14:561279 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291280 }
initial.commit09911bf2008-07-26 23:55:291281}
1282
[email protected]5fa57942010-04-21 23:07:221283void AutomationProvider::DeleteCookie(const GURL& url,
1284 const std::string& cookie_name,
1285 int handle, bool* success) {
1286 *success = false;
1287 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1288 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]9eaa18e2010-06-29 20:51:011289 ChromeThread::PostTask(
1290 ChromeThread::IO, FROM_HERE,
1291 new DeleteCookieTask(url, cookie_name,
1292 tab->profile()->GetRequestContext()));
[email protected]5fa57942010-04-21 23:07:221293 *success = true;
1294 }
1295}
1296
[email protected]a503c97c2010-07-16 13:05:481297void AutomationProvider::ShowCollectedCookiesDialog(
1298 int handle, bool* success) {
1299 *success = false;
1300 if (tab_tracker_->ContainsHandle(handle)) {
1301 TabContents* tab_contents =
1302 tab_tracker_->GetResource(handle)->tab_contents();
1303 tab_contents->delegate()->ShowCollectedCookiesDialog(tab_contents);
1304 *success = true;
1305 }
1306}
1307
[email protected]71f65dd2009-02-11 19:14:561308void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1309 *success = false;
initial.commit09911bf2008-07-26 23:55:291310 if (tab_tracker_->ContainsHandle(handle)) {
1311 NavigationController* tab = tab_tracker_->GetResource(handle);
1312 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541313 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561314 *success = true;
initial.commit09911bf2008-07-26 23:55:291315 }
initial.commit09911bf2008-07-26 23:55:291316}
1317
[email protected]71f65dd2009-02-11 19:14:561318void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1319 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291320
1321 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561322 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341323 TabContents* tab_contents =
1324 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161325 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1326 if (rph)
1327 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291328 }
initial.commit09911bf2008-07-26 23:55:291329}
1330
1331void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331332 NOTREACHED() << "This function has been deprecated. "
1333 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291334}
1335
[email protected]71f65dd2009-02-11 19:14:561336void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291337 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561338 const std::wstring& script,
1339 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291340 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341341 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1342 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571343 // Set the routing id of this message with the controller.
1344 // This routing id needs to be remembered for the reverse
1345 // communication while sending back the response of
1346 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331347 std::wstring set_automation_id;
1348 SStringPrintf(&set_automation_id,
1349 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561350 reply_message->routing_id());
1351
1352 DCHECK(reply_message_ == NULL);
1353 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291354
[email protected]57c6a652009-05-04 07:58:341355 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331356 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341357 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061358 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571359 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291360 }
1361
1362 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561363 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1364 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291365 }
1366}
1367
[email protected]71f65dd2009-02-11 19:14:561368void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1369 *visible = false;
[email protected]20e93d12008-08-28 16:31:571370
[email protected]59560e0b2009-06-04 03:30:221371 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251372#if defined(OS_CHROMEOS)
1373 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1374 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1375 for (BrowserList::const_iterator it = BrowserList::begin();
1376 it != BrowserList::end(); ++it) {
1377 if ((*it)->type() == Browser::TYPE_POPUP) {
1378 const GURL& url =
1379 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1380
1381 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1382 url.host() == chrome::kChromeUIFileBrowseHost) {
1383 *visible = true;
1384 break;
1385 }
1386 }
1387 }
1388#else
[email protected]59560e0b2009-06-04 03:30:221389 Browser* browser = browser_tracker_->GetResource(handle);
1390 if (browser) {
1391 *visible = browser->window()->IsDownloadShelfVisible();
1392 }
[email protected]f5bf8ccf2010-02-05 18:19:251393#endif
[email protected]59560e0b2009-06-04 03:30:221394 }
initial.commit09911bf2008-07-26 23:55:291395}
1396
[email protected]59560e0b2009-06-04 03:30:221397void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1398 if (browser_tracker_->ContainsHandle(handle)) {
1399 Browser* browser = browser_tracker_->GetResource(handle);
1400 if (browser) {
1401 if (visible)
1402 browser->window()->GetDownloadShelf()->Show();
1403 else
1404 browser->window()->GetDownloadShelf()->Close();
1405 }
1406 }
1407}
1408
[email protected]34930432009-11-09 00:12:091409void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1410 *visible = false;
1411
1412 if (browser_tracker_->ContainsHandle(handle)) {
1413 Browser* browser = browser_tracker_->GetResource(handle);
1414 if (browser)
1415 *visible = browser->window()->IsFullscreen();
1416 }
1417}
1418
1419void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1420 bool* visible) {
1421 *visible = false;
1422
1423 if (browser_tracker_->ContainsHandle(handle)) {
1424 Browser* browser = browser_tracker_->GetResource(handle);
1425 if (browser)
1426 *visible = browser->window()->IsFullscreenBubbleVisible();
1427 }
1428}
[email protected]59560e0b2009-06-04 03:30:221429
[email protected]71f65dd2009-02-11 19:14:561430void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1431 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291432 if (tab_tracker_->ContainsHandle(handle)) {
1433 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111434 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291435 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561436 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291437 }
1438 }
initial.commit09911bf2008-07-26 23:55:291439}
1440
initial.commit09911bf2008-07-26 23:55:291441void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561442 int handle, const std::wstring& find_request,
1443 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311444 NOTREACHED() << "This function has been deprecated."
1445 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561446 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311447 return;
1448}
1449
[email protected]4f999132009-03-31 18:08:401450void AutomationProvider::HandleFindRequest(
1451 int handle,
1452 const AutomationMsg_Find_Params& params,
1453 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291454 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561455 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1456 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291457 return;
1458 }
1459
1460 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111461 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291462
1463 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141464 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291465
[email protected]57c6a652009-05-04 07:58:341466 tab_contents->set_current_find_request_id(
1467 FindInPageNotificationObserver::kFindInPageRequestId);
1468 tab_contents->render_view_host()->StartFinding(
1469 FindInPageNotificationObserver::kFindInPageRequestId,
1470 params.search_string, params.forward, params.match_case,
1471 params.find_next);
initial.commit09911bf2008-07-26 23:55:291472}
1473
[email protected]5f8af2a2008-08-06 22:49:451474void AutomationProvider::HandleOpenFindInPageRequest(
1475 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291476 if (browser_tracker_->ContainsHandle(handle)) {
1477 Browser* browser = browser_tracker_->GetResource(handle);
1478 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451479 }
1480}
1481
[email protected]71f65dd2009-02-11 19:14:561482void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561483 *visible = false;
[email protected]855c0142009-09-28 22:35:241484 Browser* browser = browser_tracker_->GetResource(handle);
1485 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581486 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171487 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241488 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291489 }
[email protected]20e93d12008-08-28 16:31:571490}
1491
[email protected]71f65dd2009-02-11 19:14:561492void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1493 int* y) {
[email protected]9e0534b2008-10-21 15:03:011494 gfx::Point position(0, 0);
1495 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291496 if (browser_tracker_->ContainsHandle(handle)) {
1497 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581498 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171499 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581500 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291501 }
[email protected]20e93d12008-08-28 16:31:571502
[email protected]71f65dd2009-02-11 19:14:561503 *x = position.x();
1504 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571505}
1506
[email protected]4512cb52010-04-05 19:50:251507// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1508// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581509void AutomationProvider::GetBookmarkBarVisibility(int handle,
1510 bool* visible,
1511 bool* animating) {
1512 *visible = false;
1513 *animating = false;
1514
1515 if (browser_tracker_->ContainsHandle(handle)) {
1516 Browser* browser = browser_tracker_->GetResource(handle);
1517 if (browser) {
[email protected]472f099b2010-05-27 17:07:121518#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1519 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1520
[email protected]ab6ca392010-04-07 00:44:131521 // IsBookmarkBarVisible() line looks correct but is not
1522 // consistent across platforms. Specifically, on Mac/Linux, it
1523 // returns false if the bar is hidden in a pref (even if visible
1524 // on the NTP). On ChromeOS, it returned true if on NTP
1525 // independent of the pref. Making the code more consistent
1526 // caused a perf bot regression on Windows (which shares views).
1527 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251528 *visible = browser->profile()->GetPrefs()->GetBoolean(
1529 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401530#else
1531 *visible = browser->window()->IsBookmarkBarVisible();
1532#endif
[email protected]c3240722010-03-05 21:52:581533 *animating = browser->window()->IsBookmarkBarAnimating();
1534 }
1535 }
1536}
1537
[email protected]6d8ffc9f2010-03-12 18:27:531538void AutomationProvider::GetBookmarksAsJSON(int handle,
1539 std::string* bookmarks_as_json,
1540 bool *success) {
1541 *success = false;
1542 if (browser_tracker_->ContainsHandle(handle)) {
1543 Browser* browser = browser_tracker_->GetResource(handle);
1544 if (browser) {
1545 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1546 return;
1547 }
1548 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1549 browser->profile(),
1550 browser->profile()->GetBookmarkModel());
1551 *success = storage->SerializeData(bookmarks_as_json);
1552 }
1553 }
1554}
1555
1556void AutomationProvider::WaitForBookmarkModelToLoad(
1557 int handle,
1558 IPC::Message* reply_message) {
1559 if (browser_tracker_->ContainsHandle(handle)) {
1560 Browser* browser = browser_tracker_->GetResource(handle);
1561 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1562 if (model->IsLoaded()) {
1563 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1564 reply_message, true);
1565 Send(reply_message);
1566 } else {
1567 // The observer will delete itself when done.
1568 new AutomationProviderBookmarkModelObserver(this, reply_message,
1569 model);
1570 }
1571 }
1572}
1573
1574void AutomationProvider::AddBookmarkGroup(int handle,
1575 int64 parent_id, int index,
1576 std::wstring title,
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* parent = model->GetNodeByID(parent_id);
1587 DCHECK(parent);
1588 if (parent) {
1589 const BookmarkNode* child = model->AddGroup(parent, index,
[email protected]ff4c1d82010-08-04 16:58:121590 WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:531591 DCHECK(child);
1592 if (child)
1593 *success = true;
1594 }
1595 }
1596 }
1597 *success = false;
1598}
1599
1600void AutomationProvider::AddBookmarkURL(int handle,
1601 int64 parent_id, int index,
1602 std::wstring title, const GURL& url,
1603 bool* success) {
1604 if (browser_tracker_->ContainsHandle(handle)) {
1605 Browser* browser = browser_tracker_->GetResource(handle);
1606 if (browser) {
1607 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1608 if (!model->IsLoaded()) {
1609 *success = false;
1610 return;
1611 }
1612 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1613 DCHECK(parent);
1614 if (parent) {
1615 const BookmarkNode* child = model->AddURL(parent, index,
[email protected]ff4c1d82010-08-04 16:58:121616 WideToUTF16Hack(title), url);
[email protected]6d8ffc9f2010-03-12 18:27:531617 DCHECK(child);
1618 if (child)
1619 *success = true;
1620 }
1621 }
1622 }
1623 *success = false;
1624}
1625
1626void AutomationProvider::ReparentBookmark(int handle,
1627 int64 id, int64 new_parent_id,
1628 int index,
1629 bool* success) {
1630 if (browser_tracker_->ContainsHandle(handle)) {
1631 Browser* browser = browser_tracker_->GetResource(handle);
1632 if (browser) {
1633 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1634 if (!model->IsLoaded()) {
1635 *success = false;
1636 return;
1637 }
1638 const BookmarkNode* node = model->GetNodeByID(id);
1639 DCHECK(node);
1640 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1641 DCHECK(new_parent);
1642 if (node && new_parent) {
1643 model->Move(node, new_parent, index);
1644 *success = true;
1645 }
1646 }
1647 }
1648 *success = false;
1649}
1650
1651void AutomationProvider::SetBookmarkTitle(int handle,
1652 int64 id, std::wstring title,
1653 bool* success) {
1654 if (browser_tracker_->ContainsHandle(handle)) {
1655 Browser* browser = browser_tracker_->GetResource(handle);
1656 if (browser) {
1657 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1658 if (!model->IsLoaded()) {
1659 *success = false;
1660 return;
1661 }
1662 const BookmarkNode* node = model->GetNodeByID(id);
1663 DCHECK(node);
1664 if (node) {
[email protected]ff4c1d82010-08-04 16:58:121665 model->SetTitle(node, WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:531666 *success = true;
1667 }
1668 }
1669 }
1670 *success = false;
1671}
1672
1673void AutomationProvider::SetBookmarkURL(int handle,
1674 int64 id, const GURL& url,
1675 bool* success) {
1676 if (browser_tracker_->ContainsHandle(handle)) {
1677 Browser* browser = browser_tracker_->GetResource(handle);
1678 if (browser) {
1679 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1680 if (!model->IsLoaded()) {
1681 *success = false;
1682 return;
1683 }
1684 const BookmarkNode* node = model->GetNodeByID(id);
1685 DCHECK(node);
1686 if (node) {
1687 model->SetURL(node, url);
1688 *success = true;
1689 }
1690 }
1691 }
1692 *success = false;
1693}
1694
1695void AutomationProvider::RemoveBookmark(int handle,
1696 int64 id,
1697 bool* success) {
1698 if (browser_tracker_->ContainsHandle(handle)) {
1699 Browser* browser = browser_tracker_->GetResource(handle);
1700 if (browser) {
1701 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1702 if (!model->IsLoaded()) {
1703 *success = false;
1704 return;
1705 }
1706 const BookmarkNode* node = model->GetNodeByID(id);
1707 DCHECK(node);
1708 if (node) {
1709 const BookmarkNode* parent = node->GetParent();
1710 DCHECK(parent);
1711 model->Remove(parent, parent->IndexOfChild(node));
1712 *success = true;
1713 }
1714 }
1715 }
1716 *success = false;
1717}
1718
[email protected]ef413ca2010-05-25 21:09:141719// Sample json input: { "command": "SetWindowDimensions",
1720// "x": 20, # optional
1721// "y": 20, # optional
1722// "width": 800, # optional
1723// "height": 600 } # optional
1724void AutomationProvider::SetWindowDimensions(Browser* browser,
1725 DictionaryValue* args,
1726 IPC::Message* reply_message) {
1727 gfx::Rect rect = browser->window()->GetRestoredBounds();
1728 int x, y, width, height;
[email protected]ff4c1d82010-08-04 16:58:121729 if (args->GetInteger("x", &x))
[email protected]ef413ca2010-05-25 21:09:141730 rect.set_x(x);
[email protected]ff4c1d82010-08-04 16:58:121731 if (args->GetInteger("y", &y))
[email protected]ef413ca2010-05-25 21:09:141732 rect.set_y(y);
[email protected]ff4c1d82010-08-04 16:58:121733 if (args->GetInteger("width", &width))
[email protected]ef413ca2010-05-25 21:09:141734 rect.set_width(width);
[email protected]ff4c1d82010-08-04 16:58:121735 if (args->GetInteger("height", &height))
[email protected]ef413ca2010-05-25 21:09:141736 rect.set_height(height);
1737 browser->window()->SetBounds(rect);
[email protected]7c983cc2010-07-16 11:33:341738 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
[email protected]ef413ca2010-05-25 21:09:141739}
1740
[email protected]38b5a3852010-07-21 06:49:521741ListValue* AutomationProvider::GetInfobarsInfo(TabContents* tc) {
1742 // Each infobar may have different properties depending on the type.
1743 ListValue* infobars = new ListValue;
1744 for (int infobar_index = 0;
1745 infobar_index < tc->infobar_delegate_count();
1746 ++infobar_index) {
1747 DictionaryValue* infobar_item = new DictionaryValue;
1748 InfoBarDelegate* infobar = tc->GetInfoBarDelegateAt(infobar_index);
1749 if (infobar->AsConfirmInfoBarDelegate()) {
1750 // Also covers ThemeInstalledInfoBarDelegate and
1751 // CrashedExtensionInfoBarDelegate.
[email protected]ff4c1d82010-08-04 16:58:121752 infobar_item->SetString("type", "confirm_infobar");
[email protected]38b5a3852010-07-21 06:49:521753 ConfirmInfoBarDelegate* confirm_infobar =
1754 infobar->AsConfirmInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:581755 infobar_item->SetString("text", confirm_infobar->GetMessageText());
1756 infobar_item->SetString("link_text", confirm_infobar->GetLinkText());
[email protected]38b5a3852010-07-21 06:49:521757 ListValue* buttons_list = new ListValue;
1758 int buttons = confirm_infobar->GetButtons();
1759 if (ConfirmInfoBarDelegate::BUTTON_OK & buttons) {
1760 StringValue* button_label = new StringValue(
1761 confirm_infobar->GetButtonLabel(
1762 ConfirmInfoBarDelegate::BUTTON_OK));
1763 buttons_list->Append(button_label);
1764 }
1765 if (ConfirmInfoBarDelegate::BUTTON_CANCEL & buttons) {
1766 StringValue* button_label = new StringValue(
1767 confirm_infobar->GetButtonLabel(
1768 ConfirmInfoBarDelegate::BUTTON_CANCEL));
1769 buttons_list->Append(button_label);
1770 }
[email protected]ff4c1d82010-08-04 16:58:121771 infobar_item->Set("buttons", buttons_list);
[email protected]38b5a3852010-07-21 06:49:521772 } else if (infobar->AsAlertInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121773 infobar_item->SetString("type", "alert_infobar");
[email protected]38b5a3852010-07-21 06:49:521774 AlertInfoBarDelegate* alert_infobar =
1775 infobar->AsAlertInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:581776 infobar_item->SetString("text", alert_infobar->GetMessageText());
[email protected]38b5a3852010-07-21 06:49:521777 } else if (infobar->AsLinkInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121778 infobar_item->SetString("type", "link_infobar");
[email protected]38b5a3852010-07-21 06:49:521779 LinkInfoBarDelegate* link_infobar = infobar->AsLinkInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:581780 infobar_item->SetString("link_text", link_infobar->GetLinkText());
[email protected]38b5a3852010-07-21 06:49:521781 } else if (infobar->AsTranslateInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121782 infobar_item->SetString("type", "translate_infobar");
[email protected]38b5a3852010-07-21 06:49:521783 TranslateInfoBarDelegate* translate_infobar =
1784 infobar->AsTranslateInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:121785 infobar_item->SetString("original_lang_code",
[email protected]38b5a3852010-07-21 06:49:521786 translate_infobar->GetOriginalLanguageCode());
[email protected]ff4c1d82010-08-04 16:58:121787 infobar_item->SetString("target_lang_code",
[email protected]38b5a3852010-07-21 06:49:521788 translate_infobar->GetTargetLanguageCode());
1789 } else if (infobar->AsExtensionInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121790 infobar_item->SetString("type", "extension_infobar");
[email protected]38b5a3852010-07-21 06:49:521791 } else {
[email protected]ff4c1d82010-08-04 16:58:121792 infobar_item->SetString("type", "unknown_infobar");
[email protected]38b5a3852010-07-21 06:49:521793 }
1794 infobars->Append(infobar_item);
1795 }
1796 return infobars;
1797}
1798
1799// Sample json input: { "command": "WaitForInfobarCount",
1800// "count": COUNT,
1801// "tab_index": INDEX }
1802// Sample output: {}
1803void AutomationProvider::WaitForInfobarCount(Browser* browser,
1804 DictionaryValue* args,
1805 IPC::Message* reply_message) {
1806 int tab_index;
1807 int count;
[email protected]ff4c1d82010-08-04 16:58:121808 if (!args->GetInteger("count", &count) || count < 0 ||
1809 !args->GetInteger("tab_index", &tab_index) || tab_index < 0) {
[email protected]38b5a3852010-07-21 06:49:521810 AutomationJSONReply(this, reply_message).SendError(
1811 "Missing or invalid args: 'count', 'tab_index'.");
1812 return;
1813 }
1814
1815 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
1816 // Observer deletes itself.
1817 new WaitForInfobarCountObserver(this, reply_message, tab_contents, count);
1818}
1819
[email protected]e004a2d2010-07-22 04:55:281820// Sample json input: { "command": "PerformActionOnInfobar",
1821// "action": "dismiss",
1822// "infobar_index": 0,
1823// "tab_index": 0 }
1824// Sample output: {}
1825void AutomationProvider::PerformActionOnInfobar(Browser* browser,
1826 DictionaryValue* args,
1827 IPC::Message* reply_message) {
1828 AutomationJSONReply reply(this, reply_message);
1829 int tab_index;
1830 int infobar_index;
1831 std::string action;
[email protected]ff4c1d82010-08-04 16:58:121832 if (!args->GetInteger("tab_index", &tab_index) ||
1833 !args->GetInteger("infobar_index", &infobar_index) ||
1834 !args->GetString("action", &action)) {
[email protected]e004a2d2010-07-22 04:55:281835 reply.SendError("Invalid or missing args");
1836 return;
1837 }
1838 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
1839 if (!tab_contents) {
1840 reply.SendError(StringPrintf("No such tab at index %d", tab_index));
1841 return;
1842 }
1843 InfoBarDelegate* infobar = NULL;
1844 if (infobar_index < 0 ||
1845 infobar_index >= tab_contents->infobar_delegate_count() ||
1846 !(infobar = tab_contents->GetInfoBarDelegateAt(infobar_index))) {
1847 reply.SendError(StringPrintf("No such infobar at index %d", infobar_index));
1848 return;
1849 }
1850 if ("dismiss" == action) {
1851 infobar->InfoBarDismissed();
1852 tab_contents->RemoveInfoBar(infobar);
1853 reply.SendSuccess(NULL);
1854 return;
1855 }
1856 if ("accept" == action || "cancel" == action) {
1857 ConfirmInfoBarDelegate* confirm_infobar;
1858 if (!(confirm_infobar = infobar->AsConfirmInfoBarDelegate())) {
1859 reply.SendError("Not a confirm infobar");
1860 return;
1861 }
1862 if ("accept" == action) {
1863 if (confirm_infobar->Accept())
1864 tab_contents->RemoveInfoBar(infobar);
1865 } else if ("cancel" == action) {
1866 if (confirm_infobar->Cancel())
1867 tab_contents->RemoveInfoBar(infobar);
1868 }
1869 reply.SendSuccess(NULL);
1870 return;
1871 }
1872 reply.SendError("Invalid action");
1873}
1874
[email protected]26adfd312010-07-20 01:04:461875namespace {
1876
1877// Task to get info about BrowserChildProcessHost. Must run on IO thread to
1878// honor the semantics of BrowserChildProcessHost.
1879// Used by AutomationProvider::GetBrowserInfo().
1880class GetChildProcessHostInfoTask : public Task {
1881 public:
1882 GetChildProcessHostInfoTask(base::WaitableEvent* event,
1883 ListValue* child_processes)
1884 : event_(event),
1885 child_processes_(child_processes) {}
1886
1887 virtual void Run() {
1888 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
1889 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1890 // Only add processes which are already started,
1891 // since we need their handle.
1892 if ((*iter)->handle() == base::kNullProcessHandle) {
1893 continue;
1894 }
1895 ChildProcessInfo* info = *iter;
1896 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121897 item->SetString("name", WideToUTF16Hack(info->name()));
1898 item->SetString("type",
1899 WideToUTF16Hack(ChildProcessInfo::GetTypeNameInEnglish(
1900 info->type())));
1901 item->SetInteger("pid", base::GetProcId(info->handle()));
[email protected]26adfd312010-07-20 01:04:461902 child_processes_->Append(item);
1903 }
1904 event_->Signal();
1905 }
1906
1907 private:
1908 base::WaitableEvent* const event_; // weak
1909 ListValue* child_processes_;
1910
1911 DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask);
1912};
1913
1914} // namespace
1915
[email protected]a9ff2c02010-05-13 17:33:051916// Sample json input: { "command": "GetBrowserInfo" }
1917// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1918// sample json output.
[email protected]53329582010-05-14 21:10:581919void AutomationProvider::GetBrowserInfo(Browser* browser,
1920 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051921 IPC::Message* reply_message) {
[email protected]a9ff2c02010-05-13 17:33:051922 DictionaryValue* properties = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121923 properties->SetString("ChromeVersion", chrome::kChromeVersion);
1924 properties->SetString("BrowserProcessExecutableName",
1925 WideToUTF16Hack(chrome::kBrowserProcessExecutableName));
1926 properties->SetString("HelperProcessExecutableName",
1927 WideToUTF16Hack(chrome::kHelperProcessExecutableName));
1928 properties->SetString("BrowserProcessExecutablePath",
1929 WideToUTF16Hack(chrome::kBrowserProcessExecutablePath));
1930 properties->SetString("HelperProcessExecutablePath",
[email protected]a9ff2c02010-05-13 17:33:051931 chrome::kHelperProcessExecutablePath);
[email protected]ff4c1d82010-08-04 16:58:121932 properties->SetString("command_line_string",
[email protected]a9ff2c02010-05-13 17:33:051933 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001934
1935 std::string branding;
1936#if defined(GOOGLE_CHROME_BUILD)
1937 branding = "Google Chrome";
1938#elif defined(CHROMIUM_BUILD)
1939 branding = "Chromium";
1940#else
1941 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051942#endif
[email protected]ff4c1d82010-08-04 16:58:121943 properties->SetString("branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051944
1945 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:121946 return_value->Set("properties", properties);
[email protected]a9ff2c02010-05-13 17:33:051947
[email protected]ff4c1d82010-08-04 16:58:121948 return_value->SetInteger("browser_pid", base::GetCurrentProcId());
[email protected]ef413ca2010-05-25 21:09:141949 // Add info about all windows in a list of dictionaries, one dictionary
1950 // item per window.
1951 ListValue* windows = new ListValue;
1952 int windex = 0;
1953 for (BrowserList::const_iterator it = BrowserList::begin();
1954 it != BrowserList::end();
1955 ++it, ++windex) {
1956 DictionaryValue* browser_item = new DictionaryValue;
1957 browser = *it;
[email protected]ff4c1d82010-08-04 16:58:121958 browser_item->SetInteger("index", windex);
[email protected]ef413ca2010-05-25 21:09:141959 // Window properties
1960 gfx::Rect rect = browser->window()->GetRestoredBounds();
[email protected]ff4c1d82010-08-04 16:58:121961 browser_item->SetInteger("x", rect.x());
1962 browser_item->SetInteger("y", rect.y());
1963 browser_item->SetInteger("width", rect.width());
1964 browser_item->SetInteger("height", rect.height());
1965 browser_item->SetBoolean("fullscreen",
[email protected]ef413ca2010-05-25 21:09:141966 browser->window()->IsFullscreen());
[email protected]ff4c1d82010-08-04 16:58:121967 browser_item->SetInteger("selected_tab", browser->selected_index());
1968 browser_item->SetBoolean("incognito",
[email protected]ef413ca2010-05-25 21:09:141969 browser->profile()->IsOffTheRecord());
1970 // For each window, add info about all tabs in a list of dictionaries,
1971 // one dictionary item per tab.
1972 ListValue* tabs = new ListValue;
1973 for (int i = 0; i < browser->tab_count(); ++i) {
1974 TabContents* tc = browser->GetTabContentsAt(i);
1975 DictionaryValue* tab = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121976 tab->SetInteger("index", i);
1977 tab->SetString("url", tc->GetURL().spec());
1978 tab->SetInteger("renderer_pid",
[email protected]ef413ca2010-05-25 21:09:141979 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
[email protected]ff4c1d82010-08-04 16:58:121980 tab->Set("infobars", GetInfobarsInfo(tc));
[email protected]ef413ca2010-05-25 21:09:141981 tabs->Append(tab);
1982 }
[email protected]ff4c1d82010-08-04 16:58:121983 browser_item->Set("tabs", tabs);
[email protected]ef413ca2010-05-25 21:09:141984
1985 windows->Append(browser_item);
1986 }
[email protected]ff4c1d82010-08-04 16:58:121987 return_value->Set("windows", windows);
[email protected]ef413ca2010-05-25 21:09:141988
[email protected]ff4c1d82010-08-04 16:58:121989 return_value->SetString("child_process_path",
[email protected]ef413ca2010-05-25 21:09:141990 ChildProcessHost::GetChildPath(true).value());
1991 // Child processes are the processes for plugins and other workers.
1992 // Add all child processes in a list of dictionaries, one dictionary item
1993 // per child process.
1994 ListValue* child_processes = new ListValue;
[email protected]26adfd312010-07-20 01:04:461995 base::WaitableEvent event(true /* manual reset */,
1996 false /* not initially signaled */);
1997 CHECK(ChromeThread::PostTask(
1998 ChromeThread::IO, FROM_HERE,
1999 new GetChildProcessHostInfoTask(&event, child_processes)));
2000 event.Wait();
[email protected]ff4c1d82010-08-04 16:58:122001 return_value->Set("child_processes", child_processes);
[email protected]ef413ca2010-05-25 21:09:142002
2003 // Add all extension processes in a list of dictionaries, one dictionary
2004 // item per extension process.
2005 ListValue* extension_processes = new ListValue;
2006 ProfileManager* profile_manager = g_browser_process->profile_manager();
2007 for (ProfileManager::const_iterator it = profile_manager->begin();
2008 it != profile_manager->end(); ++it) {
2009 ExtensionProcessManager* process_manager =
2010 (*it)->GetExtensionProcessManager();
2011 ExtensionProcessManager::const_iterator jt;
2012 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
2013 ExtensionHost* ex_host = *jt;
2014 // Don't add dead extension processes.
2015 if (!ex_host->IsRenderViewLive())
2016 continue;
2017 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122018 item->SetString("name", ex_host->extension()->name());
[email protected]ef413ca2010-05-25 21:09:142019 item->SetInteger(
[email protected]ff4c1d82010-08-04 16:58:122020 "pid",
[email protected]ef413ca2010-05-25 21:09:142021 base::GetProcId(ex_host->render_process_host()->GetHandle()));
2022 extension_processes->Append(item);
2023 }
2024 }
[email protected]ff4c1d82010-08-04 16:58:122025 return_value->Set("extension_processes", extension_processes);
[email protected]7c983cc2010-07-16 11:33:342026 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]a9ff2c02010-05-13 17:33:052027}
2028
[email protected]24e2b102010-04-29 17:56:472029// Sample json input: { "command": "GetHistoryInfo",
2030// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:362031// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582032void AutomationProvider::GetHistoryInfo(Browser* browser,
2033 DictionaryValue* args,
2034 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:362035 consumer_.CancelAllRequests();
2036
[email protected]e53668962010-06-23 15:35:252037 string16 search_text;
2038 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:362039
2040 // Fetch history.
2041 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2042 history::QueryOptions options;
2043 // The observer owns itself. It deletes itself after it fetches history.
2044 AutomationProviderHistoryObserver* history_observer =
2045 new AutomationProviderHistoryObserver(this, reply_message);
2046 hs->QueryHistory(
2047 search_text,
2048 options,
2049 &consumer_,
2050 NewCallback(history_observer,
2051 &AutomationProviderHistoryObserver::HistoryQueryComplete));
2052}
2053
[email protected]bbe6aa02010-05-07 17:27:292054// Sample json input: { "command": "AddHistoryItem",
2055// "item": { "URL": "http://www.google.com",
2056// "title": "Google", # optional
2057// "time": 12345 # optional (time_t)
2058// } }
2059// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:582060void AutomationProvider::AddHistoryItem(Browser* browser,
2061 DictionaryValue* args,
2062 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:292063 DictionaryValue* item = NULL;
[email protected]ff4c1d82010-08-04 16:58:122064 args->GetDictionary("item", &item);
[email protected]bbe6aa02010-05-07 17:27:292065 string16 url_text;
[email protected]e53668962010-06-23 15:35:252066 string16 title;
[email protected]bbe6aa02010-05-07 17:27:292067 base::Time time = base::Time::Now();
[email protected]7c983cc2010-07-16 11:33:342068 AutomationJSONReply reply(this, reply_message);
[email protected]bbe6aa02010-05-07 17:27:292069
[email protected]7c983cc2010-07-16 11:33:342070 if (!item->GetString("url", &url_text)) {
2071 reply.SendError("bad args (no URL in dict?)");
2072 return;
[email protected]bbe6aa02010-05-07 17:27:292073 }
[email protected]7c983cc2010-07-16 11:33:342074 GURL gurl(url_text);
2075 item->GetString("title", &title); // Don't care if it fails.
2076 int it;
2077 double dt;
[email protected]ff4c1d82010-08-04 16:58:122078 if (item->GetInteger("time", &it))
[email protected]7c983cc2010-07-16 11:33:342079 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:122080 else if (item->GetReal("time", &dt))
[email protected]7c983cc2010-07-16 11:33:342081 time = base::Time::FromDoubleT(dt);
[email protected]f6ff0df2010-07-11 22:41:432082
[email protected]7c983cc2010-07-16 11:33:342083 // Ideas for "dummy" values (e.g. id_scope) came from
2084 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
2085 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2086 const void* id_scope = reinterpret_cast<void*>(1);
2087 hs->AddPage(gurl, time,
2088 id_scope,
2089 0,
2090 GURL(),
2091 PageTransition::LINK,
2092 history::RedirectList(),
2093 false);
2094 if (title.length())
2095 hs->SetPageTitle(gurl, title);
2096 reply.SendSuccess(NULL);
[email protected]bbe6aa02010-05-07 17:27:292097}
2098
[email protected]24e2b102010-04-29 17:56:472099// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:362100// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582101void AutomationProvider::GetDownloadsInfo(Browser* browser,
2102 DictionaryValue* args,
2103 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:392104 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]7c983cc2010-07-16 11:33:342105 AutomationJSONReply reply(this, reply_message);
[email protected]d4adc292010-04-15 18:06:392106
2107 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:342108 reply.SendError("no download manager");
2109 return;
[email protected]d4adc292010-04-15 18:06:392110 }
[email protected]82f37b02010-07-29 22:04:572111
2112 std::vector<DownloadItem*> downloads;
2113 profile_->GetDownloadManager()->GetAllDownloads(FilePath(), &downloads);
[email protected]d4adc292010-04-15 18:06:392114
2115 std::map<DownloadItem::DownloadState, std::string> state_to_string;
2116 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
2117 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
2118 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
2119 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
2120
2121 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
2122 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
2123 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
2124 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
2125 std::string("DANGEROUS_BUT_VALIDATED");
2126
2127 ListValue* list_of_downloads = new ListValue;
2128 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
2129 it != downloads.end();
2130 it++) { // Fill info about each download item.
2131 DictionaryValue* dl_item_value = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122132 dl_item_value->SetInteger("id", static_cast<int>((*it)->id()));
2133 dl_item_value->SetString("url", (*it)->url().spec());
2134 dl_item_value->SetString("referrer_url", (*it)->referrer_url().spec());
2135 dl_item_value->SetString("file_name", (*it)->GetFileName().value());
2136 dl_item_value->SetString("full_path", (*it)->full_path().value());
2137 dl_item_value->SetBoolean("is_paused", (*it)->is_paused());
2138 dl_item_value->SetBoolean("open_when_complete",
[email protected]d4adc292010-04-15 18:06:392139 (*it)->open_when_complete());
[email protected]ff4c1d82010-08-04 16:58:122140 dl_item_value->SetBoolean("is_extension_install",
[email protected]d4adc292010-04-15 18:06:392141 (*it)->is_extension_install());
[email protected]ff4c1d82010-08-04 16:58:122142 dl_item_value->SetBoolean("is_temporary", (*it)->is_temporary());
2143 dl_item_value->SetBoolean("is_otr", (*it)->is_otr()); // off-the-record
2144 dl_item_value->SetString("state", state_to_string[(*it)->state()]);
2145 dl_item_value->SetString("safety_state",
[email protected]d4adc292010-04-15 18:06:392146 safety_state_to_string[(*it)->safety_state()]);
[email protected]ff4c1d82010-08-04 16:58:122147 dl_item_value->SetInteger("PercentComplete", (*it)->PercentComplete());
[email protected]d4adc292010-04-15 18:06:392148 list_of_downloads->Append(dl_item_value);
2149 }
[email protected]ff4c1d82010-08-04 16:58:122150 return_value->Set("downloads", list_of_downloads);
[email protected]d4adc292010-04-15 18:06:392151
[email protected]7c983cc2010-07-16 11:33:342152 reply.SendSuccess(return_value.get());
[email protected]d4adc292010-04-15 18:06:392153 // All value objects allocated above are owned by |return_value|
2154 // and get freed by it.
2155}
2156
[email protected]59a611242010-04-02 02:24:042157void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:582158 Browser* browser,
[email protected]59a611242010-04-02 02:24:042159 DictionaryValue* args,
2160 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:342161 AutomationJSONReply reply(this, reply_message);
[email protected]59a611242010-04-02 02:24:042162
2163 // Look for a quick return.
2164 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:342165 reply.SendSuccess(NULL); // No download manager.
2166 return;
[email protected]59a611242010-04-02 02:24:042167 }
[email protected]82f37b02010-07-29 22:04:572168 std::vector<DownloadItem*> downloads;
2169 profile_->GetDownloadManager()->GetCurrentDownloads(FilePath(), &downloads);
2170 if (downloads.empty()) {
[email protected]7c983cc2010-07-16 11:33:342171 reply.SendSuccess(NULL);
[email protected]f6ff0df2010-07-11 22:41:432172 return;
2173 }
[email protected]59a611242010-04-02 02:24:042174
2175 // The observer owns itself. When the last observed item pings, it
2176 // deletes itself.
2177 AutomationProviderDownloadItemObserver* item_observer =
2178 new AutomationProviderDownloadItemObserver(
2179 this, reply_message, downloads.size());
2180 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2181 i != downloads.end();
2182 i++) {
2183 (*i)->AddObserver(item_observer);
2184 }
2185}
2186
[email protected]24e2b102010-04-29 17:56:472187// Sample json input: { "command": "GetPrefsInfo" }
2188// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582189void AutomationProvider::GetPrefsInfo(Browser* browser,
2190 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472191 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:472192 const PrefService::PreferenceSet& prefs =
2193 profile_->GetPrefs()->preference_set();
2194 DictionaryValue* items = new DictionaryValue;
2195 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
2196 it != prefs.end(); ++it) {
2197 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
2198 }
2199 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:122200 return_value->Set("prefs", items); // return_value owns items.
[email protected]7c983cc2010-07-16 11:33:342201 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]24e2b102010-04-29 17:56:472202}
2203
2204// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:582205void AutomationProvider::SetPrefs(Browser* browser,
2206 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472207 IPC::Message* reply_message) {
[email protected]57ecc4b2010-08-11 03:02:512208 std::string path;
[email protected]24e2b102010-04-29 17:56:472209 Value* val;
[email protected]7c983cc2010-07-16 11:33:342210 AutomationJSONReply reply(this, reply_message);
[email protected]57ecc4b2010-08-11 03:02:512211 if (args->GetString("path", &path) && args->Get("value", &val)) {
[email protected]24e2b102010-04-29 17:56:472212 PrefService* pref_service = profile_->GetPrefs();
2213 const PrefService::Preference* pref =
2214 pref_service->FindPreference(path.c_str());
2215 if (!pref) { // Not a registered pref.
[email protected]7c983cc2010-07-16 11:33:342216 reply.SendError("pref not registered.");
2217 return;
[email protected]24e2b102010-04-29 17:56:472218 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7c983cc2010-07-16 11:33:342219 reply.SendError("pref is managed. cannot be changed.");
2220 return;
[email protected]24e2b102010-04-29 17:56:472221 } else { // Set the pref.
2222 pref_service->Set(path.c_str(), *val);
2223 }
2224 } else {
[email protected]7c983cc2010-07-16 11:33:342225 reply.SendError("no pref path or value given.");
2226 return;
[email protected]24e2b102010-04-29 17:56:472227 }
2228
[email protected]7c983cc2010-07-16 11:33:342229 reply.SendSuccess(NULL);
[email protected]24e2b102010-04-29 17:56:472230}
2231
[email protected]53329582010-05-14 21:10:582232// Sample json input: { "command": "GetOmniboxInfo" }
2233// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
2234void AutomationProvider::GetOmniboxInfo(Browser* browser,
2235 DictionaryValue* args,
2236 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582237 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2238
2239 LocationBar* loc_bar = browser->window()->GetLocationBar();
2240 AutocompleteEditView* edit_view = loc_bar->location_entry();
2241 AutocompleteEditModel* model = edit_view->model();
2242
2243 // Fill up matches.
2244 ListValue* matches = new ListValue;
2245 const AutocompleteResult& result = model->result();
2246 for (AutocompleteResult::const_iterator i = result.begin();
2247 i != result.end(); ++i) {
2248 const AutocompleteMatch& match = *i;
2249 DictionaryValue* item = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:122250 item->SetString("type", AutocompleteMatch::TypeToString(match.type));
2251 item->SetBoolean("starred", match.starred);
2252 item->SetString("destination_url", match.destination_url.spec());
2253 item->SetString("contents", WideToUTF16Hack(match.contents));
2254 item->SetString("description", WideToUTF16Hack(match.description));
[email protected]53329582010-05-14 21:10:582255 matches->Append(item);
2256 }
[email protected]ff4c1d82010-08-04 16:58:122257 return_value->Set("matches", matches);
[email protected]53329582010-05-14 21:10:582258
2259 // Fill up other properties.
2260 DictionaryValue* properties = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:122261 properties->SetBoolean("has_focus", model->has_focus());
2262 properties->SetBoolean("query_in_progress", model->query_in_progress());
2263 properties->SetString("keyword", WideToUTF16Hack(model->keyword()));
2264 properties->SetString("text", WideToUTF16Hack(edit_view->GetText()));
2265 return_value->Set("properties", properties);
[email protected]53329582010-05-14 21:10:582266
[email protected]7c983cc2010-07-16 11:33:342267 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]53329582010-05-14 21:10:582268}
2269
2270// Sample json input: { "command": "SetOmniboxText",
2271// "text": "goog" }
2272void AutomationProvider::SetOmniboxText(Browser* browser,
2273 DictionaryValue* args,
2274 IPC::Message* reply_message) {
[email protected]a748ff62010-08-14 17:25:322275 string16 text;
[email protected]7c983cc2010-07-16 11:33:342276 AutomationJSONReply reply(this, reply_message);
[email protected]a748ff62010-08-14 17:25:322277 if (!args->GetString("text", &text)) {
[email protected]7c983cc2010-07-16 11:33:342278 reply.SendError("text missing");
2279 return;
[email protected]53329582010-05-14 21:10:582280 }
[email protected]7c983cc2010-07-16 11:33:342281 browser->FocusLocationBar();
2282 LocationBar* loc_bar = browser->window()->GetLocationBar();
2283 AutocompleteEditView* edit_view = loc_bar->location_entry();
2284 edit_view->model()->OnSetFocus(false);
[email protected]a748ff62010-08-14 17:25:322285 edit_view->SetUserText(UTF16ToWideHack(text));
[email protected]7c983cc2010-07-16 11:33:342286 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:582287}
2288
2289// Sample json input: { "command": "OmniboxMovePopupSelection",
2290// "count": 1 }
2291// Negative count implies up, positive implies down. Count values will be
2292// capped by the size of the popup list.
2293void AutomationProvider::OmniboxMovePopupSelection(
2294 Browser* browser,
2295 DictionaryValue* args,
2296 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582297 int count;
[email protected]7c983cc2010-07-16 11:33:342298 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122299 if (!args->GetInteger("count", &count)) {
[email protected]7c983cc2010-07-16 11:33:342300 reply.SendError("count missing");
2301 return;
[email protected]53329582010-05-14 21:10:582302 }
[email protected]7c983cc2010-07-16 11:33:342303 LocationBar* loc_bar = browser->window()->GetLocationBar();
2304 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2305 model->OnUpOrDownKeyPressed(count);
2306 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:582307}
2308
2309// Sample json input: { "command": "OmniboxAcceptInput" }
2310void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2311 DictionaryValue* args,
2312 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282313 NavigationController& controller =
2314 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122315 // Setup observer to wait until the selected item loads.
2316 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282317 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122318 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582319
2320 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582321}
2322
[email protected]a3cd5022010-06-16 18:25:292323// Sample json input: { "command": "GetInitialLoadTimes" }
2324// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2325void AutomationProvider::GetInitialLoadTimes(
2326 Browser*,
2327 DictionaryValue*,
2328 IPC::Message* reply_message) {
2329 scoped_ptr<DictionaryValue> return_value(
2330 initial_load_observer_->GetTimingInformation());
[email protected]f6ff0df2010-07-11 22:41:432331
2332 std::string json_return;
2333 base::JSONWriter::Write(return_value.get(), false, &json_return);
2334 AutomationMsg_SendJSONRequest::WriteReplyParams(
2335 reply_message, json_return, true);
2336 Send(reply_message);
[email protected]a3cd5022010-06-16 18:25:292337}
2338
[email protected]f7d48012010-05-06 08:17:052339// Sample json input: { "command": "GetPluginsInfo" }
2340// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582341void AutomationProvider::GetPluginsInfo(Browser* browser,
2342 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052343 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052344 std::vector<WebPluginInfo> plugins;
2345 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2346 ListValue* items = new ListValue;
2347 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2348 it != plugins.end();
2349 ++it) {
2350 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122351 item->SetString("name", it->name);
2352 item->SetString("path", it->path.value());
2353 item->SetString("version", it->version);
2354 item->SetString("desc", it->desc);
2355 item->SetBoolean("enabled", it->enabled);
[email protected]f7d48012010-05-06 08:17:052356 // Add info about mime types.
2357 ListValue* mime_types = new ListValue();
2358 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2359 it->mime_types.begin();
2360 type_it != it->mime_types.end();
2361 ++type_it) {
2362 DictionaryValue* mime_type = new DictionaryValue();
[email protected]ff4c1d82010-08-04 16:58:122363 mime_type->SetString("mimeType", type_it->mime_type);
2364 mime_type->SetString("description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052365
2366 ListValue* file_extensions = new ListValue();
2367 for (std::vector<std::string>::const_iterator ext_it =
2368 type_it->file_extensions.begin();
2369 ext_it != type_it->file_extensions.end();
2370 ++ext_it) {
2371 file_extensions->Append(new StringValue(*ext_it));
2372 }
[email protected]ff4c1d82010-08-04 16:58:122373 mime_type->Set("fileExtensions", file_extensions);
[email protected]f7d48012010-05-06 08:17:052374
2375 mime_types->Append(mime_type);
2376 }
[email protected]ff4c1d82010-08-04 16:58:122377 item->Set("mimeTypes", mime_types);
[email protected]f7d48012010-05-06 08:17:052378 items->Append(item);
2379 }
2380 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:122381 return_value->Set("plugins", items); // return_value owns items.
[email protected]f7d48012010-05-06 08:17:052382
[email protected]7c983cc2010-07-16 11:33:342383 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f7d48012010-05-06 08:17:052384}
2385
2386// Sample json input:
2387// { "command": "EnablePlugin",
2388// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582389void AutomationProvider::EnablePlugin(Browser* browser,
2390 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052391 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052392 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342393 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122394 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342395 reply.SendError("path not specified.");
2396 return;
[email protected]f6ff0df2010-07-11 22:41:432397 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342398 reply.SendError(StringPrintf("Could not enable plugin for path %s.",
2399 path.c_str()));
2400 return;
[email protected]f6ff0df2010-07-11 22:41:432401 }
[email protected]7c983cc2010-07-16 11:33:342402 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052403}
2404
2405// Sample json input:
2406// { "command": "DisablePlugin",
2407// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582408void AutomationProvider::DisablePlugin(Browser* browser,
2409 DictionaryValue* args,
2410 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052411 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342412 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122413 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342414 reply.SendError("path not specified.");
2415 return;
[email protected]f6ff0df2010-07-11 22:41:432416 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342417 reply.SendError(StringPrintf("Could not disable plugin for path %s.",
2418 path.c_str()));
2419 return;
[email protected]f6ff0df2010-07-11 22:41:432420 }
[email protected]7c983cc2010-07-16 11:33:342421 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052422}
2423
[email protected]7060bb292010-06-24 00:52:492424// Sample json input:
2425// { "command": "SaveTabContents",
2426// "tab_index": 0,
2427// "filename": <a full pathname> }
2428// Sample json output:
2429// {}
2430void AutomationProvider::SaveTabContents(Browser* browser,
2431 DictionaryValue* args,
2432 IPC::Message* reply_message) {
[email protected]7060bb292010-06-24 00:52:492433 int tab_index = 0;
2434 FilePath::StringType filename;
2435 FilePath::StringType parent_directory;
2436 TabContents* tab_contents = NULL;
2437
[email protected]ff4c1d82010-08-04 16:58:122438 if (!args->GetInteger("tab_index", &tab_index) ||
2439 !args->GetString("filename", &filename)) {
[email protected]26adfd312010-07-20 01:04:462440 AutomationJSONReply(this, reply_message).SendError(
2441 "tab_index or filename param missing");
[email protected]7c983cc2010-07-16 11:33:342442 return;
[email protected]7060bb292010-06-24 00:52:492443 } else {
2444 tab_contents = browser->GetTabContentsAt(tab_index);
2445 if (!tab_contents) {
[email protected]26adfd312010-07-20 01:04:462446 AutomationJSONReply(this, reply_message).SendError(
2447 "no tab at tab_index");
[email protected]7060bb292010-06-24 00:52:492448 return;
2449 }
2450 }
[email protected]7c983cc2010-07-16 11:33:342451 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2452 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2453 parent_directory = FilePath(filename).DirName().value();
2454 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2455 SavePackage::SAVE_AS_ONLY_HTML)) {
[email protected]26adfd312010-07-20 01:04:462456 AutomationJSONReply(this, reply_message).SendError(
2457 "Could not initiate SavePage");
[email protected]7c983cc2010-07-16 11:33:342458 return;
2459 }
2460 // The observer will delete itself when done.
2461 new SavePackageNotificationObserver(tab_contents->save_package(),
2462 this, reply_message);
[email protected]7060bb292010-06-24 00:52:492463}
2464
[email protected]c5aa5322010-07-15 19:00:072465// Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
2466// json input.
2467// Sample json output: "{}"
2468void AutomationProvider::ImportSettings(Browser* browser,
2469 DictionaryValue* args,
2470 IPC::Message* reply_message) {
[email protected]c5aa5322010-07-15 19:00:072471 // Map from the json string passed over to the import item masks.
2472 std::map<std::string, ImportItem> string_to_import_item;
2473 string_to_import_item["HISTORY"] = importer::HISTORY;
2474 string_to_import_item["FAVORITES"] = importer::FAVORITES;
2475 string_to_import_item["COOKIES"] = importer::COOKIES;
2476 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
2477 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
2478 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
2479 string_to_import_item["ALL"] = importer::ALL;
2480
[email protected]a748ff62010-08-14 17:25:322481 string16 browser_name;
[email protected]c5aa5322010-07-15 19:00:072482 int import_items = 0;
2483 ListValue* import_items_list = NULL;
2484 bool first_run;
2485
[email protected]a748ff62010-08-14 17:25:322486 if (!args->GetString("import_from", &browser_name) ||
[email protected]ff4c1d82010-08-04 16:58:122487 !args->GetBoolean("first_run", &first_run) ||
2488 !args->GetList("import_items", &import_items_list)) {
[email protected]7c983cc2010-07-16 11:33:342489 AutomationJSONReply(this, reply_message).SendError(
2490 "Incorrect type for one or more of the arguments.");
[email protected]c5aa5322010-07-15 19:00:072491 return;
2492 }
2493
2494 int num_items = import_items_list->GetSize();
2495 for (int i = 0; i < num_items; i++) {
2496 std::string item;
2497 import_items_list->GetString(i, &item);
2498 // If the provided string is not part of the map, error out.
2499 if (!ContainsKey(string_to_import_item, item)) {
[email protected]7c983cc2010-07-16 11:33:342500 AutomationJSONReply(this, reply_message).SendError(
2501 "Invalid item string found in import_items.");
[email protected]c5aa5322010-07-15 19:00:072502 return;
2503 }
2504 import_items |= string_to_import_item[item];
2505 }
2506
2507 ImporterHost* importer_host = new ImporterHost();
2508 // Get the correct ProfileInfo based on the browser they user provided.
2509 importer::ProfileInfo profile_info;
2510 int num_browsers = importer_host->GetAvailableProfileCount();
2511 int i = 0;
2512 for ( ; i < num_browsers; i++) {
[email protected]a748ff62010-08-14 17:25:322513 string16 name = WideToUTF16Hack(importer_host->GetSourceProfileNameAt(i));
[email protected]c5aa5322010-07-15 19:00:072514 if (name == browser_name) {
2515 profile_info = importer_host->GetSourceProfileInfoAt(i);
2516 break;
2517 }
2518 }
2519 // If we made it to the end of the loop, then the input was bad.
2520 if (i == num_browsers) {
[email protected]7c983cc2010-07-16 11:33:342521 AutomationJSONReply(this, reply_message).SendError(
2522 "Invalid browser name string found.");
[email protected]c5aa5322010-07-15 19:00:072523 return;
2524 }
2525
2526 Profile* profile = browser->profile();
2527
2528 importer_host->SetObserver(
2529 new AutomationProviderImportSettingsObserver(this, reply_message));
2530 importer_host->StartImportSettings(profile_info, profile, import_items,
2531 new ProfileWriter(profile), first_run);
2532}
2533
[email protected]95222282010-07-26 17:43:022534namespace {
2535
2536// Translates a dictionary password to a PasswordForm struct.
2537webkit_glue::PasswordForm GetPasswordFormFromDict(
2538 const DictionaryValue& password_dict) {
2539
2540 // If the time is specified, change time to the specified time.
2541 base::Time time = base::Time::Now();
2542 int it;
2543 double dt;
[email protected]ff4c1d82010-08-04 16:58:122544 if (password_dict.GetInteger("time", &it))
[email protected]95222282010-07-26 17:43:022545 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:122546 else if (password_dict.GetReal("time", &dt))
[email protected]95222282010-07-26 17:43:022547 time = base::Time::FromDoubleT(dt);
2548
2549 std::string signon_realm;
2550 string16 username_value;
2551 string16 password_value;
2552 string16 origin_url_text;
2553 string16 username_element;
2554 string16 password_element;
2555 string16 submit_element;
2556 string16 action_target_text;
2557 bool blacklist = false;
2558 string16 old_password_element;
2559 string16 old_password_value;
2560
2561 // We don't care if any of these fail - they are either optional or checked
2562 // before this function is called.
[email protected]ff4c1d82010-08-04 16:58:122563 password_dict.GetString("signon_realm", &signon_realm);
[email protected]698f7f42010-08-04 19:35:332564 password_dict.GetString("username_value", &username_value);
2565 password_dict.GetString("password_value", &password_value);
2566 password_dict.GetString("origin_url", &origin_url_text);
2567 password_dict.GetString("username_element", &username_element);
2568 password_dict.GetString("password_element", &password_element);
2569 password_dict.GetString("submit_element", &submit_element);
2570 password_dict.GetString("action_target", &action_target_text);
[email protected]ff4c1d82010-08-04 16:58:122571 password_dict.GetBoolean("blacklist", &blacklist);
[email protected]95222282010-07-26 17:43:022572
2573 GURL origin_gurl(origin_url_text);
2574 GURL action_target(action_target_text);
2575
2576 webkit_glue::PasswordForm password_form;
2577 password_form.signon_realm = signon_realm;
2578 password_form.username_value = username_value;
2579 password_form.password_value = password_value;
2580 password_form.origin = origin_gurl;
2581 password_form.username_element = username_element;
2582 password_form.password_element = password_element;
2583 password_form.submit_element = submit_element;
2584 password_form.action = action_target;
2585 password_form.blacklisted_by_user = blacklist;
2586 password_form.date_created = time;
2587
2588 return password_form;
2589}
2590
2591} // namespace
2592
[email protected]5bcfe1672010-07-16 20:51:572593// See AddSavedPassword() in chrome/test/functional/pyauto.py for sample json
2594// input.
2595// Sample json output: { "password_added": true }
2596void AutomationProvider::AddSavedPassword(Browser* browser,
2597 DictionaryValue* args,
2598 IPC::Message* reply_message) {
[email protected]5bcfe1672010-07-16 20:51:572599 AutomationJSONReply reply(this, reply_message);
[email protected]95222282010-07-26 17:43:022600 DictionaryValue* password_dict = NULL;
[email protected]5bcfe1672010-07-16 20:51:572601
[email protected]ff4c1d82010-08-04 16:58:122602 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:022603 reply.SendError("Password must be a dictionary.");
[email protected]5bcfe1672010-07-16 20:51:572604 return;
2605 }
2606
[email protected]95222282010-07-26 17:43:022607 // The signon realm is effectively the primary key and must be included.
2608 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:122609 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:022610 reply.SendError("Password must include signon_realm.");
2611 return;
2612 }
2613 webkit_glue::PasswordForm new_password =
2614 GetPasswordFormFromDict(*password_dict);
[email protected]5bcfe1672010-07-16 20:51:572615
2616 Profile* profile = browser->profile();
2617 // Use IMPLICIT_ACCESS since new passwords aren't added off the record.
2618 PasswordStore* password_store =
2619 profile->GetPasswordStore(Profile::IMPLICIT_ACCESS);
2620
2621 // Set the return based on whether setting the password succeeded.
2622 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2623
2624 // It will be null if it's accessed in an incognito window.
2625 if (password_store != NULL) {
2626 password_store->AddLogin(new_password);
[email protected]ff4c1d82010-08-04 16:58:122627 return_value->SetBoolean("password_added", true);
[email protected]5bcfe1672010-07-16 20:51:572628 } else {
[email protected]ff4c1d82010-08-04 16:58:122629 return_value->SetBoolean("password_added", false);
[email protected]5bcfe1672010-07-16 20:51:572630 }
2631
2632 reply.SendSuccess(return_value.get());
2633}
2634
[email protected]95222282010-07-26 17:43:022635// See RemoveSavedPassword() in chrome/test/functional/pyauto.py for sample
2636// json input.
2637// Sample json output: {}
2638void AutomationProvider::RemoveSavedPassword(Browser* browser,
2639 DictionaryValue* args,
2640 IPC::Message* reply_message) {
2641 AutomationJSONReply reply(this, reply_message);
2642 DictionaryValue* password_dict = NULL;
2643
[email protected]ff4c1d82010-08-04 16:58:122644 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:022645 reply.SendError("Password must be a dictionary.");
2646 return;
2647 }
2648
2649 // The signon realm is effectively the primary key and must be included.
2650 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:122651 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:022652 reply.SendError("Password must include signon_realm.");
2653 return;
2654 }
2655 webkit_glue::PasswordForm to_remove =
2656 GetPasswordFormFromDict(*password_dict);
2657
2658 Profile* profile = browser->profile();
2659 // Use EXPLICIT_ACCESS since passwords can be removed off the record.
2660 PasswordStore* password_store =
2661 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
2662
2663 password_store->RemoveLogin(to_remove);
2664 reply.SendSuccess(NULL);
2665}
2666
[email protected]5bcfe1672010-07-16 20:51:572667// Sample json input: { "command": "GetSavedPasswords" }
2668// Refer to GetSavedPasswords() in chrome/test/pyautolib/pyauto.py for sample
2669// json output.
2670void AutomationProvider::GetSavedPasswords(Browser* browser,
2671 DictionaryValue* args,
2672 IPC::Message* reply_message) {
2673 Profile* profile = browser->profile();
2674 // Use EXPLICIT_ACCESS since saved passwords can be retreived off the record.
2675 PasswordStore* password_store =
2676 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
2677 password_store->GetAutofillableLogins(
2678 new AutomationProviderGetPasswordsObserver(this, reply_message));
2679 // Observer deletes itself after returning.
2680}
2681
[email protected]a0fc50d72010-07-14 21:14:192682// Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
2683// json input.
2684// Sample json output: {}
2685void AutomationProvider::ClearBrowsingData(Browser* browser,
2686 DictionaryValue* args,
2687 IPC::Message* reply_message) {
[email protected]a0fc50d72010-07-14 21:14:192688 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
2689 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
2690 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
2691 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
2692 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
2693 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
2694
2695 std::map<std::string, int> string_to_mask_value;
2696 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
2697 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
2698 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
2699 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
2700 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
2701 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
2702
2703 std::string time_period;
2704 ListValue* to_remove;
[email protected]ff4c1d82010-08-04 16:58:122705 if (!args->GetString("time_period", &time_period) ||
2706 !args->GetList("to_remove", &to_remove)) {
[email protected]7c983cc2010-07-16 11:33:342707 AutomationJSONReply(this, reply_message).SendError(
2708 "time_period must be a string and to_remove a list.");
[email protected]a0fc50d72010-07-14 21:14:192709 return;
2710 }
2711
2712 int remove_mask = 0;
2713 int num_removals = to_remove->GetSize();
2714 for (int i = 0; i < num_removals; i++) {
2715 std::string removal;
2716 to_remove->GetString(i, &removal);
2717 // If the provided string is not part of the map, then error out.
2718 if (!ContainsKey(string_to_mask_value, removal)) {
[email protected]7c983cc2010-07-16 11:33:342719 AutomationJSONReply(this, reply_message).SendError(
2720 "Invalid browsing data string found in to_remove.");
[email protected]a0fc50d72010-07-14 21:14:192721 return;
2722 }
2723 remove_mask |= string_to_mask_value[removal];
2724 }
2725
2726 if (!ContainsKey(string_to_time_period, time_period)) {
[email protected]7c983cc2010-07-16 11:33:342727 AutomationJSONReply(this, reply_message).SendError(
2728 "Invalid string for time_period.");
[email protected]a0fc50d72010-07-14 21:14:192729 return;
2730 }
2731
2732 BrowsingDataRemover* remover = new BrowsingDataRemover(
2733 profile(), string_to_time_period[time_period], base::Time());
2734
2735 remover->AddObserver(
2736 new AutomationProviderBrowsingDataObserver(this, reply_message));
2737 remover->Remove(remove_mask);
2738 // BrowsingDataRemover deletes itself using DeleteTask.
2739 // The observer also deletes itself after sending the reply.
2740}
2741
[email protected]3dda5b02010-07-27 16:35:422742namespace {
2743
2744 // Get the TabContents from a dictionary of arguments.
2745 TabContents* GetTabContentsFromDict(const Browser* browser,
2746 const DictionaryValue* args,
2747 std::string* error_message) {
2748 int tab_index;
[email protected]ff4c1d82010-08-04 16:58:122749 if (!args->GetInteger("tab_index", &tab_index)) {
[email protected]3dda5b02010-07-27 16:35:422750 *error_message = "Must include tab_index.";
2751 return NULL;
2752 }
2753
2754 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2755 if (!tab_contents) {
2756 *error_message = StringPrintf("No tab at index %d.", tab_index);
2757 return NULL;
2758 }
2759 return tab_contents;
2760 }
2761
2762 // Get the TranslateInfoBarDelegate from TabContents.
2763 TranslateInfoBarDelegate* GetTranslateInfoBarDelegate(
2764 TabContents* tab_contents) {
2765 for (int i = 0; i < tab_contents->infobar_delegate_count(); i++) {
2766 InfoBarDelegate* infobar = tab_contents->GetInfoBarDelegateAt(i);
2767 if (infobar->AsTranslateInfoBarDelegate())
2768 return infobar->AsTranslateInfoBarDelegate();
2769 }
2770 // No translate infobar.
2771 return NULL;
2772 }
2773
2774} // namespace
2775
2776// See GetTranslateInfo() in chrome/test/pyautolib/pyauto.py for sample json
2777// input and output.
2778void AutomationProvider::GetTranslateInfo(Browser* browser,
2779 DictionaryValue* args,
2780 IPC::Message* reply_message) {
2781 std::string error_message;
2782 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2783 &error_message);
2784 if (!tab_contents) {
2785 AutomationJSONReply(this, reply_message).SendError(error_message);
2786 return;
2787 }
2788
2789 // Get the translate bar if there is one and pass it to the observer.
2790 // The observer will check for null and populate the information accordingly.
2791 TranslateInfoBarDelegate* translate_bar =
2792 GetTranslateInfoBarDelegate(tab_contents);
2793
2794 TabLanguageDeterminedObserver* observer = new TabLanguageDeterminedObserver(
2795 this, reply_message, tab_contents, translate_bar);
2796 // If the language for the page hasn't been loaded yet, then just make
2797 // the observer, otherwise call observe directly.
2798 std::string language = tab_contents->language_state().original_language();
2799 if (!language.empty()) {
2800 observer->Observe(NotificationType::TAB_LANGUAGE_DETERMINED,
2801 Source<TabContents>(tab_contents),
2802 Details<std::string>(&language));
2803 }
2804}
2805
2806// See SelectTranslateOption() in chrome/test/pyautolib/pyauto.py for sample
2807// json input.
2808// Sample json output: {}
2809void AutomationProvider::SelectTranslateOption(Browser* browser,
2810 DictionaryValue* args,
2811 IPC::Message* reply_message) {
2812 std::string option;
2813 std::string error_message;
2814 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2815 &error_message);
2816 if (!tab_contents) {
2817 AutomationJSONReply(this, reply_message).SendError(error_message);
2818 return;
2819 }
2820
2821 TranslateInfoBarDelegate* translate_bar =
2822 GetTranslateInfoBarDelegate(tab_contents);
2823 if (!translate_bar) {
2824 AutomationJSONReply(this, reply_message)
2825 .SendError("There is no translate bar open.");
2826 return;
2827 }
2828
[email protected]ff4c1d82010-08-04 16:58:122829 if (!args->GetString("option", &option)) {
[email protected]3dda5b02010-07-27 16:35:422830 AutomationJSONReply(this, reply_message).SendError("Must include option");
2831 return;
2832 }
2833
2834 if (option == "translate_page") {
2835 // Make a new notification observer which will send the reply.
2836 new PageTranslatedObserver(this, reply_message, tab_contents);
2837 translate_bar->Translate();
2838 return;
[email protected]da1913e2010-08-04 23:50:152839 } else if (option == "set_target_language") {
2840 string16 target_language;
2841 if (!args->GetString("target_language", &target_language)) {
2842 AutomationJSONReply(this, reply_message).
2843 SendError("Must include target_language string.");
2844 return;
2845 }
2846 // Get the target language index based off of the language name.
2847 int target_language_index = -1;
2848 for (int i = 0; i < translate_bar->GetLanguageCount(); i++) {
2849 if (translate_bar->GetLanguageDisplayableNameAt(i) == target_language) {
2850 target_language_index = i;
2851 break;
2852 }
2853 }
2854 if (target_language_index == -1) {
2855 AutomationJSONReply(this, reply_message)
2856 .SendError("Invalid target language string.");
2857 return;
2858 }
2859 // If the page has already been translated it will be translated again to
2860 // the new language. The observer will wait until the page has been
2861 // translated to reply.
2862 if (translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE) {
2863 new PageTranslatedObserver(this, reply_message, tab_contents);
2864 translate_bar->SetTargetLanguage(target_language_index);
2865 return;
2866 }
2867 // Otherwise just send the reply back immediately.
2868 translate_bar->SetTargetLanguage(target_language_index);
2869 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2870 return_value->SetBoolean("translation_success", true);
2871 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2872 return;
[email protected]4a47d76122010-08-10 18:11:162873 } else if (option == "click_always_translate_lang_button") {
2874 if (!translate_bar->ShouldShowAlwaysTranslateButton()) {
2875 AutomationJSONReply(this, reply_message)
2876 .SendError("Always translate button not showing.");
2877 return;
2878 }
2879 // Clicking 'Always Translate' triggers a translation. The observer will
2880 // wait until the translation is complete before sending the reply.
2881 new PageTranslatedObserver(this, reply_message, tab_contents);
2882 translate_bar->AlwaysTranslatePageLanguage();
2883 return;
[email protected]3dda5b02010-07-27 16:35:422884 }
2885
2886 AutomationJSONReply reply(this, reply_message);
2887 if (option == "never_translate_language") {
2888 if (translate_bar->IsLanguageBlacklisted()) {
2889 reply.SendError("The language was already blacklisted.");
2890 return;
2891 }
2892 translate_bar->ToggleLanguageBlacklist();
2893 reply.SendSuccess(NULL);
2894 } else if (option == "never_translate_site") {
2895 if (translate_bar->IsSiteBlacklisted()) {
2896 reply.SendError("The site was already blacklisted.");
2897 return;
2898 }
2899 translate_bar->ToggleSiteBlacklist();
2900 reply.SendSuccess(NULL);
2901 } else if (option == "toggle_always_translate") {
2902 translate_bar->ToggleAlwaysTranslate();
2903 reply.SendSuccess(NULL);
2904 } else if (option == "revert_translation") {
2905 translate_bar->RevertTranslation();
2906 reply.SendSuccess(NULL);
[email protected]4a47d76122010-08-10 18:11:162907 } else if (option == "click_never_translate_lang_button") {
2908 if (!translate_bar->ShouldShowNeverTranslateButton()) {
2909 reply.SendError("Always translate button not showing.");
2910 return;
2911 }
2912 translate_bar->NeverTranslatePageLanguage();
2913 reply.SendSuccess(NULL);
2914 } else if (option == "decline_translation") {
2915 // This is the function called when an infobar is dismissed or when the
2916 // user clicks the 'Nope' translate button.
2917 translate_bar->TranslationDeclined();
[email protected]a9add882010-08-16 20:37:482918 tab_contents->RemoveInfoBar(translate_bar);
[email protected]4a47d76122010-08-10 18:11:162919 reply.SendSuccess(NULL);
[email protected]3dda5b02010-07-27 16:35:422920 } else {
2921 reply.SendError("Invalid string found for option.");
2922 }
2923}
2924
[email protected]f89ee5d2010-08-02 16:39:122925// See WaitUntilTranslateComplete() in chrome/test/pyautolib/pyauto.py for
2926// sample json input and output.
2927void AutomationProvider::WaitUntilTranslateComplete(
2928 Browser* browser, DictionaryValue* args, IPC::Message* reply_message) {
2929 std::string error_message;
2930 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2931 &error_message);
2932 if (!tab_contents) {
2933 AutomationJSONReply(this, reply_message).SendError(error_message);
2934 return;
2935 }
2936
[email protected]f89ee5d2010-08-02 16:39:122937 TranslateInfoBarDelegate* translate_bar =
2938 GetTranslateInfoBarDelegate(tab_contents);
2939 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]14a0aac2010-08-05 15:52:592940
[email protected]f89ee5d2010-08-02 16:39:122941 if (!translate_bar) {
[email protected]57ecc4b2010-08-11 03:02:512942 return_value->SetBoolean("translation_success", false);
[email protected]14a0aac2010-08-05 15:52:592943 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2944 return;
[email protected]f89ee5d2010-08-02 16:39:122945 }
[email protected]14a0aac2010-08-05 15:52:592946
2947 // If the translation is still pending, the observer will wait
2948 // for it to finish and then reply.
2949 if (translate_bar->type() == TranslateInfoBarDelegate::TRANSLATING) {
2950 new PageTranslatedObserver(this, reply_message, tab_contents);
2951 return;
2952 }
2953
2954 // Otherwise send back the success or failure of the attempted translation.
2955 return_value->SetBoolean(
[email protected]57ecc4b2010-08-11 03:02:512956 "translation_success",
[email protected]14a0aac2010-08-05 15:52:592957 translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE);
2958 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f89ee5d2010-08-02 16:39:122959}
2960
[email protected]4d1929f12010-07-10 00:09:032961// Sample json input: { "command": "GetThemeInfo" }
2962// Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
2963void AutomationProvider::GetThemeInfo(Browser* browser,
2964 DictionaryValue* args,
2965 IPC::Message* reply_message) {
2966 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2967 Extension* theme = browser->profile()->GetTheme();
2968 if (theme) {
[email protected]ff4c1d82010-08-04 16:58:122969 return_value->SetString("name", theme->name());
2970 return_value->Set("images", theme->GetThemeImages()->DeepCopy());
2971 return_value->Set("colors", theme->GetThemeColors()->DeepCopy());
2972 return_value->Set("tints", theme->GetThemeTints()->DeepCopy());
[email protected]4d1929f12010-07-10 00:09:032973 }
[email protected]7c983cc2010-07-16 11:33:342974 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]4d1929f12010-07-10 00:09:032975}
2976
[email protected]32a69cf2010-08-03 16:27:012977// Sample json input: { "command": "GetExtensionsInfo" }
2978// See GetExtensionsInfo() in chrome/test/pyautolib/pyauto.py for sample json
2979// output.
2980void AutomationProvider::GetExtensionsInfo(Browser* browser,
2981 DictionaryValue* args,
2982 IPC::Message* reply_message) {
2983 AutomationJSONReply reply(this, reply_message);
2984 ExtensionsService* service = profile()->GetExtensionsService();
2985 if (!service) {
2986 reply.SendError("No extensions service.");
2987 }
2988 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2989 ListValue* extensions_values = new ListValue;
2990 const ExtensionList* extensions = service->extensions();
2991 for (ExtensionList::const_iterator it = extensions->begin();
2992 it != extensions->end(); ++it) {
2993 const Extension* extension = *it;
2994 DictionaryValue* extension_value = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122995 extension_value->SetString("id", extension->id());
2996 extension_value->SetString("version", extension->VersionString());
2997 extension_value->SetString("name", extension->name());
2998 extension_value->SetString("public_key", extension->public_key());
2999 extension_value->SetString("description", extension->description());
3000 extension_value->SetString("background_url",
[email protected]32a69cf2010-08-03 16:27:013001 extension->background_url().spec());
[email protected]ff4c1d82010-08-04 16:58:123002 extension_value->SetString("options_url",
[email protected]32a69cf2010-08-03 16:27:013003 extension->options_url().spec());
3004 extensions_values->Append(extension_value);
3005 }
[email protected]ff4c1d82010-08-04 16:58:123006 return_value->Set("extensions", extensions_values);
[email protected]32a69cf2010-08-03 16:27:013007 reply.SendSuccess(return_value.get());
3008}
3009
3010// See UninstallExtensionById() in chrome/test/pyautolib/pyauto.py for sample
3011// json input.
3012// Sample json output: {}
3013void AutomationProvider::UninstallExtensionById(Browser* browser,
3014 DictionaryValue* args,
3015 IPC::Message* reply_message) {
3016 AutomationJSONReply reply(this, reply_message);
3017 std::string id;
[email protected]ff4c1d82010-08-04 16:58:123018 if (!args->GetString("id", &id)) {
[email protected]32a69cf2010-08-03 16:27:013019 reply.SendError("Must include string id.");
3020 return;
3021 }
3022 ExtensionsService* service = profile()->GetExtensionsService();
3023 if (!service) {
3024 reply.SendError("No extensions service.");
3025 return;
3026 }
3027 ExtensionUnloadNotificationObserver observer;
3028 service->UninstallExtension(id, false);
3029 reply.SendSuccess(NULL);
3030}
3031
[email protected]55846ad842010-07-09 18:22:563032// Sample json input:
3033// { "command": "GetAutoFillProfile" }
3034// Refer to GetAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
3035// json output.
3036void AutomationProvider::GetAutoFillProfile(Browser* browser,
3037 DictionaryValue* args,
3038 IPC::Message* reply_message) {
[email protected]55846ad842010-07-09 18:22:563039 // Get the AutoFillProfiles currently in the database.
3040 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:123041 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:563042 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
[email protected]7c983cc2010-07-16 11:33:343043 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:563044
3045 if (tab_contents) {
3046 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
3047 ->GetPersonalDataManager();
3048 if (pdm) {
3049 std::vector<AutoFillProfile*> autofill_profiles = pdm->profiles();
3050 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
3051
3052 ListValue* profiles = GetListFromAutoFillProfiles(autofill_profiles);
3053 ListValue* cards = GetListFromCreditCards(credit_cards);
3054
3055 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3056
[email protected]ff4c1d82010-08-04 16:58:123057 return_value->Set("profiles", profiles);
3058 return_value->Set("credit_cards", cards);
[email protected]7c983cc2010-07-16 11:33:343059 reply.SendSuccess(return_value.get());
[email protected]55846ad842010-07-09 18:22:563060 } else {
[email protected]7c983cc2010-07-16 11:33:343061 reply.SendError("No PersonalDataManager.");
3062 return;
[email protected]55846ad842010-07-09 18:22:563063 }
3064 } else {
[email protected]7c983cc2010-07-16 11:33:343065 reply.SendError("No tab at that index.");
3066 return;
[email protected]55846ad842010-07-09 18:22:563067 }
[email protected]55846ad842010-07-09 18:22:563068}
3069
3070// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
3071// json input.
3072// Sample json output: {}
3073void AutomationProvider::FillAutoFillProfile(Browser* browser,
3074 DictionaryValue* args,
3075 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:343076 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:563077 ListValue* profiles = NULL;
3078 ListValue* cards = NULL;
[email protected]ff4c1d82010-08-04 16:58:123079 args->GetList("profiles", &profiles);
3080 args->GetList("credit_cards", &cards);
[email protected]7c983cc2010-07-16 11:33:343081 std::string error_mesg;
[email protected]55846ad842010-07-09 18:22:563082
3083 std::vector<AutoFillProfile> autofill_profiles;
3084 std::vector<CreditCard> credit_cards;
3085 // Create an AutoFillProfile for each of the dictionary profiles.
3086 if (profiles) {
[email protected]7c983cc2010-07-16 11:33:343087 autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg);
[email protected]55846ad842010-07-09 18:22:563088 }
3089 // Create a CreditCard for each of the dictionary values.
3090 if (cards) {
[email protected]7c983cc2010-07-16 11:33:343091 credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
3092 }
3093 if (!error_mesg.empty()) {
3094 reply.SendError(error_mesg);
3095 return;
[email protected]55846ad842010-07-09 18:22:563096 }
3097
3098 // Save the AutoFillProfiles.
3099 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:123100 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:563101 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
3102
3103 if (tab_contents) {
[email protected]ce6b0122010-07-19 19:07:303104 PersonalDataManager* pdm = tab_contents->profile()
[email protected]55846ad842010-07-09 18:22:563105 ->GetPersonalDataManager();
3106 if (pdm) {
3107 pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
3108 cards? &credit_cards : NULL);
3109 } else {
[email protected]7c983cc2010-07-16 11:33:343110 reply.SendError("No PersonalDataManager.");
3111 return;
[email protected]55846ad842010-07-09 18:22:563112 }
3113 } else {
[email protected]7c983cc2010-07-16 11:33:343114 reply.SendError("No tab at that index.");
3115 return;
[email protected]55846ad842010-07-09 18:22:563116 }
[email protected]7c983cc2010-07-16 11:33:343117 reply.SendSuccess(NULL);
[email protected]55846ad842010-07-09 18:22:563118}
3119
3120/* static */
3121ListValue* AutomationProvider::GetListFromAutoFillProfiles(
3122 std::vector<AutoFillProfile*> autofill_profiles) {
3123 ListValue* profiles = new ListValue;
3124
3125 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string
3126 = GetAutoFillFieldToStringMap();
3127
3128 // For each AutoFillProfile, transform it to a dictionary object to return.
3129 for (std::vector<AutoFillProfile*>::iterator it = autofill_profiles.begin();
3130 it != autofill_profiles.end(); ++it) {
3131 AutoFillProfile* profile = *it;
3132 DictionaryValue* profile_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:123133 profile_info->SetString("label", profile->Label());
[email protected]55846ad842010-07-09 18:22:563134 // For each of the types, if it has a value, add it to the dictionary.
3135 for (std::map<AutoFillFieldType, std::wstring>::iterator
3136 type_it = autofill_type_to_string.begin();
3137 type_it != autofill_type_to_string.end(); ++type_it) {
3138 string16 value = profile->GetFieldText(AutoFillType(type_it->first));
3139 if (value.length()) { // If there was something stored for that value.
[email protected]99922662010-08-17 16:24:253140 profile_info->SetString(WideToUTF8(type_it->second), value);
[email protected]55846ad842010-07-09 18:22:563141 }
3142 }
3143 profiles->Append(profile_info);
3144 }
3145 return profiles;
3146}
3147
3148/* static */
3149ListValue* AutomationProvider::GetListFromCreditCards(
3150 std::vector<CreditCard*> credit_cards) {
3151 ListValue* cards = new ListValue;
3152
3153 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
3154 GetCreditCardFieldToStringMap();
3155
3156 // For each AutoFillProfile, transform it to a dictionary object to return.
3157 for (std::vector<CreditCard*>::iterator it = credit_cards.begin();
3158 it != credit_cards.end(); ++it) {
3159 CreditCard* card = *it;
3160 DictionaryValue* card_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:123161 card_info->SetString("label", card->Label());
[email protected]55846ad842010-07-09 18:22:563162 // For each of the types, if it has a value, add it to the dictionary.
3163 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3164 credit_card_type_to_string.begin();
3165 type_it != credit_card_type_to_string.end(); ++type_it) {
3166 string16 value = card->GetFieldText(AutoFillType(type_it->first));
3167 // If there was something stored for that value.
3168 if (value.length()) {
[email protected]99922662010-08-17 16:24:253169 card_info->SetString(WideToUTF8(type_it->second), value);
[email protected]55846ad842010-07-09 18:22:563170 }
3171 }
3172 cards->Append(card_info);
3173 }
3174 return cards;
3175}
3176
3177/* static */
3178std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
[email protected]7c983cc2010-07-16 11:33:343179 const ListValue& profiles, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:563180 std::vector<AutoFillProfile> autofill_profiles;
3181 DictionaryValue* profile_info = NULL;
3182 string16 profile_label;
3183 string16 current_value;
3184
3185 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string =
3186 GetAutoFillFieldToStringMap();
3187
3188 int num_profiles = profiles.GetSize();
3189 for (int i = 0; i < num_profiles; i++) {
3190 profiles.GetDictionary(i, &profile_info);
3191 profile_info->GetString("label", &profile_label);
3192 // Choose an id of 0 so that a unique id will be created.
3193 AutoFillProfile profile(profile_label, 0);
3194 // Loop through the possible profile types and add those provided.
3195 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3196 autofill_type_to_string.begin();
3197 type_it != autofill_type_to_string.end(); ++type_it) {
[email protected]99922662010-08-17 16:24:253198 if (profile_info->HasKey(WideToUTF8(type_it->second))) {
[email protected]698f7f42010-08-04 19:35:333199 if (profile_info->GetString(WideToUTF8(type_it->second),
3200 &current_value)) {
[email protected]55846ad842010-07-09 18:22:563201 profile.SetInfo(AutoFillType(type_it->first), current_value);
3202 } else {
[email protected]7c983cc2010-07-16 11:33:343203 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:563204 break;
3205 }
3206 }
3207 }
3208 autofill_profiles.push_back(profile);
3209 }
3210 return autofill_profiles;
3211}
3212
3213/* static */
3214std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
[email protected]7c983cc2010-07-16 11:33:343215 const ListValue& cards, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:563216 std::vector<CreditCard> credit_cards;
3217 DictionaryValue* card_info = NULL;
3218 string16 card_label;
3219 string16 current_value;
3220
3221 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
3222 GetCreditCardFieldToStringMap();
3223
3224 int num_credit_cards = cards.GetSize();
3225 for (int i = 0; i < num_credit_cards; i++) {
3226 cards.GetDictionary(i, &card_info);
3227 card_info->GetString("label", &card_label);
3228 CreditCard card(card_label, 0);
3229 // Loop through the possible credit card fields and add those provided.
3230 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3231 credit_card_type_to_string.begin();
3232 type_it != credit_card_type_to_string.end(); ++type_it) {
[email protected]99922662010-08-17 16:24:253233 if (card_info->HasKey(WideToUTF8(type_it->second))) {
[email protected]698f7f42010-08-04 19:35:333234 if (card_info->GetString(WideToUTF8(type_it->second), &current_value)) {
[email protected]55846ad842010-07-09 18:22:563235 card.SetInfo(AutoFillType(type_it->first), current_value);
3236 } else {
[email protected]7c983cc2010-07-16 11:33:343237 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:563238 break;
3239 }
3240 }
3241 }
3242 credit_cards.push_back(card);
3243 }
3244 return credit_cards;
3245}
3246
3247/* static */
3248std::map<AutoFillFieldType, std::wstring>
3249 AutomationProvider::GetAutoFillFieldToStringMap() {
3250 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string;
3251 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
3252 autofill_type_to_string[NAME_MIDDLE] = L"NAME_MIDDLE";
3253 autofill_type_to_string[NAME_LAST] = L"NAME_LAST";
3254 autofill_type_to_string[COMPANY_NAME] = L"COMPANY_NAME";
3255 autofill_type_to_string[EMAIL_ADDRESS] = L"EMAIL_ADDRESS";
3256 autofill_type_to_string[ADDRESS_HOME_LINE1] = L"ADDRESS_HOME_LINE1";
3257 autofill_type_to_string[ADDRESS_HOME_LINE2] = L"ADDRESS_HOME_LINE2";
3258 autofill_type_to_string[ADDRESS_HOME_CITY] = L"ADDRESS_HOME_CITY";
3259 autofill_type_to_string[ADDRESS_HOME_STATE] = L"ADDRESS_HOME_STATE";
3260 autofill_type_to_string[ADDRESS_HOME_ZIP] = L"ADDRESS_HOME_ZIP";
3261 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = L"ADDRESS_HOME_COUNTRY";
3262 autofill_type_to_string[PHONE_HOME_NUMBER] = L"PHONE_HOME_NUMBER";
3263 autofill_type_to_string[PHONE_FAX_NUMBER] = L"PHONE_FAX_NUMBER";
3264 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
3265 return autofill_type_to_string;
3266}
3267
3268/* static */
3269std::map<AutoFillFieldType, std::wstring>
3270 AutomationProvider::GetCreditCardFieldToStringMap() {
3271 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string;
3272 credit_card_type_to_string[CREDIT_CARD_NAME] = L"CREDIT_CARD_NAME";
3273 credit_card_type_to_string[CREDIT_CARD_NUMBER] = L"CREDIT_CARD_NUMBER";
[email protected]55846ad842010-07-09 18:22:563274 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = L"CREDIT_CARD_EXP_MONTH";
3275 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
3276 L"CREDIT_CARD_EXP_4_DIGIT_YEAR";
3277 return credit_card_type_to_string;
3278}
3279
[email protected]53329582010-05-14 21:10:583280void AutomationProvider::SendJSONRequest(int handle,
3281 std::string json_request,
3282 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:043283 Browser* browser = NULL;
[email protected]59a611242010-04-02 02:24:043284 scoped_ptr<Value> values;
3285
3286 // Basic error checking.
3287 if (browser_tracker_->ContainsHandle(handle)) {
3288 browser = browser_tracker_->GetResource(handle);
3289 }
3290 if (!browser) {
[email protected]7c983cc2010-07-16 11:33:343291 AutomationJSONReply(this, reply_message).SendError("no browser object");
3292 return;
3293 }
3294 base::JSONReader reader;
3295 std::string error;
3296 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
3297 if (!error.empty()) {
3298 AutomationJSONReply(this, reply_message).SendError(error);
3299 return;
[email protected]59a611242010-04-02 02:24:043300 }
3301
3302 // Make sure input is a dict with a string command.
3303 std::string command;
3304 DictionaryValue* dict_value = NULL;
[email protected]7c983cc2010-07-16 11:33:343305 if (values->GetType() != Value::TYPE_DICTIONARY) {
3306 AutomationJSONReply(this, reply_message).SendError("not a dict");
3307 return;
3308 }
3309 // Ownership remains with "values" variable.
3310 dict_value = static_cast<DictionaryValue*>(values.get());
3311 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
3312 AutomationJSONReply(this, reply_message).SendError(
3313 "no command key in dict or not a string command");
3314 return;
[email protected]59a611242010-04-02 02:24:043315 }
3316
[email protected]24e2b102010-04-29 17:56:473317 // Map json commands to their handlers.
3318 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:053319 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
3320 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
3321 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
3322
[email protected]a9ff2c02010-05-13 17:33:053323 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
[email protected]7c983cc2010-07-16 11:33:343324
[email protected]38b5a3852010-07-21 06:49:523325 handler_map["WaitForInfobarCount"] = &AutomationProvider::WaitForInfobarCount;
[email protected]e004a2d2010-07-22 04:55:283326 handler_map["PerformActionOnInfobar"] =
3327 &AutomationProvider::PerformActionOnInfobar;
[email protected]38b5a3852010-07-21 06:49:523328
[email protected]24e2b102010-04-29 17:56:473329 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:293330 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:053331
[email protected]53329582010-05-14 21:10:583332 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
3333 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
3334 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
3335 handler_map["OmniboxMovePopupSelection"] =
3336 &AutomationProvider::OmniboxMovePopupSelection;
3337
[email protected]24e2b102010-04-29 17:56:473338 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
3339 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:053340
[email protected]ef413ca2010-05-25 21:09:143341 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
3342
[email protected]f7d48012010-05-06 08:17:053343 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:473344 handler_map["WaitForAllDownloadsToComplete"] =
3345 &AutomationProvider::WaitForDownloadsToComplete;
3346
[email protected]a3cd5022010-06-16 18:25:293347 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
3348
[email protected]7060bb292010-06-24 00:52:493349 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
3350
[email protected]c5aa5322010-07-15 19:00:073351 handler_map["ImportSettings"] = &AutomationProvider::ImportSettings;
3352
[email protected]5bcfe1672010-07-16 20:51:573353 handler_map["AddSavedPassword"] = &AutomationProvider::AddSavedPassword;
[email protected]95222282010-07-26 17:43:023354 handler_map["RemoveSavedPassword"] =
3355 &AutomationProvider::RemoveSavedPassword;
[email protected]5bcfe1672010-07-16 20:51:573356 handler_map["GetSavedPasswords"] = &AutomationProvider::GetSavedPasswords;
3357
[email protected]a0fc50d72010-07-14 21:14:193358 handler_map["ClearBrowsingData"] = &AutomationProvider::ClearBrowsingData;
3359
[email protected]4d1929f12010-07-10 00:09:033360 // SetTheme() implemented using InstallExtension().
3361 handler_map["GetThemeInfo"] = &AutomationProvider::GetThemeInfo;
3362
[email protected]32a69cf2010-08-03 16:27:013363 // InstallExtension() present in pyauto.py.
3364 handler_map["GetExtensionsInfo"] = &AutomationProvider::GetExtensionsInfo;
3365 handler_map["UninstallExtensionById"] =
3366 &AutomationProvider::UninstallExtensionById;
3367
[email protected]3dda5b02010-07-27 16:35:423368 handler_map["SelectTranslateOption"] =
3369 &AutomationProvider::SelectTranslateOption;
3370 handler_map["GetTranslateInfo"] = &AutomationProvider::GetTranslateInfo;
[email protected]f89ee5d2010-08-02 16:39:123371 handler_map["WaitUntilTranslateComplete"] =
3372 &AutomationProvider::WaitUntilTranslateComplete;
[email protected]3dda5b02010-07-27 16:35:423373
[email protected]55846ad842010-07-09 18:22:563374 handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
3375 handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
3376
[email protected]7c983cc2010-07-16 11:33:343377 if (handler_map.find(std::string(command)) != handler_map.end()) {
3378 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]1ac875d22010-07-16 09:57:583379 } else {
[email protected]7c983cc2010-07-16 11:33:343380 std::string error_string = "Unknown command. Options: ";
3381 for (std::map<std::string, JsonHandler>::const_iterator it =
3382 handler_map.begin(); it != handler_map.end(); ++it) {
3383 error_string += it->first + ", ";
3384 }
3385 AutomationJSONReply(this, reply_message).SendError(error_string);
[email protected]1ac875d22010-07-16 09:57:583386 }
[email protected]59a611242010-04-02 02:24:043387}
3388
initial.commit09911bf2008-07-26 23:55:293389void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:563390 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:343391 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
3392 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:563393 DCHECK(reply_message_ == NULL);
3394 reply_message_ = reply_message;
3395
[email protected]d9f9b792009-06-24 13:17:123396 DevToolsManager::GetInstance()->InspectElement(
3397 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:293398 } else {
[email protected]71f65dd2009-02-11 19:14:563399 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
3400 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293401 }
3402}
3403
3404void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:093405 if (reply_message_) {
3406 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
3407 num_resources);
3408 Send(reply_message_);
3409 reply_message_ = NULL;
3410 }
initial.commit09911bf2008-07-26 23:55:293411}
3412
[email protected]a7eee32f2009-05-22 18:08:173413class SetProxyConfigTask : public Task {
3414 public:
[email protected]be180c802009-10-23 06:33:313415 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
3416 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:253417 : request_context_getter_(request_context_getter),
3418 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:173419 virtual void Run() {
3420 // First, deserialize the JSON string. If this fails, log and bail.
3421 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:393422 std::string error_msg;
3423 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:173424 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
3425 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:393426 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:173427 return;
3428 }
3429
3430 scoped_ptr<DictionaryValue> dict(
3431 static_cast<DictionaryValue*>(root.release()));
3432 // Now put together a proxy configuration from the deserialized string.
3433 net::ProxyConfig pc;
3434 PopulateProxyConfig(*dict.get(), &pc);
3435
[email protected]be180c802009-10-23 06:33:313436 net::ProxyService* proxy_service =
3437 request_context_getter_->GetURLRequestContext()->proxy_service();
3438 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:173439 scoped_ptr<net::ProxyConfigService> proxy_config_service(
3440 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:313441 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:173442 }
3443
3444 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
3445 DCHECK(pc);
3446 bool no_proxy = false;
3447 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
3448 // Make no changes to the ProxyConfig.
3449 return;
3450 }
3451 bool auto_config;
3452 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:483453 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:173454 }
3455 std::string pac_url;
3456 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:483457 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:173458 }
3459 std::string proxy_bypass_list;
3460 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:483461 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:173462 }
3463 std::string proxy_server;
3464 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:483465 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:173466 }
3467 }
3468
3469 private:
[email protected]be180c802009-10-23 06:33:313470 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:173471 std::string proxy_config_;
3472};
3473
3474
3475void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:313476 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
3477 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:173478 FilePath user_data_dir;
3479 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
3480 ProfileManager* profile_manager = g_browser_process->profile_manager();
3481 DCHECK(profile_manager);
3482 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
3483 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:313484 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:173485 }
[email protected]be180c802009-10-23 06:33:313486 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:173487
[email protected]fae20792009-10-28 20:31:583488 ChromeThread::PostTask(
3489 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:313490 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:173491}
3492
[email protected]4f3dc372009-02-24 00:10:293493void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:333494 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:293495 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:293496 if (tab_tracker_->ContainsHandle(handle)) {
3497 NavigationController* tab = tab_tracker_->GetResource(handle);
3498 DownloadManager* dlm = tab->profile()->GetDownloadManager();
3499 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:333500 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:293501 }
initial.commit09911bf2008-07-26 23:55:293502}
3503
[email protected]6a5670d22009-10-27 16:21:343504void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:143505 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:533506 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
3507 reply_message);
3508}
3509
3510void AutomationProvider::OpenNewBrowserWindowOfType(
3511 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:143512 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:293513 // We may have no current browser windows open so don't rely on
3514 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:533515 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
3516 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:053517 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:153518 if (show)
[email protected]15952e462008-11-14 00:29:053519 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:293520}
3521
[email protected]71f65dd2009-02-11 19:14:563522void AutomationProvider::GetWindowForBrowser(int browser_handle,
3523 bool* success,
3524 int* handle) {
3525 *success = false;
3526 *handle = 0;
initial.commit09911bf2008-07-26 23:55:293527
3528 if (browser_tracker_->ContainsHandle(browser_handle)) {
3529 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:203530 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:293531 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:203532 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:563533 *success = true;
initial.commit09911bf2008-07-26 23:55:293534 }
initial.commit09911bf2008-07-26 23:55:293535}
3536
3537void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:563538 int browser_handle,
3539 bool* success,
3540 int* autocomplete_edit_handle) {
3541 *success = false;
3542 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:293543
3544 if (browser_tracker_->ContainsHandle(browser_handle)) {
3545 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:063546 LocationBar* loc_bar = browser->window()->GetLocationBar();
3547 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:293548 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:563549 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
3550 *success = true;
initial.commit09911bf2008-07-26 23:55:293551 }
initial.commit09911bf2008-07-26 23:55:293552}
initial.commit09911bf2008-07-26 23:55:293553
[email protected]71f65dd2009-02-11 19:14:563554void AutomationProvider::ShowInterstitialPage(int tab_handle,
3555 const std::string& html_text,
3556 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293557 if (tab_tracker_->ContainsHandle(tab_handle)) {
3558 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:113559 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:403560
[email protected]7dad3d5f2010-03-04 00:27:013561 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:403562 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:343563 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:403564 GURL("about:interstitial"),
3565 html_text);
3566 interstitial->Show();
3567 return;
initial.commit09911bf2008-07-26 23:55:293568 }
[email protected]71f65dd2009-02-11 19:14:563569
[email protected]457f5cf2009-08-18 16:37:523570 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
3571 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563572 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293573}
3574
[email protected]71f65dd2009-02-11 19:14:563575void AutomationProvider::HideInterstitialPage(int tab_handle,
3576 bool* success) {
3577 *success = false;
[email protected]57c6a652009-05-04 07:58:343578 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
3579 if (tab_contents && tab_contents->interstitial_page()) {
3580 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:563581 *success = true;
initial.commit09911bf2008-07-26 23:55:293582 }
initial.commit09911bf2008-07-26 23:55:293583}
3584
[email protected]71f65dd2009-02-11 19:14:563585void AutomationProvider::CloseTab(int tab_handle,
3586 bool wait_until_closed,
3587 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293588 if (tab_tracker_->ContainsHandle(tab_handle)) {
3589 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
3590 int index;
3591 Browser* browser = Browser::GetBrowserForController(controller, &index);
3592 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:143593 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:113594 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:453595 return;
initial.commit09911bf2008-07-26 23:55:293596 }
[email protected]de246f52009-02-25 18:25:453597
3598 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:553599 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293600}
3601
[email protected]71f65dd2009-02-11 19:14:563602void AutomationProvider::CloseBrowser(int browser_handle,
3603 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293604 if (browser_tracker_->ContainsHandle(browser_handle)) {
3605 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563606 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:563607 reply_message);
[email protected]f3e99e32008-07-30 04:48:393608 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:293609 } else {
3610 NOTREACHED();
3611 }
3612}
3613
[email protected]71f65dd2009-02-11 19:14:563614void AutomationProvider::CloseBrowserAsync(int browser_handle) {
3615 if (browser_tracker_->ContainsHandle(browser_handle)) {
3616 Browser* browser = browser_tracker_->GetResource(browser_handle);
3617 browser->window()->Close();
3618 } else {
3619 NOTREACHED();
3620 }
3621}
3622
[email protected]71f65dd2009-02-11 19:14:563623void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
3624 IPC::Message* reply_message) {
3625 if (tab_tracker_->ContainsHandle(tab_handle)) {
3626 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3627 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:143628 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:563629 }
3630}
3631
[email protected]71f65dd2009-02-11 19:14:563632void AutomationProvider::GetSecurityState(int handle, bool* success,
3633 SecurityStyle* security_style,
3634 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:483635 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:293636 if (tab_tracker_->ContainsHandle(handle)) {
3637 NavigationController* tab = tab_tracker_->GetResource(handle);
3638 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563639 *success = true;
3640 *security_style = entry->ssl().security_style();
3641 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:483642 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:293643 } else {
[email protected]71f65dd2009-02-11 19:14:563644 *success = false;
3645 *security_style = SECURITY_STYLE_UNKNOWN;
3646 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:483647 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:293648 }
3649}
3650
[email protected]71f65dd2009-02-11 19:14:563651void AutomationProvider::GetPageType(int handle, bool* success,
3652 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:293653 if (tab_tracker_->ContainsHandle(handle)) {
3654 NavigationController* tab = tab_tracker_->GetResource(handle);
3655 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563656 *page_type = entry->page_type();
3657 *success = true;
initial.commit09911bf2008-07-26 23:55:293658 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:343659 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:563660 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:343661 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:563662 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293663 } else {
[email protected]71f65dd2009-02-11 19:14:563664 *success = false;
3665 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293666 }
3667}
3668
[email protected]84abba62009-10-07 17:01:443669void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
3670 int* duration_ms) {
3671 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
3672 event_name);
3673}
3674
[email protected]71f65dd2009-02-11 19:14:563675void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
3676 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293677 if (tab_tracker_->ContainsHandle(handle)) {
3678 NavigationController* tab = tab_tracker_->GetResource(handle);
3679 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:073680 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:403681 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:473682 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:343683 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:293684 if (ssl_blocking_page) {
3685 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:013686 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:563687 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:293688 return;
3689 }
3690 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:523691 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3692 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:563693 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293694 return;
3695 }
3696 }
3697 }
3698 // We failed.
[email protected]457f5cf2009-08-18 16:37:523699 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3700 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563701 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293702}
3703
[email protected]71f65dd2009-02-11 19:14:563704void AutomationProvider::BringBrowserToFront(int browser_handle,
3705 bool* success) {
initial.commit09911bf2008-07-26 23:55:293706 if (browser_tracker_->ContainsHandle(browser_handle)) {
3707 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:063708 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:563709 *success = true;
initial.commit09911bf2008-07-26 23:55:293710 } else {
[email protected]71f65dd2009-02-11 19:14:563711 *success = false;
initial.commit09911bf2008-07-26 23:55:293712 }
3713}
3714
[email protected]bdb7ff62010-07-20 01:56:523715void AutomationProvider::IsMenuCommandEnabled(int browser_handle,
3716 int message_num,
3717 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:293718 if (browser_tracker_->ContainsHandle(browser_handle)) {
3719 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563720 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:143721 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:293722 } else {
[email protected]71f65dd2009-02-11 19:14:563723 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:293724 }
3725}
3726
[email protected]71f65dd2009-02-11 19:14:563727void AutomationProvider::PrintNow(int tab_handle,
3728 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:573729 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:343730 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3731 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:293732 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:573733 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:143734 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:343735 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:573736 return;
initial.commit09911bf2008-07-26 23:55:293737 }
[email protected]71f65dd2009-02-11 19:14:563738 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
3739 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293740}
[email protected]d301c952009-07-13 15:02:413741
[email protected]71f65dd2009-02-11 19:14:563742void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:113743 const FilePath& file_name,
3744 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:563745 int type,
3746 bool* success) {
initial.commit09911bf2008-07-26 23:55:293747 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:563748 *success = false;
initial.commit09911bf2008-07-26 23:55:293749 return;
3750 }
3751
3752 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3753 Browser* browser = FindAndActivateTab(nav);
3754 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:143755 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:563756 *success = false;
initial.commit09911bf2008-07-26 23:55:293757 return;
3758 }
3759
initial.commit09911bf2008-07-26 23:55:293760 SavePackage::SavePackageType save_type =
3761 static_cast<SavePackage::SavePackageType>(type);
3762 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
3763 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:343764 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:293765
[email protected]71f65dd2009-02-11 19:14:563766 *success = true;
initial.commit09911bf2008-07-26 23:55:293767}
3768
[email protected]71f65dd2009-02-11 19:14:563769void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
3770 bool* success,
3771 std::wstring* text) {
3772 *success = false;
initial.commit09911bf2008-07-26 23:55:293773 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563774 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:523775 GetText();
[email protected]71f65dd2009-02-11 19:14:563776 *success = true;
initial.commit09911bf2008-07-26 23:55:293777 }
initial.commit09911bf2008-07-26 23:55:293778}
3779
[email protected]71f65dd2009-02-11 19:14:563780void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
3781 const std::wstring& text,
3782 bool* success) {
3783 *success = false;
initial.commit09911bf2008-07-26 23:55:293784 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:523785 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
3786 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:563787 *success = true;
initial.commit09911bf2008-07-26 23:55:293788 }
initial.commit09911bf2008-07-26 23:55:293789}
3790
3791void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:563792 int autocomplete_edit_handle,
3793 bool* success,
3794 std::vector<AutocompleteMatchData>* matches) {
3795 *success = false;
initial.commit09911bf2008-07-26 23:55:293796 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:273797 const AutocompleteResult& result = autocomplete_edit_tracker_->
3798 GetResource(autocomplete_edit_handle)->model()->result();
3799 for (AutocompleteResult::const_iterator i = result.begin();
3800 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:563801 matches->push_back(AutocompleteMatchData(*i));
3802 *success = true;
initial.commit09911bf2008-07-26 23:55:293803 }
initial.commit09911bf2008-07-26 23:55:293804}
3805
3806void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:563807 int autocomplete_edit_handle,
3808 bool* success,
3809 bool* query_in_progress) {
3810 *success = false;
3811 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:293812 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563813 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:523814 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:563815 *success = true;
initial.commit09911bf2008-07-26 23:55:293816 }
initial.commit09911bf2008-07-26 23:55:293817}
3818
[email protected]63514af2010-03-30 17:17:233819#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:193820
[email protected]5ae5bed2009-08-21 18:52:443821#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:393822
[email protected]57c6a652009-05-04 07:58:343823TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:573824 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:573825 if (tab_tracker_->ContainsHandle(handle)) {
3826 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:343827 if (tab)
3828 *tab = nav_controller;
3829 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:573830 }
[email protected]57c6a652009-05-04 07:58:343831 return NULL;
[email protected]20e93d12008-08-28 16:31:573832}
3833
initial.commit09911bf2008-07-26 23:55:293834TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
3835 : AutomationProvider(profile) {
3836 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:143837 registrar_.Add(this, NotificationType::SESSION_END,
3838 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:293839}
3840
3841TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:293842 BrowserList::RemoveObserver(this);
3843}
3844
3845void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:143846 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:293847 AutomationProvider::OnChannelError();
3848}
3849
[email protected]679082052010-07-21 21:30:133850void TestingAutomationProvider::OnBrowserAdded(const Browser* browser) {
3851}
3852
initial.commit09911bf2008-07-26 23:55:293853void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
3854 // For backwards compatibility with the testing automation interface, we
3855 // want the automation provider (and hence the process) to go away when the
3856 // last browser goes away.
[email protected]c984d9f2010-07-20 20:52:203857 if (BrowserList::size() == 1 && !CommandLine::ForCurrentProcess()->HasSwitch(
3858 switches::kKeepAliveForTest)) {
[email protected]4f3dc372009-02-24 00:10:293859 // If you change this, update Observer for NotificationType::SESSION_END
3860 // below.
[email protected]295039bd2008-08-15 04:32:573861 MessageLoop::current()->PostTask(FROM_HERE,
3862 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:293863 }
3864}
3865
3866void TestingAutomationProvider::Observe(NotificationType type,
3867 const NotificationSource& source,
3868 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563869 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:293870 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
3871 // before the task runs resulting in this object not being deleted. This
3872 // Release balance out the Release scheduled by OnBrowserRemoving.
3873 Release();
3874}
[email protected]295039bd2008-08-15 04:32:573875
3876void TestingAutomationProvider::OnRemoveProvider() {
3877 AutomationProviderList::GetInstance()->RemoveProvider(this);
3878}
[email protected]8a3422c92008-09-24 17:42:423879
[email protected]816633a2009-11-11 21:48:183880void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:563881 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:423882 if (tab_tracker_->ContainsHandle(handle)) {
3883 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:343884 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:113885 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423886 }
[email protected]8a3422c92008-09-24 17:42:423887}
3888
[email protected]816633a2009-11-11 21:48:183889void AutomationProvider::ClickInfoBarAccept(int handle,
3890 int info_bar_index,
3891 bool wait_for_navigation,
3892 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:423893 bool success = false;
3894 if (tab_tracker_->ContainsHandle(handle)) {
3895 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3896 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:113897 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423898 if (info_bar_index >= 0 && info_bar_index < count) {
3899 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:013900 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:423901 }
[email protected]eb9ba192008-12-02 02:41:343902 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:113903 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:343904 info_bar_index);
3905 if (delegate->AsConfirmInfoBarDelegate())
3906 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:423907 success = true;
3908 }
3909 }
[email protected]4f3dc372009-02-24 00:10:293910 }
[email protected]58f622a62009-10-04 01:17:553911
3912 // This "!wait_for_navigation || !success condition" logic looks suspicious.
3913 // It will send a failure message when success is true but
3914 // |wait_for_navigation| is false.
3915 // TODO(phajdan.jr): investgate whether the reply param (currently
3916 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:423917 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:183918 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:523919 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:423920}
3921
[email protected]71f65dd2009-02-11 19:14:563922void AutomationProvider::GetLastNavigationTime(int handle,
3923 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:423924 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:563925 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:423926}
3927
[email protected]71f65dd2009-02-11 19:14:563928void AutomationProvider::WaitForNavigation(int handle,
3929 int64 last_navigation_time,
3930 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:253931 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:423932 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:253933
[email protected]8a3422c92008-09-24 17:42:423934 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:563935 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:523936 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3937 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553938 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293939 return;
[email protected]8a3422c92008-09-24 17:42:423940 }
3941
[email protected]7dad3d5f2010-03-04 00:27:013942 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423943}
3944
[email protected]71f65dd2009-02-11 19:14:563945void AutomationProvider::SetIntPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513946 const std::string& name,
[email protected]71f65dd2009-02-11 19:14:563947 int value,
3948 bool* success) {
3949 *success = false;
[email protected]8a3422c92008-09-24 17:42:423950 if (browser_tracker_->ContainsHandle(handle)) {
3951 Browser* browser = browser_tracker_->GetResource(handle);
3952 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563953 *success = true;
[email protected]8a3422c92008-09-24 17:42:423954 }
[email protected]8a3422c92008-09-24 17:42:423955}
[email protected]97fa6ce32008-12-19 01:48:163956
[email protected]71f65dd2009-02-11 19:14:563957void AutomationProvider::SetStringPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513958 const std::string& name,
[email protected]ddd231e2010-06-29 20:35:193959 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563960 bool* success) {
3961 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163962 if (browser_tracker_->ContainsHandle(handle)) {
3963 Browser* browser = browser_tracker_->GetResource(handle);
3964 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563965 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163966 }
[email protected]97fa6ce32008-12-19 01:48:163967}
3968
[email protected]71f65dd2009-02-11 19:14:563969void AutomationProvider::GetBooleanPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513970 const std::string& name,
[email protected]b8f48d12009-11-09 20:14:363971 bool* success,
3972 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563973 *success = false;
3974 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163975 if (browser_tracker_->ContainsHandle(handle)) {
3976 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563977 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3978 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163979 }
[email protected]97fa6ce32008-12-19 01:48:163980}
3981
[email protected]71f65dd2009-02-11 19:14:563982void AutomationProvider::SetBooleanPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513983 const std::string& name,
[email protected]71f65dd2009-02-11 19:14:563984 bool value,
3985 bool* success) {
3986 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163987 if (browser_tracker_->ContainsHandle(handle)) {
3988 Browser* browser = browser_tracker_->GetResource(handle);
3989 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563990 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163991 }
[email protected]97fa6ce32008-12-19 01:48:163992}
3993
3994// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563995void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403996 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163997 if (tab_tracker_->ContainsHandle(tab_handle)) {
3998 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3999 Browser* browser = FindAndActivateTab(nav);
4000 DCHECK(browser);
4001
[email protected]57c6a652009-05-04 07:58:344002 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
4003 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:164004 }
[email protected]97fa6ce32008-12-19 01:48:164005}
4006
[email protected]b8f48d12009-11-09 20:14:364007// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:564008void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:404009 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:564010 bool* success) {
4011 *success = false;
[email protected]97fa6ce32008-12-19 01:48:164012 if (tab_tracker_->ContainsHandle(tab_handle)) {
4013 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:194014 if (!nav)
4015 return;
[email protected]97fa6ce32008-12-19 01:48:164016 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:164017
[email protected]2f2afba2010-04-01 01:53:194018 // If the browser has UI, simulate what a user would do.
4019 // Activate the tab and then click the encoding menu.
4020 if (browser &&
4021 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:164022 int selected_encoding_id =
4023 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
4024 if (selected_encoding_id) {
4025 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:564026 *success = true;
[email protected]97fa6ce32008-12-19 01:48:164027 }
[email protected]2f2afba2010-04-01 01:53:194028 } else {
4029 // There is no UI, Chrome probably runs as Chrome-Frame mode.
4030 // Try to get TabContents and call its override_encoding method.
4031 TabContents* contents = nav->tab_contents();
4032 if (!contents)
4033 return;
4034 const std::string selected_encoding =
4035 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
4036 if (selected_encoding.empty())
4037 return;
4038 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:164039 }
4040 }
[email protected]97fa6ce32008-12-19 01:48:164041}
[email protected]5bcdb312009-01-07 21:43:204042
[email protected]4d434a1a2009-02-11 21:06:574043void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:204044 SavePackage::SetShouldPromptUser(should_prompt);
4045}
[email protected]87eab222009-03-13 00:47:454046
[email protected]66ba4932009-06-04 19:22:134047void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
4048 *count = -1; // -1 is the error code
4049 if (tab_tracker_->ContainsHandle(handle)) {
4050 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
4051 TabContents* tab_contents = nav_controller->tab_contents();
4052 if (tab_contents) {
4053 BlockedPopupContainer* container =
4054 tab_contents->blocked_popup_container();
4055 if (container) {
4056 *count = static_cast<int>(container->GetBlockedPopupCount());
4057 } else {
4058 // If we don't have a container, we don't have any blocked popups to
4059 // contain!
4060 *count = 0;
4061 }
4062 }
4063 }
4064}
[email protected]f7a68432009-07-29 23:18:194065
4066void AutomationProvider::SelectAll(int tab_handle) {
4067 RenderViewHost* view = GetViewForTab(tab_handle);
4068 if (!view) {
4069 NOTREACHED();
4070 return;
4071 }
4072
4073 view->SelectAll();
4074}
4075
4076void AutomationProvider::Cut(int tab_handle) {
4077 RenderViewHost* view = GetViewForTab(tab_handle);
4078 if (!view) {
4079 NOTREACHED();
4080 return;
4081 }
4082
4083 view->Cut();
4084}
4085
4086void AutomationProvider::Copy(int tab_handle) {
4087 RenderViewHost* view = GetViewForTab(tab_handle);
4088 if (!view) {
4089 NOTREACHED();
4090 return;
4091 }
4092
4093 view->Copy();
4094}
4095
4096void AutomationProvider::Paste(int tab_handle) {
4097 RenderViewHost* view = GetViewForTab(tab_handle);
4098 if (!view) {
4099 NOTREACHED();
4100 return;
4101 }
4102
4103 view->Paste();
4104}
4105
4106void AutomationProvider::ReloadAsync(int tab_handle) {
4107 if (tab_tracker_->ContainsHandle(tab_handle)) {
4108 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4109 if (!tab) {
4110 NOTREACHED();
4111 return;
4112 }
4113
[email protected]106a0812010-03-18 00:15:124114 const bool check_for_repost = true;
4115 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:194116 }
4117}
4118
4119void AutomationProvider::StopAsync(int tab_handle) {
4120 RenderViewHost* view = GetViewForTab(tab_handle);
4121 if (!view) {
[email protected]8b2b3312009-09-14 18:38:364122 // We tolerate StopAsync being called even before a view has been created.
4123 // So just log a warning instead of a NOTREACHED().
4124 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:194125 return;
4126 }
4127
4128 view->Stop();
4129}
4130
[email protected]1bb5f892009-10-06 01:44:574131void AutomationProvider::OnSetPageFontSize(int tab_handle,
4132 int font_size) {
4133 AutomationPageFontSize automation_font_size =
4134 static_cast<AutomationPageFontSize>(font_size);
4135
4136 if (automation_font_size < SMALLEST_FONT ||
4137 automation_font_size > LARGEST_FONT) {
4138 DLOG(ERROR) << "Invalid font size specified : "
4139 << font_size;
4140 return;
4141 }
4142
4143 if (tab_tracker_->ContainsHandle(tab_handle)) {
4144 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4145 DCHECK(tab != NULL);
4146 if (tab && tab->tab_contents()) {
4147 DCHECK(tab->tab_contents()->profile() != NULL);
4148 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
4149 prefs::kWebKitDefaultFontSize, font_size);
4150 }
4151 }
4152}
4153
[email protected]bc73b4e52010-03-26 04:16:204154void AutomationProvider::RemoveBrowsingData(int remove_mask) {
4155 BrowsingDataRemover* remover;
4156 remover = new BrowsingDataRemover(profile(),
4157 BrowsingDataRemover::EVERYTHING, // All time periods.
4158 base::Time());
4159 remover->Remove(remove_mask);
4160 // BrowsingDataRemover deletes itself.
4161}
[email protected]1bb5f892009-10-06 01:44:574162
[email protected]2949e90d2009-08-21 15:32:524163void AutomationProvider::WaitForBrowserWindowCountToBecome(
4164 int target_count, IPC::Message* reply_message) {
4165 if (static_cast<int>(BrowserList::size()) == target_count) {
4166 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
4167 reply_message, true);
4168 Send(reply_message);
4169 return;
4170 }
4171
4172 // Set up an observer (it will delete itself).
4173 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
4174}
4175
4176void AutomationProvider::WaitForAppModalDialogToBeShown(
4177 IPC::Message* reply_message) {
4178 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
4179 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
4180 reply_message, true);
4181 Send(reply_message);
4182 return;
4183 }
4184
4185 // Set up an observer (it will delete itself).
4186 new AppModalDialogShownObserver(this, reply_message);
4187}
4188
[email protected]1126a1d32009-08-26 15:39:264189void AutomationProvider::GoBackBlockUntilNavigationsComplete(
4190 int handle, int number_of_navigations, IPC::Message* reply_message) {
4191 if (tab_tracker_->ContainsHandle(handle)) {
4192 NavigationController* tab = tab_tracker_->GetResource(handle);
4193 Browser* browser = FindAndActivateTab(tab);
4194 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:014195 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
4196 false);
[email protected]1126a1d32009-08-26 15:39:264197 browser->GoBack(CURRENT_TAB);
4198 return;
4199 }
4200 }
4201
4202 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
4203 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
4204 Send(reply_message);
4205}
4206
4207void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
4208 int handle, int number_of_navigations, IPC::Message* reply_message) {
4209 if (tab_tracker_->ContainsHandle(handle)) {
4210 NavigationController* tab = tab_tracker_->GetResource(handle);
4211 Browser* browser = FindAndActivateTab(tab);
4212 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:014213 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
4214 false);
[email protected]1126a1d32009-08-26 15:39:264215 browser->GoForward(CURRENT_TAB);
4216 return;
4217 }
4218 }
4219
4220 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
4221 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
4222 Send(reply_message);
4223}
4224
[email protected]f7a68432009-07-29 23:18:194225RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
4226 if (tab_tracker_->ContainsHandle(tab_handle)) {
4227 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4228 if (!tab) {
4229 NOTREACHED();
4230 return NULL;
4231 }
4232
4233 TabContents* tab_contents = tab->tab_contents();
4234 if (!tab_contents) {
4235 NOTREACHED();
4236 return NULL;
4237 }
4238
4239 RenderViewHost* view_host = tab_contents->render_view_host();
4240 return view_host;
4241 }
4242
4243 return NULL;
4244}
[email protected]675595f2009-08-26 22:32:044245
4246void AutomationProvider::GetBrowserForWindow(int window_handle,
4247 bool* success,
4248 int* browser_handle) {
4249 *success = false;
4250 *browser_handle = 0;
4251
4252 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
4253 if (!window)
4254 return;
4255
4256 BrowserList::const_iterator iter = BrowserList::begin();
4257 for (;iter != BrowserList::end(); ++iter) {
4258 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
4259 if (window == this_window) {
4260 // Add() returns the existing handle for the resource if any.
4261 *browser_handle = browser_tracker_->Add(*iter);
4262 *success = true;
4263 return;
4264 }
4265 }
4266}
[email protected]d11c8e92009-10-20 23:26:404267
4268void AutomationProvider::InstallExtension(const FilePath& crx_path,
4269 IPC::Message* reply_message) {
4270 ExtensionsService* service = profile_->GetExtensionsService();
4271 if (service) {
4272 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:194273 new ExtensionInstallNotificationObserver(this,
4274 AutomationMsg_InstallExtension::ID,
4275 reply_message);
[email protected]d11c8e92009-10-20 23:26:404276
4277 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:164278 scoped_refptr<CrxInstaller> installer(
4279 new CrxInstaller(install_dir,
4280 service,
4281 NULL)); // silent install, no UI
4282 installer->set_allow_privilege_increase(true);
4283 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:404284 } else {
4285 AutomationMsg_InstallExtension::WriteReplyParams(
4286 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
4287 Send(reply_message);
4288 }
4289}
4290
4291void AutomationProvider::LoadExpandedExtension(
4292 const FilePath& extension_dir,
4293 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:384294 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:404295 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:194296 new ExtensionInstallNotificationObserver(
4297 this,
4298 AutomationMsg_LoadExpandedExtension::ID,
4299 reply_message);
[email protected]d11c8e92009-10-20 23:26:404300
4301 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:404302 } else {
4303 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
4304 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
4305 Send(reply_message);
4306 }
4307}
[email protected]673fd2c02010-02-04 23:10:004308
[email protected]a1e62d12010-03-16 02:18:434309void AutomationProvider::GetEnabledExtensions(
4310 std::vector<FilePath>* result) {
4311 ExtensionsService* service = profile_->GetExtensionsService();
4312 DCHECK(service);
4313 if (service->extensions_enabled()) {
4314 const ExtensionList* extensions = service->extensions();
4315 DCHECK(extensions);
4316 for (size_t i = 0; i < extensions->size(); ++i) {
4317 Extension* extension = (*extensions)[i];
4318 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:124319 if (extension->location() == Extension::INTERNAL ||
4320 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:074321 result->push_back(extension->path());
4322 }
[email protected]a1e62d12010-03-16 02:18:434323 }
4324 }
4325}
4326
[email protected]790788ac2010-04-06 17:52:194327void AutomationProvider::WaitForExtensionTestResult(
4328 IPC::Message* reply_message) {
4329 DCHECK(reply_message_ == NULL);
4330 reply_message_ = reply_message;
4331 // Call MaybeSendResult, because the result might have come in before
4332 // we were waiting on it.
4333 extension_test_result_observer_->MaybeSendResult();
4334}
4335
4336void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:094337 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:194338 ExtensionsService* service = profile_->GetExtensionsService();
4339 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
4340 if (service && manager) {
4341 // The observer will delete itself when done.
4342 new ExtensionReadyNotificationObserver(
4343 manager,
4344 this,
4345 AutomationMsg_InstallExtensionAndGetHandle::ID,
4346 reply_message);
4347
[email protected]d7e5525d2010-04-20 14:37:094348 ExtensionInstallUI* client =
4349 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:194350 scoped_refptr<CrxInstaller> installer(
4351 new CrxInstaller(service->install_directory(),
4352 service,
[email protected]d7e5525d2010-04-20 14:37:094353 client));
[email protected]790788ac2010-04-06 17:52:194354 installer->set_allow_privilege_increase(true);
4355 installer->InstallCrx(crx_path);
4356 } else {
4357 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
4358 reply_message, 0);
4359 Send(reply_message);
4360 }
4361}
4362
4363void AutomationProvider::UninstallExtension(int extension_handle,
4364 bool* success) {
4365 *success = false;
4366 Extension* extension = GetExtension(extension_handle);
4367 ExtensionsService* service = profile_->GetExtensionsService();
4368 if (extension && service) {
4369 ExtensionUnloadNotificationObserver observer;
4370 service->UninstallExtension(extension->id(), false);
4371 // The extension unload notification should have been sent synchronously
4372 // with the uninstall. Just to be safe, check that it was received.
4373 *success = observer.did_receive_unload_notification();
4374 }
4375}
4376
4377void AutomationProvider::EnableExtension(int extension_handle,
4378 IPC::Message* reply_message) {
4379 Extension* extension = GetDisabledExtension(extension_handle);
4380 ExtensionsService* service = profile_->GetExtensionsService();
4381 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
4382 // Only enable if this extension is disabled.
4383 if (extension && service && manager) {
4384 // The observer will delete itself when done.
4385 new ExtensionReadyNotificationObserver(
4386 manager,
4387 this,
4388 AutomationMsg_EnableExtension::ID,
4389 reply_message);
4390 service->EnableExtension(extension->id());
4391 } else {
4392 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
4393 Send(reply_message);
4394 }
4395}
4396
4397void AutomationProvider::DisableExtension(int extension_handle,
4398 bool* success) {
4399 *success = false;
4400 Extension* extension = GetEnabledExtension(extension_handle);
4401 ExtensionsService* service = profile_->GetExtensionsService();
4402 if (extension && service) {
4403 ExtensionUnloadNotificationObserver observer;
4404 service->DisableExtension(extension->id());
4405 // The extension unload notification should have been sent synchronously
4406 // with the disable. Just to be safe, check that it was received.
4407 *success = observer.did_receive_unload_notification();
4408 }
4409}
4410
4411void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
4412 int extension_handle, int browser_handle,
4413 IPC::Message* reply_message) {
4414 bool success = false;
4415 Extension* extension = GetEnabledExtension(extension_handle);
4416 ExtensionsService* service = profile_->GetExtensionsService();
4417 ExtensionMessageService* message_service =
4418 profile_->GetExtensionMessageService();
4419 Browser* browser = browser_tracker_->GetResource(browser_handle);
4420 if (extension && service && message_service && browser) {
4421 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
4422 if (extension->page_action()) {
4423 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
4424 browser->profile(), extension->id(), "action", tab_id, "", 1);
4425 success = true;
4426 } else if (extension->browser_action()) {
4427 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
4428 browser->profile(), extension->id(), browser);
4429 success = true;
4430 }
4431 }
4432 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
4433 reply_message, success);
4434 Send(reply_message);
4435}
4436
4437void AutomationProvider::MoveExtensionBrowserAction(
4438 int extension_handle, int index, bool* success) {
4439 *success = false;
4440 Extension* extension = GetEnabledExtension(extension_handle);
4441 ExtensionsService* service = profile_->GetExtensionsService();
4442 if (extension && service) {
4443 ExtensionToolbarModel* toolbar = service->toolbar_model();
4444 if (toolbar) {
4445 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
4446 toolbar->MoveBrowserAction(extension, index);
4447 *success = true;
4448 } else {
4449 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
4450 }
4451 }
4452 }
4453}
4454
4455void AutomationProvider::GetExtensionProperty(
4456 int extension_handle,
4457 AutomationMsg_ExtensionProperty type,
4458 bool* success,
4459 std::string* value) {
4460 *success = false;
4461 Extension* extension = GetExtension(extension_handle);
4462 ExtensionsService* service = profile_->GetExtensionsService();
4463 if (extension && service) {
4464 ExtensionToolbarModel* toolbar = service->toolbar_model();
4465 int found_index = -1;
4466 int index = 0;
4467 switch (type) {
4468 case AUTOMATION_MSG_EXTENSION_ID:
4469 *value = extension->id();
4470 *success = true;
4471 break;
4472 case AUTOMATION_MSG_EXTENSION_NAME:
4473 *value = extension->name();
4474 *success = true;
4475 break;
4476 case AUTOMATION_MSG_EXTENSION_VERSION:
4477 *value = extension->VersionString();
4478 *success = true;
4479 break;
4480 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
4481 if (toolbar) {
4482 for (ExtensionList::const_iterator iter = toolbar->begin();
4483 iter != toolbar->end(); iter++) {
4484 // Skip this extension if we are in incognito mode
4485 // and it is not incognito-enabled.
4486 if (profile_->IsOffTheRecord() &&
4487 !service->IsIncognitoEnabled(*iter))
4488 continue;
4489 if (*iter == extension) {
4490 found_index = index;
4491 break;
4492 }
4493 index++;
4494 }
[email protected]528c56d2010-07-30 19:28:444495 *value = base::IntToString(found_index);
[email protected]790788ac2010-04-06 17:52:194496 *success = true;
4497 }
4498 break;
4499 default:
4500 LOG(WARNING) << "Trying to get undefined extension property";
4501 break;
4502 }
4503 }
4504}
4505
[email protected]673fd2c02010-02-04 23:10:004506void AutomationProvider::SaveAsAsync(int tab_handle) {
4507 NavigationController* tab = NULL;
4508 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
4509 if (tab_contents)
4510 tab_contents->OnSavePage();
4511}
[email protected]7dad3d5f2010-03-04 00:27:014512
4513void AutomationProvider::SetContentSetting(
4514 int handle,
4515 const std::string& host,
4516 ContentSettingsType content_type,
4517 ContentSetting setting,
4518 bool* success) {
4519 *success = false;
4520 if (browser_tracker_->ContainsHandle(handle)) {
4521 Browser* browser = browser_tracker_->GetResource(handle);
4522 HostContentSettingsMap* map =
4523 browser->profile()->GetHostContentSettingsMap();
4524 if (host.empty()) {
4525 map->SetDefaultContentSetting(content_type, setting);
4526 } else {
[email protected]0314ae02010-04-08 09:18:294527 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
[email protected]ca352452010-08-06 11:14:094528 content_type, "", setting);
[email protected]7dad3d5f2010-03-04 00:27:014529 }
4530 *success = true;
4531 }
4532}
[email protected]cc824372010-03-31 15:33:014533
4534#if !defined(TOOLKIT_VIEWS)
4535void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
4536 NOTIMPLEMENTED();
4537};
4538
4539void AutomationProvider::WaitForFocusedViewIDToChange(
4540 int handle, int previous_view_id, IPC::Message* reply_message) {
4541 NOTIMPLEMENTED();
4542}
4543
4544void AutomationProvider::StartTrackingPopupMenus(
4545 int browser_handle, bool* success) {
4546 NOTIMPLEMENTED();
4547}
4548
4549void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
4550 NOTIMPLEMENTED();
4551}
4552#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:094553
4554void AutomationProvider::ResetToDefaultTheme() {
4555 profile_->ClearTheme();
4556}