blob: cbc6cd436d4ac0037af5377a9eb2b1ef7ee8dbf8 [file] [log] [blame]
[email protected]3b5f7022010-03-25 20:37:401// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]202e7a72009-06-15 03:48:369#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3110#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]7060bb292010-06-24 00:52:4912#include "base/file_path.h"
[email protected]c6cb1992009-04-13 16:45:2913#include "base/file_version_info.h"
[email protected]93d49d72009-10-23 20:00:2014#include "base/json/json_reader.h"
[email protected]59a611242010-04-02 02:24:0415#include "base/json/json_writer.h"
[email protected]93364da2010-06-29 18:03:4416#include "base/json/string_escape.h"
[email protected]bc1407f2009-09-29 00:33:3517#include "base/keyboard_codes.h"
[email protected]5fac9622009-02-04 21:49:3818#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/path_service.h"
[email protected]201b2732009-11-13 18:57:4620#include "base/process_util.h"
[email protected]f44265b2009-05-19 18:52:5021#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2722#include "base/string_util.h"
[email protected]9eaa18e2010-06-29 20:51:0123#include "base/task.h"
[email protected]5fac9622009-02-04 21:49:3824#include "base/thread.h"
[email protected]6d8ffc9f2010-03-12 18:27:5325#include "base/utf_string_conversions.h"
[email protected]a7eee32f2009-05-22 18:08:1726#include "base/values.h"
[email protected]9eaa18e2010-06-29 20:51:0127#include "base/waitable_event.h"
[email protected]4f3dc372009-02-24 00:10:2928#include "chrome/app/chrome_dll_resource.h"
[email protected]bcff05a2010-04-14 01:46:4329#include "chrome/app/chrome_version_info.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]790788ac2010-04-06 17:52:1933#include "chrome/browser/automation/automation_extension_tracker.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0835#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]f44265b2009-05-19 18:52:5036#include "chrome/browser/automation/extension_port_container.h"
[email protected]12802702010-07-09 19:43:0937#include "chrome/browser/autocomplete/autocomplete_edit.h"
[email protected]66ba4932009-06-04 19:22:1338#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5339#include "chrome/browser/bookmarks/bookmark_model.h"
40#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1441#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0742#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3943#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2044#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0545#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5846#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2947#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1248#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5949#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2250#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0551#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4052#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1953#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1454#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4055#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5556#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1957#include "chrome/browser/extensions/extension_tabs_module.h"
58#include "chrome/browser/extensions/extension_toolbar_model.h"
59#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1660#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5861#include "chrome/browser/find_bar.h"
62#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2963#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0164#include "chrome/browser/host_content_settings_map.h"
[email protected]c5aa5322010-07-15 19:00:0765#include "chrome/browser/importer/importer.h"
66#include "chrome/browser/importer/importer_data_types.h"
[email protected]0ac83682010-01-22 17:46:2767#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0668#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0169#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5370#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2471#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0872#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0573#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1774#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0775#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2576#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0377#include "chrome/browser/ssl/ssl_manager.h"
78#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]b5558cf22010-07-12 17:30:0679#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]57c6a652009-05-04 07:58:3480#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4581#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1782#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0583#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2984#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1985#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1786#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5587#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1488#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5789#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2590#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5691#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5792#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1793#include "net/proxy/proxy_service.h"
94#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2195#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3096#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2897#include "views/event.h"
[email protected]f7d48012010-05-06 08:17:0598#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2999
[email protected]de246f52009-02-25 18:25:45100#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:35101#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:45102#endif // defined(OS_WIN)
103
[email protected]e1acf6f2008-10-27 20:43:33104using base::Time;
105
[email protected]cbab76d2008-10-13 22:42:47106class AutomationInterstitialPage : public InterstitialPage {
107 public:
[email protected]57c6a652009-05-04 07:58:34108 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47109 const GURL& url,
110 const std::string& contents)
111 : InterstitialPage(tab, true, url),
112 contents_(contents) {
113 }
114
115 virtual std::string GetHTMLContents() { return contents_; }
116
117 private:
118 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29119
[email protected]cbab76d2008-10-13 22:42:47120 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
121};
122
[email protected]c2cb8542009-08-20 21:16:51123class ClickTask : public Task {
124 public:
[email protected]fc2e0872009-08-21 22:14:41125 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51126 virtual ~ClickTask() {}
127
128 virtual void Run() {
129 ui_controls::MouseButton button = ui_controls::LEFT;
130 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
131 views::Event::EF_LEFT_BUTTON_DOWN) {
132 button = ui_controls::LEFT;
133 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
134 views::Event::EF_RIGHT_BUTTON_DOWN) {
135 button = ui_controls::RIGHT;
136 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
137 views::Event::EF_MIDDLE_BUTTON_DOWN) {
138 button = ui_controls::MIDDLE;
139 } else {
140 NOTREACHED();
141 }
142
[email protected]fc2e0872009-08-21 22:14:41143 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51144 }
145
146 private:
[email protected]c2cb8542009-08-20 21:16:51147 int flags_;
148
149 DISALLOW_COPY_AND_ASSIGN(ClickTask);
150};
[email protected]c2cb8542009-08-20 21:16:51151
initial.commit09911bf2008-07-26 23:55:29152AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57153 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56154 profile_(profile),
[email protected]cc824372010-03-31 15:33:01155 reply_message_(NULL),
156 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29157 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19158 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29159 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20160 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29161 autocomplete_edit_tracker_.reset(
162 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29163 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
164 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44165 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19166 extension_test_result_observer_.reset(
167 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13168 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29169}
170
171AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50172 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
173 port_containers_.end());
174 port_containers_.clear();
175
[email protected]0da050b92008-08-19 19:29:47176 // Make sure that any outstanding NotificationObservers also get destroyed.
177 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31178 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47179 while ((observer = it.GetNext()) != NULL)
180 delete observer;
[email protected]528211a2010-01-14 15:25:13181
182 if (channel_.get()) {
183 channel_->Close();
184 }
185 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29186}
187
[email protected]9a3a293b2009-06-04 22:28:16188void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06189 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57190 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06191 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
192 automation_resource_message_filter_,
193 g_browser_process->io_thread()->message_loop(),
194 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43195 scoped_ptr<FileVersionInfo> version_info(
196 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40197 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43198 if (version_info != NULL) {
199 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40200 }
[email protected]c6cb1992009-04-13 16:45:29201
202 // Send a hello message with our current automation protocol version.
203 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29204}
205
206void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
207 if (expected_tabs == 0) {
208 Send(new AutomationMsg_InitialLoadsComplete(0));
209 } else {
210 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
211 }
212}
213
214NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58215 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01216 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29217 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58218 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01219 number_of_navigations,
220 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29221
[email protected]71f65dd2009-02-11 19:14:56222 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29223 return observer;
224}
225
[email protected]faf2ee42010-05-11 14:26:17226void AutomationProvider::RemoveNavigationStatusListener(
227 NotificationObserver* obs) {
228 notification_observer_list_.RemoveObserver(obs);
229}
230
initial.commit09911bf2008-07-26 23:55:29231NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14232 Browser* parent,
233 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56234 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14235 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29236 notification_observer_list_.AddObserver(observer);
237
238 return observer;
239}
240
[email protected]faf2ee42010-05-11 14:26:17241void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29242 notification_observer_list_.RemoveObserver(obs);
243}
244
245void AutomationProvider::AddLoginHandler(NavigationController* tab,
246 LoginHandler* handler) {
247 login_handler_map_[tab] = handler;
248}
249
250void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
251 DCHECK(login_handler_map_[tab]);
252 login_handler_map_.erase(tab);
253}
254
[email protected]f44265b2009-05-19 18:52:50255void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
256 int port_id = port->port_id();
257 DCHECK_NE(-1, port_id);
258 DCHECK(port_containers_.find(port_id) == port_containers_.end());
259
260 port_containers_[port_id] = port;
261}
262
263void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
264 int port_id = port->port_id();
265 DCHECK_NE(-1, port_id);
266
267 PortContainerMap::iterator it = port_containers_.find(port_id);
268 DCHECK(it != port_containers_.end());
269
270 if (it != port_containers_.end()) {
271 delete it->second;
272 port_containers_.erase(it);
273 }
274}
275
276ExtensionPortContainer* AutomationProvider::GetPortContainer(
277 int port_id) const {
278 PortContainerMap::const_iterator it = port_containers_.find(port_id);
279 if (it == port_containers_.end())
280 return NULL;
281
282 return it->second;
283}
284
initial.commit09911bf2008-07-26 23:55:29285int AutomationProvider::GetIndexForNavigationController(
286 const NavigationController* controller, const Browser* parent) const {
287 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12288 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29289}
290
[email protected]790788ac2010-04-06 17:52:19291int AutomationProvider::AddExtension(Extension* extension) {
292 DCHECK(extension);
293 return extension_tracker_->Add(extension);
294}
295
296Extension* AutomationProvider::GetExtension(int extension_handle) {
297 return extension_tracker_->GetResource(extension_handle);
298}
299
300Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
301 Extension* extension = extension_tracker_->GetResource(extension_handle);
302 ExtensionsService* service = profile_->GetExtensionsService();
303 if (extension && service &&
304 service->GetExtensionById(extension->id(), false))
305 return extension;
306 return NULL;
307}
308
309Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
310 Extension* extension = extension_tracker_->GetResource(extension_handle);
311 ExtensionsService* service = profile_->GetExtensionsService();
312 if (extension && service &&
313 service->GetExtensionById(extension->id(), true) &&
314 !service->GetExtensionById(extension->id(), false))
315 return extension;
316 return NULL;
317}
318
initial.commit09911bf2008-07-26 23:55:29319void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
320 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14321 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56322 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
323 CloseBrowserAsync)
324 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
325 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
326 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
327 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
328 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
329 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22330 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]1c58a5c2009-05-21 18:47:14331 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58332 IPC_MESSAGE_HANDLER_DELAY_REPLY(
333 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
334 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56335 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11336 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
337 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56338 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
339 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
340 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
341 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14342 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56343 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
344 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
345 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14346 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29347 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
348 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56349 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36350 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56351 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29352 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56353 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29354 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
355 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56356 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14357 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24358 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44359 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33360 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44361 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33362 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24363 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14364 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24365 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15366 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14367 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24368 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35369 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14370 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30371#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56372 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
373 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30374#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56375 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53376 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56377 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37378#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56379 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45380#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56381 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
382 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03383 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56384 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14385 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09386 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
387 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
388 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29389 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14390 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56391 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
392 ExecuteJavascript)
393 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29394 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14395 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
396 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56397 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
398 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14399 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17400 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14401 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14402 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53403 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
404 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14405 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56406 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14407 GetAutocompleteEditForBrowser)
408 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56409 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14410 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56411 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14412 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56413 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
414 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14415 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
416 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44417 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
418 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56419 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
420 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29421 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
422 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
423 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56424 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41425 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56426 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
427 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29428 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56429 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29430 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56431 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29432 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56433 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29434 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56435 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45436 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14437 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56438 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57439 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56440 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57441 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56442 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
443 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53444 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
445 GetBookmarksAsJSON)
446 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
447 WaitForBookmarkModelToLoad)
448 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
449 AddBookmarkGroup)
450 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
451 AddBookmarkURL)
452 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
453 ReparentBookmark)
454 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
455 SetBookmarkTitle)
456 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
457 SetBookmarkURL)
458 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
459 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04460 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
461 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18462 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
463 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
464 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56465 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42466 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56467 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
468 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14469 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56470 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44471 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56472 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20473 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14474 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56475 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16476 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56477 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16478 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56479 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16480 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14481 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20482 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
483 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14484 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22485 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13486 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19487 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
488 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
489 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
490 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
491 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
492 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52493 IPC_MESSAGE_HANDLER_DELAY_REPLY(
494 AutomationMsg_WaitForBrowserWindowCountToBecome,
495 WaitForBrowserWindowCountToBecome)
496 IPC_MESSAGE_HANDLER_DELAY_REPLY(
497 AutomationMsg_WaitForAppModalDialogToBeShown,
498 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26499 IPC_MESSAGE_HANDLER_DELAY_REPLY(
500 AutomationMsg_GoBackBlockUntilNavigationsComplete,
501 GoBackBlockUntilNavigationsComplete)
502 IPC_MESSAGE_HANDLER_DELAY_REPLY(
503 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
504 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57505 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40506 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
507 InstallExtension)
508 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
509 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43510 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
511 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19512 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
513 WaitForExtensionTestResult)
514 IPC_MESSAGE_HANDLER_DELAY_REPLY(
515 AutomationMsg_InstallExtensionAndGetHandle,
516 InstallExtensionAndGetHandle)
517 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
518 UninstallExtension)
519 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
520 EnableExtension)
521 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
522 DisableExtension)
523 IPC_MESSAGE_HANDLER_DELAY_REPLY(
524 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
525 ExecuteExtensionActionInActiveTabAsync)
526 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
527 MoveExtensionBrowserAction)
528 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
529 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57530 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
531 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00532 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01533 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20534 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00535 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01536#if defined(TOOLKIT_VIEWS)
537 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
538 WaitForFocusedViewIDToChange)
539 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
540 StartTrackingPopupMenus)
541 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
542 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00543#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52544#if defined(OS_WIN)
545 // These are for use with external tabs.
546 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
547 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
548 ProcessUnhandledAccelerator)
549 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
550 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
551 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
552 OnForwardContextMenuCommandToChrome)
553 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
554 NavigateInExternalTab)
555 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
556 NavigateExternalTabAtIndex)
557 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
558 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
559 SetEnableExtensionAutomation)
560 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
561 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00562 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
[email protected]1f71d5882010-07-15 20:39:07563 IPC_MESSAGE_HANDLER(AutomationMsg_RunUnloadHandlers, OnRunUnloadHandlers)
[email protected]bdd5a9c92010-06-14 18:21:00564#endif // defined(OS_WIN)
565#if defined(OS_CHROMEOS)
566 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
567 LoginWithUserAndPass)
568#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29569 IPC_END_MESSAGE_MAP()
570}
571
[email protected]71f65dd2009-02-11 19:14:56572void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
573 *status = -1;
initial.commit09911bf2008-07-26 23:55:29574 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
575 Browser* browser = browser_tracker_->GetResource(handle);
576 if (at_index >= 0 && at_index < browser->tab_count()) {
577 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56578 *status = 0;
initial.commit09911bf2008-07-26 23:55:29579 }
580 }
initial.commit09911bf2008-07-26 23:55:29581}
582
[email protected]71f65dd2009-02-11 19:14:56583void AutomationProvider::AppendTab(int handle, const GURL& url,
584 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29585 int append_tab_response = -1; // -1 is the error code
586 NotificationObserver* observer = NULL;
587
588 if (browser_tracker_->ContainsHandle(handle)) {
589 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14590 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38591 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39592 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
593 NULL, std::string());
initial.commit09911bf2008-07-26 23:55:29594 if (tab_contents) {
595 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57596 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29597 }
598 }
599
600 if (append_tab_response < 0) {
601 // The append tab failed. Remove the TabStripObserver
602 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17603 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29604 delete observer;
605 }
606
[email protected]71f65dd2009-02-11 19:14:56607 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
608 append_tab_response);
609 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29610 }
611}
612
[email protected]71f65dd2009-02-11 19:14:56613void AutomationProvider::NavigateToURL(int handle, const GURL& url,
614 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58615 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
616}
617
618void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
619 int handle, const GURL& url, int number_of_navigations,
620 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29621 if (tab_tracker_->ContainsHandle(handle)) {
622 NavigationController* tab = tab_tracker_->GetResource(handle);
623
624 // Simulate what a user would do. Activate the tab and then navigate.
625 // We could allow navigating in a background tab in future.
626 Browser* browser = FindAndActivateTab(tab);
627
628 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01629 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
630 false);
[email protected]71f65dd2009-02-11 19:14:56631
initial.commit09911bf2008-07-26 23:55:29632 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50633 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29634 return;
635 }
636 }
[email protected]71f65dd2009-02-11 19:14:56637
638 AutomationMsg_NavigateToURL::WriteReplyParams(
639 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
640 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29641}
[email protected]2949e90d2009-08-21 15:32:52642
[email protected]c70f9b82010-04-21 07:31:11643void AutomationProvider::NavigationAsync(int handle,
644 const GURL& url,
645 bool* status) {
646 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
647}
648
649void AutomationProvider::NavigationAsyncWithDisposition(
650 int handle,
651 const GURL& url,
652 WindowOpenDisposition disposition,
653 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56654 *status = false;
initial.commit09911bf2008-07-26 23:55:29655
656 if (tab_tracker_->ContainsHandle(handle)) {
657 NavigationController* tab = tab_tracker_->GetResource(handle);
658
659 // Simulate what a user would do. Activate the tab and then navigate.
660 // We could allow navigating in a background tab in future.
661 Browser* browser = FindAndActivateTab(tab);
662
663 if (browser) {
664 // Don't add any listener unless a callback mechanism is desired.
665 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11666 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56667 *status = true;
initial.commit09911bf2008-07-26 23:55:29668 }
669 }
initial.commit09911bf2008-07-26 23:55:29670}
671
[email protected]71f65dd2009-02-11 19:14:56672void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29673 if (tab_tracker_->ContainsHandle(handle)) {
674 NavigationController* tab = tab_tracker_->GetResource(handle);
675 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14676 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01677 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29678 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29679 return;
680 }
681 }
[email protected]71f65dd2009-02-11 19:14:56682
683 AutomationMsg_GoBack::WriteReplyParams(
684 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
685 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29686}
687
[email protected]71f65dd2009-02-11 19:14:56688void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29689 if (tab_tracker_->ContainsHandle(handle)) {
690 NavigationController* tab = tab_tracker_->GetResource(handle);
691 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14692 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01693 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29694 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29695 return;
696 }
697 }
[email protected]71f65dd2009-02-11 19:14:56698
699 AutomationMsg_GoForward::WriteReplyParams(
700 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
701 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29702}
703
[email protected]71f65dd2009-02-11 19:14:56704void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29705 if (tab_tracker_->ContainsHandle(handle)) {
706 NavigationController* tab = tab_tracker_->GetResource(handle);
707 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14708 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01709 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28710 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29711 return;
712 }
713 }
[email protected]71f65dd2009-02-11 19:14:56714
715 AutomationMsg_Reload::WriteReplyParams(
716 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
717 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29718}
719
[email protected]71f65dd2009-02-11 19:14:56720void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29721 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56722 const std::wstring& password,
723 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29724 if (tab_tracker_->ContainsHandle(tab_handle)) {
725 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
726 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
727
728 if (iter != login_handler_map_.end()) {
729 // If auth is needed again after this, assume login has failed. This is
730 // not strictly correct, because a navigation can require both proxy and
731 // server auth, but it should be OK for now.
732 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01733 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29734 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52735 return;
initial.commit09911bf2008-07-26 23:55:29736 }
737 }
[email protected]de246f52009-02-25 18:25:45738
[email protected]457f5cf2009-08-18 16:37:52739 AutomationMsg_SetAuth::WriteReplyParams(
740 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
741 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29742}
743
[email protected]71f65dd2009-02-11 19:14:56744void AutomationProvider::CancelAuth(int tab_handle,
745 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29746 if (tab_tracker_->ContainsHandle(tab_handle)) {
747 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
748 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
749
750 if (iter != login_handler_map_.end()) {
751 // If auth is needed again after this, something is screwy.
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->CancelAuth();
[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_CancelAuth::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::NeedsAuth(int tab_handle, bool* needs_auth) {
765 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29766
767 if (tab_tracker_->ContainsHandle(tab_handle)) {
768 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
769 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
770
771 if (iter != login_handler_map_.end()) {
772 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56773 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29774 }
775 }
initial.commit09911bf2008-07-26 23:55:29776}
777
[email protected]71f65dd2009-02-11 19:14:56778void AutomationProvider::GetRedirectsFrom(int tab_handle,
779 const GURL& source_url,
780 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29781 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
782 if (tab_tracker_->ContainsHandle(tab_handle)) {
783 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
784 HistoryService* history_service =
785 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
786
787 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
788 "has no history service";
789 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56790 DCHECK(reply_message_ == NULL);
791 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29792 // Schedule a history query for redirects. The response will be sent
793 // asynchronously from the callback the history system uses to notify us
794 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29795 redirect_query_ = history_service->QueryRedirectsFrom(
796 source_url, &consumer_,
797 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
798 return; // Response will be sent when query completes.
799 }
800 }
801
802 // Send failure response.
[email protected]deb57402009-02-06 01:35:30803 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56804 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
805 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29806}
807
[email protected]71f65dd2009-02-11 19:14:56808void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
809 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29810 if (browser_tracker_->ContainsHandle(handle)) {
811 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56812 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29813 }
initial.commit09911bf2008-07-26 23:55:29814}
815
[email protected]202e7a72009-06-15 03:48:36816void AutomationProvider::GetBrowserLocale(string16* locale) {
817 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06818 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36819}
820
[email protected]71f65dd2009-02-11 19:14:56821void AutomationProvider::GetBrowserWindowCount(int* window_count) {
822 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29823}
824
[email protected]24497032009-05-01 17:00:29825void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
826 *window_count = static_cast<int>(
827 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
828}
829
[email protected]71f65dd2009-02-11 19:14:56830void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
831 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07832 AppModalDialog* dialog_delegate =
833 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50834 *showing_dialog = (dialog_delegate != NULL);
835 if (*showing_dialog)
836 *dialog_button = dialog_delegate->GetDialogButtons();
837 else
[email protected]478ff2ed2009-04-21 23:49:18838 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20839}
840
[email protected]71f65dd2009-02-11 19:14:56841void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
842 *success = false;
[email protected]fad84eab2008-12-05 00:37:20843
[email protected]1f460072009-05-28 17:02:07844 AppModalDialog* dialog_delegate =
845 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50846 if (dialog_delegate &&
847 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18848 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
849 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28850 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56851 *success = true;
[email protected]fad84eab2008-12-05 00:37:20852 }
[email protected]478ff2ed2009-04-21 23:49:18853 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
854 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56855 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28856 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56857 *success = true;
[email protected]fad84eab2008-12-05 00:37:20858 }
859 }
[email protected]c274acc2008-11-11 20:13:44860}
861
[email protected]fedaa7d2010-01-26 20:34:57862void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
863 if (browser_tracker_->ContainsHandle(handle)) {
864 Browser* browser = browser_tracker_->GetResource(handle);
865 browser->profile()->ShutdownSessionService();
866 *result = true;
867 } else {
868 *result = false;
869 }
870}
871
[email protected]71f65dd2009-02-11 19:14:56872void AutomationProvider::GetBrowserWindow(int index, int* handle) {
873 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29874 if (index >= 0) {
875 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30876 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29877 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56878 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29879 }
880 }
initial.commit09911bf2008-07-26 23:55:29881}
882
[email protected]24497032009-05-01 17:00:29883void AutomationProvider::FindNormalBrowserWindow(int* handle) {
884 *handle = 0;
885 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31886 Browser::TYPE_NORMAL,
887 false);
[email protected]24497032009-05-01 17:00:29888 if (browser)
889 *handle = browser_tracker_->Add(browser);
890}
891
[email protected]71f65dd2009-02-11 19:14:56892void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
893 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29894 Browser* browser = BrowserList::GetLastActive();
895 if (browser)
[email protected]71f65dd2009-02-11 19:14:56896 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29897}
898
[email protected]b2aa3ed72010-02-01 18:37:14899#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28900// TODO(estade): use this implementation for all platforms?
901void AutomationProvider::GetActiveWindow(int* handle) {
902 gfx::NativeWindow window =
903 BrowserList::GetLastActive()->window()->GetNativeHandle();
904 *handle = window_tracker_->Add(window);
905}
906#endif
907
[email protected]4f6381ee2009-04-16 02:46:33908void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
909 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56910 *success = false;
[email protected]4ae62752008-08-04 23:28:47911 if (browser_tracker_->ContainsHandle(handle)) {
912 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14913 if (browser->command_updater()->SupportsCommand(command) &&
914 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47915 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56916 *success = true;
[email protected]4ae62752008-08-04 23:28:47917 }
918 }
[email protected]4ae62752008-08-04 23:28:47919}
920
[email protected]4f6381ee2009-04-16 02:46:33921void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56922 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53923 // List of commands which just finish synchronously and don't require
924 // setting up an observer.
925 static const int kSynchronousCommands[] = {
926 IDC_HOME,
927 IDC_SELECT_NEXT_TAB,
928 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25929 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53930 };
[email protected]56e71b7c2009-03-27 03:05:56931 if (browser_tracker_->ContainsHandle(handle)) {
932 Browser* browser = browser_tracker_->GetResource(handle);
933 if (browser->command_updater()->SupportsCommand(command) &&
934 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53935 // First check if we can handle the command without using an observer.
936 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
937 if (command == kSynchronousCommands[i]) {
938 browser->ExecuteCommand(command);
939 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
940 true);
941 Send(reply_message);
942 return;
943 }
944 }
945
946 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42947 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
948 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27949 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42950 return;
951 }
[email protected]56e71b7c2009-03-27 03:05:56952 }
953 }
[email protected]49a14a82009-03-31 04:16:44954 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56955 Send(reply_message);
956}
957
[email protected]fc2e0872009-08-21 22:14:41958// This task just adds another task to the event queue. This is useful if
959// you want to ensure that any tasks added to the event queue after this one
960// have already been processed by the time |task| is run.
961class InvokeTaskLaterTask : public Task {
962 public:
963 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
964 virtual ~InvokeTaskLaterTask() {}
965
966 virtual void Run() {
967 MessageLoop::current()->PostTask(FROM_HERE, task_);
968 }
969
970 private:
971 Task* task_;
972
973 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
974};
975
initial.commit09911bf2008-07-26 23:55:29976void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
977 int handle,
[email protected]d1a5941e2009-08-13 23:34:24978 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29979 int flags) {
[email protected]b410bc32009-08-14 01:11:14980 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51981 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41982 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29983 }
984}
985
[email protected]60507b12009-11-02 23:51:35986void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
987 int handle,
988 const gfx::Point& location) {
989 if (window_tracker_->ContainsHandle(handle))
990 ui_controls::SendMouseMove(location.x(), location.y());
991}
992
initial.commit09911bf2008-07-26 23:55:29993void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
994 int handle,
[email protected]bc1407f2009-09-29 00:33:35995 int key,
initial.commit09911bf2008-07-26 23:55:29996 int flags) {
[email protected]b410bc32009-08-14 01:11:14997 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:29998 return;
999
[email protected]b410bc32009-08-14 01:11:141000 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291001 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351002 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381003 ((flags & views::Event::EF_CONTROL_DOWN) ==
1004 views::Event::EF_CONTROL_DOWN),
1005 ((flags & views::Event::EF_SHIFT_DOWN) ==
1006 views::Event::EF_SHIFT_DOWN),
1007 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301008 views::Event::EF_ALT_DOWN),
1009 ((flags & views::Event::EF_COMMAND_DOWN) ==
1010 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291011}
initial.commit09911bf2008-07-26 23:55:291012
[email protected]71f65dd2009-02-11 19:14:561013void AutomationProvider::IsWindowActive(int handle, bool* success,
1014 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291015 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171016 *is_active =
1017 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561018 *success = true;
initial.commit09911bf2008-07-26 23:55:291019 } else {
[email protected]71f65dd2009-02-11 19:14:561020 *success = false;
1021 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291022 }
1023}
1024
[email protected]71f65dd2009-02-11 19:14:561025void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1026 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291027
1028 if (browser_tracker_->ContainsHandle(handle)) {
1029 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561030 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291031 }
initial.commit09911bf2008-07-26 23:55:291032}
1033
[email protected]982921f12009-10-27 21:43:531034void AutomationProvider::GetType(int handle, int* type_as_int) {
1035 *type_as_int = -1; // -1 is the error code
1036
1037 if (browser_tracker_->ContainsHandle(handle)) {
1038 Browser* browser = browser_tracker_->GetResource(handle);
1039 *type_as_int = static_cast<int>(browser->type());
1040 }
1041}
1042
[email protected]71f65dd2009-02-11 19:14:561043void AutomationProvider::GetTab(int win_handle, int tab_index,
1044 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561045 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291046 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1047 Browser* browser = browser_tracker_->GetResource(win_handle);
1048 if (tab_index < browser->tab_count()) {
1049 TabContents* tab_contents =
1050 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571051 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291052 }
1053 }
initial.commit09911bf2008-07-26 23:55:291054}
1055
[email protected]71f65dd2009-02-11 19:14:561056void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1057 std::wstring* title) {
1058 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291059 if (tab_tracker_->ContainsHandle(handle)) {
1060 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361061 NavigationEntry* entry = tab->GetActiveEntry();
1062 if (entry != NULL) {
1063 *title = UTF16ToWideHack(entry->title());
1064 } else {
1065 *title = std::wstring();
1066 }
[email protected]71f65dd2009-02-11 19:14:561067 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291068 }
initial.commit09911bf2008-07-26 23:55:291069}
1070
[email protected]77bc6732009-04-20 22:01:031071void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1072 *tabstrip_index = -1; // -1 is the error code
1073
1074 if (tab_tracker_->ContainsHandle(handle)) {
1075 NavigationController* tab = tab_tracker_->GetResource(handle);
1076 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121077 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031078 }
1079}
1080
initial.commit09911bf2008-07-26 23:55:291081void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1082 if (window_tracker_->ContainsHandle(handle)) {
1083 window_tracker_->Remove(window_tracker_->GetResource(handle));
1084 }
1085}
1086
1087void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161088 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571089 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291090}
1091
1092// TODO(brettw) change this to accept GURLs when history supports it
1093void AutomationProvider::OnRedirectQueryComplete(
1094 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371095 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291096 bool success,
[email protected]379c2b12009-07-01 21:50:331097 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291098 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561099 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291100
[email protected]deb57402009-02-06 01:35:301101 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101102 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291103 if (success) {
initial.commit09911bf2008-07-26 23:55:291104 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301105 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291106 }
1107
[email protected]4f3dc372009-02-24 00:10:291108 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301109
[email protected]71f65dd2009-02-11 19:14:561110 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231111 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561112 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291113}
1114
1115bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571116 DCHECK(channel_.get());
1117 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291118}
1119
1120Browser* AutomationProvider::FindAndActivateTab(
1121 NavigationController* controller) {
1122 int tab_index;
1123 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1124 if (browser)
1125 browser->SelectTabContentsAt(tab_index, true);
1126
1127 return browser;
1128}
1129
[email protected]9eaa18e2010-06-29 20:51:011130namespace {
1131
1132class GetCookiesTask : public Task {
1133 public:
1134 GetCookiesTask(const GURL& url,
1135 URLRequestContextGetter* context_getter,
1136 base::WaitableEvent* event,
1137 std::string* cookies)
1138 : url_(url),
1139 context_getter_(context_getter),
1140 event_(event),
1141 cookies_(cookies) {}
1142
1143 virtual void Run() {
1144 *cookies_ = context_getter_->GetCookieStore()->GetCookies(url_);
1145 event_->Signal();
1146 }
1147
1148 private:
1149 const GURL& url_;
1150 URLRequestContextGetter* const context_getter_;
1151 base::WaitableEvent* const event_;
1152 std::string* const cookies_;
1153
1154 DISALLOW_COPY_AND_ASSIGN(GetCookiesTask);
1155};
1156
1157std::string GetCookiesForURL(
1158 const GURL& url,
1159 URLRequestContextGetter* context_getter) {
1160 std::string cookies;
1161 base::WaitableEvent event(true /* manual reset */,
1162 false /* not initially signaled */);
1163 CHECK(ChromeThread::PostTask(
1164 ChromeThread::IO, FROM_HERE,
1165 new GetCookiesTask(url, context_getter, &event, &cookies)));
1166 event.Wait();
1167 return cookies;
1168}
1169
1170class SetCookieTask : public Task {
1171 public:
1172 SetCookieTask(const GURL& url,
1173 const std::string& value,
1174 URLRequestContextGetter* context_getter,
1175 base::WaitableEvent* event,
1176 bool* rv)
1177 : url_(url),
1178 value_(value),
1179 context_getter_(context_getter),
1180 event_(event),
1181 rv_(rv) {}
1182
1183 virtual void Run() {
1184 *rv_ = context_getter_->GetCookieStore()->SetCookie(url_, value_);
1185 event_->Signal();
1186 }
1187
1188 private:
1189 const GURL& url_;
1190 const std::string& value_;
1191 URLRequestContextGetter* const context_getter_;
1192 base::WaitableEvent* const event_;
1193 bool* const rv_;
1194
1195 DISALLOW_COPY_AND_ASSIGN(SetCookieTask);
1196};
1197
1198bool SetCookieForURL(
1199 const GURL& url,
1200 const std::string& value,
1201 URLRequestContextGetter* context_getter) {
1202 base::WaitableEvent event(true /* manual reset */,
1203 false /* not initially signaled */);
1204 bool rv = false;
1205 CHECK(ChromeThread::PostTask(
1206 ChromeThread::IO, FROM_HERE,
1207 new SetCookieTask(url, value, context_getter, &event, &rv)));
1208 event.Wait();
1209 return rv;
1210}
1211
1212class DeleteCookieTask : public Task {
1213 public:
1214 DeleteCookieTask(const GURL& url,
1215 const std::string& name,
1216 const scoped_refptr<URLRequestContextGetter>& context_getter)
1217 : url_(url),
1218 name_(name),
1219 context_getter_(context_getter) {}
1220
1221 virtual void Run() {
1222 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
1223 cookie_store->DeleteCookie(url_, name_);
1224 }
1225
1226 private:
1227 const GURL url_;
1228 const std::string name_;
1229 const scoped_refptr<URLRequestContextGetter> context_getter_;
1230
1231 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
1232};
1233
1234} // namespace
1235
[email protected]71f65dd2009-02-11 19:14:561236void AutomationProvider::GetCookies(const GURL& url, int handle,
1237 int* value_size,
1238 std::string* value) {
1239 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291240 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1241 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311242
1243 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001244 scoped_refptr<URLRequestContextGetter> request_context =
1245 tab->tab_contents()->request_context();
1246 if (!request_context.get())
1247 request_context = tab->profile()->GetRequestContext();
1248
[email protected]9eaa18e2010-06-29 20:51:011249 *value = GetCookiesForURL(url, request_context.get());
[email protected]71f65dd2009-02-11 19:14:561250 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291251 }
initial.commit09911bf2008-07-26 23:55:291252}
1253
[email protected]71f65dd2009-02-11 19:14:561254void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291255 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561256 int handle,
1257 int* response_value) {
1258 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291259
1260 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1261 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311262
[email protected]dfa46e5f2009-11-17 18:48:431263 scoped_refptr<URLRequestContextGetter> request_context =
1264 tab->tab_contents()->request_context();
1265 if (!request_context.get())
1266 request_context = tab->profile()->GetRequestContext();
1267
[email protected]9eaa18e2010-06-29 20:51:011268 if (SetCookieForURL(url, value, request_context.get()))
[email protected]71f65dd2009-02-11 19:14:561269 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291270 }
initial.commit09911bf2008-07-26 23:55:291271}
1272
[email protected]5fa57942010-04-21 23:07:221273void AutomationProvider::DeleteCookie(const GURL& url,
1274 const std::string& cookie_name,
1275 int handle, bool* success) {
1276 *success = false;
1277 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1278 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]9eaa18e2010-06-29 20:51:011279 ChromeThread::PostTask(
1280 ChromeThread::IO, FROM_HERE,
1281 new DeleteCookieTask(url, cookie_name,
1282 tab->profile()->GetRequestContext()));
[email protected]5fa57942010-04-21 23:07:221283 *success = true;
1284 }
1285}
1286
[email protected]71f65dd2009-02-11 19:14:561287void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1288 *success = false;
initial.commit09911bf2008-07-26 23:55:291289 if (tab_tracker_->ContainsHandle(handle)) {
1290 NavigationController* tab = tab_tracker_->GetResource(handle);
1291 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541292 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561293 *success = true;
initial.commit09911bf2008-07-26 23:55:291294 }
initial.commit09911bf2008-07-26 23:55:291295}
1296
[email protected]71f65dd2009-02-11 19:14:561297void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1298 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291299
1300 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561301 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341302 TabContents* tab_contents =
1303 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161304 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1305 if (rph)
1306 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291307 }
initial.commit09911bf2008-07-26 23:55:291308}
1309
1310void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331311 NOTREACHED() << "This function has been deprecated. "
1312 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291313}
1314
[email protected]71f65dd2009-02-11 19:14:561315void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291316 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561317 const std::wstring& script,
1318 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291319 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341320 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1321 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571322 // Set the routing id of this message with the controller.
1323 // This routing id needs to be remembered for the reverse
1324 // communication while sending back the response of
1325 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331326 std::wstring set_automation_id;
1327 SStringPrintf(&set_automation_id,
1328 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561329 reply_message->routing_id());
1330
1331 DCHECK(reply_message_ == NULL);
1332 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291333
[email protected]57c6a652009-05-04 07:58:341334 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331335 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341336 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061337 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571338 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291339 }
1340
1341 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561342 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1343 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291344 }
1345}
1346
[email protected]71f65dd2009-02-11 19:14:561347void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1348 *visible = false;
[email protected]20e93d12008-08-28 16:31:571349
[email protected]59560e0b2009-06-04 03:30:221350 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251351#if defined(OS_CHROMEOS)
1352 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1353 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1354 for (BrowserList::const_iterator it = BrowserList::begin();
1355 it != BrowserList::end(); ++it) {
1356 if ((*it)->type() == Browser::TYPE_POPUP) {
1357 const GURL& url =
1358 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1359
1360 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1361 url.host() == chrome::kChromeUIFileBrowseHost) {
1362 *visible = true;
1363 break;
1364 }
1365 }
1366 }
1367#else
[email protected]59560e0b2009-06-04 03:30:221368 Browser* browser = browser_tracker_->GetResource(handle);
1369 if (browser) {
1370 *visible = browser->window()->IsDownloadShelfVisible();
1371 }
[email protected]f5bf8ccf2010-02-05 18:19:251372#endif
[email protected]59560e0b2009-06-04 03:30:221373 }
initial.commit09911bf2008-07-26 23:55:291374}
1375
[email protected]59560e0b2009-06-04 03:30:221376void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1377 if (browser_tracker_->ContainsHandle(handle)) {
1378 Browser* browser = browser_tracker_->GetResource(handle);
1379 if (browser) {
1380 if (visible)
1381 browser->window()->GetDownloadShelf()->Show();
1382 else
1383 browser->window()->GetDownloadShelf()->Close();
1384 }
1385 }
1386}
1387
[email protected]34930432009-11-09 00:12:091388void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1389 *visible = false;
1390
1391 if (browser_tracker_->ContainsHandle(handle)) {
1392 Browser* browser = browser_tracker_->GetResource(handle);
1393 if (browser)
1394 *visible = browser->window()->IsFullscreen();
1395 }
1396}
1397
1398void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1399 bool* visible) {
1400 *visible = false;
1401
1402 if (browser_tracker_->ContainsHandle(handle)) {
1403 Browser* browser = browser_tracker_->GetResource(handle);
1404 if (browser)
1405 *visible = browser->window()->IsFullscreenBubbleVisible();
1406 }
1407}
[email protected]59560e0b2009-06-04 03:30:221408
[email protected]71f65dd2009-02-11 19:14:561409void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1410 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291411 if (tab_tracker_->ContainsHandle(handle)) {
1412 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111413 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291414 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561415 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291416 }
1417 }
initial.commit09911bf2008-07-26 23:55:291418}
1419
initial.commit09911bf2008-07-26 23:55:291420void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561421 int handle, const std::wstring& find_request,
1422 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311423 NOTREACHED() << "This function has been deprecated."
1424 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561425 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311426 return;
1427}
1428
[email protected]4f999132009-03-31 18:08:401429void AutomationProvider::HandleFindRequest(
1430 int handle,
1431 const AutomationMsg_Find_Params& params,
1432 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291433 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561434 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1435 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291436 return;
1437 }
1438
1439 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111440 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291441
1442 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141443 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291444
[email protected]57c6a652009-05-04 07:58:341445 tab_contents->set_current_find_request_id(
1446 FindInPageNotificationObserver::kFindInPageRequestId);
1447 tab_contents->render_view_host()->StartFinding(
1448 FindInPageNotificationObserver::kFindInPageRequestId,
1449 params.search_string, params.forward, params.match_case,
1450 params.find_next);
initial.commit09911bf2008-07-26 23:55:291451}
1452
[email protected]5f8af2a2008-08-06 22:49:451453void AutomationProvider::HandleOpenFindInPageRequest(
1454 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291455 if (browser_tracker_->ContainsHandle(handle)) {
1456 Browser* browser = browser_tracker_->GetResource(handle);
1457 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451458 }
1459}
1460
[email protected]71f65dd2009-02-11 19:14:561461void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561462 *visible = false;
[email protected]855c0142009-09-28 22:35:241463 Browser* browser = browser_tracker_->GetResource(handle);
1464 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581465 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171466 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241467 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291468 }
[email protected]20e93d12008-08-28 16:31:571469}
1470
[email protected]71f65dd2009-02-11 19:14:561471void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1472 int* y) {
[email protected]9e0534b2008-10-21 15:03:011473 gfx::Point position(0, 0);
1474 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291475 if (browser_tracker_->ContainsHandle(handle)) {
1476 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581477 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171478 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581479 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291480 }
[email protected]20e93d12008-08-28 16:31:571481
[email protected]71f65dd2009-02-11 19:14:561482 *x = position.x();
1483 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571484}
1485
[email protected]4512cb52010-04-05 19:50:251486// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1487// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581488void AutomationProvider::GetBookmarkBarVisibility(int handle,
1489 bool* visible,
1490 bool* animating) {
1491 *visible = false;
1492 *animating = false;
1493
1494 if (browser_tracker_->ContainsHandle(handle)) {
1495 Browser* browser = browser_tracker_->GetResource(handle);
1496 if (browser) {
[email protected]472f099b2010-05-27 17:07:121497#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1498 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1499
[email protected]ab6ca392010-04-07 00:44:131500 // IsBookmarkBarVisible() line looks correct but is not
1501 // consistent across platforms. Specifically, on Mac/Linux, it
1502 // returns false if the bar is hidden in a pref (even if visible
1503 // on the NTP). On ChromeOS, it returned true if on NTP
1504 // independent of the pref. Making the code more consistent
1505 // caused a perf bot regression on Windows (which shares views).
1506 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251507 *visible = browser->profile()->GetPrefs()->GetBoolean(
1508 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401509#else
1510 *visible = browser->window()->IsBookmarkBarVisible();
1511#endif
[email protected]c3240722010-03-05 21:52:581512 *animating = browser->window()->IsBookmarkBarAnimating();
1513 }
1514 }
1515}
1516
[email protected]6d8ffc9f2010-03-12 18:27:531517void AutomationProvider::GetBookmarksAsJSON(int handle,
1518 std::string* bookmarks_as_json,
1519 bool *success) {
1520 *success = false;
1521 if (browser_tracker_->ContainsHandle(handle)) {
1522 Browser* browser = browser_tracker_->GetResource(handle);
1523 if (browser) {
1524 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1525 return;
1526 }
1527 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1528 browser->profile(),
1529 browser->profile()->GetBookmarkModel());
1530 *success = storage->SerializeData(bookmarks_as_json);
1531 }
1532 }
1533}
1534
1535void AutomationProvider::WaitForBookmarkModelToLoad(
1536 int handle,
1537 IPC::Message* reply_message) {
1538 if (browser_tracker_->ContainsHandle(handle)) {
1539 Browser* browser = browser_tracker_->GetResource(handle);
1540 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1541 if (model->IsLoaded()) {
1542 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1543 reply_message, true);
1544 Send(reply_message);
1545 } else {
1546 // The observer will delete itself when done.
1547 new AutomationProviderBookmarkModelObserver(this, reply_message,
1548 model);
1549 }
1550 }
1551}
1552
1553void AutomationProvider::AddBookmarkGroup(int handle,
1554 int64 parent_id, int index,
1555 std::wstring title,
1556 bool* success) {
1557 if (browser_tracker_->ContainsHandle(handle)) {
1558 Browser* browser = browser_tracker_->GetResource(handle);
1559 if (browser) {
1560 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1561 if (!model->IsLoaded()) {
1562 *success = false;
1563 return;
1564 }
1565 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1566 DCHECK(parent);
1567 if (parent) {
1568 const BookmarkNode* child = model->AddGroup(parent, index,
1569 WideToUTF16(title));
1570 DCHECK(child);
1571 if (child)
1572 *success = true;
1573 }
1574 }
1575 }
1576 *success = false;
1577}
1578
1579void AutomationProvider::AddBookmarkURL(int handle,
1580 int64 parent_id, int index,
1581 std::wstring title, const GURL& url,
1582 bool* success) {
1583 if (browser_tracker_->ContainsHandle(handle)) {
1584 Browser* browser = browser_tracker_->GetResource(handle);
1585 if (browser) {
1586 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1587 if (!model->IsLoaded()) {
1588 *success = false;
1589 return;
1590 }
1591 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1592 DCHECK(parent);
1593 if (parent) {
1594 const BookmarkNode* child = model->AddURL(parent, index,
1595 WideToUTF16(title), url);
1596 DCHECK(child);
1597 if (child)
1598 *success = true;
1599 }
1600 }
1601 }
1602 *success = false;
1603}
1604
1605void AutomationProvider::ReparentBookmark(int handle,
1606 int64 id, int64 new_parent_id,
1607 int index,
1608 bool* success) {
1609 if (browser_tracker_->ContainsHandle(handle)) {
1610 Browser* browser = browser_tracker_->GetResource(handle);
1611 if (browser) {
1612 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1613 if (!model->IsLoaded()) {
1614 *success = false;
1615 return;
1616 }
1617 const BookmarkNode* node = model->GetNodeByID(id);
1618 DCHECK(node);
1619 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1620 DCHECK(new_parent);
1621 if (node && new_parent) {
1622 model->Move(node, new_parent, index);
1623 *success = true;
1624 }
1625 }
1626 }
1627 *success = false;
1628}
1629
1630void AutomationProvider::SetBookmarkTitle(int handle,
1631 int64 id, std::wstring title,
1632 bool* success) {
1633 if (browser_tracker_->ContainsHandle(handle)) {
1634 Browser* browser = browser_tracker_->GetResource(handle);
1635 if (browser) {
1636 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1637 if (!model->IsLoaded()) {
1638 *success = false;
1639 return;
1640 }
1641 const BookmarkNode* node = model->GetNodeByID(id);
1642 DCHECK(node);
1643 if (node) {
1644 model->SetTitle(node, WideToUTF16(title));
1645 *success = true;
1646 }
1647 }
1648 }
1649 *success = false;
1650}
1651
1652void AutomationProvider::SetBookmarkURL(int handle,
1653 int64 id, const GURL& url,
1654 bool* success) {
1655 if (browser_tracker_->ContainsHandle(handle)) {
1656 Browser* browser = browser_tracker_->GetResource(handle);
1657 if (browser) {
1658 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1659 if (!model->IsLoaded()) {
1660 *success = false;
1661 return;
1662 }
1663 const BookmarkNode* node = model->GetNodeByID(id);
1664 DCHECK(node);
1665 if (node) {
1666 model->SetURL(node, url);
1667 *success = true;
1668 }
1669 }
1670 }
1671 *success = false;
1672}
1673
1674void AutomationProvider::RemoveBookmark(int handle,
1675 int64 id,
1676 bool* success) {
1677 if (browser_tracker_->ContainsHandle(handle)) {
1678 Browser* browser = browser_tracker_->GetResource(handle);
1679 if (browser) {
1680 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1681 if (!model->IsLoaded()) {
1682 *success = false;
1683 return;
1684 }
1685 const BookmarkNode* node = model->GetNodeByID(id);
1686 DCHECK(node);
1687 if (node) {
1688 const BookmarkNode* parent = node->GetParent();
1689 DCHECK(parent);
1690 model->Remove(parent, parent->IndexOfChild(node));
1691 *success = true;
1692 }
1693 }
1694 }
1695 *success = false;
1696}
1697
[email protected]ef413ca2010-05-25 21:09:141698// Sample json input: { "command": "SetWindowDimensions",
1699// "x": 20, # optional
1700// "y": 20, # optional
1701// "width": 800, # optional
1702// "height": 600 } # optional
1703void AutomationProvider::SetWindowDimensions(Browser* browser,
1704 DictionaryValue* args,
1705 IPC::Message* reply_message) {
1706 gfx::Rect rect = browser->window()->GetRestoredBounds();
1707 int x, y, width, height;
1708 if (args->GetInteger(L"x", &x))
1709 rect.set_x(x);
1710 if (args->GetInteger(L"y", &y))
1711 rect.set_y(y);
1712 if (args->GetInteger(L"width", &width))
1713 rect.set_width(width);
1714 if (args->GetInteger(L"height", &height))
1715 rect.set_height(height);
1716 browser->window()->SetBounds(rect);
[email protected]1ac875d22010-07-16 09:57:581717 AutomationMsg_SendJSONRequest::WriteReplyParams(
1718 reply_message, std::string("{}"), true);
1719 Send(reply_message);
[email protected]ef413ca2010-05-25 21:09:141720}
1721
[email protected]a9ff2c02010-05-13 17:33:051722// Sample json input: { "command": "GetBrowserInfo" }
1723// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1724// sample json output.
[email protected]53329582010-05-14 21:10:581725void AutomationProvider::GetBrowserInfo(Browser* browser,
1726 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051727 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:581728 std::string json_return;
1729 bool reply_return = true;
1730
[email protected]a9ff2c02010-05-13 17:33:051731 DictionaryValue* properties = new DictionaryValue;
1732 properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
1733 properties->SetString(L"BrowserProcessExecutableName",
1734 chrome::kBrowserProcessExecutableName);
1735 properties->SetString(L"HelperProcessExecutableName",
1736 chrome::kHelperProcessExecutableName);
1737 properties->SetString(L"BrowserProcessExecutablePath",
1738 chrome::kBrowserProcessExecutablePath);
1739 properties->SetString(L"HelperProcessExecutablePath",
1740 chrome::kHelperProcessExecutablePath);
[email protected]a9ff2c02010-05-13 17:33:051741 properties->SetString(L"command_line_string",
1742 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001743
1744 std::string branding;
1745#if defined(GOOGLE_CHROME_BUILD)
1746 branding = "Google Chrome";
1747#elif defined(CHROMIUM_BUILD)
1748 branding = "Chromium";
1749#else
1750 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051751#endif
[email protected]44eed9f2010-06-28 22:04:001752 properties->SetString(L"branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051753
1754 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1755 return_value->Set(L"properties", properties);
1756
[email protected]ef413ca2010-05-25 21:09:141757 return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
1758 // Add info about all windows in a list of dictionaries, one dictionary
1759 // item per window.
1760 ListValue* windows = new ListValue;
1761 int windex = 0;
1762 for (BrowserList::const_iterator it = BrowserList::begin();
1763 it != BrowserList::end();
1764 ++it, ++windex) {
1765 DictionaryValue* browser_item = new DictionaryValue;
1766 browser = *it;
1767 browser_item->SetInteger(L"index", windex);
1768 // Window properties
1769 gfx::Rect rect = browser->window()->GetRestoredBounds();
1770 browser_item->SetInteger(L"x", rect.x());
1771 browser_item->SetInteger(L"y", rect.y());
1772 browser_item->SetInteger(L"width", rect.width());
1773 browser_item->SetInteger(L"height", rect.height());
1774 browser_item->SetBoolean(L"fullscreen",
1775 browser->window()->IsFullscreen());
1776 browser_item->SetInteger(L"selected_tab", browser->selected_index());
1777 browser_item->SetBoolean(L"incognito",
1778 browser->profile()->IsOffTheRecord());
1779 // For each window, add info about all tabs in a list of dictionaries,
1780 // one dictionary item per tab.
1781 ListValue* tabs = new ListValue;
1782 for (int i = 0; i < browser->tab_count(); ++i) {
1783 TabContents* tc = browser->GetTabContentsAt(i);
1784 DictionaryValue* tab = new DictionaryValue;
1785 tab->SetInteger(L"index", i);
1786 tab->SetString(L"url", tc->GetURL().spec());
1787 tab->SetInteger(L"renderer_pid",
1788 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
1789 tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
1790 tabs->Append(tab);
1791 }
1792 browser_item->Set(L"tabs", tabs);
1793
1794 windows->Append(browser_item);
1795 }
1796 return_value->Set(L"windows", windows);
1797
1798 return_value->SetString(L"child_process_path",
1799 ChildProcessHost::GetChildPath(true).value());
1800 // Child processes are the processes for plugins and other workers.
1801 // Add all child processes in a list of dictionaries, one dictionary item
1802 // per child process.
1803 ListValue* child_processes = new ListValue;
[email protected]d27893f62010-07-03 05:47:421804 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
[email protected]ef413ca2010-05-25 21:09:141805 // Only add processes which are already started, since we need their handle.
1806 if ((*iter)->handle() != base::kNullProcessHandle) {
1807 ChildProcessInfo* info = *iter;
1808 DictionaryValue* item = new DictionaryValue;
1809 item->SetString(L"name", info->name());
1810 item->SetString(L"type",
1811 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
1812 item->SetInteger(L"pid", base::GetProcId(info->handle()));
1813 child_processes->Append(item);
1814 }
1815 }
1816 return_value->Set(L"child_processes", child_processes);
1817
1818 // Add all extension processes in a list of dictionaries, one dictionary
1819 // item per extension process.
1820 ListValue* extension_processes = new ListValue;
1821 ProfileManager* profile_manager = g_browser_process->profile_manager();
1822 for (ProfileManager::const_iterator it = profile_manager->begin();
1823 it != profile_manager->end(); ++it) {
1824 ExtensionProcessManager* process_manager =
1825 (*it)->GetExtensionProcessManager();
1826 ExtensionProcessManager::const_iterator jt;
1827 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1828 ExtensionHost* ex_host = *jt;
1829 // Don't add dead extension processes.
1830 if (!ex_host->IsRenderViewLive())
1831 continue;
1832 DictionaryValue* item = new DictionaryValue;
1833 item->SetString(L"name", ex_host->extension()->name());
1834 item->SetInteger(
1835 L"pid",
1836 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1837 extension_processes->Append(item);
1838 }
1839 }
1840 return_value->Set(L"extension_processes", extension_processes);
[email protected]1ac875d22010-07-16 09:57:581841
1842 base::JSONWriter::Write(return_value.get(), false, &json_return);
1843 AutomationMsg_SendJSONRequest::WriteReplyParams(
1844 reply_message, json_return, reply_return);
1845 Send(reply_message);
[email protected]a9ff2c02010-05-13 17:33:051846}
1847
[email protected]24e2b102010-04-29 17:56:471848// Sample json input: { "command": "GetHistoryInfo",
1849// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361850// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581851void AutomationProvider::GetHistoryInfo(Browser* browser,
1852 DictionaryValue* args,
1853 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361854 consumer_.CancelAllRequests();
1855
[email protected]e53668962010-06-23 15:35:251856 string16 search_text;
1857 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:361858
1859 // Fetch history.
1860 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1861 history::QueryOptions options;
1862 // The observer owns itself. It deletes itself after it fetches history.
1863 AutomationProviderHistoryObserver* history_observer =
1864 new AutomationProviderHistoryObserver(this, reply_message);
1865 hs->QueryHistory(
1866 search_text,
1867 options,
1868 &consumer_,
1869 NewCallback(history_observer,
1870 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1871}
1872
[email protected]bbe6aa02010-05-07 17:27:291873// Sample json input: { "command": "AddHistoryItem",
1874// "item": { "URL": "http://www.google.com",
1875// "title": "Google", # optional
1876// "time": 12345 # optional (time_t)
1877// } }
1878// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581879void AutomationProvider::AddHistoryItem(Browser* browser,
1880 DictionaryValue* args,
1881 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:581882 bool reply_return = true;
1883 std::string json_return = "{}";
1884
[email protected]bbe6aa02010-05-07 17:27:291885 DictionaryValue* item = NULL;
1886 args->GetDictionary(L"item", &item);
1887 string16 url_text;
[email protected]e53668962010-06-23 15:35:251888 string16 title;
[email protected]bbe6aa02010-05-07 17:27:291889 base::Time time = base::Time::Now();
1890
[email protected]1ac875d22010-07-16 09:57:581891 if (item->GetString("url", &url_text)) {
1892 GURL gurl(url_text);
1893 item->GetString("title", &title); // Don't care if it fails.
1894 int it;
1895 double dt;
1896 if (item->GetInteger(L"time", &it))
1897 time = base::Time::FromTimeT(it);
1898 else if (item->GetReal(L"time", &dt))
1899 time = base::Time::FromDoubleT(dt);
1900
1901 // Ideas for "dummy" values (e.g. id_scope) came from
1902 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1903 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1904 const void* id_scope = reinterpret_cast<void*>(1);
1905 hs->AddPage(gurl, time,
1906 id_scope,
1907 0,
1908 GURL(),
1909 PageTransition::LINK,
1910 history::RedirectList(),
1911 false);
1912 if (title.length())
1913 hs->SetPageTitle(gurl, title);
1914 } else {
1915 json_return = JSONErrorString("bad args (no URL in dict?)");
1916 reply_return = false;
[email protected]bbe6aa02010-05-07 17:27:291917 }
[email protected]f6ff0df2010-07-11 22:41:431918
[email protected]1ac875d22010-07-16 09:57:581919 AutomationMsg_SendJSONRequest::WriteReplyParams(
1920 reply_message, json_return, reply_return);
1921 Send(reply_message);
[email protected]bbe6aa02010-05-07 17:27:291922}
1923
[email protected]24e2b102010-04-29 17:56:471924// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361925// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581926void AutomationProvider::GetDownloadsInfo(Browser* browser,
1927 DictionaryValue* args,
1928 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:581929 std::string json_return;
1930 bool reply_return = true;
[email protected]d4adc292010-04-15 18:06:391931 AutomationProviderDownloadManagerObserver observer;
1932 std::vector<DownloadItem*> downloads;
1933 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1934
1935 if (!profile_->HasCreatedDownloadManager()) {
[email protected]1ac875d22010-07-16 09:57:581936 json_return = JSONErrorString("no download manager");
1937 reply_return = false;
1938 } else {
1939 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1940 // since that would be transient; a download might enter and empty out
1941 // the current download queue too soon to be noticed.
1942 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1943 downloads = observer.Downloads();
[email protected]d4adc292010-04-15 18:06:391944 }
1945
1946 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1947 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1948 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1949 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1950 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1951
1952 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1953 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1954 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1955 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1956 std::string("DANGEROUS_BUT_VALIDATED");
1957
1958 ListValue* list_of_downloads = new ListValue;
1959 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1960 it != downloads.end();
1961 it++) { // Fill info about each download item.
1962 DictionaryValue* dl_item_value = new DictionaryValue;
1963 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1964 dl_item_value->SetString(L"url", (*it)->url().spec());
1965 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1966 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1967 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
1968 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
1969 dl_item_value->SetBoolean(L"open_when_complete",
1970 (*it)->open_when_complete());
1971 dl_item_value->SetBoolean(L"is_extension_install",
1972 (*it)->is_extension_install());
1973 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
1974 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
1975 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
1976 dl_item_value->SetString(L"safety_state",
1977 safety_state_to_string[(*it)->safety_state()]);
1978 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
1979 list_of_downloads->Append(dl_item_value);
1980 }
1981 return_value->Set(L"downloads", list_of_downloads);
[email protected]1ac875d22010-07-16 09:57:581982 base::JSONWriter::Write(return_value.get(), false, &json_return);
[email protected]d4adc292010-04-15 18:06:391983
[email protected]1ac875d22010-07-16 09:57:581984 AutomationMsg_SendJSONRequest::WriteReplyParams(
1985 reply_message, json_return, reply_return);
1986 Send(reply_message);
[email protected]d4adc292010-04-15 18:06:391987 // All value objects allocated above are owned by |return_value|
1988 // and get freed by it.
1989}
1990
[email protected]59a611242010-04-02 02:24:041991void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:581992 Browser* browser,
[email protected]59a611242010-04-02 02:24:041993 DictionaryValue* args,
1994 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:581995 std::string json_return;
1996 bool reply_return = true;
[email protected]59a611242010-04-02 02:24:041997 AutomationProviderDownloadManagerObserver observer;
1998 std::vector<DownloadItem*> downloads;
1999
2000 // Look for a quick return.
2001 if (!profile_->HasCreatedDownloadManager()) {
[email protected]1ac875d22010-07-16 09:57:582002 json_return = JSONErrorString("no download manager");
2003 reply_return = false;
2004 } else {
2005 profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
2006 FilePath());
2007 downloads = observer.Downloads();
2008 if (downloads.size() == 0) {
2009 json_return = "{}";
2010 }
[email protected]59a611242010-04-02 02:24:042011 }
[email protected]1ac875d22010-07-16 09:57:582012 if (!json_return.empty()) {
2013 AutomationMsg_SendJSONRequest::WriteReplyParams(
2014 reply_message, json_return, reply_return);
2015 Send(reply_message);
[email protected]f6ff0df2010-07-11 22:41:432016 return;
2017 }
[email protected]59a611242010-04-02 02:24:042018
2019 // The observer owns itself. When the last observed item pings, it
2020 // deletes itself.
2021 AutomationProviderDownloadItemObserver* item_observer =
2022 new AutomationProviderDownloadItemObserver(
2023 this, reply_message, downloads.size());
2024 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2025 i != downloads.end();
2026 i++) {
2027 (*i)->AddObserver(item_observer);
2028 }
2029}
2030
[email protected]24e2b102010-04-29 17:56:472031// Sample json input: { "command": "GetPrefsInfo" }
2032// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582033void AutomationProvider::GetPrefsInfo(Browser* browser,
2034 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472035 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582036 std::string json_return;
2037 bool reply_return = true;
2038
[email protected]24e2b102010-04-29 17:56:472039 const PrefService::PreferenceSet& prefs =
2040 profile_->GetPrefs()->preference_set();
2041 DictionaryValue* items = new DictionaryValue;
2042 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
2043 it != prefs.end(); ++it) {
2044 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
2045 }
2046 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2047 return_value->Set(L"prefs", items); // return_value owns items.
[email protected]1ac875d22010-07-16 09:57:582048
2049 base::JSONWriter::Write(return_value.get(), false, &json_return);
2050 AutomationMsg_SendJSONRequest::WriteReplyParams(
2051 reply_message, json_return, reply_return);
2052 Send(reply_message);
[email protected]24e2b102010-04-29 17:56:472053}
2054
2055// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:582056void AutomationProvider::SetPrefs(Browser* browser,
2057 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472058 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582059 bool reply_return = true;
2060 std::string json_return = "{}";
[email protected]24e2b102010-04-29 17:56:472061 std::wstring path;
2062 Value* val;
2063 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
2064 PrefService* pref_service = profile_->GetPrefs();
2065 const PrefService::Preference* pref =
2066 pref_service->FindPreference(path.c_str());
2067 if (!pref) { // Not a registered pref.
[email protected]1ac875d22010-07-16 09:57:582068 json_return = JSONErrorString("pref not registered.");
2069 reply_return = false;
[email protected]24e2b102010-04-29 17:56:472070 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]1ac875d22010-07-16 09:57:582071 json_return = JSONErrorString("pref is managed. cannot be changed.");
2072 reply_return = false;
[email protected]24e2b102010-04-29 17:56:472073 } else { // Set the pref.
2074 pref_service->Set(path.c_str(), *val);
2075 }
2076 } else {
[email protected]1ac875d22010-07-16 09:57:582077 json_return = JSONErrorString("no pref path or value given.");
2078 reply_return = false;
[email protected]24e2b102010-04-29 17:56:472079 }
2080
[email protected]1ac875d22010-07-16 09:57:582081 AutomationMsg_SendJSONRequest::WriteReplyParams(
2082 reply_message, json_return, reply_return);
2083 Send(reply_message);
[email protected]24e2b102010-04-29 17:56:472084}
2085
[email protected]53329582010-05-14 21:10:582086// Sample json input: { "command": "GetOmniboxInfo" }
2087// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
2088void AutomationProvider::GetOmniboxInfo(Browser* browser,
2089 DictionaryValue* args,
2090 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582091 std::string json_return;
2092 bool reply_return = true;
[email protected]53329582010-05-14 21:10:582093 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2094
2095 LocationBar* loc_bar = browser->window()->GetLocationBar();
2096 AutocompleteEditView* edit_view = loc_bar->location_entry();
2097 AutocompleteEditModel* model = edit_view->model();
2098
2099 // Fill up matches.
2100 ListValue* matches = new ListValue;
2101 const AutocompleteResult& result = model->result();
2102 for (AutocompleteResult::const_iterator i = result.begin();
2103 i != result.end(); ++i) {
2104 const AutocompleteMatch& match = *i;
2105 DictionaryValue* item = new DictionaryValue; // owned by return_value
2106 item->SetString(L"type", AutocompleteMatch::TypeToString(match.type));
2107 item->SetBoolean(L"starred", match.starred);
2108 item->SetString(L"destination_url", match.destination_url.spec());
2109 item->SetString(L"contents", match.contents);
2110 item->SetString(L"description", match.description);
2111 matches->Append(item);
2112 }
2113 return_value->Set(L"matches", matches);
2114
2115 // Fill up other properties.
2116 DictionaryValue* properties = new DictionaryValue; // owned by return_value
2117 properties->SetBoolean(L"has_focus", model->has_focus());
2118 properties->SetBoolean(L"query_in_progress", model->query_in_progress());
2119 properties->SetString(L"keyword", model->keyword());
2120 properties->SetString(L"text", edit_view->GetText());
2121 return_value->Set(L"properties", properties);
2122
[email protected]1ac875d22010-07-16 09:57:582123 base::JSONWriter::Write(return_value.get(), false, &json_return);
2124 AutomationMsg_SendJSONRequest::WriteReplyParams(
2125 reply_message, json_return, reply_return);
2126 Send(reply_message);
[email protected]53329582010-05-14 21:10:582127}
2128
2129// Sample json input: { "command": "SetOmniboxText",
2130// "text": "goog" }
2131void AutomationProvider::SetOmniboxText(Browser* browser,
2132 DictionaryValue* args,
2133 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582134 std::string json_return = "{}";
2135 bool reply_return = true;
[email protected]53329582010-05-14 21:10:582136 std::wstring text;
[email protected]1ac875d22010-07-16 09:57:582137
[email protected]53329582010-05-14 21:10:582138 if (!args->GetString(L"text", &text)) {
[email protected]1ac875d22010-07-16 09:57:582139 json_return = JSONErrorString("text missing");
2140 reply_return = false;
2141 } else {
2142 browser->FocusLocationBar();
2143 LocationBar* loc_bar = browser->window()->GetLocationBar();
2144 AutocompleteEditView* edit_view = loc_bar->location_entry();
2145 edit_view->model()->OnSetFocus(false);
2146 edit_view->SetUserText(text);
[email protected]53329582010-05-14 21:10:582147 }
[email protected]1ac875d22010-07-16 09:57:582148
2149 AutomationMsg_SendJSONRequest::WriteReplyParams(
2150 reply_message, json_return, reply_return);
2151 Send(reply_message);
[email protected]53329582010-05-14 21:10:582152}
2153
2154// Sample json input: { "command": "OmniboxMovePopupSelection",
2155// "count": 1 }
2156// Negative count implies up, positive implies down. Count values will be
2157// capped by the size of the popup list.
2158void AutomationProvider::OmniboxMovePopupSelection(
2159 Browser* browser,
2160 DictionaryValue* args,
2161 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582162 std::string json_return = "{}";
2163 bool reply_return = true;
[email protected]53329582010-05-14 21:10:582164 int count;
[email protected]1ac875d22010-07-16 09:57:582165
[email protected]53329582010-05-14 21:10:582166 if (!args->GetInteger(L"count", &count)) {
[email protected]1ac875d22010-07-16 09:57:582167 json_return = JSONErrorString("count missing");
2168 reply_return = false;
2169 } else {
2170 LocationBar* loc_bar = browser->window()->GetLocationBar();
2171 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2172 model->OnUpOrDownKeyPressed(count);
[email protected]53329582010-05-14 21:10:582173 }
[email protected]1ac875d22010-07-16 09:57:582174
2175 AutomationMsg_SendJSONRequest::WriteReplyParams(
2176 reply_message, json_return, reply_return);
2177 Send(reply_message);
[email protected]53329582010-05-14 21:10:582178}
2179
2180// Sample json input: { "command": "OmniboxAcceptInput" }
2181void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2182 DictionaryValue* args,
2183 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282184 NavigationController& controller =
2185 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122186 // Setup observer to wait until the selected item loads.
2187 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282188 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122189 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582190
2191 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582192}
2193
[email protected]a3cd5022010-06-16 18:25:292194// Sample json input: { "command": "GetInitialLoadTimes" }
2195// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2196void AutomationProvider::GetInitialLoadTimes(
2197 Browser*,
2198 DictionaryValue*,
2199 IPC::Message* reply_message) {
2200 scoped_ptr<DictionaryValue> return_value(
2201 initial_load_observer_->GetTimingInformation());
[email protected]f6ff0df2010-07-11 22:41:432202
2203 std::string json_return;
2204 base::JSONWriter::Write(return_value.get(), false, &json_return);
2205 AutomationMsg_SendJSONRequest::WriteReplyParams(
2206 reply_message, json_return, true);
2207 Send(reply_message);
[email protected]a3cd5022010-06-16 18:25:292208}
2209
[email protected]f7d48012010-05-06 08:17:052210// Sample json input: { "command": "GetPluginsInfo" }
2211// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582212void AutomationProvider::GetPluginsInfo(Browser* browser,
2213 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052214 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582215 std::string json_return;
2216 bool reply_return = true;
2217
[email protected]f7d48012010-05-06 08:17:052218 std::vector<WebPluginInfo> plugins;
2219 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2220 ListValue* items = new ListValue;
2221 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2222 it != plugins.end();
2223 ++it) {
2224 DictionaryValue* item = new DictionaryValue;
[email protected]c9d811372010-06-23 21:44:572225 item->SetStringFromUTF16(L"name", it->name);
[email protected]f7d48012010-05-06 08:17:052226 item->SetString(L"path", it->path.value());
[email protected]c9d811372010-06-23 21:44:572227 item->SetStringFromUTF16(L"version", it->version);
2228 item->SetStringFromUTF16(L"desc", it->desc);
[email protected]f7d48012010-05-06 08:17:052229 item->SetBoolean(L"enabled", it->enabled);
2230 // Add info about mime types.
2231 ListValue* mime_types = new ListValue();
2232 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2233 it->mime_types.begin();
2234 type_it != it->mime_types.end();
2235 ++type_it) {
2236 DictionaryValue* mime_type = new DictionaryValue();
2237 mime_type->SetString(L"mimeType", type_it->mime_type);
[email protected]c9d811372010-06-23 21:44:572238 mime_type->SetStringFromUTF16(L"description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052239
2240 ListValue* file_extensions = new ListValue();
2241 for (std::vector<std::string>::const_iterator ext_it =
2242 type_it->file_extensions.begin();
2243 ext_it != type_it->file_extensions.end();
2244 ++ext_it) {
2245 file_extensions->Append(new StringValue(*ext_it));
2246 }
2247 mime_type->Set(L"fileExtensions", file_extensions);
2248
2249 mime_types->Append(mime_type);
2250 }
2251 item->Set(L"mimeTypes", mime_types);
2252 items->Append(item);
2253 }
2254 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2255 return_value->Set(L"plugins", items); // return_value owns items.
2256
[email protected]1ac875d22010-07-16 09:57:582257 base::JSONWriter::Write(return_value.get(), false, &json_return);
2258 AutomationMsg_SendJSONRequest::WriteReplyParams(
2259 reply_message, json_return, reply_return);
2260 Send(reply_message);
[email protected]f7d48012010-05-06 08:17:052261}
2262
2263// Sample json input:
2264// { "command": "EnablePlugin",
2265// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582266void AutomationProvider::EnablePlugin(Browser* browser,
2267 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052268 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582269 std::string json_return = "{}";
2270 bool reply_return = true;
[email protected]f7d48012010-05-06 08:17:052271 FilePath::StringType path;
[email protected]f6ff0df2010-07-11 22:41:432272 if (!args->GetString(L"path", &path)) {
[email protected]1ac875d22010-07-16 09:57:582273 json_return = JSONErrorString("path not specified.");
2274 reply_return = false;
[email protected]f6ff0df2010-07-11 22:41:432275 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
[email protected]1ac875d22010-07-16 09:57:582276 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2277 " for path %s.\"}", path.c_str());
2278 reply_return = false;
[email protected]f6ff0df2010-07-11 22:41:432279 }
[email protected]1ac875d22010-07-16 09:57:582280
2281 AutomationMsg_SendJSONRequest::WriteReplyParams(
2282 reply_message, json_return, reply_return);
2283 Send(reply_message);
[email protected]f7d48012010-05-06 08:17:052284}
2285
2286// Sample json input:
2287// { "command": "DisablePlugin",
2288// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582289void AutomationProvider::DisablePlugin(Browser* browser,
2290 DictionaryValue* args,
2291 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582292 std::string json_return = "{}";
2293 bool reply_return = true;
[email protected]f7d48012010-05-06 08:17:052294 FilePath::StringType path;
[email protected]f6ff0df2010-07-11 22:41:432295 if (!args->GetString(L"path", &path)) {
[email protected]1ac875d22010-07-16 09:57:582296 json_return = JSONErrorString("path not specified.");
2297 reply_return = false;
[email protected]f6ff0df2010-07-11 22:41:432298 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
[email protected]1ac875d22010-07-16 09:57:582299 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2300 " for path %s.\"}", path.c_str());
2301 reply_return = false;
[email protected]f6ff0df2010-07-11 22:41:432302 }
[email protected]1ac875d22010-07-16 09:57:582303
2304 AutomationMsg_SendJSONRequest::WriteReplyParams(
2305 reply_message, json_return, reply_return);
2306 Send(reply_message);
[email protected]f7d48012010-05-06 08:17:052307}
2308
[email protected]7060bb292010-06-24 00:52:492309// Sample json input:
2310// { "command": "SaveTabContents",
2311// "tab_index": 0,
2312// "filename": <a full pathname> }
2313// Sample json output:
2314// {}
2315void AutomationProvider::SaveTabContents(Browser* browser,
2316 DictionaryValue* args,
2317 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582318 std::string json_return;
[email protected]7060bb292010-06-24 00:52:492319 int tab_index = 0;
2320 FilePath::StringType filename;
2321 FilePath::StringType parent_directory;
2322 TabContents* tab_contents = NULL;
2323
2324 if (!args->GetInteger(L"tab_index", &tab_index) ||
2325 !args->GetString(L"filename", &filename)) {
[email protected]1ac875d22010-07-16 09:57:582326 json_return = JSONErrorString("tab_index or filename param missing");
[email protected]7060bb292010-06-24 00:52:492327 } else {
2328 tab_contents = browser->GetTabContentsAt(tab_index);
2329 if (!tab_contents) {
[email protected]1ac875d22010-07-16 09:57:582330 json_return = JSONErrorString("no tab at tab_index");
2331 }
2332 }
2333 if (tab_contents) {
2334 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2335 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2336 parent_directory = FilePath(filename).DirName().value();
2337 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2338 SavePackage::SAVE_AS_ONLY_HTML)) {
2339 json_return = JSONErrorString("Could not initiate SavePage");
2340 } else {
2341 // The observer will delete itself when done.
2342 new SavePackageNotificationObserver(tab_contents->save_package(),
2343 this, reply_message);
[email protected]7060bb292010-06-24 00:52:492344 return;
2345 }
2346 }
[email protected]1ac875d22010-07-16 09:57:582347
2348 // If we get here, error.
2349 DCHECK(!json_return.empty());
2350 AutomationMsg_SendJSONRequest::WriteReplyParams(
2351 reply_message, json_return, false);
2352 Send(reply_message);
[email protected]7060bb292010-06-24 00:52:492353}
2354
[email protected]c5aa5322010-07-15 19:00:072355// Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
2356// json input.
2357// Sample json output: "{}"
2358void AutomationProvider::ImportSettings(Browser* browser,
2359 DictionaryValue* args,
2360 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582361 std::string json_return = "{}";
2362
[email protected]c5aa5322010-07-15 19:00:072363 // Map from the json string passed over to the import item masks.
2364 std::map<std::string, ImportItem> string_to_import_item;
2365 string_to_import_item["HISTORY"] = importer::HISTORY;
2366 string_to_import_item["FAVORITES"] = importer::FAVORITES;
2367 string_to_import_item["COOKIES"] = importer::COOKIES;
2368 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
2369 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
2370 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
2371 string_to_import_item["ALL"] = importer::ALL;
2372
2373 std::wstring browser_name;
2374 int import_items = 0;
2375 ListValue* import_items_list = NULL;
2376 bool first_run;
2377
2378 if (!args->GetString(L"import_from", &browser_name) ||
2379 !args->GetBoolean(L"first_run", &first_run) ||
2380 !args->GetList(L"import_items", &import_items_list)) {
[email protected]1ac875d22010-07-16 09:57:582381 std::string json_return =
2382 JSONErrorString("Incorrect type for one or more of the arguments.");
2383 AutomationMsg_SendJSONRequest::WriteReplyParams(
2384 reply_message, json_return, false);
2385 Send(reply_message);
[email protected]c5aa5322010-07-15 19:00:072386 return;
2387 }
2388
2389 int num_items = import_items_list->GetSize();
2390 for (int i = 0; i < num_items; i++) {
2391 std::string item;
2392 import_items_list->GetString(i, &item);
2393 // If the provided string is not part of the map, error out.
2394 if (!ContainsKey(string_to_import_item, item)) {
[email protected]1ac875d22010-07-16 09:57:582395 json_return =
2396 JSONErrorString("Invalid item string found in import_items.");
2397 AutomationMsg_SendJSONRequest::WriteReplyParams(
2398 reply_message, json_return, false);
2399 Send(reply_message);
[email protected]c5aa5322010-07-15 19:00:072400 return;
2401 }
2402 import_items |= string_to_import_item[item];
2403 }
2404
2405 ImporterHost* importer_host = new ImporterHost();
2406 // Get the correct ProfileInfo based on the browser they user provided.
2407 importer::ProfileInfo profile_info;
2408 int num_browsers = importer_host->GetAvailableProfileCount();
2409 int i = 0;
2410 for ( ; i < num_browsers; i++) {
2411 std::wstring name = importer_host->GetSourceProfileNameAt(i);
2412 if (name == browser_name) {
2413 profile_info = importer_host->GetSourceProfileInfoAt(i);
2414 break;
2415 }
2416 }
2417 // If we made it to the end of the loop, then the input was bad.
2418 if (i == num_browsers) {
[email protected]1ac875d22010-07-16 09:57:582419 json_return =
2420 JSONErrorString("Invalid browser name string found.");
2421 AutomationMsg_SendJSONRequest::WriteReplyParams(
2422 reply_message, json_return, false);
2423 Send(reply_message);
[email protected]c5aa5322010-07-15 19:00:072424 return;
2425 }
2426
2427 Profile* profile = browser->profile();
2428
2429 importer_host->SetObserver(
2430 new AutomationProviderImportSettingsObserver(this, reply_message));
2431 importer_host->StartImportSettings(profile_info, profile, import_items,
2432 new ProfileWriter(profile), first_run);
2433}
2434
[email protected]a0fc50d72010-07-14 21:14:192435// Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
2436// json input.
2437// Sample json output: {}
2438void AutomationProvider::ClearBrowsingData(Browser* browser,
2439 DictionaryValue* args,
2440 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582441 std::string json_return = "{}";
2442
[email protected]a0fc50d72010-07-14 21:14:192443 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
2444 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
2445 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
2446 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
2447 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
2448 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
2449
2450 std::map<std::string, int> string_to_mask_value;
2451 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
2452 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
2453 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
2454 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
2455 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
2456 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
2457
2458 std::string time_period;
2459 ListValue* to_remove;
2460 if (!args->GetString(L"time_period", &time_period) ||
2461 !args->GetList(L"to_remove", &to_remove)) {
[email protected]1ac875d22010-07-16 09:57:582462 // TODO(nirnimesh): Here and below refactor returns with pending CL.
2463 std::string json_return =
2464 JSONErrorString("time_period must be a string and to_remove a list.");
2465 AutomationMsg_SendJSONRequest::WriteReplyParams(
2466 reply_message, json_return, false);
2467 Send(reply_message);
[email protected]a0fc50d72010-07-14 21:14:192468 return;
2469 }
2470
2471 int remove_mask = 0;
2472 int num_removals = to_remove->GetSize();
2473 for (int i = 0; i < num_removals; i++) {
2474 std::string removal;
2475 to_remove->GetString(i, &removal);
2476 // If the provided string is not part of the map, then error out.
2477 if (!ContainsKey(string_to_mask_value, removal)) {
[email protected]1ac875d22010-07-16 09:57:582478 std::string json_return =
2479 JSONErrorString("Invalid browsing data string found in to_remove.");
2480 AutomationMsg_SendJSONRequest::WriteReplyParams(
2481 reply_message, json_return, false);
2482 Send(reply_message);
[email protected]a0fc50d72010-07-14 21:14:192483 return;
2484 }
2485 remove_mask |= string_to_mask_value[removal];
2486 }
2487
2488 if (!ContainsKey(string_to_time_period, time_period)) {
[email protected]1ac875d22010-07-16 09:57:582489 std::string json_return =
2490 JSONErrorString("Invalid string for time_period.");
2491 AutomationMsg_SendJSONRequest::WriteReplyParams(
2492 reply_message, json_return, false);
2493 Send(reply_message);
[email protected]a0fc50d72010-07-14 21:14:192494 return;
2495 }
2496
2497 BrowsingDataRemover* remover = new BrowsingDataRemover(
2498 profile(), string_to_time_period[time_period], base::Time());
2499
2500 remover->AddObserver(
2501 new AutomationProviderBrowsingDataObserver(this, reply_message));
2502 remover->Remove(remove_mask);
2503 // BrowsingDataRemover deletes itself using DeleteTask.
2504 // The observer also deletes itself after sending the reply.
2505}
2506
[email protected]4d1929f12010-07-10 00:09:032507// Sample json input: { "command": "GetThemeInfo" }
2508// Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
2509void AutomationProvider::GetThemeInfo(Browser* browser,
2510 DictionaryValue* args,
2511 IPC::Message* reply_message) {
2512 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2513 Extension* theme = browser->profile()->GetTheme();
2514 if (theme) {
2515 return_value->SetString(L"name", theme->name());
2516 return_value->Set(L"images", theme->GetThemeImages()->DeepCopy());
2517 return_value->Set(L"colors", theme->GetThemeColors()->DeepCopy());
2518 return_value->Set(L"tints", theme->GetThemeTints()->DeepCopy());
2519 }
[email protected]1ac875d22010-07-16 09:57:582520
2521 std::string json_return;
2522 base::JSONWriter::Write(return_value.get(), false, &json_return);
2523 AutomationMsg_SendJSONRequest::WriteReplyParams(
2524 reply_message, json_return, true);
2525 Send(reply_message);
[email protected]4d1929f12010-07-10 00:09:032526}
2527
[email protected]55846ad842010-07-09 18:22:562528// Sample json input:
2529// { "command": "GetAutoFillProfile" }
2530// Refer to GetAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2531// json output.
2532void AutomationProvider::GetAutoFillProfile(Browser* browser,
2533 DictionaryValue* args,
2534 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582535 std::string json_return;
2536 bool reply_return = true;
2537
[email protected]55846ad842010-07-09 18:22:562538 // Get the AutoFillProfiles currently in the database.
2539 int tab_index = 0;
2540 args->GetInteger(L"tab_index", &tab_index);
2541 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2542
2543 if (tab_contents) {
2544 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
2545 ->GetPersonalDataManager();
2546 if (pdm) {
2547 std::vector<AutoFillProfile*> autofill_profiles = pdm->profiles();
2548 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
2549
2550 ListValue* profiles = GetListFromAutoFillProfiles(autofill_profiles);
2551 ListValue* cards = GetListFromCreditCards(credit_cards);
2552
2553 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2554
2555 return_value->Set(L"profiles", profiles);
2556 return_value->Set(L"credit_cards", cards);
[email protected]1ac875d22010-07-16 09:57:582557
2558 base::JSONWriter::Write(return_value.get(), false, &json_return);
[email protected]55846ad842010-07-09 18:22:562559 } else {
[email protected]1ac875d22010-07-16 09:57:582560 json_return = JSONErrorString("No PersonalDataManager.");
2561 reply_return = false;
[email protected]55846ad842010-07-09 18:22:562562 }
2563 } else {
[email protected]1ac875d22010-07-16 09:57:582564 json_return = JSONErrorString("No tab at that index.");
2565 reply_return = false;
[email protected]55846ad842010-07-09 18:22:562566 }
[email protected]1ac875d22010-07-16 09:57:582567
2568 AutomationMsg_SendJSONRequest::WriteReplyParams(reply_message, json_return,
2569 reply_return);
2570 Send(reply_message);
[email protected]55846ad842010-07-09 18:22:562571}
2572
2573// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2574// json input.
2575// Sample json output: {}
2576void AutomationProvider::FillAutoFillProfile(Browser* browser,
2577 DictionaryValue* args,
2578 IPC::Message* reply_message) {
[email protected]1ac875d22010-07-16 09:57:582579 std::string json_return = "{}";
2580 bool reply_return = true;
2581
[email protected]55846ad842010-07-09 18:22:562582 ListValue* profiles = NULL;
2583 ListValue* cards = NULL;
2584 args->GetList(L"profiles", &profiles);
2585 args->GetList(L"credit_cards", &cards);
2586
2587 std::vector<AutoFillProfile> autofill_profiles;
2588 std::vector<CreditCard> credit_cards;
2589 // Create an AutoFillProfile for each of the dictionary profiles.
2590 if (profiles) {
[email protected]1ac875d22010-07-16 09:57:582591 autofill_profiles = GetAutoFillProfilesFromList(*profiles, &json_return);
[email protected]55846ad842010-07-09 18:22:562592 }
2593 // Create a CreditCard for each of the dictionary values.
2594 if (cards) {
[email protected]1ac875d22010-07-16 09:57:582595 credit_cards = GetCreditCardsFromList(*cards, &json_return);
[email protected]55846ad842010-07-09 18:22:562596 }
2597
2598 // Save the AutoFillProfiles.
2599 int tab_index = 0;
2600 args->GetInteger(L"tab_index", &tab_index);
2601 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2602
2603 if (tab_contents) {
2604 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
2605 ->GetPersonalDataManager();
2606 if (pdm) {
2607 pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
2608 cards? &credit_cards : NULL);
2609 } else {
[email protected]1ac875d22010-07-16 09:57:582610 json_return = JSONErrorString("No PersonalDataManager.");
2611 reply_return = false;
[email protected]55846ad842010-07-09 18:22:562612 }
2613 } else {
[email protected]1ac875d22010-07-16 09:57:582614 json_return = JSONErrorString("No tab at that index.");
2615 reply_return = false;
[email protected]55846ad842010-07-09 18:22:562616 }
[email protected]1ac875d22010-07-16 09:57:582617 AutomationMsg_SendJSONRequest::WriteReplyParams(
2618 reply_message, json_return, reply_return);
2619 Send(reply_message);
[email protected]55846ad842010-07-09 18:22:562620}
2621
2622/* static */
2623ListValue* AutomationProvider::GetListFromAutoFillProfiles(
2624 std::vector<AutoFillProfile*> autofill_profiles) {
2625 ListValue* profiles = new ListValue;
2626
2627 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string
2628 = GetAutoFillFieldToStringMap();
2629
2630 // For each AutoFillProfile, transform it to a dictionary object to return.
2631 for (std::vector<AutoFillProfile*>::iterator it = autofill_profiles.begin();
2632 it != autofill_profiles.end(); ++it) {
2633 AutoFillProfile* profile = *it;
2634 DictionaryValue* profile_info = new DictionaryValue;
2635 profile_info->SetStringFromUTF16(L"label", profile->Label());
2636 // For each of the types, if it has a value, add it to the dictionary.
2637 for (std::map<AutoFillFieldType, std::wstring>::iterator
2638 type_it = autofill_type_to_string.begin();
2639 type_it != autofill_type_to_string.end(); ++type_it) {
2640 string16 value = profile->GetFieldText(AutoFillType(type_it->first));
2641 if (value.length()) { // If there was something stored for that value.
2642 profile_info->SetStringFromUTF16(type_it->second, value);
2643 }
2644 }
2645 profiles->Append(profile_info);
2646 }
2647 return profiles;
2648}
2649
2650/* static */
2651ListValue* AutomationProvider::GetListFromCreditCards(
2652 std::vector<CreditCard*> credit_cards) {
2653 ListValue* cards = new ListValue;
2654
2655 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2656 GetCreditCardFieldToStringMap();
2657
2658 // For each AutoFillProfile, transform it to a dictionary object to return.
2659 for (std::vector<CreditCard*>::iterator it = credit_cards.begin();
2660 it != credit_cards.end(); ++it) {
2661 CreditCard* card = *it;
2662 DictionaryValue* card_info = new DictionaryValue;
2663 card_info->SetStringFromUTF16(L"label", card->Label());
2664 // For each of the types, if it has a value, add it to the dictionary.
2665 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2666 credit_card_type_to_string.begin();
2667 type_it != credit_card_type_to_string.end(); ++type_it) {
2668 string16 value = card->GetFieldText(AutoFillType(type_it->first));
2669 // If there was something stored for that value.
2670 if (value.length()) {
2671 card_info->SetStringFromUTF16(type_it->second, value);
2672 }
2673 }
2674 cards->Append(card_info);
2675 }
2676 return cards;
2677}
2678
2679/* static */
2680std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
[email protected]1ac875d22010-07-16 09:57:582681 const ListValue& profiles, std::string* json_return) {
[email protected]55846ad842010-07-09 18:22:562682 std::vector<AutoFillProfile> autofill_profiles;
2683 DictionaryValue* profile_info = NULL;
2684 string16 profile_label;
2685 string16 current_value;
2686
2687 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string =
2688 GetAutoFillFieldToStringMap();
2689
2690 int num_profiles = profiles.GetSize();
2691 for (int i = 0; i < num_profiles; i++) {
2692 profiles.GetDictionary(i, &profile_info);
2693 profile_info->GetString("label", &profile_label);
2694 // Choose an id of 0 so that a unique id will be created.
2695 AutoFillProfile profile(profile_label, 0);
2696 // Loop through the possible profile types and add those provided.
2697 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2698 autofill_type_to_string.begin();
2699 type_it != autofill_type_to_string.end(); ++type_it) {
2700 if (profile_info->HasKey(type_it->second)) {
2701 if (profile_info->GetStringAsUTF16(type_it->second, &current_value)) {
2702 profile.SetInfo(AutoFillType(type_it->first), current_value);
2703 } else {
[email protected]1ac875d22010-07-16 09:57:582704 *json_return = JSONErrorString("All values must be strings");
[email protected]55846ad842010-07-09 18:22:562705 break;
2706 }
2707 }
2708 }
2709 autofill_profiles.push_back(profile);
2710 }
2711 return autofill_profiles;
2712}
2713
2714/* static */
2715std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
[email protected]1ac875d22010-07-16 09:57:582716 const ListValue& cards, std::string* json_return) {
[email protected]55846ad842010-07-09 18:22:562717 std::vector<CreditCard> credit_cards;
2718 DictionaryValue* card_info = NULL;
2719 string16 card_label;
2720 string16 current_value;
2721
2722 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2723 GetCreditCardFieldToStringMap();
2724
2725 int num_credit_cards = cards.GetSize();
2726 for (int i = 0; i < num_credit_cards; i++) {
2727 cards.GetDictionary(i, &card_info);
2728 card_info->GetString("label", &card_label);
2729 CreditCard card(card_label, 0);
2730 // Loop through the possible credit card fields and add those provided.
2731 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2732 credit_card_type_to_string.begin();
2733 type_it != credit_card_type_to_string.end(); ++type_it) {
2734 if (card_info->HasKey(type_it->second)) {
2735 if (card_info->GetStringAsUTF16(type_it->second, &current_value)) {
2736 card.SetInfo(AutoFillType(type_it->first), current_value);
2737 } else {
[email protected]1ac875d22010-07-16 09:57:582738 *json_return = JSONErrorString("All values must be strings");
[email protected]55846ad842010-07-09 18:22:562739 break;
2740 }
2741 }
2742 }
2743 credit_cards.push_back(card);
2744 }
2745 return credit_cards;
2746}
2747
2748/* static */
2749std::map<AutoFillFieldType, std::wstring>
2750 AutomationProvider::GetAutoFillFieldToStringMap() {
2751 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string;
2752 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2753 autofill_type_to_string[NAME_MIDDLE] = L"NAME_MIDDLE";
2754 autofill_type_to_string[NAME_LAST] = L"NAME_LAST";
2755 autofill_type_to_string[COMPANY_NAME] = L"COMPANY_NAME";
2756 autofill_type_to_string[EMAIL_ADDRESS] = L"EMAIL_ADDRESS";
2757 autofill_type_to_string[ADDRESS_HOME_LINE1] = L"ADDRESS_HOME_LINE1";
2758 autofill_type_to_string[ADDRESS_HOME_LINE2] = L"ADDRESS_HOME_LINE2";
2759 autofill_type_to_string[ADDRESS_HOME_CITY] = L"ADDRESS_HOME_CITY";
2760 autofill_type_to_string[ADDRESS_HOME_STATE] = L"ADDRESS_HOME_STATE";
2761 autofill_type_to_string[ADDRESS_HOME_ZIP] = L"ADDRESS_HOME_ZIP";
2762 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = L"ADDRESS_HOME_COUNTRY";
2763 autofill_type_to_string[PHONE_HOME_NUMBER] = L"PHONE_HOME_NUMBER";
2764 autofill_type_to_string[PHONE_FAX_NUMBER] = L"PHONE_FAX_NUMBER";
2765 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2766 return autofill_type_to_string;
2767}
2768
2769/* static */
2770std::map<AutoFillFieldType, std::wstring>
2771 AutomationProvider::GetCreditCardFieldToStringMap() {
2772 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string;
2773 credit_card_type_to_string[CREDIT_CARD_NAME] = L"CREDIT_CARD_NAME";
2774 credit_card_type_to_string[CREDIT_CARD_NUMBER] = L"CREDIT_CARD_NUMBER";
2775 credit_card_type_to_string[CREDIT_CARD_TYPE] = L"CREDIT_CARD_TYPE";
2776 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = L"CREDIT_CARD_EXP_MONTH";
2777 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
2778 L"CREDIT_CARD_EXP_4_DIGIT_YEAR";
2779 return credit_card_type_to_string;
2780}
2781
[email protected]1ac875d22010-07-16 09:57:582782/* static */
2783std::string AutomationProvider::JSONErrorString(const std::string& err) {
2784 std::string prefix = "{\"error\": \"";
2785 std::string no_quote_err;
2786 std::string suffix = "\"}";
2787
2788 base::JsonDoubleQuote(err, false, &no_quote_err);
2789 return prefix + no_quote_err + suffix;
2790}
2791
[email protected]53329582010-05-14 21:10:582792void AutomationProvider::SendJSONRequest(int handle,
2793 std::string json_request,
2794 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042795 Browser* browser = NULL;
[email protected]1ac875d22010-07-16 09:57:582796 std::string error_string;
[email protected]59a611242010-04-02 02:24:042797 scoped_ptr<Value> values;
2798
2799 // Basic error checking.
2800 if (browser_tracker_->ContainsHandle(handle)) {
2801 browser = browser_tracker_->GetResource(handle);
2802 }
2803 if (!browser) {
[email protected]1ac875d22010-07-16 09:57:582804 error_string = "no browser object";
2805 } else {
2806 base::JSONReader reader;
2807 std::string error;
2808 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
2809 if (!error.empty()) {
2810 error_string = error;
2811 }
[email protected]59a611242010-04-02 02:24:042812 }
2813
2814 // Make sure input is a dict with a string command.
2815 std::string command;
2816 DictionaryValue* dict_value = NULL;
[email protected]1ac875d22010-07-16 09:57:582817 if (error_string.empty()) {
2818 if (values->GetType() != Value::TYPE_DICTIONARY) {
2819 error_string = "not a dict or no command key in dict";
2820 } else {
2821 // Ownership remains with "values" variable.
2822 dict_value = static_cast<DictionaryValue*>(values.get());
2823 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2824 error_string = "no command key in dict or not a string command";
2825 }
2826 }
[email protected]59a611242010-04-02 02:24:042827 }
2828
[email protected]24e2b102010-04-29 17:56:472829 // Map json commands to their handlers.
2830 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052831 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2832 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2833 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2834
[email protected]a9ff2c02010-05-13 17:33:052835 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
[email protected]24e2b102010-04-29 17:56:472836 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292837 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052838
[email protected]53329582010-05-14 21:10:582839 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2840 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2841 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2842 handler_map["OmniboxMovePopupSelection"] =
2843 &AutomationProvider::OmniboxMovePopupSelection;
2844
[email protected]24e2b102010-04-29 17:56:472845 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2846 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052847
[email protected]ef413ca2010-05-25 21:09:142848 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2849
[email protected]f7d48012010-05-06 08:17:052850 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472851 handler_map["WaitForAllDownloadsToComplete"] =
2852 &AutomationProvider::WaitForDownloadsToComplete;
2853
[email protected]a3cd5022010-06-16 18:25:292854 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
2855
[email protected]7060bb292010-06-24 00:52:492856 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
2857
[email protected]c5aa5322010-07-15 19:00:072858 handler_map["ImportSettings"] = &AutomationProvider::ImportSettings;
2859
[email protected]a0fc50d72010-07-14 21:14:192860 handler_map["ClearBrowsingData"] = &AutomationProvider::ClearBrowsingData;
2861
[email protected]4d1929f12010-07-10 00:09:032862 // SetTheme() implemented using InstallExtension().
2863 handler_map["GetThemeInfo"] = &AutomationProvider::GetThemeInfo;
2864
[email protected]55846ad842010-07-09 18:22:562865 handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
2866 handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
2867
[email protected]1ac875d22010-07-16 09:57:582868 if (error_string.empty()) {
2869 if (handler_map.find(std::string(command)) != handler_map.end()) {
2870 (this->*handler_map[command])(browser, dict_value, reply_message);
2871 return;
2872 } else {
2873 error_string = "Unknown command. Options: ";
2874 for (std::map<std::string, JsonHandler>::const_iterator it =
2875 handler_map.begin(); it != handler_map.end(); ++it) {
2876 error_string += it->first + ", ";
2877 }
[email protected]3b9a9ab2010-07-16 07:35:572878 }
[email protected]f6ff0df2010-07-11 22:41:432879 }
[email protected]1ac875d22010-07-16 09:57:582880
2881 // If we hit an error, return info.
2882 // Return a dict of {"error", "descriptive_string_for_error"}.
2883 // Else return an empty dict.
2884 std::string json_string;
2885 bool success = true;
2886 if (!error_string.empty()) {
2887 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
2888 dict->SetString(L"error", error_string);
2889 base::JSONWriter::Write(dict.get(), false, &json_string);
2890 success = false;
2891 } else {
2892 json_string = "{}";
2893 }
2894 AutomationMsg_SendJSONRequest::WriteReplyParams(
2895 reply_message, json_string, success);
2896 Send(reply_message);
[email protected]59a611242010-04-02 02:24:042897}
2898
initial.commit09911bf2008-07-26 23:55:292899void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562900 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342901 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2902 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562903 DCHECK(reply_message_ == NULL);
2904 reply_message_ = reply_message;
2905
[email protected]d9f9b792009-06-24 13:17:122906 DevToolsManager::GetInstance()->InspectElement(
2907 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292908 } else {
[email protected]71f65dd2009-02-11 19:14:562909 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2910 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292911 }
2912}
2913
2914void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092915 if (reply_message_) {
2916 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2917 num_resources);
2918 Send(reply_message_);
2919 reply_message_ = NULL;
2920 }
initial.commit09911bf2008-07-26 23:55:292921}
2922
[email protected]a7eee32f2009-05-22 18:08:172923class SetProxyConfigTask : public Task {
2924 public:
[email protected]be180c802009-10-23 06:33:312925 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2926 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252927 : request_context_getter_(request_context_getter),
2928 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172929 virtual void Run() {
2930 // First, deserialize the JSON string. If this fails, log and bail.
2931 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392932 std::string error_msg;
2933 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172934 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2935 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392936 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172937 return;
2938 }
2939
2940 scoped_ptr<DictionaryValue> dict(
2941 static_cast<DictionaryValue*>(root.release()));
2942 // Now put together a proxy configuration from the deserialized string.
2943 net::ProxyConfig pc;
2944 PopulateProxyConfig(*dict.get(), &pc);
2945
[email protected]be180c802009-10-23 06:33:312946 net::ProxyService* proxy_service =
2947 request_context_getter_->GetURLRequestContext()->proxy_service();
2948 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172949 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2950 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312951 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172952 }
2953
2954 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2955 DCHECK(pc);
2956 bool no_proxy = false;
2957 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2958 // Make no changes to the ProxyConfig.
2959 return;
2960 }
2961 bool auto_config;
2962 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482963 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172964 }
2965 std::string pac_url;
2966 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482967 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172968 }
2969 std::string proxy_bypass_list;
2970 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482971 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172972 }
2973 std::string proxy_server;
2974 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482975 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172976 }
2977 }
2978
2979 private:
[email protected]be180c802009-10-23 06:33:312980 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172981 std::string proxy_config_;
2982};
2983
2984
2985void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312986 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2987 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172988 FilePath user_data_dir;
2989 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2990 ProfileManager* profile_manager = g_browser_process->profile_manager();
2991 DCHECK(profile_manager);
2992 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2993 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312994 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172995 }
[email protected]be180c802009-10-23 06:33:312996 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172997
[email protected]fae20792009-10-28 20:31:582998 ChromeThread::PostTask(
2999 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:313000 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:173001}
3002
[email protected]4f3dc372009-02-24 00:10:293003void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:333004 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:293005 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:293006 if (tab_tracker_->ContainsHandle(handle)) {
3007 NavigationController* tab = tab_tracker_->GetResource(handle);
3008 DownloadManager* dlm = tab->profile()->GetDownloadManager();
3009 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:333010 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:293011 }
initial.commit09911bf2008-07-26 23:55:293012}
3013
[email protected]6a5670d22009-10-27 16:21:343014void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:143015 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:533016 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
3017 reply_message);
3018}
3019
3020void AutomationProvider::OpenNewBrowserWindowOfType(
3021 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:143022 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:293023 // We may have no current browser windows open so don't rely on
3024 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:533025 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
3026 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:053027 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:153028 if (show)
[email protected]15952e462008-11-14 00:29:053029 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:293030}
3031
[email protected]71f65dd2009-02-11 19:14:563032void AutomationProvider::GetWindowForBrowser(int browser_handle,
3033 bool* success,
3034 int* handle) {
3035 *success = false;
3036 *handle = 0;
initial.commit09911bf2008-07-26 23:55:293037
3038 if (browser_tracker_->ContainsHandle(browser_handle)) {
3039 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:203040 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:293041 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:203042 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:563043 *success = true;
initial.commit09911bf2008-07-26 23:55:293044 }
initial.commit09911bf2008-07-26 23:55:293045}
3046
3047void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:563048 int browser_handle,
3049 bool* success,
3050 int* autocomplete_edit_handle) {
3051 *success = false;
3052 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:293053
3054 if (browser_tracker_->ContainsHandle(browser_handle)) {
3055 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:063056 LocationBar* loc_bar = browser->window()->GetLocationBar();
3057 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:293058 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:563059 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
3060 *success = true;
initial.commit09911bf2008-07-26 23:55:293061 }
initial.commit09911bf2008-07-26 23:55:293062}
initial.commit09911bf2008-07-26 23:55:293063
[email protected]71f65dd2009-02-11 19:14:563064void AutomationProvider::ShowInterstitialPage(int tab_handle,
3065 const std::string& html_text,
3066 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293067 if (tab_tracker_->ContainsHandle(tab_handle)) {
3068 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:113069 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:403070
[email protected]7dad3d5f2010-03-04 00:27:013071 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:403072 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:343073 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:403074 GURL("about:interstitial"),
3075 html_text);
3076 interstitial->Show();
3077 return;
initial.commit09911bf2008-07-26 23:55:293078 }
[email protected]71f65dd2009-02-11 19:14:563079
[email protected]457f5cf2009-08-18 16:37:523080 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
3081 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563082 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293083}
3084
[email protected]71f65dd2009-02-11 19:14:563085void AutomationProvider::HideInterstitialPage(int tab_handle,
3086 bool* success) {
3087 *success = false;
[email protected]57c6a652009-05-04 07:58:343088 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
3089 if (tab_contents && tab_contents->interstitial_page()) {
3090 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:563091 *success = true;
initial.commit09911bf2008-07-26 23:55:293092 }
initial.commit09911bf2008-07-26 23:55:293093}
3094
[email protected]71f65dd2009-02-11 19:14:563095void AutomationProvider::CloseTab(int tab_handle,
3096 bool wait_until_closed,
3097 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293098 if (tab_tracker_->ContainsHandle(tab_handle)) {
3099 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
3100 int index;
3101 Browser* browser = Browser::GetBrowserForController(controller, &index);
3102 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:143103 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:113104 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:453105 return;
initial.commit09911bf2008-07-26 23:55:293106 }
[email protected]de246f52009-02-25 18:25:453107
3108 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:553109 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293110}
3111
[email protected]71f65dd2009-02-11 19:14:563112void AutomationProvider::CloseBrowser(int browser_handle,
3113 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293114 if (browser_tracker_->ContainsHandle(browser_handle)) {
3115 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563116 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:563117 reply_message);
[email protected]f3e99e32008-07-30 04:48:393118 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:293119 } else {
3120 NOTREACHED();
3121 }
3122}
3123
[email protected]71f65dd2009-02-11 19:14:563124void AutomationProvider::CloseBrowserAsync(int browser_handle) {
3125 if (browser_tracker_->ContainsHandle(browser_handle)) {
3126 Browser* browser = browser_tracker_->GetResource(browser_handle);
3127 browser->window()->Close();
3128 } else {
3129 NOTREACHED();
3130 }
3131}
3132
[email protected]71f65dd2009-02-11 19:14:563133void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
3134 IPC::Message* reply_message) {
3135 if (tab_tracker_->ContainsHandle(tab_handle)) {
3136 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3137 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:143138 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:563139 }
3140}
3141
[email protected]71f65dd2009-02-11 19:14:563142void AutomationProvider::GetSecurityState(int handle, bool* success,
3143 SecurityStyle* security_style,
3144 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:483145 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:293146 if (tab_tracker_->ContainsHandle(handle)) {
3147 NavigationController* tab = tab_tracker_->GetResource(handle);
3148 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563149 *success = true;
3150 *security_style = entry->ssl().security_style();
3151 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:483152 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:293153 } else {
[email protected]71f65dd2009-02-11 19:14:563154 *success = false;
3155 *security_style = SECURITY_STYLE_UNKNOWN;
3156 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:483157 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:293158 }
3159}
3160
[email protected]71f65dd2009-02-11 19:14:563161void AutomationProvider::GetPageType(int handle, bool* success,
3162 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:293163 if (tab_tracker_->ContainsHandle(handle)) {
3164 NavigationController* tab = tab_tracker_->GetResource(handle);
3165 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563166 *page_type = entry->page_type();
3167 *success = true;
initial.commit09911bf2008-07-26 23:55:293168 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:343169 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:563170 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:343171 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:563172 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293173 } else {
[email protected]71f65dd2009-02-11 19:14:563174 *success = false;
3175 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293176 }
3177}
3178
[email protected]84abba62009-10-07 17:01:443179void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
3180 int* duration_ms) {
3181 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
3182 event_name);
3183}
3184
[email protected]71f65dd2009-02-11 19:14:563185void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
3186 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293187 if (tab_tracker_->ContainsHandle(handle)) {
3188 NavigationController* tab = tab_tracker_->GetResource(handle);
3189 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:073190 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:403191 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:473192 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:343193 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:293194 if (ssl_blocking_page) {
3195 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:013196 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:563197 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:293198 return;
3199 }
3200 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:523201 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3202 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:563203 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293204 return;
3205 }
3206 }
3207 }
3208 // We failed.
[email protected]457f5cf2009-08-18 16:37:523209 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3210 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563211 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293212}
3213
[email protected]71f65dd2009-02-11 19:14:563214void AutomationProvider::BringBrowserToFront(int browser_handle,
3215 bool* success) {
initial.commit09911bf2008-07-26 23:55:293216 if (browser_tracker_->ContainsHandle(browser_handle)) {
3217 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:063218 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:563219 *success = true;
initial.commit09911bf2008-07-26 23:55:293220 } else {
[email protected]71f65dd2009-02-11 19:14:563221 *success = false;
initial.commit09911bf2008-07-26 23:55:293222 }
3223}
3224
[email protected]71f65dd2009-02-11 19:14:563225void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
3226 int message_num,
3227 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:293228 if (browser_tracker_->ContainsHandle(browser_handle)) {
3229 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563230 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:143231 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:293232 } else {
[email protected]71f65dd2009-02-11 19:14:563233 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:293234 }
3235}
3236
[email protected]71f65dd2009-02-11 19:14:563237void AutomationProvider::PrintNow(int tab_handle,
3238 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:573239 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:343240 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3241 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:293242 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:573243 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:143244 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:343245 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:573246 return;
initial.commit09911bf2008-07-26 23:55:293247 }
[email protected]71f65dd2009-02-11 19:14:563248 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
3249 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293250}
[email protected]d301c952009-07-13 15:02:413251
[email protected]71f65dd2009-02-11 19:14:563252void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:113253 const FilePath& file_name,
3254 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:563255 int type,
3256 bool* success) {
initial.commit09911bf2008-07-26 23:55:293257 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:563258 *success = false;
initial.commit09911bf2008-07-26 23:55:293259 return;
3260 }
3261
3262 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3263 Browser* browser = FindAndActivateTab(nav);
3264 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:143265 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:563266 *success = false;
initial.commit09911bf2008-07-26 23:55:293267 return;
3268 }
3269
initial.commit09911bf2008-07-26 23:55:293270 SavePackage::SavePackageType save_type =
3271 static_cast<SavePackage::SavePackageType>(type);
3272 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
3273 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:343274 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:293275
[email protected]71f65dd2009-02-11 19:14:563276 *success = true;
initial.commit09911bf2008-07-26 23:55:293277}
3278
[email protected]71f65dd2009-02-11 19:14:563279void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
3280 bool* success,
3281 std::wstring* text) {
3282 *success = false;
initial.commit09911bf2008-07-26 23:55:293283 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563284 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:523285 GetText();
[email protected]71f65dd2009-02-11 19:14:563286 *success = true;
initial.commit09911bf2008-07-26 23:55:293287 }
initial.commit09911bf2008-07-26 23:55:293288}
3289
[email protected]71f65dd2009-02-11 19:14:563290void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
3291 const std::wstring& text,
3292 bool* success) {
3293 *success = false;
initial.commit09911bf2008-07-26 23:55:293294 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:523295 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
3296 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:563297 *success = true;
initial.commit09911bf2008-07-26 23:55:293298 }
initial.commit09911bf2008-07-26 23:55:293299}
3300
3301void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:563302 int autocomplete_edit_handle,
3303 bool* success,
3304 std::vector<AutocompleteMatchData>* matches) {
3305 *success = false;
initial.commit09911bf2008-07-26 23:55:293306 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:273307 const AutocompleteResult& result = autocomplete_edit_tracker_->
3308 GetResource(autocomplete_edit_handle)->model()->result();
3309 for (AutocompleteResult::const_iterator i = result.begin();
3310 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:563311 matches->push_back(AutocompleteMatchData(*i));
3312 *success = true;
initial.commit09911bf2008-07-26 23:55:293313 }
initial.commit09911bf2008-07-26 23:55:293314}
3315
3316void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:563317 int autocomplete_edit_handle,
3318 bool* success,
3319 bool* query_in_progress) {
3320 *success = false;
3321 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:293322 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563323 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:523324 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:563325 *success = true;
initial.commit09911bf2008-07-26 23:55:293326 }
initial.commit09911bf2008-07-26 23:55:293327}
3328
[email protected]63514af2010-03-30 17:17:233329#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:193330
[email protected]5ae5bed2009-08-21 18:52:443331#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:393332
[email protected]57c6a652009-05-04 07:58:343333TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:573334 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:573335 if (tab_tracker_->ContainsHandle(handle)) {
3336 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:343337 if (tab)
3338 *tab = nav_controller;
3339 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:573340 }
[email protected]57c6a652009-05-04 07:58:343341 return NULL;
[email protected]20e93d12008-08-28 16:31:573342}
3343
initial.commit09911bf2008-07-26 23:55:293344TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
3345 : AutomationProvider(profile) {
3346 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:143347 registrar_.Add(this, NotificationType::SESSION_END,
3348 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:293349}
3350
3351TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:293352 BrowserList::RemoveObserver(this);
3353}
3354
3355void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:143356 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:293357 AutomationProvider::OnChannelError();
3358}
3359
3360void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
3361 // For backwards compatibility with the testing automation interface, we
3362 // want the automation provider (and hence the process) to go away when the
3363 // last browser goes away.
3364 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:293365 // If you change this, update Observer for NotificationType::SESSION_END
3366 // below.
[email protected]295039bd2008-08-15 04:32:573367 MessageLoop::current()->PostTask(FROM_HERE,
3368 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:293369 }
3370}
3371
3372void TestingAutomationProvider::Observe(NotificationType type,
3373 const NotificationSource& source,
3374 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563375 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:293376 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
3377 // before the task runs resulting in this object not being deleted. This
3378 // Release balance out the Release scheduled by OnBrowserRemoving.
3379 Release();
3380}
[email protected]295039bd2008-08-15 04:32:573381
3382void TestingAutomationProvider::OnRemoveProvider() {
3383 AutomationProviderList::GetInstance()->RemoveProvider(this);
3384}
[email protected]8a3422c92008-09-24 17:42:423385
[email protected]816633a2009-11-11 21:48:183386void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:563387 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:423388 if (tab_tracker_->ContainsHandle(handle)) {
3389 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:343390 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:113391 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423392 }
[email protected]8a3422c92008-09-24 17:42:423393}
3394
[email protected]816633a2009-11-11 21:48:183395void AutomationProvider::ClickInfoBarAccept(int handle,
3396 int info_bar_index,
3397 bool wait_for_navigation,
3398 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:423399 bool success = false;
3400 if (tab_tracker_->ContainsHandle(handle)) {
3401 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3402 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:113403 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423404 if (info_bar_index >= 0 && info_bar_index < count) {
3405 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:013406 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:423407 }
[email protected]eb9ba192008-12-02 02:41:343408 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:113409 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:343410 info_bar_index);
3411 if (delegate->AsConfirmInfoBarDelegate())
3412 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:423413 success = true;
3414 }
3415 }
[email protected]4f3dc372009-02-24 00:10:293416 }
[email protected]58f622a62009-10-04 01:17:553417
3418 // This "!wait_for_navigation || !success condition" logic looks suspicious.
3419 // It will send a failure message when success is true but
3420 // |wait_for_navigation| is false.
3421 // TODO(phajdan.jr): investgate whether the reply param (currently
3422 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:423423 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:183424 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:523425 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:423426}
3427
[email protected]71f65dd2009-02-11 19:14:563428void AutomationProvider::GetLastNavigationTime(int handle,
3429 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:423430 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:563431 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:423432}
3433
[email protected]71f65dd2009-02-11 19:14:563434void AutomationProvider::WaitForNavigation(int handle,
3435 int64 last_navigation_time,
3436 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:253437 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:423438 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:253439
[email protected]8a3422c92008-09-24 17:42:423440 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:563441 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:523442 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3443 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553444 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293445 return;
[email protected]8a3422c92008-09-24 17:42:423446 }
3447
[email protected]7dad3d5f2010-03-04 00:27:013448 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423449}
3450
[email protected]71f65dd2009-02-11 19:14:563451void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163452 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563453 int value,
3454 bool* success) {
3455 *success = false;
[email protected]8a3422c92008-09-24 17:42:423456 if (browser_tracker_->ContainsHandle(handle)) {
3457 Browser* browser = browser_tracker_->GetResource(handle);
3458 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563459 *success = true;
[email protected]8a3422c92008-09-24 17:42:423460 }
[email protected]8a3422c92008-09-24 17:42:423461}
[email protected]97fa6ce32008-12-19 01:48:163462
[email protected]71f65dd2009-02-11 19:14:563463void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163464 const std::wstring& name,
[email protected]ddd231e2010-06-29 20:35:193465 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563466 bool* success) {
3467 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163468 if (browser_tracker_->ContainsHandle(handle)) {
3469 Browser* browser = browser_tracker_->GetResource(handle);
3470 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563471 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163472 }
[email protected]97fa6ce32008-12-19 01:48:163473}
3474
[email protected]71f65dd2009-02-11 19:14:563475void AutomationProvider::GetBooleanPreference(int handle,
3476 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:363477 bool* success,
3478 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563479 *success = false;
3480 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163481 if (browser_tracker_->ContainsHandle(handle)) {
3482 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563483 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3484 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163485 }
[email protected]97fa6ce32008-12-19 01:48:163486}
3487
[email protected]71f65dd2009-02-11 19:14:563488void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163489 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563490 bool value,
3491 bool* success) {
3492 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163493 if (browser_tracker_->ContainsHandle(handle)) {
3494 Browser* browser = browser_tracker_->GetResource(handle);
3495 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563496 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163497 }
[email protected]97fa6ce32008-12-19 01:48:163498}
3499
3500// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563501void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403502 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163503 if (tab_tracker_->ContainsHandle(tab_handle)) {
3504 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3505 Browser* browser = FindAndActivateTab(nav);
3506 DCHECK(browser);
3507
[email protected]57c6a652009-05-04 07:58:343508 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3509 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163510 }
[email protected]97fa6ce32008-12-19 01:48:163511}
3512
[email protected]b8f48d12009-11-09 20:14:363513// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563514void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:403515 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:563516 bool* success) {
3517 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163518 if (tab_tracker_->ContainsHandle(tab_handle)) {
3519 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193520 if (!nav)
3521 return;
[email protected]97fa6ce32008-12-19 01:48:163522 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163523
[email protected]2f2afba2010-04-01 01:53:193524 // If the browser has UI, simulate what a user would do.
3525 // Activate the tab and then click the encoding menu.
3526 if (browser &&
3527 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163528 int selected_encoding_id =
3529 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3530 if (selected_encoding_id) {
3531 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563532 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163533 }
[email protected]2f2afba2010-04-01 01:53:193534 } else {
3535 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3536 // Try to get TabContents and call its override_encoding method.
3537 TabContents* contents = nav->tab_contents();
3538 if (!contents)
3539 return;
3540 const std::string selected_encoding =
3541 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
3542 if (selected_encoding.empty())
3543 return;
3544 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163545 }
3546 }
[email protected]97fa6ce32008-12-19 01:48:163547}
[email protected]5bcdb312009-01-07 21:43:203548
[email protected]4d434a1a2009-02-11 21:06:573549void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203550 SavePackage::SetShouldPromptUser(should_prompt);
3551}
[email protected]87eab222009-03-13 00:47:453552
[email protected]66ba4932009-06-04 19:22:133553void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3554 *count = -1; // -1 is the error code
3555 if (tab_tracker_->ContainsHandle(handle)) {
3556 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3557 TabContents* tab_contents = nav_controller->tab_contents();
3558 if (tab_contents) {
3559 BlockedPopupContainer* container =
3560 tab_contents->blocked_popup_container();
3561 if (container) {
3562 *count = static_cast<int>(container->GetBlockedPopupCount());
3563 } else {
3564 // If we don't have a container, we don't have any blocked popups to
3565 // contain!
3566 *count = 0;
3567 }
3568 }
3569 }
3570}
[email protected]f7a68432009-07-29 23:18:193571
3572void AutomationProvider::SelectAll(int tab_handle) {
3573 RenderViewHost* view = GetViewForTab(tab_handle);
3574 if (!view) {
3575 NOTREACHED();
3576 return;
3577 }
3578
3579 view->SelectAll();
3580}
3581
3582void AutomationProvider::Cut(int tab_handle) {
3583 RenderViewHost* view = GetViewForTab(tab_handle);
3584 if (!view) {
3585 NOTREACHED();
3586 return;
3587 }
3588
3589 view->Cut();
3590}
3591
3592void AutomationProvider::Copy(int tab_handle) {
3593 RenderViewHost* view = GetViewForTab(tab_handle);
3594 if (!view) {
3595 NOTREACHED();
3596 return;
3597 }
3598
3599 view->Copy();
3600}
3601
3602void AutomationProvider::Paste(int tab_handle) {
3603 RenderViewHost* view = GetViewForTab(tab_handle);
3604 if (!view) {
3605 NOTREACHED();
3606 return;
3607 }
3608
3609 view->Paste();
3610}
3611
3612void AutomationProvider::ReloadAsync(int tab_handle) {
3613 if (tab_tracker_->ContainsHandle(tab_handle)) {
3614 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3615 if (!tab) {
3616 NOTREACHED();
3617 return;
3618 }
3619
[email protected]106a0812010-03-18 00:15:123620 const bool check_for_repost = true;
3621 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193622 }
3623}
3624
3625void AutomationProvider::StopAsync(int tab_handle) {
3626 RenderViewHost* view = GetViewForTab(tab_handle);
3627 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363628 // We tolerate StopAsync being called even before a view has been created.
3629 // So just log a warning instead of a NOTREACHED().
3630 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193631 return;
3632 }
3633
3634 view->Stop();
3635}
3636
[email protected]1bb5f892009-10-06 01:44:573637void AutomationProvider::OnSetPageFontSize(int tab_handle,
3638 int font_size) {
3639 AutomationPageFontSize automation_font_size =
3640 static_cast<AutomationPageFontSize>(font_size);
3641
3642 if (automation_font_size < SMALLEST_FONT ||
3643 automation_font_size > LARGEST_FONT) {
3644 DLOG(ERROR) << "Invalid font size specified : "
3645 << font_size;
3646 return;
3647 }
3648
3649 if (tab_tracker_->ContainsHandle(tab_handle)) {
3650 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3651 DCHECK(tab != NULL);
3652 if (tab && tab->tab_contents()) {
3653 DCHECK(tab->tab_contents()->profile() != NULL);
3654 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3655 prefs::kWebKitDefaultFontSize, font_size);
3656 }
3657 }
3658}
3659
[email protected]bc73b4e52010-03-26 04:16:203660void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3661 BrowsingDataRemover* remover;
3662 remover = new BrowsingDataRemover(profile(),
3663 BrowsingDataRemover::EVERYTHING, // All time periods.
3664 base::Time());
3665 remover->Remove(remove_mask);
3666 // BrowsingDataRemover deletes itself.
3667}
[email protected]1bb5f892009-10-06 01:44:573668
[email protected]2949e90d2009-08-21 15:32:523669void AutomationProvider::WaitForBrowserWindowCountToBecome(
3670 int target_count, IPC::Message* reply_message) {
3671 if (static_cast<int>(BrowserList::size()) == target_count) {
3672 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3673 reply_message, true);
3674 Send(reply_message);
3675 return;
3676 }
3677
3678 // Set up an observer (it will delete itself).
3679 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3680}
3681
3682void AutomationProvider::WaitForAppModalDialogToBeShown(
3683 IPC::Message* reply_message) {
3684 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3685 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3686 reply_message, true);
3687 Send(reply_message);
3688 return;
3689 }
3690
3691 // Set up an observer (it will delete itself).
3692 new AppModalDialogShownObserver(this, reply_message);
3693}
3694
[email protected]1126a1d32009-08-26 15:39:263695void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3696 int handle, int number_of_navigations, IPC::Message* reply_message) {
3697 if (tab_tracker_->ContainsHandle(handle)) {
3698 NavigationController* tab = tab_tracker_->GetResource(handle);
3699 Browser* browser = FindAndActivateTab(tab);
3700 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013701 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3702 false);
[email protected]1126a1d32009-08-26 15:39:263703 browser->GoBack(CURRENT_TAB);
3704 return;
3705 }
3706 }
3707
3708 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3709 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3710 Send(reply_message);
3711}
3712
3713void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3714 int handle, int number_of_navigations, IPC::Message* reply_message) {
3715 if (tab_tracker_->ContainsHandle(handle)) {
3716 NavigationController* tab = tab_tracker_->GetResource(handle);
3717 Browser* browser = FindAndActivateTab(tab);
3718 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013719 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3720 false);
[email protected]1126a1d32009-08-26 15:39:263721 browser->GoForward(CURRENT_TAB);
3722 return;
3723 }
3724 }
3725
3726 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3727 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3728 Send(reply_message);
3729}
3730
[email protected]f7a68432009-07-29 23:18:193731RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3732 if (tab_tracker_->ContainsHandle(tab_handle)) {
3733 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3734 if (!tab) {
3735 NOTREACHED();
3736 return NULL;
3737 }
3738
3739 TabContents* tab_contents = tab->tab_contents();
3740 if (!tab_contents) {
3741 NOTREACHED();
3742 return NULL;
3743 }
3744
3745 RenderViewHost* view_host = tab_contents->render_view_host();
3746 return view_host;
3747 }
3748
3749 return NULL;
3750}
[email protected]675595f2009-08-26 22:32:043751
3752void AutomationProvider::GetBrowserForWindow(int window_handle,
3753 bool* success,
3754 int* browser_handle) {
3755 *success = false;
3756 *browser_handle = 0;
3757
3758 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3759 if (!window)
3760 return;
3761
3762 BrowserList::const_iterator iter = BrowserList::begin();
3763 for (;iter != BrowserList::end(); ++iter) {
3764 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3765 if (window == this_window) {
3766 // Add() returns the existing handle for the resource if any.
3767 *browser_handle = browser_tracker_->Add(*iter);
3768 *success = true;
3769 return;
3770 }
3771 }
3772}
[email protected]d11c8e92009-10-20 23:26:403773
3774void AutomationProvider::InstallExtension(const FilePath& crx_path,
3775 IPC::Message* reply_message) {
3776 ExtensionsService* service = profile_->GetExtensionsService();
3777 if (service) {
3778 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193779 new ExtensionInstallNotificationObserver(this,
3780 AutomationMsg_InstallExtension::ID,
3781 reply_message);
[email protected]d11c8e92009-10-20 23:26:403782
3783 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163784 scoped_refptr<CrxInstaller> installer(
3785 new CrxInstaller(install_dir,
3786 service,
3787 NULL)); // silent install, no UI
3788 installer->set_allow_privilege_increase(true);
3789 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403790 } else {
3791 AutomationMsg_InstallExtension::WriteReplyParams(
3792 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3793 Send(reply_message);
3794 }
3795}
3796
3797void AutomationProvider::LoadExpandedExtension(
3798 const FilePath& extension_dir,
3799 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383800 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403801 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193802 new ExtensionInstallNotificationObserver(
3803 this,
3804 AutomationMsg_LoadExpandedExtension::ID,
3805 reply_message);
[email protected]d11c8e92009-10-20 23:26:403806
3807 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403808 } else {
3809 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3810 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3811 Send(reply_message);
3812 }
3813}
[email protected]673fd2c02010-02-04 23:10:003814
[email protected]a1e62d12010-03-16 02:18:433815void AutomationProvider::GetEnabledExtensions(
3816 std::vector<FilePath>* result) {
3817 ExtensionsService* service = profile_->GetExtensionsService();
3818 DCHECK(service);
3819 if (service->extensions_enabled()) {
3820 const ExtensionList* extensions = service->extensions();
3821 DCHECK(extensions);
3822 for (size_t i = 0; i < extensions->size(); ++i) {
3823 Extension* extension = (*extensions)[i];
3824 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123825 if (extension->location() == Extension::INTERNAL ||
3826 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073827 result->push_back(extension->path());
3828 }
[email protected]a1e62d12010-03-16 02:18:433829 }
3830 }
3831}
3832
[email protected]790788ac2010-04-06 17:52:193833void AutomationProvider::WaitForExtensionTestResult(
3834 IPC::Message* reply_message) {
3835 DCHECK(reply_message_ == NULL);
3836 reply_message_ = reply_message;
3837 // Call MaybeSendResult, because the result might have come in before
3838 // we were waiting on it.
3839 extension_test_result_observer_->MaybeSendResult();
3840}
3841
3842void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093843 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193844 ExtensionsService* service = profile_->GetExtensionsService();
3845 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3846 if (service && manager) {
3847 // The observer will delete itself when done.
3848 new ExtensionReadyNotificationObserver(
3849 manager,
3850 this,
3851 AutomationMsg_InstallExtensionAndGetHandle::ID,
3852 reply_message);
3853
[email protected]d7e5525d2010-04-20 14:37:093854 ExtensionInstallUI* client =
3855 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193856 scoped_refptr<CrxInstaller> installer(
3857 new CrxInstaller(service->install_directory(),
3858 service,
[email protected]d7e5525d2010-04-20 14:37:093859 client));
[email protected]790788ac2010-04-06 17:52:193860 installer->set_allow_privilege_increase(true);
3861 installer->InstallCrx(crx_path);
3862 } else {
3863 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3864 reply_message, 0);
3865 Send(reply_message);
3866 }
3867}
3868
3869void AutomationProvider::UninstallExtension(int extension_handle,
3870 bool* success) {
3871 *success = false;
3872 Extension* extension = GetExtension(extension_handle);
3873 ExtensionsService* service = profile_->GetExtensionsService();
3874 if (extension && service) {
3875 ExtensionUnloadNotificationObserver observer;
3876 service->UninstallExtension(extension->id(), false);
3877 // The extension unload notification should have been sent synchronously
3878 // with the uninstall. Just to be safe, check that it was received.
3879 *success = observer.did_receive_unload_notification();
3880 }
3881}
3882
3883void AutomationProvider::EnableExtension(int extension_handle,
3884 IPC::Message* reply_message) {
3885 Extension* extension = GetDisabledExtension(extension_handle);
3886 ExtensionsService* service = profile_->GetExtensionsService();
3887 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3888 // Only enable if this extension is disabled.
3889 if (extension && service && manager) {
3890 // The observer will delete itself when done.
3891 new ExtensionReadyNotificationObserver(
3892 manager,
3893 this,
3894 AutomationMsg_EnableExtension::ID,
3895 reply_message);
3896 service->EnableExtension(extension->id());
3897 } else {
3898 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3899 Send(reply_message);
3900 }
3901}
3902
3903void AutomationProvider::DisableExtension(int extension_handle,
3904 bool* success) {
3905 *success = false;
3906 Extension* extension = GetEnabledExtension(extension_handle);
3907 ExtensionsService* service = profile_->GetExtensionsService();
3908 if (extension && service) {
3909 ExtensionUnloadNotificationObserver observer;
3910 service->DisableExtension(extension->id());
3911 // The extension unload notification should have been sent synchronously
3912 // with the disable. Just to be safe, check that it was received.
3913 *success = observer.did_receive_unload_notification();
3914 }
3915}
3916
3917void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3918 int extension_handle, int browser_handle,
3919 IPC::Message* reply_message) {
3920 bool success = false;
3921 Extension* extension = GetEnabledExtension(extension_handle);
3922 ExtensionsService* service = profile_->GetExtensionsService();
3923 ExtensionMessageService* message_service =
3924 profile_->GetExtensionMessageService();
3925 Browser* browser = browser_tracker_->GetResource(browser_handle);
3926 if (extension && service && message_service && browser) {
3927 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3928 if (extension->page_action()) {
3929 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3930 browser->profile(), extension->id(), "action", tab_id, "", 1);
3931 success = true;
3932 } else if (extension->browser_action()) {
3933 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3934 browser->profile(), extension->id(), browser);
3935 success = true;
3936 }
3937 }
3938 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3939 reply_message, success);
3940 Send(reply_message);
3941}
3942
3943void AutomationProvider::MoveExtensionBrowserAction(
3944 int extension_handle, int index, bool* success) {
3945 *success = false;
3946 Extension* extension = GetEnabledExtension(extension_handle);
3947 ExtensionsService* service = profile_->GetExtensionsService();
3948 if (extension && service) {
3949 ExtensionToolbarModel* toolbar = service->toolbar_model();
3950 if (toolbar) {
3951 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3952 toolbar->MoveBrowserAction(extension, index);
3953 *success = true;
3954 } else {
3955 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3956 }
3957 }
3958 }
3959}
3960
3961void AutomationProvider::GetExtensionProperty(
3962 int extension_handle,
3963 AutomationMsg_ExtensionProperty type,
3964 bool* success,
3965 std::string* value) {
3966 *success = false;
3967 Extension* extension = GetExtension(extension_handle);
3968 ExtensionsService* service = profile_->GetExtensionsService();
3969 if (extension && service) {
3970 ExtensionToolbarModel* toolbar = service->toolbar_model();
3971 int found_index = -1;
3972 int index = 0;
3973 switch (type) {
3974 case AUTOMATION_MSG_EXTENSION_ID:
3975 *value = extension->id();
3976 *success = true;
3977 break;
3978 case AUTOMATION_MSG_EXTENSION_NAME:
3979 *value = extension->name();
3980 *success = true;
3981 break;
3982 case AUTOMATION_MSG_EXTENSION_VERSION:
3983 *value = extension->VersionString();
3984 *success = true;
3985 break;
3986 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3987 if (toolbar) {
3988 for (ExtensionList::const_iterator iter = toolbar->begin();
3989 iter != toolbar->end(); iter++) {
3990 // Skip this extension if we are in incognito mode
3991 // and it is not incognito-enabled.
3992 if (profile_->IsOffTheRecord() &&
3993 !service->IsIncognitoEnabled(*iter))
3994 continue;
3995 if (*iter == extension) {
3996 found_index = index;
3997 break;
3998 }
3999 index++;
4000 }
4001 *value = IntToString(found_index);
4002 *success = true;
4003 }
4004 break;
4005 default:
4006 LOG(WARNING) << "Trying to get undefined extension property";
4007 break;
4008 }
4009 }
4010}
4011
[email protected]673fd2c02010-02-04 23:10:004012void AutomationProvider::SaveAsAsync(int tab_handle) {
4013 NavigationController* tab = NULL;
4014 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
4015 if (tab_contents)
4016 tab_contents->OnSavePage();
4017}
[email protected]7dad3d5f2010-03-04 00:27:014018
4019void AutomationProvider::SetContentSetting(
4020 int handle,
4021 const std::string& host,
4022 ContentSettingsType content_type,
4023 ContentSetting setting,
4024 bool* success) {
4025 *success = false;
4026 if (browser_tracker_->ContainsHandle(handle)) {
4027 Browser* browser = browser_tracker_->GetResource(handle);
4028 HostContentSettingsMap* map =
4029 browser->profile()->GetHostContentSettingsMap();
4030 if (host.empty()) {
4031 map->SetDefaultContentSetting(content_type, setting);
4032 } else {
[email protected]0314ae02010-04-08 09:18:294033 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
4034 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:014035 }
4036 *success = true;
4037 }
4038}
[email protected]cc824372010-03-31 15:33:014039
4040#if !defined(TOOLKIT_VIEWS)
4041void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
4042 NOTIMPLEMENTED();
4043};
4044
4045void AutomationProvider::WaitForFocusedViewIDToChange(
4046 int handle, int previous_view_id, IPC::Message* reply_message) {
4047 NOTIMPLEMENTED();
4048}
4049
4050void AutomationProvider::StartTrackingPopupMenus(
4051 int browser_handle, bool* success) {
4052 NOTIMPLEMENTED();
4053}
4054
4055void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
4056 NOTIMPLEMENTED();
4057}
4058#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:094059
4060void AutomationProvider::ResetToDefaultTheme() {
4061 profile_->ClearTheme();
4062}