blob: 10e676a8f5218c0e762126f7dbc4d292ec94fe46 [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"
[email protected]7c983cc2010-07-16 11:33:3434#include "chrome/browser/automation/automation_provider_json.h"
initial.commit09911bf2008-07-26 23:55:2935#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0836#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]f44265b2009-05-19 18:52:5037#include "chrome/browser/automation/extension_port_container.h"
[email protected]12802702010-07-09 19:43:0938#include "chrome/browser/autocomplete/autocomplete_edit.h"
[email protected]66ba4932009-06-04 19:22:1339#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5340#include "chrome/browser/bookmarks/bookmark_model.h"
41#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1442#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0743#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3944#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2045#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0546#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5847#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2948#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1249#include "chrome/browser/debugger/devtools_manager.h"
[email protected]6c69796d2010-07-16 21:41:1650#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2251#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0552#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4053#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1954#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1455#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4056#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5557#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1958#include "chrome/browser/extensions/extension_tabs_module.h"
59#include "chrome/browser/extensions/extension_toolbar_model.h"
60#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1661#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5862#include "chrome/browser/find_bar.h"
63#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2964#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0165#include "chrome/browser/host_content_settings_map.h"
[email protected]c5aa5322010-07-15 19:00:0766#include "chrome/browser/importer/importer.h"
67#include "chrome/browser/importer/importer_data_types.h"
[email protected]0ac83682010-01-22 17:46:2768#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0669#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0170#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5371#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2472#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0873#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0574#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1775#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0776#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2577#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0378#include "chrome/browser/ssl/ssl_manager.h"
79#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]b5558cf22010-07-12 17:30:0680#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]57c6a652009-05-04 07:58:3481#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4582#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1783#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0584#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2985#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1986#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1787#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5588#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1489#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5790#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2591#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5692#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5793#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1794#include "net/proxy/proxy_service.h"
95#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2196#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3097#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2898#include "views/event.h"
[email protected]5bcfe1672010-07-16 20:51:5799#include "webkit/glue/password_form.h"
[email protected]f7d48012010-05-06 08:17:05100#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:29101
[email protected]de246f52009-02-25 18:25:45102#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:35103#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:45104#endif // defined(OS_WIN)
105
[email protected]e1acf6f2008-10-27 20:43:33106using base::Time;
107
[email protected]cbab76d2008-10-13 22:42:47108class AutomationInterstitialPage : public InterstitialPage {
109 public:
[email protected]57c6a652009-05-04 07:58:34110 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47111 const GURL& url,
112 const std::string& contents)
113 : InterstitialPage(tab, true, url),
114 contents_(contents) {
115 }
116
117 virtual std::string GetHTMLContents() { return contents_; }
118
119 private:
120 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29121
[email protected]cbab76d2008-10-13 22:42:47122 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
123};
124
[email protected]c2cb8542009-08-20 21:16:51125class ClickTask : public Task {
126 public:
[email protected]fc2e0872009-08-21 22:14:41127 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51128 virtual ~ClickTask() {}
129
130 virtual void Run() {
131 ui_controls::MouseButton button = ui_controls::LEFT;
132 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
133 views::Event::EF_LEFT_BUTTON_DOWN) {
134 button = ui_controls::LEFT;
135 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
136 views::Event::EF_RIGHT_BUTTON_DOWN) {
137 button = ui_controls::RIGHT;
138 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
139 views::Event::EF_MIDDLE_BUTTON_DOWN) {
140 button = ui_controls::MIDDLE;
141 } else {
142 NOTREACHED();
143 }
144
[email protected]fc2e0872009-08-21 22:14:41145 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51146 }
147
148 private:
[email protected]c2cb8542009-08-20 21:16:51149 int flags_;
150
151 DISALLOW_COPY_AND_ASSIGN(ClickTask);
152};
[email protected]c2cb8542009-08-20 21:16:51153
initial.commit09911bf2008-07-26 23:55:29154AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57155 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56156 profile_(profile),
[email protected]cc824372010-03-31 15:33:01157 reply_message_(NULL),
158 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29159 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19160 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29161 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20162 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29163 autocomplete_edit_tracker_.reset(
164 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29165 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
166 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44167 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19168 extension_test_result_observer_.reset(
169 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13170 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29171}
172
173AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50174 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
175 port_containers_.end());
176 port_containers_.clear();
177
[email protected]0da050b92008-08-19 19:29:47178 // Make sure that any outstanding NotificationObservers also get destroyed.
179 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31180 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47181 while ((observer = it.GetNext()) != NULL)
182 delete observer;
[email protected]528211a2010-01-14 15:25:13183
184 if (channel_.get()) {
185 channel_->Close();
186 }
187 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29188}
189
[email protected]9a3a293b2009-06-04 22:28:16190void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06191 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57192 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06193 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
194 automation_resource_message_filter_,
195 g_browser_process->io_thread()->message_loop(),
196 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43197 scoped_ptr<FileVersionInfo> version_info(
198 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40199 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43200 if (version_info != NULL) {
201 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40202 }
[email protected]c6cb1992009-04-13 16:45:29203
204 // Send a hello message with our current automation protocol version.
205 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29206}
207
208void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
209 if (expected_tabs == 0) {
210 Send(new AutomationMsg_InitialLoadsComplete(0));
211 } else {
212 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
213 }
214}
215
216NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58217 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01218 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29219 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58220 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01221 number_of_navigations,
222 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29223
[email protected]71f65dd2009-02-11 19:14:56224 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29225 return observer;
226}
227
[email protected]faf2ee42010-05-11 14:26:17228void AutomationProvider::RemoveNavigationStatusListener(
229 NotificationObserver* obs) {
230 notification_observer_list_.RemoveObserver(obs);
231}
232
initial.commit09911bf2008-07-26 23:55:29233NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14234 Browser* parent,
235 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56236 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14237 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29238 notification_observer_list_.AddObserver(observer);
239
240 return observer;
241}
242
[email protected]faf2ee42010-05-11 14:26:17243void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29244 notification_observer_list_.RemoveObserver(obs);
245}
246
247void AutomationProvider::AddLoginHandler(NavigationController* tab,
248 LoginHandler* handler) {
249 login_handler_map_[tab] = handler;
250}
251
252void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
253 DCHECK(login_handler_map_[tab]);
254 login_handler_map_.erase(tab);
255}
256
[email protected]f44265b2009-05-19 18:52:50257void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
258 int port_id = port->port_id();
259 DCHECK_NE(-1, port_id);
260 DCHECK(port_containers_.find(port_id) == port_containers_.end());
261
262 port_containers_[port_id] = port;
263}
264
265void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
266 int port_id = port->port_id();
267 DCHECK_NE(-1, port_id);
268
269 PortContainerMap::iterator it = port_containers_.find(port_id);
270 DCHECK(it != port_containers_.end());
271
272 if (it != port_containers_.end()) {
273 delete it->second;
274 port_containers_.erase(it);
275 }
276}
277
278ExtensionPortContainer* AutomationProvider::GetPortContainer(
279 int port_id) const {
280 PortContainerMap::const_iterator it = port_containers_.find(port_id);
281 if (it == port_containers_.end())
282 return NULL;
283
284 return it->second;
285}
286
initial.commit09911bf2008-07-26 23:55:29287int AutomationProvider::GetIndexForNavigationController(
288 const NavigationController* controller, const Browser* parent) const {
289 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12290 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29291}
292
[email protected]790788ac2010-04-06 17:52:19293int AutomationProvider::AddExtension(Extension* extension) {
294 DCHECK(extension);
295 return extension_tracker_->Add(extension);
296}
297
298Extension* AutomationProvider::GetExtension(int extension_handle) {
299 return extension_tracker_->GetResource(extension_handle);
300}
301
302Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
303 Extension* extension = extension_tracker_->GetResource(extension_handle);
304 ExtensionsService* service = profile_->GetExtensionsService();
305 if (extension && service &&
306 service->GetExtensionById(extension->id(), false))
307 return extension;
308 return NULL;
309}
310
311Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
312 Extension* extension = extension_tracker_->GetResource(extension_handle);
313 ExtensionsService* service = profile_->GetExtensionsService();
314 if (extension && service &&
315 service->GetExtensionById(extension->id(), true) &&
316 !service->GetExtensionById(extension->id(), false))
317 return extension;
318 return NULL;
319}
320
initial.commit09911bf2008-07-26 23:55:29321void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
322 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14323 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56324 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
325 CloseBrowserAsync)
326 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
327 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
328 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
329 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
330 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
331 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22332 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]a503c97c2010-07-16 13:05:48333 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog,
334 ShowCollectedCookiesDialog)
[email protected]1c58a5c2009-05-21 18:47:14335 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58336 IPC_MESSAGE_HANDLER_DELAY_REPLY(
337 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
338 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56339 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11340 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
341 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56342 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
343 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
344 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
345 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14346 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56347 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
348 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
349 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14350 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29351 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
352 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56353 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36354 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56355 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29356 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56357 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29358 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
359 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56360 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14361 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24362 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44363 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33364 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44365 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33366 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24367 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14368 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24369 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15370 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14371 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24372 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35373 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14374 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30375#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56376 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
377 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30378#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56379 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53380 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56381 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37382#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56383 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45384#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56385 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
386 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03387 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56388 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14389 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09390 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
391 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
392 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29393 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14394 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56395 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
396 ExecuteJavascript)
397 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29398 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14399 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
400 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56401 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
402 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14403 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17404 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14405 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14406 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53407 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
408 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14409 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56410 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14411 GetAutocompleteEditForBrowser)
412 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56413 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14414 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56415 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14416 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56417 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
418 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14419 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
420 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44421 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
422 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56423 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
424 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29425 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
426 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
427 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56428 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41429 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56430 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
431 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29432 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56433 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29434 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56435 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29436 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56437 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29438 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56439 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45440 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14441 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56442 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57443 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56444 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57445 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56446 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
447 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53448 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
449 GetBookmarksAsJSON)
450 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
451 WaitForBookmarkModelToLoad)
452 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
453 AddBookmarkGroup)
454 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
455 AddBookmarkURL)
456 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
457 ReparentBookmark)
458 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
459 SetBookmarkTitle)
460 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
461 SetBookmarkURL)
462 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
463 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04464 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
465 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18466 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
467 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
468 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56469 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42470 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56471 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
472 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14473 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56474 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44475 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56476 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20477 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14478 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56479 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16480 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56481 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16482 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56483 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16484 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14485 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20486 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
487 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14488 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22489 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13490 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19491 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
492 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
493 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
494 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
495 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
496 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52497 IPC_MESSAGE_HANDLER_DELAY_REPLY(
498 AutomationMsg_WaitForBrowserWindowCountToBecome,
499 WaitForBrowserWindowCountToBecome)
500 IPC_MESSAGE_HANDLER_DELAY_REPLY(
501 AutomationMsg_WaitForAppModalDialogToBeShown,
502 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26503 IPC_MESSAGE_HANDLER_DELAY_REPLY(
504 AutomationMsg_GoBackBlockUntilNavigationsComplete,
505 GoBackBlockUntilNavigationsComplete)
506 IPC_MESSAGE_HANDLER_DELAY_REPLY(
507 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
508 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57509 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40510 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
511 InstallExtension)
512 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
513 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43514 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
515 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19516 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
517 WaitForExtensionTestResult)
518 IPC_MESSAGE_HANDLER_DELAY_REPLY(
519 AutomationMsg_InstallExtensionAndGetHandle,
520 InstallExtensionAndGetHandle)
521 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
522 UninstallExtension)
523 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
524 EnableExtension)
525 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
526 DisableExtension)
527 IPC_MESSAGE_HANDLER_DELAY_REPLY(
528 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
529 ExecuteExtensionActionInActiveTabAsync)
530 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
531 MoveExtensionBrowserAction)
532 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
533 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57534 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
535 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00536 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01537 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20538 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00539 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01540#if defined(TOOLKIT_VIEWS)
541 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
542 WaitForFocusedViewIDToChange)
543 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
544 StartTrackingPopupMenus)
545 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
546 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00547#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52548#if defined(OS_WIN)
549 // These are for use with external tabs.
550 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
551 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
552 ProcessUnhandledAccelerator)
553 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
554 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
555 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
556 OnForwardContextMenuCommandToChrome)
557 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
558 NavigateInExternalTab)
559 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
560 NavigateExternalTabAtIndex)
561 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
562 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
563 SetEnableExtensionAutomation)
564 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
565 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00566 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
[email protected]1f71d5882010-07-15 20:39:07567 IPC_MESSAGE_HANDLER(AutomationMsg_RunUnloadHandlers, OnRunUnloadHandlers)
[email protected]bdd5a9c92010-06-14 18:21:00568#endif // defined(OS_WIN)
569#if defined(OS_CHROMEOS)
570 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
571 LoginWithUserAndPass)
572#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29573 IPC_END_MESSAGE_MAP()
574}
575
[email protected]71f65dd2009-02-11 19:14:56576void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
577 *status = -1;
initial.commit09911bf2008-07-26 23:55:29578 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
579 Browser* browser = browser_tracker_->GetResource(handle);
580 if (at_index >= 0 && at_index < browser->tab_count()) {
581 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56582 *status = 0;
initial.commit09911bf2008-07-26 23:55:29583 }
584 }
initial.commit09911bf2008-07-26 23:55:29585}
586
[email protected]71f65dd2009-02-11 19:14:56587void AutomationProvider::AppendTab(int handle, const GURL& url,
588 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29589 int append_tab_response = -1; // -1 is the error code
590 NotificationObserver* observer = NULL;
591
592 if (browser_tracker_->ContainsHandle(handle)) {
593 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14594 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38595 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39596 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
597 NULL, std::string());
initial.commit09911bf2008-07-26 23:55:29598 if (tab_contents) {
599 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57600 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29601 }
602 }
603
604 if (append_tab_response < 0) {
605 // The append tab failed. Remove the TabStripObserver
606 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17607 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29608 delete observer;
609 }
610
[email protected]71f65dd2009-02-11 19:14:56611 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
612 append_tab_response);
613 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29614 }
615}
616
[email protected]71f65dd2009-02-11 19:14:56617void AutomationProvider::NavigateToURL(int handle, const GURL& url,
618 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58619 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
620}
621
622void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
623 int handle, const GURL& url, int number_of_navigations,
624 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29625 if (tab_tracker_->ContainsHandle(handle)) {
626 NavigationController* tab = tab_tracker_->GetResource(handle);
627
628 // Simulate what a user would do. Activate the tab and then navigate.
629 // We could allow navigating in a background tab in future.
630 Browser* browser = FindAndActivateTab(tab);
631
632 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01633 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
634 false);
[email protected]71f65dd2009-02-11 19:14:56635
initial.commit09911bf2008-07-26 23:55:29636 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50637 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29638 return;
639 }
640 }
[email protected]71f65dd2009-02-11 19:14:56641
642 AutomationMsg_NavigateToURL::WriteReplyParams(
643 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
644 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29645}
[email protected]2949e90d2009-08-21 15:32:52646
[email protected]c70f9b82010-04-21 07:31:11647void AutomationProvider::NavigationAsync(int handle,
648 const GURL& url,
649 bool* status) {
650 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
651}
652
653void AutomationProvider::NavigationAsyncWithDisposition(
654 int handle,
655 const GURL& url,
656 WindowOpenDisposition disposition,
657 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56658 *status = false;
initial.commit09911bf2008-07-26 23:55:29659
660 if (tab_tracker_->ContainsHandle(handle)) {
661 NavigationController* tab = tab_tracker_->GetResource(handle);
662
663 // Simulate what a user would do. Activate the tab and then navigate.
664 // We could allow navigating in a background tab in future.
665 Browser* browser = FindAndActivateTab(tab);
666
667 if (browser) {
668 // Don't add any listener unless a callback mechanism is desired.
669 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11670 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56671 *status = true;
initial.commit09911bf2008-07-26 23:55:29672 }
673 }
initial.commit09911bf2008-07-26 23:55:29674}
675
[email protected]71f65dd2009-02-11 19:14:56676void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29677 if (tab_tracker_->ContainsHandle(handle)) {
678 NavigationController* tab = tab_tracker_->GetResource(handle);
679 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14680 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01681 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29682 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29683 return;
684 }
685 }
[email protected]71f65dd2009-02-11 19:14:56686
687 AutomationMsg_GoBack::WriteReplyParams(
688 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
689 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29690}
691
[email protected]71f65dd2009-02-11 19:14:56692void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29693 if (tab_tracker_->ContainsHandle(handle)) {
694 NavigationController* tab = tab_tracker_->GetResource(handle);
695 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14696 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01697 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29698 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29699 return;
700 }
701 }
[email protected]71f65dd2009-02-11 19:14:56702
703 AutomationMsg_GoForward::WriteReplyParams(
704 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
705 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29706}
707
[email protected]71f65dd2009-02-11 19:14:56708void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29709 if (tab_tracker_->ContainsHandle(handle)) {
710 NavigationController* tab = tab_tracker_->GetResource(handle);
711 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14712 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01713 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28714 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29715 return;
716 }
717 }
[email protected]71f65dd2009-02-11 19:14:56718
719 AutomationMsg_Reload::WriteReplyParams(
720 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
721 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29722}
723
[email protected]71f65dd2009-02-11 19:14:56724void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29725 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56726 const std::wstring& password,
727 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29728 if (tab_tracker_->ContainsHandle(tab_handle)) {
729 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
730 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
731
732 if (iter != login_handler_map_.end()) {
733 // If auth is needed again after this, assume login has failed. This is
734 // not strictly correct, because a navigation can require both proxy and
735 // server auth, but it should be OK for now.
736 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01737 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29738 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52739 return;
initial.commit09911bf2008-07-26 23:55:29740 }
741 }
[email protected]de246f52009-02-25 18:25:45742
[email protected]457f5cf2009-08-18 16:37:52743 AutomationMsg_SetAuth::WriteReplyParams(
744 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
745 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29746}
747
[email protected]71f65dd2009-02-11 19:14:56748void AutomationProvider::CancelAuth(int tab_handle,
749 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29750 if (tab_tracker_->ContainsHandle(tab_handle)) {
751 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
752 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
753
754 if (iter != login_handler_map_.end()) {
755 // If auth is needed again after this, something is screwy.
756 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01757 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29758 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52759 return;
initial.commit09911bf2008-07-26 23:55:29760 }
761 }
[email protected]de246f52009-02-25 18:25:45762
[email protected]457f5cf2009-08-18 16:37:52763 AutomationMsg_CancelAuth::WriteReplyParams(
764 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
765 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29766}
767
[email protected]71f65dd2009-02-11 19:14:56768void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
769 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29770
771 if (tab_tracker_->ContainsHandle(tab_handle)) {
772 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
773 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
774
775 if (iter != login_handler_map_.end()) {
776 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56777 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29778 }
779 }
initial.commit09911bf2008-07-26 23:55:29780}
781
[email protected]71f65dd2009-02-11 19:14:56782void AutomationProvider::GetRedirectsFrom(int tab_handle,
783 const GURL& source_url,
784 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29785 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
786 if (tab_tracker_->ContainsHandle(tab_handle)) {
787 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
788 HistoryService* history_service =
789 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
790
791 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
792 "has no history service";
793 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56794 DCHECK(reply_message_ == NULL);
795 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29796 // Schedule a history query for redirects. The response will be sent
797 // asynchronously from the callback the history system uses to notify us
798 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29799 redirect_query_ = history_service->QueryRedirectsFrom(
800 source_url, &consumer_,
801 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
802 return; // Response will be sent when query completes.
803 }
804 }
805
806 // Send failure response.
[email protected]deb57402009-02-06 01:35:30807 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56808 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
809 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29810}
811
[email protected]71f65dd2009-02-11 19:14:56812void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
813 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29814 if (browser_tracker_->ContainsHandle(handle)) {
815 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56816 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29817 }
initial.commit09911bf2008-07-26 23:55:29818}
819
[email protected]202e7a72009-06-15 03:48:36820void AutomationProvider::GetBrowserLocale(string16* locale) {
821 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06822 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36823}
824
[email protected]71f65dd2009-02-11 19:14:56825void AutomationProvider::GetBrowserWindowCount(int* window_count) {
826 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29827}
828
[email protected]24497032009-05-01 17:00:29829void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
830 *window_count = static_cast<int>(
831 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
832}
833
[email protected]71f65dd2009-02-11 19:14:56834void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
835 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07836 AppModalDialog* dialog_delegate =
837 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50838 *showing_dialog = (dialog_delegate != NULL);
839 if (*showing_dialog)
840 *dialog_button = dialog_delegate->GetDialogButtons();
841 else
[email protected]478ff2ed2009-04-21 23:49:18842 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20843}
844
[email protected]71f65dd2009-02-11 19:14:56845void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
846 *success = false;
[email protected]fad84eab2008-12-05 00:37:20847
[email protected]1f460072009-05-28 17:02:07848 AppModalDialog* dialog_delegate =
849 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50850 if (dialog_delegate &&
851 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18852 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
853 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28854 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56855 *success = true;
[email protected]fad84eab2008-12-05 00:37:20856 }
[email protected]478ff2ed2009-04-21 23:49:18857 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
858 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56859 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28860 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56861 *success = true;
[email protected]fad84eab2008-12-05 00:37:20862 }
863 }
[email protected]c274acc2008-11-11 20:13:44864}
865
[email protected]fedaa7d2010-01-26 20:34:57866void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
867 if (browser_tracker_->ContainsHandle(handle)) {
868 Browser* browser = browser_tracker_->GetResource(handle);
869 browser->profile()->ShutdownSessionService();
870 *result = true;
871 } else {
872 *result = false;
873 }
874}
875
[email protected]71f65dd2009-02-11 19:14:56876void AutomationProvider::GetBrowserWindow(int index, int* handle) {
877 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29878 if (index >= 0) {
879 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30880 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29881 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56882 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29883 }
884 }
initial.commit09911bf2008-07-26 23:55:29885}
886
[email protected]24497032009-05-01 17:00:29887void AutomationProvider::FindNormalBrowserWindow(int* handle) {
888 *handle = 0;
889 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31890 Browser::TYPE_NORMAL,
891 false);
[email protected]24497032009-05-01 17:00:29892 if (browser)
893 *handle = browser_tracker_->Add(browser);
894}
895
[email protected]71f65dd2009-02-11 19:14:56896void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
897 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29898 Browser* browser = BrowserList::GetLastActive();
899 if (browser)
[email protected]71f65dd2009-02-11 19:14:56900 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29901}
902
[email protected]b2aa3ed72010-02-01 18:37:14903#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28904// TODO(estade): use this implementation for all platforms?
905void AutomationProvider::GetActiveWindow(int* handle) {
906 gfx::NativeWindow window =
907 BrowserList::GetLastActive()->window()->GetNativeHandle();
908 *handle = window_tracker_->Add(window);
909}
910#endif
911
[email protected]4f6381ee2009-04-16 02:46:33912void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
913 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56914 *success = false;
[email protected]4ae62752008-08-04 23:28:47915 if (browser_tracker_->ContainsHandle(handle)) {
916 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14917 if (browser->command_updater()->SupportsCommand(command) &&
918 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47919 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56920 *success = true;
[email protected]4ae62752008-08-04 23:28:47921 }
922 }
[email protected]4ae62752008-08-04 23:28:47923}
924
[email protected]4f6381ee2009-04-16 02:46:33925void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56926 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53927 // List of commands which just finish synchronously and don't require
928 // setting up an observer.
929 static const int kSynchronousCommands[] = {
930 IDC_HOME,
931 IDC_SELECT_NEXT_TAB,
932 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25933 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53934 };
[email protected]56e71b7c2009-03-27 03:05:56935 if (browser_tracker_->ContainsHandle(handle)) {
936 Browser* browser = browser_tracker_->GetResource(handle);
937 if (browser->command_updater()->SupportsCommand(command) &&
938 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53939 // First check if we can handle the command without using an observer.
940 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
941 if (command == kSynchronousCommands[i]) {
942 browser->ExecuteCommand(command);
943 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
944 true);
945 Send(reply_message);
946 return;
947 }
948 }
949
950 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42951 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
952 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27953 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42954 return;
955 }
[email protected]56e71b7c2009-03-27 03:05:56956 }
957 }
[email protected]49a14a82009-03-31 04:16:44958 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56959 Send(reply_message);
960}
961
[email protected]fc2e0872009-08-21 22:14:41962// This task just adds another task to the event queue. This is useful if
963// you want to ensure that any tasks added to the event queue after this one
964// have already been processed by the time |task| is run.
965class InvokeTaskLaterTask : public Task {
966 public:
967 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
968 virtual ~InvokeTaskLaterTask() {}
969
970 virtual void Run() {
971 MessageLoop::current()->PostTask(FROM_HERE, task_);
972 }
973
974 private:
975 Task* task_;
976
977 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
978};
979
initial.commit09911bf2008-07-26 23:55:29980void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
981 int handle,
[email protected]d1a5941e2009-08-13 23:34:24982 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29983 int flags) {
[email protected]b410bc32009-08-14 01:11:14984 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51985 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41986 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29987 }
988}
989
[email protected]60507b12009-11-02 23:51:35990void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
991 int handle,
992 const gfx::Point& location) {
993 if (window_tracker_->ContainsHandle(handle))
994 ui_controls::SendMouseMove(location.x(), location.y());
995}
996
initial.commit09911bf2008-07-26 23:55:29997void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
998 int handle,
[email protected]bc1407f2009-09-29 00:33:35999 int key,
initial.commit09911bf2008-07-26 23:55:291000 int flags) {
[email protected]b410bc32009-08-14 01:11:141001 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291002 return;
1003
[email protected]b410bc32009-08-14 01:11:141004 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291005 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351006 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381007 ((flags & views::Event::EF_CONTROL_DOWN) ==
1008 views::Event::EF_CONTROL_DOWN),
1009 ((flags & views::Event::EF_SHIFT_DOWN) ==
1010 views::Event::EF_SHIFT_DOWN),
1011 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301012 views::Event::EF_ALT_DOWN),
1013 ((flags & views::Event::EF_COMMAND_DOWN) ==
1014 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291015}
initial.commit09911bf2008-07-26 23:55:291016
[email protected]71f65dd2009-02-11 19:14:561017void AutomationProvider::IsWindowActive(int handle, bool* success,
1018 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291019 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171020 *is_active =
1021 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561022 *success = true;
initial.commit09911bf2008-07-26 23:55:291023 } else {
[email protected]71f65dd2009-02-11 19:14:561024 *success = false;
1025 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291026 }
1027}
1028
[email protected]71f65dd2009-02-11 19:14:561029void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1030 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291031
1032 if (browser_tracker_->ContainsHandle(handle)) {
1033 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561034 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291035 }
initial.commit09911bf2008-07-26 23:55:291036}
1037
[email protected]982921f12009-10-27 21:43:531038void AutomationProvider::GetType(int handle, int* type_as_int) {
1039 *type_as_int = -1; // -1 is the error code
1040
1041 if (browser_tracker_->ContainsHandle(handle)) {
1042 Browser* browser = browser_tracker_->GetResource(handle);
1043 *type_as_int = static_cast<int>(browser->type());
1044 }
1045}
1046
[email protected]71f65dd2009-02-11 19:14:561047void AutomationProvider::GetTab(int win_handle, int tab_index,
1048 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561049 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291050 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1051 Browser* browser = browser_tracker_->GetResource(win_handle);
1052 if (tab_index < browser->tab_count()) {
1053 TabContents* tab_contents =
1054 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571055 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291056 }
1057 }
initial.commit09911bf2008-07-26 23:55:291058}
1059
[email protected]71f65dd2009-02-11 19:14:561060void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1061 std::wstring* title) {
1062 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291063 if (tab_tracker_->ContainsHandle(handle)) {
1064 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361065 NavigationEntry* entry = tab->GetActiveEntry();
1066 if (entry != NULL) {
1067 *title = UTF16ToWideHack(entry->title());
1068 } else {
1069 *title = std::wstring();
1070 }
[email protected]71f65dd2009-02-11 19:14:561071 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291072 }
initial.commit09911bf2008-07-26 23:55:291073}
1074
[email protected]77bc6732009-04-20 22:01:031075void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1076 *tabstrip_index = -1; // -1 is the error code
1077
1078 if (tab_tracker_->ContainsHandle(handle)) {
1079 NavigationController* tab = tab_tracker_->GetResource(handle);
1080 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121081 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031082 }
1083}
1084
initial.commit09911bf2008-07-26 23:55:291085void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1086 if (window_tracker_->ContainsHandle(handle)) {
1087 window_tracker_->Remove(window_tracker_->GetResource(handle));
1088 }
1089}
1090
1091void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161092 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571093 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291094}
1095
1096// TODO(brettw) change this to accept GURLs when history supports it
1097void AutomationProvider::OnRedirectQueryComplete(
1098 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371099 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291100 bool success,
[email protected]379c2b12009-07-01 21:50:331101 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291102 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561103 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291104
[email protected]deb57402009-02-06 01:35:301105 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101106 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291107 if (success) {
initial.commit09911bf2008-07-26 23:55:291108 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301109 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291110 }
1111
[email protected]4f3dc372009-02-24 00:10:291112 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301113
[email protected]71f65dd2009-02-11 19:14:561114 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231115 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561116 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291117}
1118
1119bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571120 DCHECK(channel_.get());
1121 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291122}
1123
1124Browser* AutomationProvider::FindAndActivateTab(
1125 NavigationController* controller) {
1126 int tab_index;
1127 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1128 if (browser)
1129 browser->SelectTabContentsAt(tab_index, true);
1130
1131 return browser;
1132}
1133
[email protected]9eaa18e2010-06-29 20:51:011134namespace {
1135
1136class GetCookiesTask : public Task {
1137 public:
1138 GetCookiesTask(const GURL& url,
1139 URLRequestContextGetter* context_getter,
1140 base::WaitableEvent* event,
1141 std::string* cookies)
1142 : url_(url),
1143 context_getter_(context_getter),
1144 event_(event),
1145 cookies_(cookies) {}
1146
1147 virtual void Run() {
1148 *cookies_ = context_getter_->GetCookieStore()->GetCookies(url_);
1149 event_->Signal();
1150 }
1151
1152 private:
1153 const GURL& url_;
1154 URLRequestContextGetter* const context_getter_;
1155 base::WaitableEvent* const event_;
1156 std::string* const cookies_;
1157
1158 DISALLOW_COPY_AND_ASSIGN(GetCookiesTask);
1159};
1160
1161std::string GetCookiesForURL(
1162 const GURL& url,
1163 URLRequestContextGetter* context_getter) {
1164 std::string cookies;
1165 base::WaitableEvent event(true /* manual reset */,
1166 false /* not initially signaled */);
1167 CHECK(ChromeThread::PostTask(
1168 ChromeThread::IO, FROM_HERE,
1169 new GetCookiesTask(url, context_getter, &event, &cookies)));
1170 event.Wait();
1171 return cookies;
1172}
1173
1174class SetCookieTask : public Task {
1175 public:
1176 SetCookieTask(const GURL& url,
1177 const std::string& value,
1178 URLRequestContextGetter* context_getter,
1179 base::WaitableEvent* event,
1180 bool* rv)
1181 : url_(url),
1182 value_(value),
1183 context_getter_(context_getter),
1184 event_(event),
1185 rv_(rv) {}
1186
1187 virtual void Run() {
1188 *rv_ = context_getter_->GetCookieStore()->SetCookie(url_, value_);
1189 event_->Signal();
1190 }
1191
1192 private:
1193 const GURL& url_;
1194 const std::string& value_;
1195 URLRequestContextGetter* const context_getter_;
1196 base::WaitableEvent* const event_;
1197 bool* const rv_;
1198
1199 DISALLOW_COPY_AND_ASSIGN(SetCookieTask);
1200};
1201
1202bool SetCookieForURL(
1203 const GURL& url,
1204 const std::string& value,
1205 URLRequestContextGetter* context_getter) {
1206 base::WaitableEvent event(true /* manual reset */,
1207 false /* not initially signaled */);
1208 bool rv = false;
1209 CHECK(ChromeThread::PostTask(
1210 ChromeThread::IO, FROM_HERE,
1211 new SetCookieTask(url, value, context_getter, &event, &rv)));
1212 event.Wait();
1213 return rv;
1214}
1215
1216class DeleteCookieTask : public Task {
1217 public:
1218 DeleteCookieTask(const GURL& url,
1219 const std::string& name,
1220 const scoped_refptr<URLRequestContextGetter>& context_getter)
1221 : url_(url),
1222 name_(name),
1223 context_getter_(context_getter) {}
1224
1225 virtual void Run() {
1226 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
1227 cookie_store->DeleteCookie(url_, name_);
1228 }
1229
1230 private:
1231 const GURL url_;
1232 const std::string name_;
1233 const scoped_refptr<URLRequestContextGetter> context_getter_;
1234
1235 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
1236};
1237
1238} // namespace
1239
[email protected]71f65dd2009-02-11 19:14:561240void AutomationProvider::GetCookies(const GURL& url, int handle,
1241 int* value_size,
1242 std::string* value) {
1243 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291244 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1245 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311246
1247 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001248 scoped_refptr<URLRequestContextGetter> request_context =
1249 tab->tab_contents()->request_context();
1250 if (!request_context.get())
1251 request_context = tab->profile()->GetRequestContext();
1252
[email protected]9eaa18e2010-06-29 20:51:011253 *value = GetCookiesForURL(url, request_context.get());
[email protected]71f65dd2009-02-11 19:14:561254 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291255 }
initial.commit09911bf2008-07-26 23:55:291256}
1257
[email protected]71f65dd2009-02-11 19:14:561258void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291259 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561260 int handle,
1261 int* response_value) {
1262 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291263
1264 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1265 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311266
[email protected]dfa46e5f2009-11-17 18:48:431267 scoped_refptr<URLRequestContextGetter> request_context =
1268 tab->tab_contents()->request_context();
1269 if (!request_context.get())
1270 request_context = tab->profile()->GetRequestContext();
1271
[email protected]9eaa18e2010-06-29 20:51:011272 if (SetCookieForURL(url, value, request_context.get()))
[email protected]71f65dd2009-02-11 19:14:561273 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291274 }
initial.commit09911bf2008-07-26 23:55:291275}
1276
[email protected]5fa57942010-04-21 23:07:221277void AutomationProvider::DeleteCookie(const GURL& url,
1278 const std::string& cookie_name,
1279 int handle, bool* success) {
1280 *success = false;
1281 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1282 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]9eaa18e2010-06-29 20:51:011283 ChromeThread::PostTask(
1284 ChromeThread::IO, FROM_HERE,
1285 new DeleteCookieTask(url, cookie_name,
1286 tab->profile()->GetRequestContext()));
[email protected]5fa57942010-04-21 23:07:221287 *success = true;
1288 }
1289}
1290
[email protected]a503c97c2010-07-16 13:05:481291void AutomationProvider::ShowCollectedCookiesDialog(
1292 int handle, bool* success) {
1293 *success = false;
1294 if (tab_tracker_->ContainsHandle(handle)) {
1295 TabContents* tab_contents =
1296 tab_tracker_->GetResource(handle)->tab_contents();
1297 tab_contents->delegate()->ShowCollectedCookiesDialog(tab_contents);
1298 *success = true;
1299 }
1300}
1301
[email protected]71f65dd2009-02-11 19:14:561302void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1303 *success = false;
initial.commit09911bf2008-07-26 23:55:291304 if (tab_tracker_->ContainsHandle(handle)) {
1305 NavigationController* tab = tab_tracker_->GetResource(handle);
1306 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541307 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561308 *success = true;
initial.commit09911bf2008-07-26 23:55:291309 }
initial.commit09911bf2008-07-26 23:55:291310}
1311
[email protected]71f65dd2009-02-11 19:14:561312void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1313 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291314
1315 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561316 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341317 TabContents* tab_contents =
1318 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161319 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1320 if (rph)
1321 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291322 }
initial.commit09911bf2008-07-26 23:55:291323}
1324
1325void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331326 NOTREACHED() << "This function has been deprecated. "
1327 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291328}
1329
[email protected]71f65dd2009-02-11 19:14:561330void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291331 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561332 const std::wstring& script,
1333 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291334 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341335 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1336 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571337 // Set the routing id of this message with the controller.
1338 // This routing id needs to be remembered for the reverse
1339 // communication while sending back the response of
1340 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331341 std::wstring set_automation_id;
1342 SStringPrintf(&set_automation_id,
1343 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561344 reply_message->routing_id());
1345
1346 DCHECK(reply_message_ == NULL);
1347 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291348
[email protected]57c6a652009-05-04 07:58:341349 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331350 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341351 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061352 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571353 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291354 }
1355
1356 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561357 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1358 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291359 }
1360}
1361
[email protected]71f65dd2009-02-11 19:14:561362void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1363 *visible = false;
[email protected]20e93d12008-08-28 16:31:571364
[email protected]59560e0b2009-06-04 03:30:221365 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251366#if defined(OS_CHROMEOS)
1367 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1368 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1369 for (BrowserList::const_iterator it = BrowserList::begin();
1370 it != BrowserList::end(); ++it) {
1371 if ((*it)->type() == Browser::TYPE_POPUP) {
1372 const GURL& url =
1373 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1374
1375 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1376 url.host() == chrome::kChromeUIFileBrowseHost) {
1377 *visible = true;
1378 break;
1379 }
1380 }
1381 }
1382#else
[email protected]59560e0b2009-06-04 03:30:221383 Browser* browser = browser_tracker_->GetResource(handle);
1384 if (browser) {
1385 *visible = browser->window()->IsDownloadShelfVisible();
1386 }
[email protected]f5bf8ccf2010-02-05 18:19:251387#endif
[email protected]59560e0b2009-06-04 03:30:221388 }
initial.commit09911bf2008-07-26 23:55:291389}
1390
[email protected]59560e0b2009-06-04 03:30:221391void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1392 if (browser_tracker_->ContainsHandle(handle)) {
1393 Browser* browser = browser_tracker_->GetResource(handle);
1394 if (browser) {
1395 if (visible)
1396 browser->window()->GetDownloadShelf()->Show();
1397 else
1398 browser->window()->GetDownloadShelf()->Close();
1399 }
1400 }
1401}
1402
[email protected]34930432009-11-09 00:12:091403void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1404 *visible = false;
1405
1406 if (browser_tracker_->ContainsHandle(handle)) {
1407 Browser* browser = browser_tracker_->GetResource(handle);
1408 if (browser)
1409 *visible = browser->window()->IsFullscreen();
1410 }
1411}
1412
1413void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1414 bool* visible) {
1415 *visible = false;
1416
1417 if (browser_tracker_->ContainsHandle(handle)) {
1418 Browser* browser = browser_tracker_->GetResource(handle);
1419 if (browser)
1420 *visible = browser->window()->IsFullscreenBubbleVisible();
1421 }
1422}
[email protected]59560e0b2009-06-04 03:30:221423
[email protected]71f65dd2009-02-11 19:14:561424void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1425 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291426 if (tab_tracker_->ContainsHandle(handle)) {
1427 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111428 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291429 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561430 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291431 }
1432 }
initial.commit09911bf2008-07-26 23:55:291433}
1434
initial.commit09911bf2008-07-26 23:55:291435void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561436 int handle, const std::wstring& find_request,
1437 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311438 NOTREACHED() << "This function has been deprecated."
1439 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561440 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311441 return;
1442}
1443
[email protected]4f999132009-03-31 18:08:401444void AutomationProvider::HandleFindRequest(
1445 int handle,
1446 const AutomationMsg_Find_Params& params,
1447 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291448 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561449 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1450 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291451 return;
1452 }
1453
1454 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111455 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291456
1457 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141458 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291459
[email protected]57c6a652009-05-04 07:58:341460 tab_contents->set_current_find_request_id(
1461 FindInPageNotificationObserver::kFindInPageRequestId);
1462 tab_contents->render_view_host()->StartFinding(
1463 FindInPageNotificationObserver::kFindInPageRequestId,
1464 params.search_string, params.forward, params.match_case,
1465 params.find_next);
initial.commit09911bf2008-07-26 23:55:291466}
1467
[email protected]5f8af2a2008-08-06 22:49:451468void AutomationProvider::HandleOpenFindInPageRequest(
1469 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291470 if (browser_tracker_->ContainsHandle(handle)) {
1471 Browser* browser = browser_tracker_->GetResource(handle);
1472 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451473 }
1474}
1475
[email protected]71f65dd2009-02-11 19:14:561476void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561477 *visible = false;
[email protected]855c0142009-09-28 22:35:241478 Browser* browser = browser_tracker_->GetResource(handle);
1479 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581480 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171481 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241482 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291483 }
[email protected]20e93d12008-08-28 16:31:571484}
1485
[email protected]71f65dd2009-02-11 19:14:561486void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1487 int* y) {
[email protected]9e0534b2008-10-21 15:03:011488 gfx::Point position(0, 0);
1489 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291490 if (browser_tracker_->ContainsHandle(handle)) {
1491 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581492 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171493 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581494 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291495 }
[email protected]20e93d12008-08-28 16:31:571496
[email protected]71f65dd2009-02-11 19:14:561497 *x = position.x();
1498 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571499}
1500
[email protected]4512cb52010-04-05 19:50:251501// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1502// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581503void AutomationProvider::GetBookmarkBarVisibility(int handle,
1504 bool* visible,
1505 bool* animating) {
1506 *visible = false;
1507 *animating = false;
1508
1509 if (browser_tracker_->ContainsHandle(handle)) {
1510 Browser* browser = browser_tracker_->GetResource(handle);
1511 if (browser) {
[email protected]472f099b2010-05-27 17:07:121512#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1513 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1514
[email protected]ab6ca392010-04-07 00:44:131515 // IsBookmarkBarVisible() line looks correct but is not
1516 // consistent across platforms. Specifically, on Mac/Linux, it
1517 // returns false if the bar is hidden in a pref (even if visible
1518 // on the NTP). On ChromeOS, it returned true if on NTP
1519 // independent of the pref. Making the code more consistent
1520 // caused a perf bot regression on Windows (which shares views).
1521 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251522 *visible = browser->profile()->GetPrefs()->GetBoolean(
1523 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401524#else
1525 *visible = browser->window()->IsBookmarkBarVisible();
1526#endif
[email protected]c3240722010-03-05 21:52:581527 *animating = browser->window()->IsBookmarkBarAnimating();
1528 }
1529 }
1530}
1531
[email protected]6d8ffc9f2010-03-12 18:27:531532void AutomationProvider::GetBookmarksAsJSON(int handle,
1533 std::string* bookmarks_as_json,
1534 bool *success) {
1535 *success = false;
1536 if (browser_tracker_->ContainsHandle(handle)) {
1537 Browser* browser = browser_tracker_->GetResource(handle);
1538 if (browser) {
1539 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1540 return;
1541 }
1542 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1543 browser->profile(),
1544 browser->profile()->GetBookmarkModel());
1545 *success = storage->SerializeData(bookmarks_as_json);
1546 }
1547 }
1548}
1549
1550void AutomationProvider::WaitForBookmarkModelToLoad(
1551 int handle,
1552 IPC::Message* reply_message) {
1553 if (browser_tracker_->ContainsHandle(handle)) {
1554 Browser* browser = browser_tracker_->GetResource(handle);
1555 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1556 if (model->IsLoaded()) {
1557 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1558 reply_message, true);
1559 Send(reply_message);
1560 } else {
1561 // The observer will delete itself when done.
1562 new AutomationProviderBookmarkModelObserver(this, reply_message,
1563 model);
1564 }
1565 }
1566}
1567
1568void AutomationProvider::AddBookmarkGroup(int handle,
1569 int64 parent_id, int index,
1570 std::wstring title,
1571 bool* success) {
1572 if (browser_tracker_->ContainsHandle(handle)) {
1573 Browser* browser = browser_tracker_->GetResource(handle);
1574 if (browser) {
1575 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1576 if (!model->IsLoaded()) {
1577 *success = false;
1578 return;
1579 }
1580 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1581 DCHECK(parent);
1582 if (parent) {
1583 const BookmarkNode* child = model->AddGroup(parent, index,
1584 WideToUTF16(title));
1585 DCHECK(child);
1586 if (child)
1587 *success = true;
1588 }
1589 }
1590 }
1591 *success = false;
1592}
1593
1594void AutomationProvider::AddBookmarkURL(int handle,
1595 int64 parent_id, int index,
1596 std::wstring title, const GURL& url,
1597 bool* success) {
1598 if (browser_tracker_->ContainsHandle(handle)) {
1599 Browser* browser = browser_tracker_->GetResource(handle);
1600 if (browser) {
1601 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1602 if (!model->IsLoaded()) {
1603 *success = false;
1604 return;
1605 }
1606 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1607 DCHECK(parent);
1608 if (parent) {
1609 const BookmarkNode* child = model->AddURL(parent, index,
1610 WideToUTF16(title), url);
1611 DCHECK(child);
1612 if (child)
1613 *success = true;
1614 }
1615 }
1616 }
1617 *success = false;
1618}
1619
1620void AutomationProvider::ReparentBookmark(int handle,
1621 int64 id, int64 new_parent_id,
1622 int index,
1623 bool* success) {
1624 if (browser_tracker_->ContainsHandle(handle)) {
1625 Browser* browser = browser_tracker_->GetResource(handle);
1626 if (browser) {
1627 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1628 if (!model->IsLoaded()) {
1629 *success = false;
1630 return;
1631 }
1632 const BookmarkNode* node = model->GetNodeByID(id);
1633 DCHECK(node);
1634 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1635 DCHECK(new_parent);
1636 if (node && new_parent) {
1637 model->Move(node, new_parent, index);
1638 *success = true;
1639 }
1640 }
1641 }
1642 *success = false;
1643}
1644
1645void AutomationProvider::SetBookmarkTitle(int handle,
1646 int64 id, std::wstring title,
1647 bool* success) {
1648 if (browser_tracker_->ContainsHandle(handle)) {
1649 Browser* browser = browser_tracker_->GetResource(handle);
1650 if (browser) {
1651 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1652 if (!model->IsLoaded()) {
1653 *success = false;
1654 return;
1655 }
1656 const BookmarkNode* node = model->GetNodeByID(id);
1657 DCHECK(node);
1658 if (node) {
1659 model->SetTitle(node, WideToUTF16(title));
1660 *success = true;
1661 }
1662 }
1663 }
1664 *success = false;
1665}
1666
1667void AutomationProvider::SetBookmarkURL(int handle,
1668 int64 id, const GURL& url,
1669 bool* success) {
1670 if (browser_tracker_->ContainsHandle(handle)) {
1671 Browser* browser = browser_tracker_->GetResource(handle);
1672 if (browser) {
1673 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1674 if (!model->IsLoaded()) {
1675 *success = false;
1676 return;
1677 }
1678 const BookmarkNode* node = model->GetNodeByID(id);
1679 DCHECK(node);
1680 if (node) {
1681 model->SetURL(node, url);
1682 *success = true;
1683 }
1684 }
1685 }
1686 *success = false;
1687}
1688
1689void AutomationProvider::RemoveBookmark(int handle,
1690 int64 id,
1691 bool* success) {
1692 if (browser_tracker_->ContainsHandle(handle)) {
1693 Browser* browser = browser_tracker_->GetResource(handle);
1694 if (browser) {
1695 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1696 if (!model->IsLoaded()) {
1697 *success = false;
1698 return;
1699 }
1700 const BookmarkNode* node = model->GetNodeByID(id);
1701 DCHECK(node);
1702 if (node) {
1703 const BookmarkNode* parent = node->GetParent();
1704 DCHECK(parent);
1705 model->Remove(parent, parent->IndexOfChild(node));
1706 *success = true;
1707 }
1708 }
1709 }
1710 *success = false;
1711}
1712
[email protected]ef413ca2010-05-25 21:09:141713// Sample json input: { "command": "SetWindowDimensions",
1714// "x": 20, # optional
1715// "y": 20, # optional
1716// "width": 800, # optional
1717// "height": 600 } # optional
1718void AutomationProvider::SetWindowDimensions(Browser* browser,
1719 DictionaryValue* args,
1720 IPC::Message* reply_message) {
1721 gfx::Rect rect = browser->window()->GetRestoredBounds();
1722 int x, y, width, height;
1723 if (args->GetInteger(L"x", &x))
1724 rect.set_x(x);
1725 if (args->GetInteger(L"y", &y))
1726 rect.set_y(y);
1727 if (args->GetInteger(L"width", &width))
1728 rect.set_width(width);
1729 if (args->GetInteger(L"height", &height))
1730 rect.set_height(height);
1731 browser->window()->SetBounds(rect);
[email protected]7c983cc2010-07-16 11:33:341732 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
[email protected]ef413ca2010-05-25 21:09:141733}
1734
[email protected]26adfd312010-07-20 01:04:461735namespace {
1736
1737// Task to get info about BrowserChildProcessHost. Must run on IO thread to
1738// honor the semantics of BrowserChildProcessHost.
1739// Used by AutomationProvider::GetBrowserInfo().
1740class GetChildProcessHostInfoTask : public Task {
1741 public:
1742 GetChildProcessHostInfoTask(base::WaitableEvent* event,
1743 ListValue* child_processes)
1744 : event_(event),
1745 child_processes_(child_processes) {}
1746
1747 virtual void Run() {
1748 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
1749 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1750 // Only add processes which are already started,
1751 // since we need their handle.
1752 if ((*iter)->handle() == base::kNullProcessHandle) {
1753 continue;
1754 }
1755 ChildProcessInfo* info = *iter;
1756 DictionaryValue* item = new DictionaryValue;
1757 item->SetString(L"name", info->name());
1758 item->SetString(L"type",
1759 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
1760 item->SetInteger(L"pid", base::GetProcId(info->handle()));
1761 child_processes_->Append(item);
1762 }
1763 event_->Signal();
1764 }
1765
1766 private:
1767 base::WaitableEvent* const event_; // weak
1768 ListValue* child_processes_;
1769
1770 DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask);
1771};
1772
1773} // namespace
1774
[email protected]a9ff2c02010-05-13 17:33:051775// Sample json input: { "command": "GetBrowserInfo" }
1776// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1777// sample json output.
[email protected]53329582010-05-14 21:10:581778void AutomationProvider::GetBrowserInfo(Browser* browser,
1779 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051780 IPC::Message* reply_message) {
[email protected]a9ff2c02010-05-13 17:33:051781 DictionaryValue* properties = new DictionaryValue;
1782 properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
1783 properties->SetString(L"BrowserProcessExecutableName",
1784 chrome::kBrowserProcessExecutableName);
1785 properties->SetString(L"HelperProcessExecutableName",
1786 chrome::kHelperProcessExecutableName);
1787 properties->SetString(L"BrowserProcessExecutablePath",
1788 chrome::kBrowserProcessExecutablePath);
1789 properties->SetString(L"HelperProcessExecutablePath",
1790 chrome::kHelperProcessExecutablePath);
[email protected]a9ff2c02010-05-13 17:33:051791 properties->SetString(L"command_line_string",
1792 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001793
1794 std::string branding;
1795#if defined(GOOGLE_CHROME_BUILD)
1796 branding = "Google Chrome";
1797#elif defined(CHROMIUM_BUILD)
1798 branding = "Chromium";
1799#else
1800 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051801#endif
[email protected]44eed9f2010-06-28 22:04:001802 properties->SetString(L"branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051803
1804 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1805 return_value->Set(L"properties", properties);
1806
[email protected]ef413ca2010-05-25 21:09:141807 return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
1808 // Add info about all windows in a list of dictionaries, one dictionary
1809 // item per window.
1810 ListValue* windows = new ListValue;
1811 int windex = 0;
1812 for (BrowserList::const_iterator it = BrowserList::begin();
1813 it != BrowserList::end();
1814 ++it, ++windex) {
1815 DictionaryValue* browser_item = new DictionaryValue;
1816 browser = *it;
1817 browser_item->SetInteger(L"index", windex);
1818 // Window properties
1819 gfx::Rect rect = browser->window()->GetRestoredBounds();
1820 browser_item->SetInteger(L"x", rect.x());
1821 browser_item->SetInteger(L"y", rect.y());
1822 browser_item->SetInteger(L"width", rect.width());
1823 browser_item->SetInteger(L"height", rect.height());
1824 browser_item->SetBoolean(L"fullscreen",
1825 browser->window()->IsFullscreen());
1826 browser_item->SetInteger(L"selected_tab", browser->selected_index());
1827 browser_item->SetBoolean(L"incognito",
1828 browser->profile()->IsOffTheRecord());
1829 // For each window, add info about all tabs in a list of dictionaries,
1830 // one dictionary item per tab.
1831 ListValue* tabs = new ListValue;
1832 for (int i = 0; i < browser->tab_count(); ++i) {
1833 TabContents* tc = browser->GetTabContentsAt(i);
1834 DictionaryValue* tab = new DictionaryValue;
1835 tab->SetInteger(L"index", i);
1836 tab->SetString(L"url", tc->GetURL().spec());
1837 tab->SetInteger(L"renderer_pid",
1838 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
1839 tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
1840 tabs->Append(tab);
1841 }
1842 browser_item->Set(L"tabs", tabs);
1843
1844 windows->Append(browser_item);
1845 }
1846 return_value->Set(L"windows", windows);
1847
1848 return_value->SetString(L"child_process_path",
1849 ChildProcessHost::GetChildPath(true).value());
1850 // Child processes are the processes for plugins and other workers.
1851 // Add all child processes in a list of dictionaries, one dictionary item
1852 // per child process.
1853 ListValue* child_processes = new ListValue;
[email protected]26adfd312010-07-20 01:04:461854 base::WaitableEvent event(true /* manual reset */,
1855 false /* not initially signaled */);
1856 CHECK(ChromeThread::PostTask(
1857 ChromeThread::IO, FROM_HERE,
1858 new GetChildProcessHostInfoTask(&event, child_processes)));
1859 event.Wait();
[email protected]ef413ca2010-05-25 21:09:141860 return_value->Set(L"child_processes", child_processes);
1861
1862 // Add all extension processes in a list of dictionaries, one dictionary
1863 // item per extension process.
1864 ListValue* extension_processes = new ListValue;
1865 ProfileManager* profile_manager = g_browser_process->profile_manager();
1866 for (ProfileManager::const_iterator it = profile_manager->begin();
1867 it != profile_manager->end(); ++it) {
1868 ExtensionProcessManager* process_manager =
1869 (*it)->GetExtensionProcessManager();
1870 ExtensionProcessManager::const_iterator jt;
1871 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1872 ExtensionHost* ex_host = *jt;
1873 // Don't add dead extension processes.
1874 if (!ex_host->IsRenderViewLive())
1875 continue;
1876 DictionaryValue* item = new DictionaryValue;
1877 item->SetString(L"name", ex_host->extension()->name());
1878 item->SetInteger(
1879 L"pid",
1880 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1881 extension_processes->Append(item);
1882 }
1883 }
1884 return_value->Set(L"extension_processes", extension_processes);
[email protected]7c983cc2010-07-16 11:33:341885 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]a9ff2c02010-05-13 17:33:051886}
1887
[email protected]24e2b102010-04-29 17:56:471888// Sample json input: { "command": "GetHistoryInfo",
1889// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361890// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581891void AutomationProvider::GetHistoryInfo(Browser* browser,
1892 DictionaryValue* args,
1893 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361894 consumer_.CancelAllRequests();
1895
[email protected]e53668962010-06-23 15:35:251896 string16 search_text;
1897 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:361898
1899 // Fetch history.
1900 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1901 history::QueryOptions options;
1902 // The observer owns itself. It deletes itself after it fetches history.
1903 AutomationProviderHistoryObserver* history_observer =
1904 new AutomationProviderHistoryObserver(this, reply_message);
1905 hs->QueryHistory(
1906 search_text,
1907 options,
1908 &consumer_,
1909 NewCallback(history_observer,
1910 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1911}
1912
[email protected]bbe6aa02010-05-07 17:27:291913// Sample json input: { "command": "AddHistoryItem",
1914// "item": { "URL": "http://www.google.com",
1915// "title": "Google", # optional
1916// "time": 12345 # optional (time_t)
1917// } }
1918// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581919void AutomationProvider::AddHistoryItem(Browser* browser,
1920 DictionaryValue* args,
1921 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:291922 DictionaryValue* item = NULL;
1923 args->GetDictionary(L"item", &item);
1924 string16 url_text;
[email protected]e53668962010-06-23 15:35:251925 string16 title;
[email protected]bbe6aa02010-05-07 17:27:291926 base::Time time = base::Time::Now();
[email protected]7c983cc2010-07-16 11:33:341927 AutomationJSONReply reply(this, reply_message);
[email protected]bbe6aa02010-05-07 17:27:291928
[email protected]7c983cc2010-07-16 11:33:341929 if (!item->GetString("url", &url_text)) {
1930 reply.SendError("bad args (no URL in dict?)");
1931 return;
[email protected]bbe6aa02010-05-07 17:27:291932 }
[email protected]7c983cc2010-07-16 11:33:341933 GURL gurl(url_text);
1934 item->GetString("title", &title); // Don't care if it fails.
1935 int it;
1936 double dt;
1937 if (item->GetInteger(L"time", &it))
1938 time = base::Time::FromTimeT(it);
1939 else if (item->GetReal(L"time", &dt))
1940 time = base::Time::FromDoubleT(dt);
[email protected]f6ff0df2010-07-11 22:41:431941
[email protected]7c983cc2010-07-16 11:33:341942 // Ideas for "dummy" values (e.g. id_scope) came from
1943 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1944 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1945 const void* id_scope = reinterpret_cast<void*>(1);
1946 hs->AddPage(gurl, time,
1947 id_scope,
1948 0,
1949 GURL(),
1950 PageTransition::LINK,
1951 history::RedirectList(),
1952 false);
1953 if (title.length())
1954 hs->SetPageTitle(gurl, title);
1955 reply.SendSuccess(NULL);
[email protected]bbe6aa02010-05-07 17:27:291956}
1957
[email protected]24e2b102010-04-29 17:56:471958// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361959// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581960void AutomationProvider::GetDownloadsInfo(Browser* browser,
1961 DictionaryValue* args,
1962 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:391963 AutomationProviderDownloadManagerObserver observer;
1964 std::vector<DownloadItem*> downloads;
1965 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]7c983cc2010-07-16 11:33:341966 AutomationJSONReply reply(this, reply_message);
[email protected]d4adc292010-04-15 18:06:391967
1968 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:341969 reply.SendError("no download manager");
1970 return;
[email protected]d4adc292010-04-15 18:06:391971 }
[email protected]7c983cc2010-07-16 11:33:341972 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1973 // since that would be transient; a download might enter and empty out
1974 // the current download queue too soon to be noticed.
1975 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1976 downloads = observer.Downloads();
[email protected]d4adc292010-04-15 18:06:391977
1978 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1979 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1980 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1981 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1982 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1983
1984 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1985 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1986 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1987 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1988 std::string("DANGEROUS_BUT_VALIDATED");
1989
1990 ListValue* list_of_downloads = new ListValue;
1991 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1992 it != downloads.end();
1993 it++) { // Fill info about each download item.
1994 DictionaryValue* dl_item_value = new DictionaryValue;
1995 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1996 dl_item_value->SetString(L"url", (*it)->url().spec());
1997 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1998 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1999 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
2000 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
2001 dl_item_value->SetBoolean(L"open_when_complete",
2002 (*it)->open_when_complete());
2003 dl_item_value->SetBoolean(L"is_extension_install",
2004 (*it)->is_extension_install());
2005 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
2006 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
2007 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
2008 dl_item_value->SetString(L"safety_state",
2009 safety_state_to_string[(*it)->safety_state()]);
2010 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
2011 list_of_downloads->Append(dl_item_value);
2012 }
2013 return_value->Set(L"downloads", list_of_downloads);
[email protected]d4adc292010-04-15 18:06:392014
[email protected]7c983cc2010-07-16 11:33:342015 reply.SendSuccess(return_value.get());
[email protected]d4adc292010-04-15 18:06:392016 // All value objects allocated above are owned by |return_value|
2017 // and get freed by it.
2018}
2019
[email protected]59a611242010-04-02 02:24:042020void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:582021 Browser* browser,
[email protected]59a611242010-04-02 02:24:042022 DictionaryValue* args,
2023 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042024 AutomationProviderDownloadManagerObserver observer;
2025 std::vector<DownloadItem*> downloads;
[email protected]7c983cc2010-07-16 11:33:342026 AutomationJSONReply reply(this, reply_message);
[email protected]59a611242010-04-02 02:24:042027
2028 // Look for a quick return.
2029 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:342030 reply.SendSuccess(NULL); // No download manager.
2031 return;
[email protected]59a611242010-04-02 02:24:042032 }
[email protected]7c983cc2010-07-16 11:33:342033 profile_->GetDownloadManager()->GetCurrentDownloads(&observer, FilePath());
2034 downloads = observer.Downloads();
2035 if (downloads.size() == 0) {
2036 reply.SendSuccess(NULL);
[email protected]f6ff0df2010-07-11 22:41:432037 return;
2038 }
[email protected]59a611242010-04-02 02:24:042039
2040 // The observer owns itself. When the last observed item pings, it
2041 // deletes itself.
2042 AutomationProviderDownloadItemObserver* item_observer =
2043 new AutomationProviderDownloadItemObserver(
2044 this, reply_message, downloads.size());
2045 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2046 i != downloads.end();
2047 i++) {
2048 (*i)->AddObserver(item_observer);
2049 }
2050}
2051
[email protected]24e2b102010-04-29 17:56:472052// Sample json input: { "command": "GetPrefsInfo" }
2053// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582054void AutomationProvider::GetPrefsInfo(Browser* browser,
2055 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472056 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:472057 const PrefService::PreferenceSet& prefs =
2058 profile_->GetPrefs()->preference_set();
2059 DictionaryValue* items = new DictionaryValue;
2060 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
2061 it != prefs.end(); ++it) {
2062 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
2063 }
2064 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2065 return_value->Set(L"prefs", items); // return_value owns items.
[email protected]7c983cc2010-07-16 11:33:342066 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]24e2b102010-04-29 17:56:472067}
2068
2069// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:582070void AutomationProvider::SetPrefs(Browser* browser,
2071 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472072 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:472073 std::wstring path;
2074 Value* val;
[email protected]7c983cc2010-07-16 11:33:342075 AutomationJSONReply reply(this, reply_message);
[email protected]24e2b102010-04-29 17:56:472076 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
2077 PrefService* pref_service = profile_->GetPrefs();
2078 const PrefService::Preference* pref =
2079 pref_service->FindPreference(path.c_str());
2080 if (!pref) { // Not a registered pref.
[email protected]7c983cc2010-07-16 11:33:342081 reply.SendError("pref not registered.");
2082 return;
[email protected]24e2b102010-04-29 17:56:472083 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7c983cc2010-07-16 11:33:342084 reply.SendError("pref is managed. cannot be changed.");
2085 return;
[email protected]24e2b102010-04-29 17:56:472086 } else { // Set the pref.
2087 pref_service->Set(path.c_str(), *val);
2088 }
2089 } else {
[email protected]7c983cc2010-07-16 11:33:342090 reply.SendError("no pref path or value given.");
2091 return;
[email protected]24e2b102010-04-29 17:56:472092 }
2093
[email protected]7c983cc2010-07-16 11:33:342094 reply.SendSuccess(NULL);
[email protected]24e2b102010-04-29 17:56:472095}
2096
[email protected]53329582010-05-14 21:10:582097// Sample json input: { "command": "GetOmniboxInfo" }
2098// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
2099void AutomationProvider::GetOmniboxInfo(Browser* browser,
2100 DictionaryValue* args,
2101 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582102 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2103
2104 LocationBar* loc_bar = browser->window()->GetLocationBar();
2105 AutocompleteEditView* edit_view = loc_bar->location_entry();
2106 AutocompleteEditModel* model = edit_view->model();
2107
2108 // Fill up matches.
2109 ListValue* matches = new ListValue;
2110 const AutocompleteResult& result = model->result();
2111 for (AutocompleteResult::const_iterator i = result.begin();
2112 i != result.end(); ++i) {
2113 const AutocompleteMatch& match = *i;
2114 DictionaryValue* item = new DictionaryValue; // owned by return_value
2115 item->SetString(L"type", AutocompleteMatch::TypeToString(match.type));
2116 item->SetBoolean(L"starred", match.starred);
2117 item->SetString(L"destination_url", match.destination_url.spec());
2118 item->SetString(L"contents", match.contents);
2119 item->SetString(L"description", match.description);
2120 matches->Append(item);
2121 }
2122 return_value->Set(L"matches", matches);
2123
2124 // Fill up other properties.
2125 DictionaryValue* properties = new DictionaryValue; // owned by return_value
2126 properties->SetBoolean(L"has_focus", model->has_focus());
2127 properties->SetBoolean(L"query_in_progress", model->query_in_progress());
2128 properties->SetString(L"keyword", model->keyword());
2129 properties->SetString(L"text", edit_view->GetText());
2130 return_value->Set(L"properties", properties);
2131
[email protected]7c983cc2010-07-16 11:33:342132 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]53329582010-05-14 21:10:582133}
2134
2135// Sample json input: { "command": "SetOmniboxText",
2136// "text": "goog" }
2137void AutomationProvider::SetOmniboxText(Browser* browser,
2138 DictionaryValue* args,
2139 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582140 std::wstring text;
[email protected]7c983cc2010-07-16 11:33:342141 AutomationJSONReply reply(this, reply_message);
[email protected]53329582010-05-14 21:10:582142 if (!args->GetString(L"text", &text)) {
[email protected]7c983cc2010-07-16 11:33:342143 reply.SendError("text missing");
2144 return;
[email protected]53329582010-05-14 21:10:582145 }
[email protected]7c983cc2010-07-16 11:33:342146 browser->FocusLocationBar();
2147 LocationBar* loc_bar = browser->window()->GetLocationBar();
2148 AutocompleteEditView* edit_view = loc_bar->location_entry();
2149 edit_view->model()->OnSetFocus(false);
2150 edit_view->SetUserText(text);
2151 reply.SendSuccess(NULL);
[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]53329582010-05-14 21:10:582162 int count;
[email protected]7c983cc2010-07-16 11:33:342163 AutomationJSONReply reply(this, reply_message);
[email protected]53329582010-05-14 21:10:582164 if (!args->GetInteger(L"count", &count)) {
[email protected]7c983cc2010-07-16 11:33:342165 reply.SendError("count missing");
2166 return;
[email protected]53329582010-05-14 21:10:582167 }
[email protected]7c983cc2010-07-16 11:33:342168 LocationBar* loc_bar = browser->window()->GetLocationBar();
2169 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2170 model->OnUpOrDownKeyPressed(count);
2171 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:582172}
2173
2174// Sample json input: { "command": "OmniboxAcceptInput" }
2175void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2176 DictionaryValue* args,
2177 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282178 NavigationController& controller =
2179 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122180 // Setup observer to wait until the selected item loads.
2181 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282182 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122183 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582184
2185 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582186}
2187
[email protected]a3cd5022010-06-16 18:25:292188// Sample json input: { "command": "GetInitialLoadTimes" }
2189// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2190void AutomationProvider::GetInitialLoadTimes(
2191 Browser*,
2192 DictionaryValue*,
2193 IPC::Message* reply_message) {
2194 scoped_ptr<DictionaryValue> return_value(
2195 initial_load_observer_->GetTimingInformation());
[email protected]f6ff0df2010-07-11 22:41:432196
2197 std::string json_return;
2198 base::JSONWriter::Write(return_value.get(), false, &json_return);
2199 AutomationMsg_SendJSONRequest::WriteReplyParams(
2200 reply_message, json_return, true);
2201 Send(reply_message);
[email protected]a3cd5022010-06-16 18:25:292202}
2203
[email protected]f7d48012010-05-06 08:17:052204// Sample json input: { "command": "GetPluginsInfo" }
2205// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582206void AutomationProvider::GetPluginsInfo(Browser* browser,
2207 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052208 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052209 std::vector<WebPluginInfo> plugins;
2210 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2211 ListValue* items = new ListValue;
2212 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2213 it != plugins.end();
2214 ++it) {
2215 DictionaryValue* item = new DictionaryValue;
[email protected]c9d811372010-06-23 21:44:572216 item->SetStringFromUTF16(L"name", it->name);
[email protected]f7d48012010-05-06 08:17:052217 item->SetString(L"path", it->path.value());
[email protected]c9d811372010-06-23 21:44:572218 item->SetStringFromUTF16(L"version", it->version);
2219 item->SetStringFromUTF16(L"desc", it->desc);
[email protected]f7d48012010-05-06 08:17:052220 item->SetBoolean(L"enabled", it->enabled);
2221 // Add info about mime types.
2222 ListValue* mime_types = new ListValue();
2223 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2224 it->mime_types.begin();
2225 type_it != it->mime_types.end();
2226 ++type_it) {
2227 DictionaryValue* mime_type = new DictionaryValue();
2228 mime_type->SetString(L"mimeType", type_it->mime_type);
[email protected]c9d811372010-06-23 21:44:572229 mime_type->SetStringFromUTF16(L"description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052230
2231 ListValue* file_extensions = new ListValue();
2232 for (std::vector<std::string>::const_iterator ext_it =
2233 type_it->file_extensions.begin();
2234 ext_it != type_it->file_extensions.end();
2235 ++ext_it) {
2236 file_extensions->Append(new StringValue(*ext_it));
2237 }
2238 mime_type->Set(L"fileExtensions", file_extensions);
2239
2240 mime_types->Append(mime_type);
2241 }
2242 item->Set(L"mimeTypes", mime_types);
2243 items->Append(item);
2244 }
2245 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2246 return_value->Set(L"plugins", items); // return_value owns items.
2247
[email protected]7c983cc2010-07-16 11:33:342248 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f7d48012010-05-06 08:17:052249}
2250
2251// Sample json input:
2252// { "command": "EnablePlugin",
2253// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582254void AutomationProvider::EnablePlugin(Browser* browser,
2255 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052256 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052257 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342258 AutomationJSONReply reply(this, reply_message);
[email protected]f6ff0df2010-07-11 22:41:432259 if (!args->GetString(L"path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342260 reply.SendError("path not specified.");
2261 return;
[email protected]f6ff0df2010-07-11 22:41:432262 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342263 reply.SendError(StringPrintf("Could not enable plugin for path %s.",
2264 path.c_str()));
2265 return;
[email protected]f6ff0df2010-07-11 22:41:432266 }
[email protected]7c983cc2010-07-16 11:33:342267 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052268}
2269
2270// Sample json input:
2271// { "command": "DisablePlugin",
2272// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582273void AutomationProvider::DisablePlugin(Browser* browser,
2274 DictionaryValue* args,
2275 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052276 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342277 AutomationJSONReply reply(this, reply_message);
[email protected]f6ff0df2010-07-11 22:41:432278 if (!args->GetString(L"path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342279 reply.SendError("path not specified.");
2280 return;
[email protected]f6ff0df2010-07-11 22:41:432281 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342282 reply.SendError(StringPrintf("Could not disable plugin for path %s.",
2283 path.c_str()));
2284 return;
[email protected]f6ff0df2010-07-11 22:41:432285 }
[email protected]7c983cc2010-07-16 11:33:342286 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052287}
2288
[email protected]7060bb292010-06-24 00:52:492289// Sample json input:
2290// { "command": "SaveTabContents",
2291// "tab_index": 0,
2292// "filename": <a full pathname> }
2293// Sample json output:
2294// {}
2295void AutomationProvider::SaveTabContents(Browser* browser,
2296 DictionaryValue* args,
2297 IPC::Message* reply_message) {
[email protected]7060bb292010-06-24 00:52:492298 int tab_index = 0;
2299 FilePath::StringType filename;
2300 FilePath::StringType parent_directory;
2301 TabContents* tab_contents = NULL;
[email protected]7060bb292010-06-24 00:52:492302
2303 if (!args->GetInteger(L"tab_index", &tab_index) ||
2304 !args->GetString(L"filename", &filename)) {
[email protected]26adfd312010-07-20 01:04:462305 AutomationJSONReply(this, reply_message).SendError(
2306 "tab_index or filename param missing");
[email protected]7c983cc2010-07-16 11:33:342307 return;
[email protected]7060bb292010-06-24 00:52:492308 } else {
2309 tab_contents = browser->GetTabContentsAt(tab_index);
2310 if (!tab_contents) {
[email protected]26adfd312010-07-20 01:04:462311 AutomationJSONReply(this, reply_message).SendError(
2312 "no tab at tab_index");
[email protected]7060bb292010-06-24 00:52:492313 return;
2314 }
2315 }
[email protected]7c983cc2010-07-16 11:33:342316 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2317 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2318 parent_directory = FilePath(filename).DirName().value();
2319 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2320 SavePackage::SAVE_AS_ONLY_HTML)) {
[email protected]26adfd312010-07-20 01:04:462321 AutomationJSONReply(this, reply_message).SendError(
2322 "Could not initiate SavePage");
[email protected]7c983cc2010-07-16 11:33:342323 return;
2324 }
2325 // The observer will delete itself when done.
2326 new SavePackageNotificationObserver(tab_contents->save_package(),
2327 this, reply_message);
[email protected]7060bb292010-06-24 00:52:492328}
2329
[email protected]c5aa5322010-07-15 19:00:072330// Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
2331// json input.
2332// Sample json output: "{}"
2333void AutomationProvider::ImportSettings(Browser* browser,
2334 DictionaryValue* args,
2335 IPC::Message* reply_message) {
[email protected]c5aa5322010-07-15 19:00:072336 // Map from the json string passed over to the import item masks.
2337 std::map<std::string, ImportItem> string_to_import_item;
2338 string_to_import_item["HISTORY"] = importer::HISTORY;
2339 string_to_import_item["FAVORITES"] = importer::FAVORITES;
2340 string_to_import_item["COOKIES"] = importer::COOKIES;
2341 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
2342 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
2343 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
2344 string_to_import_item["ALL"] = importer::ALL;
2345
2346 std::wstring browser_name;
2347 int import_items = 0;
2348 ListValue* import_items_list = NULL;
2349 bool first_run;
2350
2351 if (!args->GetString(L"import_from", &browser_name) ||
2352 !args->GetBoolean(L"first_run", &first_run) ||
2353 !args->GetList(L"import_items", &import_items_list)) {
[email protected]7c983cc2010-07-16 11:33:342354 AutomationJSONReply(this, reply_message).SendError(
2355 "Incorrect type for one or more of the arguments.");
[email protected]c5aa5322010-07-15 19:00:072356 return;
2357 }
2358
2359 int num_items = import_items_list->GetSize();
2360 for (int i = 0; i < num_items; i++) {
2361 std::string item;
2362 import_items_list->GetString(i, &item);
2363 // If the provided string is not part of the map, error out.
2364 if (!ContainsKey(string_to_import_item, item)) {
[email protected]7c983cc2010-07-16 11:33:342365 AutomationJSONReply(this, reply_message).SendError(
2366 "Invalid item string found in import_items.");
[email protected]c5aa5322010-07-15 19:00:072367 return;
2368 }
2369 import_items |= string_to_import_item[item];
2370 }
2371
2372 ImporterHost* importer_host = new ImporterHost();
2373 // Get the correct ProfileInfo based on the browser they user provided.
2374 importer::ProfileInfo profile_info;
2375 int num_browsers = importer_host->GetAvailableProfileCount();
2376 int i = 0;
2377 for ( ; i < num_browsers; i++) {
2378 std::wstring name = importer_host->GetSourceProfileNameAt(i);
2379 if (name == browser_name) {
2380 profile_info = importer_host->GetSourceProfileInfoAt(i);
2381 break;
2382 }
2383 }
2384 // If we made it to the end of the loop, then the input was bad.
2385 if (i == num_browsers) {
[email protected]7c983cc2010-07-16 11:33:342386 AutomationJSONReply(this, reply_message).SendError(
2387 "Invalid browser name string found.");
[email protected]c5aa5322010-07-15 19:00:072388 return;
2389 }
2390
2391 Profile* profile = browser->profile();
2392
2393 importer_host->SetObserver(
2394 new AutomationProviderImportSettingsObserver(this, reply_message));
2395 importer_host->StartImportSettings(profile_info, profile, import_items,
2396 new ProfileWriter(profile), first_run);
2397}
2398
[email protected]5bcfe1672010-07-16 20:51:572399// See AddSavedPassword() in chrome/test/functional/pyauto.py for sample json
2400// input.
2401// Sample json output: { "password_added": true }
2402void AutomationProvider::AddSavedPassword(Browser* browser,
2403 DictionaryValue* args,
2404 IPC::Message* reply_message) {
2405 string16 username;
2406 string16 password;
2407 base::Time time = base::Time::Now();
2408 AutomationJSONReply reply(this, reply_message);
2409
2410 if (!args->GetStringAsUTF16(L"password", &password) ||
2411 !args->GetStringAsUTF16(L"username", &username)) {
2412 reply.SendError("Username and password must be strings.");
2413 return;
2414 }
2415
2416 // If the time is specified, change time to the specified time.
2417 int it;
2418 double dt;
2419 if (args->GetInteger(L"time", &it))
2420 time = base::Time::FromTimeT(it);
2421 else if (args->GetReal(L"time", &dt))
2422 time = base::Time::FromDoubleT(dt);
2423
2424 webkit_glue::PasswordForm new_password;
2425 new_password.username_value = username;
2426 new_password.password_value = password;
2427 new_password.date_created = time;
2428
2429 Profile* profile = browser->profile();
2430 // Use IMPLICIT_ACCESS since new passwords aren't added off the record.
2431 PasswordStore* password_store =
2432 profile->GetPasswordStore(Profile::IMPLICIT_ACCESS);
2433
2434 // Set the return based on whether setting the password succeeded.
2435 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2436
2437 // It will be null if it's accessed in an incognito window.
2438 if (password_store != NULL) {
2439 password_store->AddLogin(new_password);
2440 return_value->SetBoolean(L"password_added", true);
2441 } else {
2442 return_value->SetBoolean(L"password_added", false);
2443 }
2444
2445 reply.SendSuccess(return_value.get());
2446}
2447
2448// Sample json input: { "command": "GetSavedPasswords" }
2449// Refer to GetSavedPasswords() in chrome/test/pyautolib/pyauto.py for sample
2450// json output.
2451void AutomationProvider::GetSavedPasswords(Browser* browser,
2452 DictionaryValue* args,
2453 IPC::Message* reply_message) {
2454 Profile* profile = browser->profile();
2455 // Use EXPLICIT_ACCESS since saved passwords can be retreived off the record.
2456 PasswordStore* password_store =
2457 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
2458 password_store->GetAutofillableLogins(
2459 new AutomationProviderGetPasswordsObserver(this, reply_message));
2460 // Observer deletes itself after returning.
2461}
2462
[email protected]a0fc50d72010-07-14 21:14:192463// Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
2464// json input.
2465// Sample json output: {}
2466void AutomationProvider::ClearBrowsingData(Browser* browser,
2467 DictionaryValue* args,
2468 IPC::Message* reply_message) {
[email protected]a0fc50d72010-07-14 21:14:192469 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
2470 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
2471 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
2472 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
2473 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
2474 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
2475
2476 std::map<std::string, int> string_to_mask_value;
2477 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
2478 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
2479 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
2480 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
2481 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
2482 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
2483
2484 std::string time_period;
2485 ListValue* to_remove;
2486 if (!args->GetString(L"time_period", &time_period) ||
2487 !args->GetList(L"to_remove", &to_remove)) {
[email protected]7c983cc2010-07-16 11:33:342488 AutomationJSONReply(this, reply_message).SendError(
2489 "time_period must be a string and to_remove a list.");
[email protected]a0fc50d72010-07-14 21:14:192490 return;
2491 }
2492
2493 int remove_mask = 0;
2494 int num_removals = to_remove->GetSize();
2495 for (int i = 0; i < num_removals; i++) {
2496 std::string removal;
2497 to_remove->GetString(i, &removal);
2498 // If the provided string is not part of the map, then error out.
2499 if (!ContainsKey(string_to_mask_value, removal)) {
[email protected]7c983cc2010-07-16 11:33:342500 AutomationJSONReply(this, reply_message).SendError(
2501 "Invalid browsing data string found in to_remove.");
[email protected]a0fc50d72010-07-14 21:14:192502 return;
2503 }
2504 remove_mask |= string_to_mask_value[removal];
2505 }
2506
2507 if (!ContainsKey(string_to_time_period, time_period)) {
[email protected]7c983cc2010-07-16 11:33:342508 AutomationJSONReply(this, reply_message).SendError(
2509 "Invalid string for time_period.");
[email protected]a0fc50d72010-07-14 21:14:192510 return;
2511 }
2512
2513 BrowsingDataRemover* remover = new BrowsingDataRemover(
2514 profile(), string_to_time_period[time_period], base::Time());
2515
2516 remover->AddObserver(
2517 new AutomationProviderBrowsingDataObserver(this, reply_message));
2518 remover->Remove(remove_mask);
2519 // BrowsingDataRemover deletes itself using DeleteTask.
2520 // The observer also deletes itself after sending the reply.
2521}
2522
[email protected]4d1929f12010-07-10 00:09:032523// Sample json input: { "command": "GetThemeInfo" }
2524// Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
2525void AutomationProvider::GetThemeInfo(Browser* browser,
2526 DictionaryValue* args,
2527 IPC::Message* reply_message) {
2528 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2529 Extension* theme = browser->profile()->GetTheme();
2530 if (theme) {
2531 return_value->SetString(L"name", theme->name());
2532 return_value->Set(L"images", theme->GetThemeImages()->DeepCopy());
2533 return_value->Set(L"colors", theme->GetThemeColors()->DeepCopy());
2534 return_value->Set(L"tints", theme->GetThemeTints()->DeepCopy());
2535 }
[email protected]7c983cc2010-07-16 11:33:342536 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]4d1929f12010-07-10 00:09:032537}
2538
[email protected]55846ad842010-07-09 18:22:562539// Sample json input:
2540// { "command": "GetAutoFillProfile" }
2541// Refer to GetAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2542// json output.
2543void AutomationProvider::GetAutoFillProfile(Browser* browser,
2544 DictionaryValue* args,
2545 IPC::Message* reply_message) {
[email protected]55846ad842010-07-09 18:22:562546 // Get the AutoFillProfiles currently in the database.
2547 int tab_index = 0;
2548 args->GetInteger(L"tab_index", &tab_index);
2549 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
[email protected]7c983cc2010-07-16 11:33:342550 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:562551
2552 if (tab_contents) {
2553 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
2554 ->GetPersonalDataManager();
2555 if (pdm) {
2556 std::vector<AutoFillProfile*> autofill_profiles = pdm->profiles();
2557 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
2558
2559 ListValue* profiles = GetListFromAutoFillProfiles(autofill_profiles);
2560 ListValue* cards = GetListFromCreditCards(credit_cards);
2561
2562 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2563
2564 return_value->Set(L"profiles", profiles);
2565 return_value->Set(L"credit_cards", cards);
[email protected]7c983cc2010-07-16 11:33:342566 reply.SendSuccess(return_value.get());
[email protected]55846ad842010-07-09 18:22:562567 } else {
[email protected]7c983cc2010-07-16 11:33:342568 reply.SendError("No PersonalDataManager.");
2569 return;
[email protected]55846ad842010-07-09 18:22:562570 }
2571 } else {
[email protected]7c983cc2010-07-16 11:33:342572 reply.SendError("No tab at that index.");
2573 return;
[email protected]55846ad842010-07-09 18:22:562574 }
[email protected]55846ad842010-07-09 18:22:562575}
2576
2577// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2578// json input.
2579// Sample json output: {}
2580void AutomationProvider::FillAutoFillProfile(Browser* browser,
2581 DictionaryValue* args,
2582 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:342583 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:562584 ListValue* profiles = NULL;
2585 ListValue* cards = NULL;
2586 args->GetList(L"profiles", &profiles);
2587 args->GetList(L"credit_cards", &cards);
[email protected]7c983cc2010-07-16 11:33:342588 std::string error_mesg;
[email protected]55846ad842010-07-09 18:22:562589
2590 std::vector<AutoFillProfile> autofill_profiles;
2591 std::vector<CreditCard> credit_cards;
2592 // Create an AutoFillProfile for each of the dictionary profiles.
2593 if (profiles) {
[email protected]7c983cc2010-07-16 11:33:342594 autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg);
[email protected]55846ad842010-07-09 18:22:562595 }
2596 // Create a CreditCard for each of the dictionary values.
2597 if (cards) {
[email protected]7c983cc2010-07-16 11:33:342598 credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
2599 }
2600 if (!error_mesg.empty()) {
2601 reply.SendError(error_mesg);
2602 return;
[email protected]55846ad842010-07-09 18:22:562603 }
2604
2605 // Save the AutoFillProfiles.
2606 int tab_index = 0;
2607 args->GetInteger(L"tab_index", &tab_index);
2608 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2609
2610 if (tab_contents) {
[email protected]ce6b0122010-07-19 19:07:302611 PersonalDataManager* pdm = tab_contents->profile()
[email protected]55846ad842010-07-09 18:22:562612 ->GetPersonalDataManager();
2613 if (pdm) {
2614 pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
2615 cards? &credit_cards : NULL);
2616 } else {
[email protected]7c983cc2010-07-16 11:33:342617 reply.SendError("No PersonalDataManager.");
2618 return;
[email protected]55846ad842010-07-09 18:22:562619 }
2620 } else {
[email protected]7c983cc2010-07-16 11:33:342621 reply.SendError("No tab at that index.");
2622 return;
[email protected]55846ad842010-07-09 18:22:562623 }
[email protected]7c983cc2010-07-16 11:33:342624 reply.SendSuccess(NULL);
[email protected]55846ad842010-07-09 18:22:562625}
2626
2627/* static */
2628ListValue* AutomationProvider::GetListFromAutoFillProfiles(
2629 std::vector<AutoFillProfile*> autofill_profiles) {
2630 ListValue* profiles = new ListValue;
2631
2632 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string
2633 = GetAutoFillFieldToStringMap();
2634
2635 // For each AutoFillProfile, transform it to a dictionary object to return.
2636 for (std::vector<AutoFillProfile*>::iterator it = autofill_profiles.begin();
2637 it != autofill_profiles.end(); ++it) {
2638 AutoFillProfile* profile = *it;
2639 DictionaryValue* profile_info = new DictionaryValue;
2640 profile_info->SetStringFromUTF16(L"label", profile->Label());
2641 // For each of the types, if it has a value, add it to the dictionary.
2642 for (std::map<AutoFillFieldType, std::wstring>::iterator
2643 type_it = autofill_type_to_string.begin();
2644 type_it != autofill_type_to_string.end(); ++type_it) {
2645 string16 value = profile->GetFieldText(AutoFillType(type_it->first));
2646 if (value.length()) { // If there was something stored for that value.
2647 profile_info->SetStringFromUTF16(type_it->second, value);
2648 }
2649 }
2650 profiles->Append(profile_info);
2651 }
2652 return profiles;
2653}
2654
2655/* static */
2656ListValue* AutomationProvider::GetListFromCreditCards(
2657 std::vector<CreditCard*> credit_cards) {
2658 ListValue* cards = new ListValue;
2659
2660 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2661 GetCreditCardFieldToStringMap();
2662
2663 // For each AutoFillProfile, transform it to a dictionary object to return.
2664 for (std::vector<CreditCard*>::iterator it = credit_cards.begin();
2665 it != credit_cards.end(); ++it) {
2666 CreditCard* card = *it;
2667 DictionaryValue* card_info = new DictionaryValue;
2668 card_info->SetStringFromUTF16(L"label", card->Label());
2669 // For each of the types, if it has a value, add it to the dictionary.
2670 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2671 credit_card_type_to_string.begin();
2672 type_it != credit_card_type_to_string.end(); ++type_it) {
2673 string16 value = card->GetFieldText(AutoFillType(type_it->first));
2674 // If there was something stored for that value.
2675 if (value.length()) {
2676 card_info->SetStringFromUTF16(type_it->second, value);
2677 }
2678 }
2679 cards->Append(card_info);
2680 }
2681 return cards;
2682}
2683
2684/* static */
2685std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
[email protected]7c983cc2010-07-16 11:33:342686 const ListValue& profiles, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:562687 std::vector<AutoFillProfile> autofill_profiles;
2688 DictionaryValue* profile_info = NULL;
2689 string16 profile_label;
2690 string16 current_value;
2691
2692 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string =
2693 GetAutoFillFieldToStringMap();
2694
2695 int num_profiles = profiles.GetSize();
2696 for (int i = 0; i < num_profiles; i++) {
2697 profiles.GetDictionary(i, &profile_info);
2698 profile_info->GetString("label", &profile_label);
2699 // Choose an id of 0 so that a unique id will be created.
2700 AutoFillProfile profile(profile_label, 0);
2701 // Loop through the possible profile types and add those provided.
2702 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2703 autofill_type_to_string.begin();
2704 type_it != autofill_type_to_string.end(); ++type_it) {
2705 if (profile_info->HasKey(type_it->second)) {
2706 if (profile_info->GetStringAsUTF16(type_it->second, &current_value)) {
2707 profile.SetInfo(AutoFillType(type_it->first), current_value);
2708 } else {
[email protected]7c983cc2010-07-16 11:33:342709 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:562710 break;
2711 }
2712 }
2713 }
2714 autofill_profiles.push_back(profile);
2715 }
2716 return autofill_profiles;
2717}
2718
2719/* static */
2720std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
[email protected]7c983cc2010-07-16 11:33:342721 const ListValue& cards, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:562722 std::vector<CreditCard> credit_cards;
2723 DictionaryValue* card_info = NULL;
2724 string16 card_label;
2725 string16 current_value;
2726
2727 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2728 GetCreditCardFieldToStringMap();
2729
2730 int num_credit_cards = cards.GetSize();
2731 for (int i = 0; i < num_credit_cards; i++) {
2732 cards.GetDictionary(i, &card_info);
2733 card_info->GetString("label", &card_label);
2734 CreditCard card(card_label, 0);
2735 // Loop through the possible credit card fields and add those provided.
2736 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2737 credit_card_type_to_string.begin();
2738 type_it != credit_card_type_to_string.end(); ++type_it) {
2739 if (card_info->HasKey(type_it->second)) {
2740 if (card_info->GetStringAsUTF16(type_it->second, &current_value)) {
2741 card.SetInfo(AutoFillType(type_it->first), current_value);
2742 } else {
[email protected]7c983cc2010-07-16 11:33:342743 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:562744 break;
2745 }
2746 }
2747 }
2748 credit_cards.push_back(card);
2749 }
2750 return credit_cards;
2751}
2752
2753/* static */
2754std::map<AutoFillFieldType, std::wstring>
2755 AutomationProvider::GetAutoFillFieldToStringMap() {
2756 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string;
2757 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2758 autofill_type_to_string[NAME_MIDDLE] = L"NAME_MIDDLE";
2759 autofill_type_to_string[NAME_LAST] = L"NAME_LAST";
2760 autofill_type_to_string[COMPANY_NAME] = L"COMPANY_NAME";
2761 autofill_type_to_string[EMAIL_ADDRESS] = L"EMAIL_ADDRESS";
2762 autofill_type_to_string[ADDRESS_HOME_LINE1] = L"ADDRESS_HOME_LINE1";
2763 autofill_type_to_string[ADDRESS_HOME_LINE2] = L"ADDRESS_HOME_LINE2";
2764 autofill_type_to_string[ADDRESS_HOME_CITY] = L"ADDRESS_HOME_CITY";
2765 autofill_type_to_string[ADDRESS_HOME_STATE] = L"ADDRESS_HOME_STATE";
2766 autofill_type_to_string[ADDRESS_HOME_ZIP] = L"ADDRESS_HOME_ZIP";
2767 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = L"ADDRESS_HOME_COUNTRY";
2768 autofill_type_to_string[PHONE_HOME_NUMBER] = L"PHONE_HOME_NUMBER";
2769 autofill_type_to_string[PHONE_FAX_NUMBER] = L"PHONE_FAX_NUMBER";
2770 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2771 return autofill_type_to_string;
2772}
2773
2774/* static */
2775std::map<AutoFillFieldType, std::wstring>
2776 AutomationProvider::GetCreditCardFieldToStringMap() {
2777 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string;
2778 credit_card_type_to_string[CREDIT_CARD_NAME] = L"CREDIT_CARD_NAME";
2779 credit_card_type_to_string[CREDIT_CARD_NUMBER] = L"CREDIT_CARD_NUMBER";
2780 credit_card_type_to_string[CREDIT_CARD_TYPE] = L"CREDIT_CARD_TYPE";
2781 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = L"CREDIT_CARD_EXP_MONTH";
2782 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
2783 L"CREDIT_CARD_EXP_4_DIGIT_YEAR";
2784 return credit_card_type_to_string;
2785}
2786
[email protected]53329582010-05-14 21:10:582787void AutomationProvider::SendJSONRequest(int handle,
2788 std::string json_request,
2789 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042790 Browser* browser = NULL;
[email protected]59a611242010-04-02 02:24:042791 scoped_ptr<Value> values;
2792
2793 // Basic error checking.
2794 if (browser_tracker_->ContainsHandle(handle)) {
2795 browser = browser_tracker_->GetResource(handle);
2796 }
2797 if (!browser) {
[email protected]7c983cc2010-07-16 11:33:342798 AutomationJSONReply(this, reply_message).SendError("no browser object");
2799 return;
2800 }
2801 base::JSONReader reader;
2802 std::string error;
2803 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
2804 if (!error.empty()) {
2805 AutomationJSONReply(this, reply_message).SendError(error);
2806 return;
[email protected]59a611242010-04-02 02:24:042807 }
2808
2809 // Make sure input is a dict with a string command.
2810 std::string command;
2811 DictionaryValue* dict_value = NULL;
[email protected]7c983cc2010-07-16 11:33:342812 if (values->GetType() != Value::TYPE_DICTIONARY) {
2813 AutomationJSONReply(this, reply_message).SendError("not a dict");
2814 return;
2815 }
2816 // Ownership remains with "values" variable.
2817 dict_value = static_cast<DictionaryValue*>(values.get());
2818 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2819 AutomationJSONReply(this, reply_message).SendError(
2820 "no command key in dict or not a string command");
2821 return;
[email protected]59a611242010-04-02 02:24:042822 }
2823
[email protected]24e2b102010-04-29 17:56:472824 // Map json commands to their handlers.
2825 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052826 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2827 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2828 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2829
[email protected]a9ff2c02010-05-13 17:33:052830 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
[email protected]7c983cc2010-07-16 11:33:342831
[email protected]24e2b102010-04-29 17:56:472832 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292833 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052834
[email protected]53329582010-05-14 21:10:582835 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2836 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2837 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2838 handler_map["OmniboxMovePopupSelection"] =
2839 &AutomationProvider::OmniboxMovePopupSelection;
2840
[email protected]24e2b102010-04-29 17:56:472841 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2842 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052843
[email protected]ef413ca2010-05-25 21:09:142844 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2845
[email protected]f7d48012010-05-06 08:17:052846 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472847 handler_map["WaitForAllDownloadsToComplete"] =
2848 &AutomationProvider::WaitForDownloadsToComplete;
2849
[email protected]a3cd5022010-06-16 18:25:292850 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
2851
[email protected]7060bb292010-06-24 00:52:492852 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
2853
[email protected]c5aa5322010-07-15 19:00:072854 handler_map["ImportSettings"] = &AutomationProvider::ImportSettings;
2855
[email protected]5bcfe1672010-07-16 20:51:572856 handler_map["AddSavedPassword"] = &AutomationProvider::AddSavedPassword;
2857 handler_map["GetSavedPasswords"] = &AutomationProvider::GetSavedPasswords;
2858
[email protected]a0fc50d72010-07-14 21:14:192859 handler_map["ClearBrowsingData"] = &AutomationProvider::ClearBrowsingData;
2860
[email protected]4d1929f12010-07-10 00:09:032861 // SetTheme() implemented using InstallExtension().
2862 handler_map["GetThemeInfo"] = &AutomationProvider::GetThemeInfo;
2863
[email protected]55846ad842010-07-09 18:22:562864 handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
2865 handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
2866
[email protected]7c983cc2010-07-16 11:33:342867 if (handler_map.find(std::string(command)) != handler_map.end()) {
2868 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]1ac875d22010-07-16 09:57:582869 } else {
[email protected]7c983cc2010-07-16 11:33:342870 std::string error_string = "Unknown command. Options: ";
2871 for (std::map<std::string, JsonHandler>::const_iterator it =
2872 handler_map.begin(); it != handler_map.end(); ++it) {
2873 error_string += it->first + ", ";
2874 }
2875 AutomationJSONReply(this, reply_message).SendError(error_string);
[email protected]1ac875d22010-07-16 09:57:582876 }
[email protected]59a611242010-04-02 02:24:042877}
2878
initial.commit09911bf2008-07-26 23:55:292879void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562880 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342881 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2882 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562883 DCHECK(reply_message_ == NULL);
2884 reply_message_ = reply_message;
2885
[email protected]d9f9b792009-06-24 13:17:122886 DevToolsManager::GetInstance()->InspectElement(
2887 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292888 } else {
[email protected]71f65dd2009-02-11 19:14:562889 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2890 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292891 }
2892}
2893
2894void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092895 if (reply_message_) {
2896 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2897 num_resources);
2898 Send(reply_message_);
2899 reply_message_ = NULL;
2900 }
initial.commit09911bf2008-07-26 23:55:292901}
2902
[email protected]a7eee32f2009-05-22 18:08:172903class SetProxyConfigTask : public Task {
2904 public:
[email protected]be180c802009-10-23 06:33:312905 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2906 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252907 : request_context_getter_(request_context_getter),
2908 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172909 virtual void Run() {
2910 // First, deserialize the JSON string. If this fails, log and bail.
2911 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392912 std::string error_msg;
2913 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172914 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2915 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392916 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172917 return;
2918 }
2919
2920 scoped_ptr<DictionaryValue> dict(
2921 static_cast<DictionaryValue*>(root.release()));
2922 // Now put together a proxy configuration from the deserialized string.
2923 net::ProxyConfig pc;
2924 PopulateProxyConfig(*dict.get(), &pc);
2925
[email protected]be180c802009-10-23 06:33:312926 net::ProxyService* proxy_service =
2927 request_context_getter_->GetURLRequestContext()->proxy_service();
2928 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172929 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2930 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312931 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172932 }
2933
2934 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2935 DCHECK(pc);
2936 bool no_proxy = false;
2937 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2938 // Make no changes to the ProxyConfig.
2939 return;
2940 }
2941 bool auto_config;
2942 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482943 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172944 }
2945 std::string pac_url;
2946 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482947 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172948 }
2949 std::string proxy_bypass_list;
2950 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482951 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172952 }
2953 std::string proxy_server;
2954 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482955 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172956 }
2957 }
2958
2959 private:
[email protected]be180c802009-10-23 06:33:312960 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172961 std::string proxy_config_;
2962};
2963
2964
2965void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312966 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2967 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172968 FilePath user_data_dir;
2969 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2970 ProfileManager* profile_manager = g_browser_process->profile_manager();
2971 DCHECK(profile_manager);
2972 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2973 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312974 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172975 }
[email protected]be180c802009-10-23 06:33:312976 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172977
[email protected]fae20792009-10-28 20:31:582978 ChromeThread::PostTask(
2979 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312980 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172981}
2982
[email protected]4f3dc372009-02-24 00:10:292983void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332984 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292985 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292986 if (tab_tracker_->ContainsHandle(handle)) {
2987 NavigationController* tab = tab_tracker_->GetResource(handle);
2988 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2989 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332990 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292991 }
initial.commit09911bf2008-07-26 23:55:292992}
2993
[email protected]6a5670d22009-10-27 16:21:342994void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142995 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532996 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2997 reply_message);
2998}
2999
3000void AutomationProvider::OpenNewBrowserWindowOfType(
3001 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:143002 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:293003 // We may have no current browser windows open so don't rely on
3004 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:533005 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
3006 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:053007 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:153008 if (show)
[email protected]15952e462008-11-14 00:29:053009 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:293010}
3011
[email protected]71f65dd2009-02-11 19:14:563012void AutomationProvider::GetWindowForBrowser(int browser_handle,
3013 bool* success,
3014 int* handle) {
3015 *success = false;
3016 *handle = 0;
initial.commit09911bf2008-07-26 23:55:293017
3018 if (browser_tracker_->ContainsHandle(browser_handle)) {
3019 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:203020 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:293021 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:203022 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:563023 *success = true;
initial.commit09911bf2008-07-26 23:55:293024 }
initial.commit09911bf2008-07-26 23:55:293025}
3026
3027void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:563028 int browser_handle,
3029 bool* success,
3030 int* autocomplete_edit_handle) {
3031 *success = false;
3032 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:293033
3034 if (browser_tracker_->ContainsHandle(browser_handle)) {
3035 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:063036 LocationBar* loc_bar = browser->window()->GetLocationBar();
3037 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:293038 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:563039 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
3040 *success = true;
initial.commit09911bf2008-07-26 23:55:293041 }
initial.commit09911bf2008-07-26 23:55:293042}
initial.commit09911bf2008-07-26 23:55:293043
[email protected]71f65dd2009-02-11 19:14:563044void AutomationProvider::ShowInterstitialPage(int tab_handle,
3045 const std::string& html_text,
3046 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293047 if (tab_tracker_->ContainsHandle(tab_handle)) {
3048 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:113049 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:403050
[email protected]7dad3d5f2010-03-04 00:27:013051 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:403052 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:343053 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:403054 GURL("about:interstitial"),
3055 html_text);
3056 interstitial->Show();
3057 return;
initial.commit09911bf2008-07-26 23:55:293058 }
[email protected]71f65dd2009-02-11 19:14:563059
[email protected]457f5cf2009-08-18 16:37:523060 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
3061 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563062 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293063}
3064
[email protected]71f65dd2009-02-11 19:14:563065void AutomationProvider::HideInterstitialPage(int tab_handle,
3066 bool* success) {
3067 *success = false;
[email protected]57c6a652009-05-04 07:58:343068 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
3069 if (tab_contents && tab_contents->interstitial_page()) {
3070 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:563071 *success = true;
initial.commit09911bf2008-07-26 23:55:293072 }
initial.commit09911bf2008-07-26 23:55:293073}
3074
[email protected]71f65dd2009-02-11 19:14:563075void AutomationProvider::CloseTab(int tab_handle,
3076 bool wait_until_closed,
3077 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293078 if (tab_tracker_->ContainsHandle(tab_handle)) {
3079 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
3080 int index;
3081 Browser* browser = Browser::GetBrowserForController(controller, &index);
3082 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:143083 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:113084 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:453085 return;
initial.commit09911bf2008-07-26 23:55:293086 }
[email protected]de246f52009-02-25 18:25:453087
3088 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:553089 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293090}
3091
[email protected]71f65dd2009-02-11 19:14:563092void AutomationProvider::CloseBrowser(int browser_handle,
3093 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293094 if (browser_tracker_->ContainsHandle(browser_handle)) {
3095 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563096 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:563097 reply_message);
[email protected]f3e99e32008-07-30 04:48:393098 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:293099 } else {
3100 NOTREACHED();
3101 }
3102}
3103
[email protected]71f65dd2009-02-11 19:14:563104void AutomationProvider::CloseBrowserAsync(int browser_handle) {
3105 if (browser_tracker_->ContainsHandle(browser_handle)) {
3106 Browser* browser = browser_tracker_->GetResource(browser_handle);
3107 browser->window()->Close();
3108 } else {
3109 NOTREACHED();
3110 }
3111}
3112
[email protected]71f65dd2009-02-11 19:14:563113void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
3114 IPC::Message* reply_message) {
3115 if (tab_tracker_->ContainsHandle(tab_handle)) {
3116 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3117 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:143118 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:563119 }
3120}
3121
[email protected]71f65dd2009-02-11 19:14:563122void AutomationProvider::GetSecurityState(int handle, bool* success,
3123 SecurityStyle* security_style,
3124 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:483125 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:293126 if (tab_tracker_->ContainsHandle(handle)) {
3127 NavigationController* tab = tab_tracker_->GetResource(handle);
3128 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563129 *success = true;
3130 *security_style = entry->ssl().security_style();
3131 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:483132 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:293133 } else {
[email protected]71f65dd2009-02-11 19:14:563134 *success = false;
3135 *security_style = SECURITY_STYLE_UNKNOWN;
3136 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:483137 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:293138 }
3139}
3140
[email protected]71f65dd2009-02-11 19:14:563141void AutomationProvider::GetPageType(int handle, bool* success,
3142 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:293143 if (tab_tracker_->ContainsHandle(handle)) {
3144 NavigationController* tab = tab_tracker_->GetResource(handle);
3145 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563146 *page_type = entry->page_type();
3147 *success = true;
initial.commit09911bf2008-07-26 23:55:293148 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:343149 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:563150 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:343151 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:563152 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293153 } else {
[email protected]71f65dd2009-02-11 19:14:563154 *success = false;
3155 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293156 }
3157}
3158
[email protected]84abba62009-10-07 17:01:443159void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
3160 int* duration_ms) {
3161 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
3162 event_name);
3163}
3164
[email protected]71f65dd2009-02-11 19:14:563165void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
3166 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293167 if (tab_tracker_->ContainsHandle(handle)) {
3168 NavigationController* tab = tab_tracker_->GetResource(handle);
3169 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:073170 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:403171 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:473172 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:343173 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:293174 if (ssl_blocking_page) {
3175 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:013176 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:563177 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:293178 return;
3179 }
3180 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:523181 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3182 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:563183 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293184 return;
3185 }
3186 }
3187 }
3188 // We failed.
[email protected]457f5cf2009-08-18 16:37:523189 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3190 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563191 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293192}
3193
[email protected]71f65dd2009-02-11 19:14:563194void AutomationProvider::BringBrowserToFront(int browser_handle,
3195 bool* success) {
initial.commit09911bf2008-07-26 23:55:293196 if (browser_tracker_->ContainsHandle(browser_handle)) {
3197 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:063198 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:563199 *success = true;
initial.commit09911bf2008-07-26 23:55:293200 } else {
[email protected]71f65dd2009-02-11 19:14:563201 *success = false;
initial.commit09911bf2008-07-26 23:55:293202 }
3203}
3204
[email protected]71f65dd2009-02-11 19:14:563205void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
3206 int message_num,
3207 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:293208 if (browser_tracker_->ContainsHandle(browser_handle)) {
3209 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563210 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:143211 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:293212 } else {
[email protected]71f65dd2009-02-11 19:14:563213 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:293214 }
3215}
3216
[email protected]71f65dd2009-02-11 19:14:563217void AutomationProvider::PrintNow(int tab_handle,
3218 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:573219 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:343220 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3221 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:293222 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:573223 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:143224 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:343225 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:573226 return;
initial.commit09911bf2008-07-26 23:55:293227 }
[email protected]71f65dd2009-02-11 19:14:563228 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
3229 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293230}
[email protected]d301c952009-07-13 15:02:413231
[email protected]71f65dd2009-02-11 19:14:563232void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:113233 const FilePath& file_name,
3234 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:563235 int type,
3236 bool* success) {
initial.commit09911bf2008-07-26 23:55:293237 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:563238 *success = false;
initial.commit09911bf2008-07-26 23:55:293239 return;
3240 }
3241
3242 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3243 Browser* browser = FindAndActivateTab(nav);
3244 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:143245 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:563246 *success = false;
initial.commit09911bf2008-07-26 23:55:293247 return;
3248 }
3249
initial.commit09911bf2008-07-26 23:55:293250 SavePackage::SavePackageType save_type =
3251 static_cast<SavePackage::SavePackageType>(type);
3252 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
3253 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:343254 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:293255
[email protected]71f65dd2009-02-11 19:14:563256 *success = true;
initial.commit09911bf2008-07-26 23:55:293257}
3258
[email protected]71f65dd2009-02-11 19:14:563259void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
3260 bool* success,
3261 std::wstring* text) {
3262 *success = false;
initial.commit09911bf2008-07-26 23:55:293263 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563264 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:523265 GetText();
[email protected]71f65dd2009-02-11 19:14:563266 *success = true;
initial.commit09911bf2008-07-26 23:55:293267 }
initial.commit09911bf2008-07-26 23:55:293268}
3269
[email protected]71f65dd2009-02-11 19:14:563270void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
3271 const std::wstring& text,
3272 bool* success) {
3273 *success = false;
initial.commit09911bf2008-07-26 23:55:293274 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:523275 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
3276 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:563277 *success = true;
initial.commit09911bf2008-07-26 23:55:293278 }
initial.commit09911bf2008-07-26 23:55:293279}
3280
3281void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:563282 int autocomplete_edit_handle,
3283 bool* success,
3284 std::vector<AutocompleteMatchData>* matches) {
3285 *success = false;
initial.commit09911bf2008-07-26 23:55:293286 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:273287 const AutocompleteResult& result = autocomplete_edit_tracker_->
3288 GetResource(autocomplete_edit_handle)->model()->result();
3289 for (AutocompleteResult::const_iterator i = result.begin();
3290 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:563291 matches->push_back(AutocompleteMatchData(*i));
3292 *success = true;
initial.commit09911bf2008-07-26 23:55:293293 }
initial.commit09911bf2008-07-26 23:55:293294}
3295
3296void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:563297 int autocomplete_edit_handle,
3298 bool* success,
3299 bool* query_in_progress) {
3300 *success = false;
3301 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:293302 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563303 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:523304 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:563305 *success = true;
initial.commit09911bf2008-07-26 23:55:293306 }
initial.commit09911bf2008-07-26 23:55:293307}
3308
[email protected]63514af2010-03-30 17:17:233309#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:193310
[email protected]5ae5bed2009-08-21 18:52:443311#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:393312
[email protected]57c6a652009-05-04 07:58:343313TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:573314 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:573315 if (tab_tracker_->ContainsHandle(handle)) {
3316 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:343317 if (tab)
3318 *tab = nav_controller;
3319 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:573320 }
[email protected]57c6a652009-05-04 07:58:343321 return NULL;
[email protected]20e93d12008-08-28 16:31:573322}
3323
initial.commit09911bf2008-07-26 23:55:293324TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
3325 : AutomationProvider(profile) {
3326 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:143327 registrar_.Add(this, NotificationType::SESSION_END,
3328 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:293329}
3330
3331TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:293332 BrowserList::RemoveObserver(this);
3333}
3334
3335void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:143336 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:293337 AutomationProvider::OnChannelError();
3338}
3339
3340void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
3341 // For backwards compatibility with the testing automation interface, we
3342 // want the automation provider (and hence the process) to go away when the
3343 // last browser goes away.
3344 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:293345 // If you change this, update Observer for NotificationType::SESSION_END
3346 // below.
[email protected]295039bd2008-08-15 04:32:573347 MessageLoop::current()->PostTask(FROM_HERE,
3348 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:293349 }
3350}
3351
3352void TestingAutomationProvider::Observe(NotificationType type,
3353 const NotificationSource& source,
3354 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563355 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:293356 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
3357 // before the task runs resulting in this object not being deleted. This
3358 // Release balance out the Release scheduled by OnBrowserRemoving.
3359 Release();
3360}
[email protected]295039bd2008-08-15 04:32:573361
3362void TestingAutomationProvider::OnRemoveProvider() {
3363 AutomationProviderList::GetInstance()->RemoveProvider(this);
3364}
[email protected]8a3422c92008-09-24 17:42:423365
[email protected]816633a2009-11-11 21:48:183366void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:563367 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:423368 if (tab_tracker_->ContainsHandle(handle)) {
3369 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:343370 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:113371 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423372 }
[email protected]8a3422c92008-09-24 17:42:423373}
3374
[email protected]816633a2009-11-11 21:48:183375void AutomationProvider::ClickInfoBarAccept(int handle,
3376 int info_bar_index,
3377 bool wait_for_navigation,
3378 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:423379 bool success = false;
3380 if (tab_tracker_->ContainsHandle(handle)) {
3381 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3382 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:113383 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423384 if (info_bar_index >= 0 && info_bar_index < count) {
3385 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:013386 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:423387 }
[email protected]eb9ba192008-12-02 02:41:343388 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:113389 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:343390 info_bar_index);
3391 if (delegate->AsConfirmInfoBarDelegate())
3392 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:423393 success = true;
3394 }
3395 }
[email protected]4f3dc372009-02-24 00:10:293396 }
[email protected]58f622a62009-10-04 01:17:553397
3398 // This "!wait_for_navigation || !success condition" logic looks suspicious.
3399 // It will send a failure message when success is true but
3400 // |wait_for_navigation| is false.
3401 // TODO(phajdan.jr): investgate whether the reply param (currently
3402 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:423403 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:183404 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:523405 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:423406}
3407
[email protected]71f65dd2009-02-11 19:14:563408void AutomationProvider::GetLastNavigationTime(int handle,
3409 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:423410 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:563411 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:423412}
3413
[email protected]71f65dd2009-02-11 19:14:563414void AutomationProvider::WaitForNavigation(int handle,
3415 int64 last_navigation_time,
3416 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:253417 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:423418 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:253419
[email protected]8a3422c92008-09-24 17:42:423420 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:563421 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:523422 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3423 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553424 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293425 return;
[email protected]8a3422c92008-09-24 17:42:423426 }
3427
[email protected]7dad3d5f2010-03-04 00:27:013428 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423429}
3430
[email protected]71f65dd2009-02-11 19:14:563431void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163432 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563433 int value,
3434 bool* success) {
3435 *success = false;
[email protected]8a3422c92008-09-24 17:42:423436 if (browser_tracker_->ContainsHandle(handle)) {
3437 Browser* browser = browser_tracker_->GetResource(handle);
3438 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563439 *success = true;
[email protected]8a3422c92008-09-24 17:42:423440 }
[email protected]8a3422c92008-09-24 17:42:423441}
[email protected]97fa6ce32008-12-19 01:48:163442
[email protected]71f65dd2009-02-11 19:14:563443void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163444 const std::wstring& name,
[email protected]ddd231e2010-06-29 20:35:193445 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563446 bool* success) {
3447 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163448 if (browser_tracker_->ContainsHandle(handle)) {
3449 Browser* browser = browser_tracker_->GetResource(handle);
3450 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563451 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163452 }
[email protected]97fa6ce32008-12-19 01:48:163453}
3454
[email protected]71f65dd2009-02-11 19:14:563455void AutomationProvider::GetBooleanPreference(int handle,
3456 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:363457 bool* success,
3458 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563459 *success = false;
3460 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163461 if (browser_tracker_->ContainsHandle(handle)) {
3462 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563463 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3464 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163465 }
[email protected]97fa6ce32008-12-19 01:48:163466}
3467
[email protected]71f65dd2009-02-11 19:14:563468void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163469 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563470 bool value,
3471 bool* success) {
3472 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163473 if (browser_tracker_->ContainsHandle(handle)) {
3474 Browser* browser = browser_tracker_->GetResource(handle);
3475 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563476 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163477 }
[email protected]97fa6ce32008-12-19 01:48:163478}
3479
3480// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563481void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403482 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163483 if (tab_tracker_->ContainsHandle(tab_handle)) {
3484 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3485 Browser* browser = FindAndActivateTab(nav);
3486 DCHECK(browser);
3487
[email protected]57c6a652009-05-04 07:58:343488 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3489 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163490 }
[email protected]97fa6ce32008-12-19 01:48:163491}
3492
[email protected]b8f48d12009-11-09 20:14:363493// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563494void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:403495 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:563496 bool* success) {
3497 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163498 if (tab_tracker_->ContainsHandle(tab_handle)) {
3499 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193500 if (!nav)
3501 return;
[email protected]97fa6ce32008-12-19 01:48:163502 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163503
[email protected]2f2afba2010-04-01 01:53:193504 // If the browser has UI, simulate what a user would do.
3505 // Activate the tab and then click the encoding menu.
3506 if (browser &&
3507 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163508 int selected_encoding_id =
3509 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3510 if (selected_encoding_id) {
3511 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563512 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163513 }
[email protected]2f2afba2010-04-01 01:53:193514 } else {
3515 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3516 // Try to get TabContents and call its override_encoding method.
3517 TabContents* contents = nav->tab_contents();
3518 if (!contents)
3519 return;
3520 const std::string selected_encoding =
3521 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
3522 if (selected_encoding.empty())
3523 return;
3524 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163525 }
3526 }
[email protected]97fa6ce32008-12-19 01:48:163527}
[email protected]5bcdb312009-01-07 21:43:203528
[email protected]4d434a1a2009-02-11 21:06:573529void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203530 SavePackage::SetShouldPromptUser(should_prompt);
3531}
[email protected]87eab222009-03-13 00:47:453532
[email protected]66ba4932009-06-04 19:22:133533void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3534 *count = -1; // -1 is the error code
3535 if (tab_tracker_->ContainsHandle(handle)) {
3536 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3537 TabContents* tab_contents = nav_controller->tab_contents();
3538 if (tab_contents) {
3539 BlockedPopupContainer* container =
3540 tab_contents->blocked_popup_container();
3541 if (container) {
3542 *count = static_cast<int>(container->GetBlockedPopupCount());
3543 } else {
3544 // If we don't have a container, we don't have any blocked popups to
3545 // contain!
3546 *count = 0;
3547 }
3548 }
3549 }
3550}
[email protected]f7a68432009-07-29 23:18:193551
3552void AutomationProvider::SelectAll(int tab_handle) {
3553 RenderViewHost* view = GetViewForTab(tab_handle);
3554 if (!view) {
3555 NOTREACHED();
3556 return;
3557 }
3558
3559 view->SelectAll();
3560}
3561
3562void AutomationProvider::Cut(int tab_handle) {
3563 RenderViewHost* view = GetViewForTab(tab_handle);
3564 if (!view) {
3565 NOTREACHED();
3566 return;
3567 }
3568
3569 view->Cut();
3570}
3571
3572void AutomationProvider::Copy(int tab_handle) {
3573 RenderViewHost* view = GetViewForTab(tab_handle);
3574 if (!view) {
3575 NOTREACHED();
3576 return;
3577 }
3578
3579 view->Copy();
3580}
3581
3582void AutomationProvider::Paste(int tab_handle) {
3583 RenderViewHost* view = GetViewForTab(tab_handle);
3584 if (!view) {
3585 NOTREACHED();
3586 return;
3587 }
3588
3589 view->Paste();
3590}
3591
3592void AutomationProvider::ReloadAsync(int tab_handle) {
3593 if (tab_tracker_->ContainsHandle(tab_handle)) {
3594 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3595 if (!tab) {
3596 NOTREACHED();
3597 return;
3598 }
3599
[email protected]106a0812010-03-18 00:15:123600 const bool check_for_repost = true;
3601 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193602 }
3603}
3604
3605void AutomationProvider::StopAsync(int tab_handle) {
3606 RenderViewHost* view = GetViewForTab(tab_handle);
3607 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363608 // We tolerate StopAsync being called even before a view has been created.
3609 // So just log a warning instead of a NOTREACHED().
3610 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193611 return;
3612 }
3613
3614 view->Stop();
3615}
3616
[email protected]1bb5f892009-10-06 01:44:573617void AutomationProvider::OnSetPageFontSize(int tab_handle,
3618 int font_size) {
3619 AutomationPageFontSize automation_font_size =
3620 static_cast<AutomationPageFontSize>(font_size);
3621
3622 if (automation_font_size < SMALLEST_FONT ||
3623 automation_font_size > LARGEST_FONT) {
3624 DLOG(ERROR) << "Invalid font size specified : "
3625 << font_size;
3626 return;
3627 }
3628
3629 if (tab_tracker_->ContainsHandle(tab_handle)) {
3630 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3631 DCHECK(tab != NULL);
3632 if (tab && tab->tab_contents()) {
3633 DCHECK(tab->tab_contents()->profile() != NULL);
3634 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3635 prefs::kWebKitDefaultFontSize, font_size);
3636 }
3637 }
3638}
3639
[email protected]bc73b4e52010-03-26 04:16:203640void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3641 BrowsingDataRemover* remover;
3642 remover = new BrowsingDataRemover(profile(),
3643 BrowsingDataRemover::EVERYTHING, // All time periods.
3644 base::Time());
3645 remover->Remove(remove_mask);
3646 // BrowsingDataRemover deletes itself.
3647}
[email protected]1bb5f892009-10-06 01:44:573648
[email protected]2949e90d2009-08-21 15:32:523649void AutomationProvider::WaitForBrowserWindowCountToBecome(
3650 int target_count, IPC::Message* reply_message) {
3651 if (static_cast<int>(BrowserList::size()) == target_count) {
3652 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3653 reply_message, true);
3654 Send(reply_message);
3655 return;
3656 }
3657
3658 // Set up an observer (it will delete itself).
3659 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3660}
3661
3662void AutomationProvider::WaitForAppModalDialogToBeShown(
3663 IPC::Message* reply_message) {
3664 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3665 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3666 reply_message, true);
3667 Send(reply_message);
3668 return;
3669 }
3670
3671 // Set up an observer (it will delete itself).
3672 new AppModalDialogShownObserver(this, reply_message);
3673}
3674
[email protected]1126a1d32009-08-26 15:39:263675void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3676 int handle, int number_of_navigations, IPC::Message* reply_message) {
3677 if (tab_tracker_->ContainsHandle(handle)) {
3678 NavigationController* tab = tab_tracker_->GetResource(handle);
3679 Browser* browser = FindAndActivateTab(tab);
3680 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013681 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3682 false);
[email protected]1126a1d32009-08-26 15:39:263683 browser->GoBack(CURRENT_TAB);
3684 return;
3685 }
3686 }
3687
3688 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3689 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3690 Send(reply_message);
3691}
3692
3693void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3694 int handle, int number_of_navigations, IPC::Message* reply_message) {
3695 if (tab_tracker_->ContainsHandle(handle)) {
3696 NavigationController* tab = tab_tracker_->GetResource(handle);
3697 Browser* browser = FindAndActivateTab(tab);
3698 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013699 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3700 false);
[email protected]1126a1d32009-08-26 15:39:263701 browser->GoForward(CURRENT_TAB);
3702 return;
3703 }
3704 }
3705
3706 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3707 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3708 Send(reply_message);
3709}
3710
[email protected]f7a68432009-07-29 23:18:193711RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3712 if (tab_tracker_->ContainsHandle(tab_handle)) {
3713 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3714 if (!tab) {
3715 NOTREACHED();
3716 return NULL;
3717 }
3718
3719 TabContents* tab_contents = tab->tab_contents();
3720 if (!tab_contents) {
3721 NOTREACHED();
3722 return NULL;
3723 }
3724
3725 RenderViewHost* view_host = tab_contents->render_view_host();
3726 return view_host;
3727 }
3728
3729 return NULL;
3730}
[email protected]675595f2009-08-26 22:32:043731
3732void AutomationProvider::GetBrowserForWindow(int window_handle,
3733 bool* success,
3734 int* browser_handle) {
3735 *success = false;
3736 *browser_handle = 0;
3737
3738 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3739 if (!window)
3740 return;
3741
3742 BrowserList::const_iterator iter = BrowserList::begin();
3743 for (;iter != BrowserList::end(); ++iter) {
3744 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3745 if (window == this_window) {
3746 // Add() returns the existing handle for the resource if any.
3747 *browser_handle = browser_tracker_->Add(*iter);
3748 *success = true;
3749 return;
3750 }
3751 }
3752}
[email protected]d11c8e92009-10-20 23:26:403753
3754void AutomationProvider::InstallExtension(const FilePath& crx_path,
3755 IPC::Message* reply_message) {
3756 ExtensionsService* service = profile_->GetExtensionsService();
3757 if (service) {
3758 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193759 new ExtensionInstallNotificationObserver(this,
3760 AutomationMsg_InstallExtension::ID,
3761 reply_message);
[email protected]d11c8e92009-10-20 23:26:403762
3763 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163764 scoped_refptr<CrxInstaller> installer(
3765 new CrxInstaller(install_dir,
3766 service,
3767 NULL)); // silent install, no UI
3768 installer->set_allow_privilege_increase(true);
3769 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403770 } else {
3771 AutomationMsg_InstallExtension::WriteReplyParams(
3772 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3773 Send(reply_message);
3774 }
3775}
3776
3777void AutomationProvider::LoadExpandedExtension(
3778 const FilePath& extension_dir,
3779 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383780 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403781 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193782 new ExtensionInstallNotificationObserver(
3783 this,
3784 AutomationMsg_LoadExpandedExtension::ID,
3785 reply_message);
[email protected]d11c8e92009-10-20 23:26:403786
3787 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403788 } else {
3789 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3790 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3791 Send(reply_message);
3792 }
3793}
[email protected]673fd2c02010-02-04 23:10:003794
[email protected]a1e62d12010-03-16 02:18:433795void AutomationProvider::GetEnabledExtensions(
3796 std::vector<FilePath>* result) {
3797 ExtensionsService* service = profile_->GetExtensionsService();
3798 DCHECK(service);
3799 if (service->extensions_enabled()) {
3800 const ExtensionList* extensions = service->extensions();
3801 DCHECK(extensions);
3802 for (size_t i = 0; i < extensions->size(); ++i) {
3803 Extension* extension = (*extensions)[i];
3804 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123805 if (extension->location() == Extension::INTERNAL ||
3806 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073807 result->push_back(extension->path());
3808 }
[email protected]a1e62d12010-03-16 02:18:433809 }
3810 }
3811}
3812
[email protected]790788ac2010-04-06 17:52:193813void AutomationProvider::WaitForExtensionTestResult(
3814 IPC::Message* reply_message) {
3815 DCHECK(reply_message_ == NULL);
3816 reply_message_ = reply_message;
3817 // Call MaybeSendResult, because the result might have come in before
3818 // we were waiting on it.
3819 extension_test_result_observer_->MaybeSendResult();
3820}
3821
3822void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093823 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193824 ExtensionsService* service = profile_->GetExtensionsService();
3825 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3826 if (service && manager) {
3827 // The observer will delete itself when done.
3828 new ExtensionReadyNotificationObserver(
3829 manager,
3830 this,
3831 AutomationMsg_InstallExtensionAndGetHandle::ID,
3832 reply_message);
3833
[email protected]d7e5525d2010-04-20 14:37:093834 ExtensionInstallUI* client =
3835 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193836 scoped_refptr<CrxInstaller> installer(
3837 new CrxInstaller(service->install_directory(),
3838 service,
[email protected]d7e5525d2010-04-20 14:37:093839 client));
[email protected]790788ac2010-04-06 17:52:193840 installer->set_allow_privilege_increase(true);
3841 installer->InstallCrx(crx_path);
3842 } else {
3843 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3844 reply_message, 0);
3845 Send(reply_message);
3846 }
3847}
3848
3849void AutomationProvider::UninstallExtension(int extension_handle,
3850 bool* success) {
3851 *success = false;
3852 Extension* extension = GetExtension(extension_handle);
3853 ExtensionsService* service = profile_->GetExtensionsService();
3854 if (extension && service) {
3855 ExtensionUnloadNotificationObserver observer;
3856 service->UninstallExtension(extension->id(), false);
3857 // The extension unload notification should have been sent synchronously
3858 // with the uninstall. Just to be safe, check that it was received.
3859 *success = observer.did_receive_unload_notification();
3860 }
3861}
3862
3863void AutomationProvider::EnableExtension(int extension_handle,
3864 IPC::Message* reply_message) {
3865 Extension* extension = GetDisabledExtension(extension_handle);
3866 ExtensionsService* service = profile_->GetExtensionsService();
3867 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3868 // Only enable if this extension is disabled.
3869 if (extension && service && manager) {
3870 // The observer will delete itself when done.
3871 new ExtensionReadyNotificationObserver(
3872 manager,
3873 this,
3874 AutomationMsg_EnableExtension::ID,
3875 reply_message);
3876 service->EnableExtension(extension->id());
3877 } else {
3878 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3879 Send(reply_message);
3880 }
3881}
3882
3883void AutomationProvider::DisableExtension(int extension_handle,
3884 bool* success) {
3885 *success = false;
3886 Extension* extension = GetEnabledExtension(extension_handle);
3887 ExtensionsService* service = profile_->GetExtensionsService();
3888 if (extension && service) {
3889 ExtensionUnloadNotificationObserver observer;
3890 service->DisableExtension(extension->id());
3891 // The extension unload notification should have been sent synchronously
3892 // with the disable. Just to be safe, check that it was received.
3893 *success = observer.did_receive_unload_notification();
3894 }
3895}
3896
3897void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3898 int extension_handle, int browser_handle,
3899 IPC::Message* reply_message) {
3900 bool success = false;
3901 Extension* extension = GetEnabledExtension(extension_handle);
3902 ExtensionsService* service = profile_->GetExtensionsService();
3903 ExtensionMessageService* message_service =
3904 profile_->GetExtensionMessageService();
3905 Browser* browser = browser_tracker_->GetResource(browser_handle);
3906 if (extension && service && message_service && browser) {
3907 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3908 if (extension->page_action()) {
3909 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3910 browser->profile(), extension->id(), "action", tab_id, "", 1);
3911 success = true;
3912 } else if (extension->browser_action()) {
3913 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3914 browser->profile(), extension->id(), browser);
3915 success = true;
3916 }
3917 }
3918 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3919 reply_message, success);
3920 Send(reply_message);
3921}
3922
3923void AutomationProvider::MoveExtensionBrowserAction(
3924 int extension_handle, int index, bool* success) {
3925 *success = false;
3926 Extension* extension = GetEnabledExtension(extension_handle);
3927 ExtensionsService* service = profile_->GetExtensionsService();
3928 if (extension && service) {
3929 ExtensionToolbarModel* toolbar = service->toolbar_model();
3930 if (toolbar) {
3931 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3932 toolbar->MoveBrowserAction(extension, index);
3933 *success = true;
3934 } else {
3935 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3936 }
3937 }
3938 }
3939}
3940
3941void AutomationProvider::GetExtensionProperty(
3942 int extension_handle,
3943 AutomationMsg_ExtensionProperty type,
3944 bool* success,
3945 std::string* value) {
3946 *success = false;
3947 Extension* extension = GetExtension(extension_handle);
3948 ExtensionsService* service = profile_->GetExtensionsService();
3949 if (extension && service) {
3950 ExtensionToolbarModel* toolbar = service->toolbar_model();
3951 int found_index = -1;
3952 int index = 0;
3953 switch (type) {
3954 case AUTOMATION_MSG_EXTENSION_ID:
3955 *value = extension->id();
3956 *success = true;
3957 break;
3958 case AUTOMATION_MSG_EXTENSION_NAME:
3959 *value = extension->name();
3960 *success = true;
3961 break;
3962 case AUTOMATION_MSG_EXTENSION_VERSION:
3963 *value = extension->VersionString();
3964 *success = true;
3965 break;
3966 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3967 if (toolbar) {
3968 for (ExtensionList::const_iterator iter = toolbar->begin();
3969 iter != toolbar->end(); iter++) {
3970 // Skip this extension if we are in incognito mode
3971 // and it is not incognito-enabled.
3972 if (profile_->IsOffTheRecord() &&
3973 !service->IsIncognitoEnabled(*iter))
3974 continue;
3975 if (*iter == extension) {
3976 found_index = index;
3977 break;
3978 }
3979 index++;
3980 }
3981 *value = IntToString(found_index);
3982 *success = true;
3983 }
3984 break;
3985 default:
3986 LOG(WARNING) << "Trying to get undefined extension property";
3987 break;
3988 }
3989 }
3990}
3991
[email protected]673fd2c02010-02-04 23:10:003992void AutomationProvider::SaveAsAsync(int tab_handle) {
3993 NavigationController* tab = NULL;
3994 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3995 if (tab_contents)
3996 tab_contents->OnSavePage();
3997}
[email protected]7dad3d5f2010-03-04 00:27:013998
3999void AutomationProvider::SetContentSetting(
4000 int handle,
4001 const std::string& host,
4002 ContentSettingsType content_type,
4003 ContentSetting setting,
4004 bool* success) {
4005 *success = false;
4006 if (browser_tracker_->ContainsHandle(handle)) {
4007 Browser* browser = browser_tracker_->GetResource(handle);
4008 HostContentSettingsMap* map =
4009 browser->profile()->GetHostContentSettingsMap();
4010 if (host.empty()) {
4011 map->SetDefaultContentSetting(content_type, setting);
4012 } else {
[email protected]0314ae02010-04-08 09:18:294013 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
4014 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:014015 }
4016 *success = true;
4017 }
4018}
[email protected]cc824372010-03-31 15:33:014019
4020#if !defined(TOOLKIT_VIEWS)
4021void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
4022 NOTIMPLEMENTED();
4023};
4024
4025void AutomationProvider::WaitForFocusedViewIDToChange(
4026 int handle, int previous_view_id, IPC::Message* reply_message) {
4027 NOTIMPLEMENTED();
4028}
4029
4030void AutomationProvider::StartTrackingPopupMenus(
4031 int browser_handle, bool* success) {
4032 NOTIMPLEMENTED();
4033}
4034
4035void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
4036 NOTIMPLEMENTED();
4037}
4038#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:094039
4040void AutomationProvider::ResetToDefaultTheme() {
4041 profile_->ClearTheme();
4042}