blob: 25091a2f763a9bcc15474b64b0909f5ef3403272 [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]790788ac2010-04-06 17:52:1932#include "chrome/browser/automation/automation_extension_tracker.h"
initial.commit09911bf2008-07-26 23:55:2933#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0834#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]f44265b2009-05-19 18:52:5035#include "chrome/browser/automation/extension_port_container.h"
[email protected]66ba4932009-06-04 19:22:1336#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5337#include "chrome/browser/bookmarks/bookmark_model.h"
38#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1439#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0740#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3941#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2042#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0543#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5844#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2945#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1246#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5947#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2248#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0549#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4050#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1951#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1452#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4053#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5554#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1955#include "chrome/browser/extensions/extension_tabs_module.h"
56#include "chrome/browser/extensions/extension_toolbar_model.h"
57#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1658#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5859#include "chrome/browser/find_bar.h"
60#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2961#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0162#include "chrome/browser/host_content_settings_map.h"
[email protected]0ac83682010-01-22 17:46:2763#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0664#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0165#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5366#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2467#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0868#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0569#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1770#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0771#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2572#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0373#include "chrome/browser/ssl/ssl_manager.h"
74#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3475#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4576#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1777#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0578#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2979#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1980#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1781#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5582#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1483#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5784#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2585#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5686#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5787#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1788#include "net/proxy/proxy_service.h"
89#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2190#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3091#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2892#include "views/event.h"
[email protected]f7d48012010-05-06 08:17:0593#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2994
[email protected]de246f52009-02-25 18:25:4595#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:3596#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:4597#endif // defined(OS_WIN)
98
[email protected]e1acf6f2008-10-27 20:43:3399using base::Time;
100
[email protected]cbab76d2008-10-13 22:42:47101class AutomationInterstitialPage : public InterstitialPage {
102 public:
[email protected]57c6a652009-05-04 07:58:34103 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47104 const GURL& url,
105 const std::string& contents)
106 : InterstitialPage(tab, true, url),
107 contents_(contents) {
108 }
109
110 virtual std::string GetHTMLContents() { return contents_; }
111
112 private:
113 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29114
[email protected]cbab76d2008-10-13 22:42:47115 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
116};
117
[email protected]c2cb8542009-08-20 21:16:51118class ClickTask : public Task {
119 public:
[email protected]fc2e0872009-08-21 22:14:41120 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51121 virtual ~ClickTask() {}
122
123 virtual void Run() {
124 ui_controls::MouseButton button = ui_controls::LEFT;
125 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
126 views::Event::EF_LEFT_BUTTON_DOWN) {
127 button = ui_controls::LEFT;
128 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
129 views::Event::EF_RIGHT_BUTTON_DOWN) {
130 button = ui_controls::RIGHT;
131 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
132 views::Event::EF_MIDDLE_BUTTON_DOWN) {
133 button = ui_controls::MIDDLE;
134 } else {
135 NOTREACHED();
136 }
137
[email protected]fc2e0872009-08-21 22:14:41138 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51139 }
140
141 private:
[email protected]c2cb8542009-08-20 21:16:51142 int flags_;
143
144 DISALLOW_COPY_AND_ASSIGN(ClickTask);
145};
[email protected]c2cb8542009-08-20 21:16:51146
initial.commit09911bf2008-07-26 23:55:29147AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57148 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56149 profile_(profile),
[email protected]cc824372010-03-31 15:33:01150 reply_message_(NULL),
151 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29152 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19153 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29154 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20155 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29156 autocomplete_edit_tracker_.reset(
157 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29158 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
159 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44160 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19161 extension_test_result_observer_.reset(
162 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13163 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29164}
165
166AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50167 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
168 port_containers_.end());
169 port_containers_.clear();
170
[email protected]0da050b92008-08-19 19:29:47171 // Make sure that any outstanding NotificationObservers also get destroyed.
172 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31173 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47174 while ((observer = it.GetNext()) != NULL)
175 delete observer;
[email protected]528211a2010-01-14 15:25:13176
177 if (channel_.get()) {
178 channel_->Close();
179 }
180 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29181}
182
[email protected]9a3a293b2009-06-04 22:28:16183void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06184 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57185 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06186 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
187 automation_resource_message_filter_,
188 g_browser_process->io_thread()->message_loop(),
189 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43190 scoped_ptr<FileVersionInfo> version_info(
191 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40192 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43193 if (version_info != NULL) {
194 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40195 }
[email protected]c6cb1992009-04-13 16:45:29196
197 // Send a hello message with our current automation protocol version.
198 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29199}
200
201void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
202 if (expected_tabs == 0) {
203 Send(new AutomationMsg_InitialLoadsComplete(0));
204 } else {
205 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
206 }
207}
208
209NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58210 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01211 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29212 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58213 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01214 number_of_navigations,
215 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29216
[email protected]71f65dd2009-02-11 19:14:56217 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29218 return observer;
219}
220
[email protected]faf2ee42010-05-11 14:26:17221void AutomationProvider::RemoveNavigationStatusListener(
222 NotificationObserver* obs) {
223 notification_observer_list_.RemoveObserver(obs);
224}
225
initial.commit09911bf2008-07-26 23:55:29226NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14227 Browser* parent,
228 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56229 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14230 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29231 notification_observer_list_.AddObserver(observer);
232
233 return observer;
234}
235
[email protected]faf2ee42010-05-11 14:26:17236void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29237 notification_observer_list_.RemoveObserver(obs);
238}
239
240void AutomationProvider::AddLoginHandler(NavigationController* tab,
241 LoginHandler* handler) {
242 login_handler_map_[tab] = handler;
243}
244
245void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
246 DCHECK(login_handler_map_[tab]);
247 login_handler_map_.erase(tab);
248}
249
[email protected]f44265b2009-05-19 18:52:50250void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
251 int port_id = port->port_id();
252 DCHECK_NE(-1, port_id);
253 DCHECK(port_containers_.find(port_id) == port_containers_.end());
254
255 port_containers_[port_id] = port;
256}
257
258void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
259 int port_id = port->port_id();
260 DCHECK_NE(-1, port_id);
261
262 PortContainerMap::iterator it = port_containers_.find(port_id);
263 DCHECK(it != port_containers_.end());
264
265 if (it != port_containers_.end()) {
266 delete it->second;
267 port_containers_.erase(it);
268 }
269}
270
271ExtensionPortContainer* AutomationProvider::GetPortContainer(
272 int port_id) const {
273 PortContainerMap::const_iterator it = port_containers_.find(port_id);
274 if (it == port_containers_.end())
275 return NULL;
276
277 return it->second;
278}
279
initial.commit09911bf2008-07-26 23:55:29280int AutomationProvider::GetIndexForNavigationController(
281 const NavigationController* controller, const Browser* parent) const {
282 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12283 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29284}
285
[email protected]790788ac2010-04-06 17:52:19286int AutomationProvider::AddExtension(Extension* extension) {
287 DCHECK(extension);
288 return extension_tracker_->Add(extension);
289}
290
291Extension* AutomationProvider::GetExtension(int extension_handle) {
292 return extension_tracker_->GetResource(extension_handle);
293}
294
295Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
296 Extension* extension = extension_tracker_->GetResource(extension_handle);
297 ExtensionsService* service = profile_->GetExtensionsService();
298 if (extension && service &&
299 service->GetExtensionById(extension->id(), false))
300 return extension;
301 return NULL;
302}
303
304Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
305 Extension* extension = extension_tracker_->GetResource(extension_handle);
306 ExtensionsService* service = profile_->GetExtensionsService();
307 if (extension && service &&
308 service->GetExtensionById(extension->id(), true) &&
309 !service->GetExtensionById(extension->id(), false))
310 return extension;
311 return NULL;
312}
313
initial.commit09911bf2008-07-26 23:55:29314void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
315 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14316 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56317 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
318 CloseBrowserAsync)
319 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
320 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
321 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
322 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
323 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
324 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22325 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]1c58a5c2009-05-21 18:47:14326 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58327 IPC_MESSAGE_HANDLER_DELAY_REPLY(
328 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
329 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56330 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11331 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
332 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56333 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
334 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
335 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
336 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14337 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56338 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
339 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
340 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14341 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29342 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
343 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56344 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36345 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56346 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29347 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56348 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29349 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
350 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56351 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14352 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24353 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44354 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33355 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44356 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33357 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24358 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14359 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24360 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15361 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14362 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24363 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35364 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14365 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30366#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56367 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
368 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30369#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56370 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53371 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56372 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37373#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56374 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45375#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56376 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
377 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03378 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56379 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14380 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09381 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
382 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
383 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29384 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14385 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56386 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
387 ExecuteJavascript)
388 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29389 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14390 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
391 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56392 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
393 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14394 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17395 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14396 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14397 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53398 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
399 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14400 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56401 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14402 GetAutocompleteEditForBrowser)
403 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56404 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14405 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56406 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14407 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56408 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
409 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14410 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
411 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44412 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
413 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56414 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
415 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29416 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
417 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
418 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56419 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41420 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56421 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
422 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29423 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56424 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29425 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56426 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29427 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56428 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29429 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56430 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45431 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14432 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56433 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57434 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56435 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57436 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56437 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
438 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53439 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
440 GetBookmarksAsJSON)
441 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
442 WaitForBookmarkModelToLoad)
443 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
444 AddBookmarkGroup)
445 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
446 AddBookmarkURL)
447 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
448 ReparentBookmark)
449 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
450 SetBookmarkTitle)
451 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
452 SetBookmarkURL)
453 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
454 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04455 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
456 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18457 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
458 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
459 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56460 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42461 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56462 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
463 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14464 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56465 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44466 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56467 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20468 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14469 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56470 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16471 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56472 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16473 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56474 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16475 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14476 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20477 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
478 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14479 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22480 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13481 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19482 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
483 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
484 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
485 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
486 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
487 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52488 IPC_MESSAGE_HANDLER_DELAY_REPLY(
489 AutomationMsg_WaitForBrowserWindowCountToBecome,
490 WaitForBrowserWindowCountToBecome)
491 IPC_MESSAGE_HANDLER_DELAY_REPLY(
492 AutomationMsg_WaitForAppModalDialogToBeShown,
493 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26494 IPC_MESSAGE_HANDLER_DELAY_REPLY(
495 AutomationMsg_GoBackBlockUntilNavigationsComplete,
496 GoBackBlockUntilNavigationsComplete)
497 IPC_MESSAGE_HANDLER_DELAY_REPLY(
498 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
499 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57500 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40501 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
502 InstallExtension)
503 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
504 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43505 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
506 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19507 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
508 WaitForExtensionTestResult)
509 IPC_MESSAGE_HANDLER_DELAY_REPLY(
510 AutomationMsg_InstallExtensionAndGetHandle,
511 InstallExtensionAndGetHandle)
512 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
513 UninstallExtension)
514 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
515 EnableExtension)
516 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
517 DisableExtension)
518 IPC_MESSAGE_HANDLER_DELAY_REPLY(
519 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
520 ExecuteExtensionActionInActiveTabAsync)
521 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
522 MoveExtensionBrowserAction)
523 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
524 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57525 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
526 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00527 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01528 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20529 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00530 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01531#if defined(TOOLKIT_VIEWS)
532 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
533 WaitForFocusedViewIDToChange)
534 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
535 StartTrackingPopupMenus)
536 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
537 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00538#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52539#if defined(OS_WIN)
540 // These are for use with external tabs.
541 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
542 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
543 ProcessUnhandledAccelerator)
544 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
545 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
546 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
547 OnForwardContextMenuCommandToChrome)
548 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
549 NavigateInExternalTab)
550 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
551 NavigateExternalTabAtIndex)
552 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
553 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
554 SetEnableExtensionAutomation)
555 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
556 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00557 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
558#endif // defined(OS_WIN)
559#if defined(OS_CHROMEOS)
560 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
561 LoginWithUserAndPass)
562#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29563 IPC_END_MESSAGE_MAP()
564}
565
[email protected]71f65dd2009-02-11 19:14:56566void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
567 *status = -1;
initial.commit09911bf2008-07-26 23:55:29568 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
569 Browser* browser = browser_tracker_->GetResource(handle);
570 if (at_index >= 0 && at_index < browser->tab_count()) {
571 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56572 *status = 0;
initial.commit09911bf2008-07-26 23:55:29573 }
574 }
initial.commit09911bf2008-07-26 23:55:29575}
576
[email protected]71f65dd2009-02-11 19:14:56577void AutomationProvider::AppendTab(int handle, const GURL& url,
578 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29579 int append_tab_response = -1; // -1 is the error code
580 NotificationObserver* observer = NULL;
581
582 if (browser_tracker_->ContainsHandle(handle)) {
583 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14584 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38585 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39586 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
587 NULL, std::string());
initial.commit09911bf2008-07-26 23:55:29588 if (tab_contents) {
589 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57590 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29591 }
592 }
593
594 if (append_tab_response < 0) {
595 // The append tab failed. Remove the TabStripObserver
596 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17597 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29598 delete observer;
599 }
600
[email protected]71f65dd2009-02-11 19:14:56601 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
602 append_tab_response);
603 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29604 }
605}
606
[email protected]71f65dd2009-02-11 19:14:56607void AutomationProvider::NavigateToURL(int handle, const GURL& url,
608 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58609 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
610}
611
612void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
613 int handle, const GURL& url, int number_of_navigations,
614 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29615 if (tab_tracker_->ContainsHandle(handle)) {
616 NavigationController* tab = tab_tracker_->GetResource(handle);
617
618 // Simulate what a user would do. Activate the tab and then navigate.
619 // We could allow navigating in a background tab in future.
620 Browser* browser = FindAndActivateTab(tab);
621
622 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01623 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
624 false);
[email protected]71f65dd2009-02-11 19:14:56625
initial.commit09911bf2008-07-26 23:55:29626 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50627 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29628 return;
629 }
630 }
[email protected]71f65dd2009-02-11 19:14:56631
632 AutomationMsg_NavigateToURL::WriteReplyParams(
633 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
634 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29635}
[email protected]2949e90d2009-08-21 15:32:52636
[email protected]c70f9b82010-04-21 07:31:11637void AutomationProvider::NavigationAsync(int handle,
638 const GURL& url,
639 bool* status) {
640 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
641}
642
643void AutomationProvider::NavigationAsyncWithDisposition(
644 int handle,
645 const GURL& url,
646 WindowOpenDisposition disposition,
647 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56648 *status = false;
initial.commit09911bf2008-07-26 23:55:29649
650 if (tab_tracker_->ContainsHandle(handle)) {
651 NavigationController* tab = tab_tracker_->GetResource(handle);
652
653 // Simulate what a user would do. Activate the tab and then navigate.
654 // We could allow navigating in a background tab in future.
655 Browser* browser = FindAndActivateTab(tab);
656
657 if (browser) {
658 // Don't add any listener unless a callback mechanism is desired.
659 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11660 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56661 *status = true;
initial.commit09911bf2008-07-26 23:55:29662 }
663 }
initial.commit09911bf2008-07-26 23:55:29664}
665
[email protected]71f65dd2009-02-11 19:14:56666void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29667 if (tab_tracker_->ContainsHandle(handle)) {
668 NavigationController* tab = tab_tracker_->GetResource(handle);
669 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14670 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01671 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29672 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29673 return;
674 }
675 }
[email protected]71f65dd2009-02-11 19:14:56676
677 AutomationMsg_GoBack::WriteReplyParams(
678 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
679 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29680}
681
[email protected]71f65dd2009-02-11 19:14:56682void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29683 if (tab_tracker_->ContainsHandle(handle)) {
684 NavigationController* tab = tab_tracker_->GetResource(handle);
685 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14686 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01687 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29688 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29689 return;
690 }
691 }
[email protected]71f65dd2009-02-11 19:14:56692
693 AutomationMsg_GoForward::WriteReplyParams(
694 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
695 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29696}
697
[email protected]71f65dd2009-02-11 19:14:56698void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29699 if (tab_tracker_->ContainsHandle(handle)) {
700 NavigationController* tab = tab_tracker_->GetResource(handle);
701 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14702 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01703 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28704 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29705 return;
706 }
707 }
[email protected]71f65dd2009-02-11 19:14:56708
709 AutomationMsg_Reload::WriteReplyParams(
710 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
711 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29712}
713
[email protected]71f65dd2009-02-11 19:14:56714void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29715 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56716 const std::wstring& password,
717 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29718 if (tab_tracker_->ContainsHandle(tab_handle)) {
719 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
720 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
721
722 if (iter != login_handler_map_.end()) {
723 // If auth is needed again after this, assume login has failed. This is
724 // not strictly correct, because a navigation can require both proxy and
725 // server auth, but it should be OK for now.
726 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01727 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29728 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52729 return;
initial.commit09911bf2008-07-26 23:55:29730 }
731 }
[email protected]de246f52009-02-25 18:25:45732
[email protected]457f5cf2009-08-18 16:37:52733 AutomationMsg_SetAuth::WriteReplyParams(
734 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
735 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29736}
737
[email protected]71f65dd2009-02-11 19:14:56738void AutomationProvider::CancelAuth(int tab_handle,
739 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29740 if (tab_tracker_->ContainsHandle(tab_handle)) {
741 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
742 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
743
744 if (iter != login_handler_map_.end()) {
745 // If auth is needed again after this, something is screwy.
746 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01747 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29748 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52749 return;
initial.commit09911bf2008-07-26 23:55:29750 }
751 }
[email protected]de246f52009-02-25 18:25:45752
[email protected]457f5cf2009-08-18 16:37:52753 AutomationMsg_CancelAuth::WriteReplyParams(
754 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
755 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29756}
757
[email protected]71f65dd2009-02-11 19:14:56758void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
759 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29760
761 if (tab_tracker_->ContainsHandle(tab_handle)) {
762 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
763 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
764
765 if (iter != login_handler_map_.end()) {
766 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56767 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29768 }
769 }
initial.commit09911bf2008-07-26 23:55:29770}
771
[email protected]71f65dd2009-02-11 19:14:56772void AutomationProvider::GetRedirectsFrom(int tab_handle,
773 const GURL& source_url,
774 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29775 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
776 if (tab_tracker_->ContainsHandle(tab_handle)) {
777 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
778 HistoryService* history_service =
779 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
780
781 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
782 "has no history service";
783 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56784 DCHECK(reply_message_ == NULL);
785 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29786 // Schedule a history query for redirects. The response will be sent
787 // asynchronously from the callback the history system uses to notify us
788 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29789 redirect_query_ = history_service->QueryRedirectsFrom(
790 source_url, &consumer_,
791 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
792 return; // Response will be sent when query completes.
793 }
794 }
795
796 // Send failure response.
[email protected]deb57402009-02-06 01:35:30797 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56798 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
799 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29800}
801
[email protected]71f65dd2009-02-11 19:14:56802void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
803 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29804 if (browser_tracker_->ContainsHandle(handle)) {
805 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56806 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29807 }
initial.commit09911bf2008-07-26 23:55:29808}
809
[email protected]202e7a72009-06-15 03:48:36810void AutomationProvider::GetBrowserLocale(string16* locale) {
811 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06812 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36813}
814
[email protected]71f65dd2009-02-11 19:14:56815void AutomationProvider::GetBrowserWindowCount(int* window_count) {
816 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29817}
818
[email protected]24497032009-05-01 17:00:29819void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
820 *window_count = static_cast<int>(
821 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
822}
823
[email protected]71f65dd2009-02-11 19:14:56824void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
825 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07826 AppModalDialog* dialog_delegate =
827 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50828 *showing_dialog = (dialog_delegate != NULL);
829 if (*showing_dialog)
830 *dialog_button = dialog_delegate->GetDialogButtons();
831 else
[email protected]478ff2ed2009-04-21 23:49:18832 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20833}
834
[email protected]71f65dd2009-02-11 19:14:56835void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
836 *success = false;
[email protected]fad84eab2008-12-05 00:37:20837
[email protected]1f460072009-05-28 17:02:07838 AppModalDialog* dialog_delegate =
839 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50840 if (dialog_delegate &&
841 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18842 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
843 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28844 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56845 *success = true;
[email protected]fad84eab2008-12-05 00:37:20846 }
[email protected]478ff2ed2009-04-21 23:49:18847 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
848 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56849 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28850 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56851 *success = true;
[email protected]fad84eab2008-12-05 00:37:20852 }
853 }
[email protected]c274acc2008-11-11 20:13:44854}
855
[email protected]fedaa7d2010-01-26 20:34:57856void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
857 if (browser_tracker_->ContainsHandle(handle)) {
858 Browser* browser = browser_tracker_->GetResource(handle);
859 browser->profile()->ShutdownSessionService();
860 *result = true;
861 } else {
862 *result = false;
863 }
864}
865
[email protected]71f65dd2009-02-11 19:14:56866void AutomationProvider::GetBrowserWindow(int index, int* handle) {
867 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29868 if (index >= 0) {
869 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30870 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29871 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56872 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29873 }
874 }
initial.commit09911bf2008-07-26 23:55:29875}
876
[email protected]24497032009-05-01 17:00:29877void AutomationProvider::FindNormalBrowserWindow(int* handle) {
878 *handle = 0;
879 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31880 Browser::TYPE_NORMAL,
881 false);
[email protected]24497032009-05-01 17:00:29882 if (browser)
883 *handle = browser_tracker_->Add(browser);
884}
885
[email protected]71f65dd2009-02-11 19:14:56886void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
887 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29888 Browser* browser = BrowserList::GetLastActive();
889 if (browser)
[email protected]71f65dd2009-02-11 19:14:56890 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29891}
892
[email protected]b2aa3ed72010-02-01 18:37:14893#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28894// TODO(estade): use this implementation for all platforms?
895void AutomationProvider::GetActiveWindow(int* handle) {
896 gfx::NativeWindow window =
897 BrowserList::GetLastActive()->window()->GetNativeHandle();
898 *handle = window_tracker_->Add(window);
899}
900#endif
901
[email protected]4f6381ee2009-04-16 02:46:33902void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
903 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56904 *success = false;
[email protected]4ae62752008-08-04 23:28:47905 if (browser_tracker_->ContainsHandle(handle)) {
906 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14907 if (browser->command_updater()->SupportsCommand(command) &&
908 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47909 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56910 *success = true;
[email protected]4ae62752008-08-04 23:28:47911 }
912 }
[email protected]4ae62752008-08-04 23:28:47913}
914
[email protected]4f6381ee2009-04-16 02:46:33915void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56916 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53917 // List of commands which just finish synchronously and don't require
918 // setting up an observer.
919 static const int kSynchronousCommands[] = {
920 IDC_HOME,
921 IDC_SELECT_NEXT_TAB,
922 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25923 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53924 };
[email protected]56e71b7c2009-03-27 03:05:56925 if (browser_tracker_->ContainsHandle(handle)) {
926 Browser* browser = browser_tracker_->GetResource(handle);
927 if (browser->command_updater()->SupportsCommand(command) &&
928 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53929 // First check if we can handle the command without using an observer.
930 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
931 if (command == kSynchronousCommands[i]) {
932 browser->ExecuteCommand(command);
933 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
934 true);
935 Send(reply_message);
936 return;
937 }
938 }
939
940 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42941 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
942 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27943 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42944 return;
945 }
[email protected]56e71b7c2009-03-27 03:05:56946 }
947 }
[email protected]49a14a82009-03-31 04:16:44948 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56949 Send(reply_message);
950}
951
[email protected]fc2e0872009-08-21 22:14:41952// This task just adds another task to the event queue. This is useful if
953// you want to ensure that any tasks added to the event queue after this one
954// have already been processed by the time |task| is run.
955class InvokeTaskLaterTask : public Task {
956 public:
957 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
958 virtual ~InvokeTaskLaterTask() {}
959
960 virtual void Run() {
961 MessageLoop::current()->PostTask(FROM_HERE, task_);
962 }
963
964 private:
965 Task* task_;
966
967 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
968};
969
initial.commit09911bf2008-07-26 23:55:29970void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
971 int handle,
[email protected]d1a5941e2009-08-13 23:34:24972 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29973 int flags) {
[email protected]b410bc32009-08-14 01:11:14974 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51975 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41976 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29977 }
978}
979
[email protected]60507b12009-11-02 23:51:35980void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
981 int handle,
982 const gfx::Point& location) {
983 if (window_tracker_->ContainsHandle(handle))
984 ui_controls::SendMouseMove(location.x(), location.y());
985}
986
initial.commit09911bf2008-07-26 23:55:29987void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
988 int handle,
[email protected]bc1407f2009-09-29 00:33:35989 int key,
initial.commit09911bf2008-07-26 23:55:29990 int flags) {
[email protected]b410bc32009-08-14 01:11:14991 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:29992 return;
993
[email protected]b410bc32009-08-14 01:11:14994 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:29995 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:35996 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:38997 ((flags & views::Event::EF_CONTROL_DOWN) ==
998 views::Event::EF_CONTROL_DOWN),
999 ((flags & views::Event::EF_SHIFT_DOWN) ==
1000 views::Event::EF_SHIFT_DOWN),
1001 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301002 views::Event::EF_ALT_DOWN),
1003 ((flags & views::Event::EF_COMMAND_DOWN) ==
1004 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291005}
initial.commit09911bf2008-07-26 23:55:291006
[email protected]71f65dd2009-02-11 19:14:561007void AutomationProvider::IsWindowActive(int handle, bool* success,
1008 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291009 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171010 *is_active =
1011 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561012 *success = true;
initial.commit09911bf2008-07-26 23:55:291013 } else {
[email protected]71f65dd2009-02-11 19:14:561014 *success = false;
1015 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291016 }
1017}
1018
[email protected]71f65dd2009-02-11 19:14:561019void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1020 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291021
1022 if (browser_tracker_->ContainsHandle(handle)) {
1023 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561024 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291025 }
initial.commit09911bf2008-07-26 23:55:291026}
1027
[email protected]982921f12009-10-27 21:43:531028void AutomationProvider::GetType(int handle, int* type_as_int) {
1029 *type_as_int = -1; // -1 is the error code
1030
1031 if (browser_tracker_->ContainsHandle(handle)) {
1032 Browser* browser = browser_tracker_->GetResource(handle);
1033 *type_as_int = static_cast<int>(browser->type());
1034 }
1035}
1036
[email protected]71f65dd2009-02-11 19:14:561037void AutomationProvider::GetTab(int win_handle, int tab_index,
1038 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561039 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291040 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1041 Browser* browser = browser_tracker_->GetResource(win_handle);
1042 if (tab_index < browser->tab_count()) {
1043 TabContents* tab_contents =
1044 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571045 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291046 }
1047 }
initial.commit09911bf2008-07-26 23:55:291048}
1049
[email protected]71f65dd2009-02-11 19:14:561050void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1051 std::wstring* title) {
1052 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291053 if (tab_tracker_->ContainsHandle(handle)) {
1054 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361055 NavigationEntry* entry = tab->GetActiveEntry();
1056 if (entry != NULL) {
1057 *title = UTF16ToWideHack(entry->title());
1058 } else {
1059 *title = std::wstring();
1060 }
[email protected]71f65dd2009-02-11 19:14:561061 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291062 }
initial.commit09911bf2008-07-26 23:55:291063}
1064
[email protected]77bc6732009-04-20 22:01:031065void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1066 *tabstrip_index = -1; // -1 is the error code
1067
1068 if (tab_tracker_->ContainsHandle(handle)) {
1069 NavigationController* tab = tab_tracker_->GetResource(handle);
1070 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121071 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031072 }
1073}
1074
initial.commit09911bf2008-07-26 23:55:291075void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1076 if (window_tracker_->ContainsHandle(handle)) {
1077 window_tracker_->Remove(window_tracker_->GetResource(handle));
1078 }
1079}
1080
1081void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161082 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571083 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291084}
1085
1086// TODO(brettw) change this to accept GURLs when history supports it
1087void AutomationProvider::OnRedirectQueryComplete(
1088 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371089 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291090 bool success,
[email protected]379c2b12009-07-01 21:50:331091 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291092 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561093 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291094
[email protected]deb57402009-02-06 01:35:301095 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101096 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291097 if (success) {
initial.commit09911bf2008-07-26 23:55:291098 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301099 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291100 }
1101
[email protected]4f3dc372009-02-24 00:10:291102 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301103
[email protected]71f65dd2009-02-11 19:14:561104 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231105 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561106 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291107}
1108
1109bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571110 DCHECK(channel_.get());
1111 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291112}
1113
1114Browser* AutomationProvider::FindAndActivateTab(
1115 NavigationController* controller) {
1116 int tab_index;
1117 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1118 if (browser)
1119 browser->SelectTabContentsAt(tab_index, true);
1120
1121 return browser;
1122}
1123
[email protected]9eaa18e2010-06-29 20:51:011124namespace {
1125
1126class GetCookiesTask : public Task {
1127 public:
1128 GetCookiesTask(const GURL& url,
1129 URLRequestContextGetter* context_getter,
1130 base::WaitableEvent* event,
1131 std::string* cookies)
1132 : url_(url),
1133 context_getter_(context_getter),
1134 event_(event),
1135 cookies_(cookies) {}
1136
1137 virtual void Run() {
1138 *cookies_ = context_getter_->GetCookieStore()->GetCookies(url_);
1139 event_->Signal();
1140 }
1141
1142 private:
1143 const GURL& url_;
1144 URLRequestContextGetter* const context_getter_;
1145 base::WaitableEvent* const event_;
1146 std::string* const cookies_;
1147
1148 DISALLOW_COPY_AND_ASSIGN(GetCookiesTask);
1149};
1150
1151std::string GetCookiesForURL(
1152 const GURL& url,
1153 URLRequestContextGetter* context_getter) {
1154 std::string cookies;
1155 base::WaitableEvent event(true /* manual reset */,
1156 false /* not initially signaled */);
1157 CHECK(ChromeThread::PostTask(
1158 ChromeThread::IO, FROM_HERE,
1159 new GetCookiesTask(url, context_getter, &event, &cookies)));
1160 event.Wait();
1161 return cookies;
1162}
1163
1164class SetCookieTask : public Task {
1165 public:
1166 SetCookieTask(const GURL& url,
1167 const std::string& value,
1168 URLRequestContextGetter* context_getter,
1169 base::WaitableEvent* event,
1170 bool* rv)
1171 : url_(url),
1172 value_(value),
1173 context_getter_(context_getter),
1174 event_(event),
1175 rv_(rv) {}
1176
1177 virtual void Run() {
1178 *rv_ = context_getter_->GetCookieStore()->SetCookie(url_, value_);
1179 event_->Signal();
1180 }
1181
1182 private:
1183 const GURL& url_;
1184 const std::string& value_;
1185 URLRequestContextGetter* const context_getter_;
1186 base::WaitableEvent* const event_;
1187 bool* const rv_;
1188
1189 DISALLOW_COPY_AND_ASSIGN(SetCookieTask);
1190};
1191
1192bool SetCookieForURL(
1193 const GURL& url,
1194 const std::string& value,
1195 URLRequestContextGetter* context_getter) {
1196 base::WaitableEvent event(true /* manual reset */,
1197 false /* not initially signaled */);
1198 bool rv = false;
1199 CHECK(ChromeThread::PostTask(
1200 ChromeThread::IO, FROM_HERE,
1201 new SetCookieTask(url, value, context_getter, &event, &rv)));
1202 event.Wait();
1203 return rv;
1204}
1205
1206class DeleteCookieTask : public Task {
1207 public:
1208 DeleteCookieTask(const GURL& url,
1209 const std::string& name,
1210 const scoped_refptr<URLRequestContextGetter>& context_getter)
1211 : url_(url),
1212 name_(name),
1213 context_getter_(context_getter) {}
1214
1215 virtual void Run() {
1216 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
1217 cookie_store->DeleteCookie(url_, name_);
1218 }
1219
1220 private:
1221 const GURL url_;
1222 const std::string name_;
1223 const scoped_refptr<URLRequestContextGetter> context_getter_;
1224
1225 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
1226};
1227
1228} // namespace
1229
[email protected]71f65dd2009-02-11 19:14:561230void AutomationProvider::GetCookies(const GURL& url, int handle,
1231 int* value_size,
1232 std::string* value) {
1233 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291234 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1235 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311236
1237 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001238 scoped_refptr<URLRequestContextGetter> request_context =
1239 tab->tab_contents()->request_context();
1240 if (!request_context.get())
1241 request_context = tab->profile()->GetRequestContext();
1242
[email protected]9eaa18e2010-06-29 20:51:011243 *value = GetCookiesForURL(url, request_context.get());
[email protected]71f65dd2009-02-11 19:14:561244 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291245 }
initial.commit09911bf2008-07-26 23:55:291246}
1247
[email protected]71f65dd2009-02-11 19:14:561248void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291249 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561250 int handle,
1251 int* response_value) {
1252 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291253
1254 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1255 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311256
[email protected]dfa46e5f2009-11-17 18:48:431257 scoped_refptr<URLRequestContextGetter> request_context =
1258 tab->tab_contents()->request_context();
1259 if (!request_context.get())
1260 request_context = tab->profile()->GetRequestContext();
1261
[email protected]9eaa18e2010-06-29 20:51:011262 if (SetCookieForURL(url, value, request_context.get()))
[email protected]71f65dd2009-02-11 19:14:561263 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291264 }
initial.commit09911bf2008-07-26 23:55:291265}
1266
[email protected]5fa57942010-04-21 23:07:221267void AutomationProvider::DeleteCookie(const GURL& url,
1268 const std::string& cookie_name,
1269 int handle, bool* success) {
1270 *success = false;
1271 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1272 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]9eaa18e2010-06-29 20:51:011273 ChromeThread::PostTask(
1274 ChromeThread::IO, FROM_HERE,
1275 new DeleteCookieTask(url, cookie_name,
1276 tab->profile()->GetRequestContext()));
[email protected]5fa57942010-04-21 23:07:221277 *success = true;
1278 }
1279}
1280
[email protected]71f65dd2009-02-11 19:14:561281void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1282 *success = false;
initial.commit09911bf2008-07-26 23:55:291283 if (tab_tracker_->ContainsHandle(handle)) {
1284 NavigationController* tab = tab_tracker_->GetResource(handle);
1285 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541286 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561287 *success = true;
initial.commit09911bf2008-07-26 23:55:291288 }
initial.commit09911bf2008-07-26 23:55:291289}
1290
[email protected]71f65dd2009-02-11 19:14:561291void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1292 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291293
1294 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561295 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341296 TabContents* tab_contents =
1297 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161298 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1299 if (rph)
1300 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291301 }
initial.commit09911bf2008-07-26 23:55:291302}
1303
1304void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331305 NOTREACHED() << "This function has been deprecated. "
1306 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291307}
1308
[email protected]71f65dd2009-02-11 19:14:561309void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291310 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561311 const std::wstring& script,
1312 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291313 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341314 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1315 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571316 // Set the routing id of this message with the controller.
1317 // This routing id needs to be remembered for the reverse
1318 // communication while sending back the response of
1319 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331320 std::wstring set_automation_id;
1321 SStringPrintf(&set_automation_id,
1322 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561323 reply_message->routing_id());
1324
1325 DCHECK(reply_message_ == NULL);
1326 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291327
[email protected]57c6a652009-05-04 07:58:341328 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331329 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341330 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061331 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571332 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291333 }
1334
1335 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561336 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1337 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291338 }
1339}
1340
[email protected]71f65dd2009-02-11 19:14:561341void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1342 *visible = false;
[email protected]20e93d12008-08-28 16:31:571343
[email protected]59560e0b2009-06-04 03:30:221344 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251345#if defined(OS_CHROMEOS)
1346 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1347 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1348 for (BrowserList::const_iterator it = BrowserList::begin();
1349 it != BrowserList::end(); ++it) {
1350 if ((*it)->type() == Browser::TYPE_POPUP) {
1351 const GURL& url =
1352 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1353
1354 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1355 url.host() == chrome::kChromeUIFileBrowseHost) {
1356 *visible = true;
1357 break;
1358 }
1359 }
1360 }
1361#else
[email protected]59560e0b2009-06-04 03:30:221362 Browser* browser = browser_tracker_->GetResource(handle);
1363 if (browser) {
1364 *visible = browser->window()->IsDownloadShelfVisible();
1365 }
[email protected]f5bf8ccf2010-02-05 18:19:251366#endif
[email protected]59560e0b2009-06-04 03:30:221367 }
initial.commit09911bf2008-07-26 23:55:291368}
1369
[email protected]59560e0b2009-06-04 03:30:221370void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1371 if (browser_tracker_->ContainsHandle(handle)) {
1372 Browser* browser = browser_tracker_->GetResource(handle);
1373 if (browser) {
1374 if (visible)
1375 browser->window()->GetDownloadShelf()->Show();
1376 else
1377 browser->window()->GetDownloadShelf()->Close();
1378 }
1379 }
1380}
1381
[email protected]34930432009-11-09 00:12:091382void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1383 *visible = false;
1384
1385 if (browser_tracker_->ContainsHandle(handle)) {
1386 Browser* browser = browser_tracker_->GetResource(handle);
1387 if (browser)
1388 *visible = browser->window()->IsFullscreen();
1389 }
1390}
1391
1392void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1393 bool* visible) {
1394 *visible = false;
1395
1396 if (browser_tracker_->ContainsHandle(handle)) {
1397 Browser* browser = browser_tracker_->GetResource(handle);
1398 if (browser)
1399 *visible = browser->window()->IsFullscreenBubbleVisible();
1400 }
1401}
[email protected]59560e0b2009-06-04 03:30:221402
[email protected]71f65dd2009-02-11 19:14:561403void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1404 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291405 if (tab_tracker_->ContainsHandle(handle)) {
1406 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111407 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291408 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561409 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291410 }
1411 }
initial.commit09911bf2008-07-26 23:55:291412}
1413
initial.commit09911bf2008-07-26 23:55:291414void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561415 int handle, const std::wstring& find_request,
1416 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311417 NOTREACHED() << "This function has been deprecated."
1418 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561419 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311420 return;
1421}
1422
[email protected]4f999132009-03-31 18:08:401423void AutomationProvider::HandleFindRequest(
1424 int handle,
1425 const AutomationMsg_Find_Params& params,
1426 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291427 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561428 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1429 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291430 return;
1431 }
1432
1433 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111434 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291435
1436 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141437 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291438
[email protected]57c6a652009-05-04 07:58:341439 tab_contents->set_current_find_request_id(
1440 FindInPageNotificationObserver::kFindInPageRequestId);
1441 tab_contents->render_view_host()->StartFinding(
1442 FindInPageNotificationObserver::kFindInPageRequestId,
1443 params.search_string, params.forward, params.match_case,
1444 params.find_next);
initial.commit09911bf2008-07-26 23:55:291445}
1446
[email protected]5f8af2a2008-08-06 22:49:451447void AutomationProvider::HandleOpenFindInPageRequest(
1448 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291449 if (browser_tracker_->ContainsHandle(handle)) {
1450 Browser* browser = browser_tracker_->GetResource(handle);
1451 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451452 }
1453}
1454
[email protected]71f65dd2009-02-11 19:14:561455void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561456 *visible = false;
[email protected]855c0142009-09-28 22:35:241457 Browser* browser = browser_tracker_->GetResource(handle);
1458 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581459 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171460 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241461 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291462 }
[email protected]20e93d12008-08-28 16:31:571463}
1464
[email protected]71f65dd2009-02-11 19:14:561465void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1466 int* y) {
[email protected]9e0534b2008-10-21 15:03:011467 gfx::Point position(0, 0);
1468 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291469 if (browser_tracker_->ContainsHandle(handle)) {
1470 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581471 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171472 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581473 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291474 }
[email protected]20e93d12008-08-28 16:31:571475
[email protected]71f65dd2009-02-11 19:14:561476 *x = position.x();
1477 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571478}
1479
[email protected]4512cb52010-04-05 19:50:251480// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1481// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581482void AutomationProvider::GetBookmarkBarVisibility(int handle,
1483 bool* visible,
1484 bool* animating) {
1485 *visible = false;
1486 *animating = false;
1487
1488 if (browser_tracker_->ContainsHandle(handle)) {
1489 Browser* browser = browser_tracker_->GetResource(handle);
1490 if (browser) {
[email protected]472f099b2010-05-27 17:07:121491#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1492 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1493
[email protected]ab6ca392010-04-07 00:44:131494 // IsBookmarkBarVisible() line looks correct but is not
1495 // consistent across platforms. Specifically, on Mac/Linux, it
1496 // returns false if the bar is hidden in a pref (even if visible
1497 // on the NTP). On ChromeOS, it returned true if on NTP
1498 // independent of the pref. Making the code more consistent
1499 // caused a perf bot regression on Windows (which shares views).
1500 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251501 *visible = browser->profile()->GetPrefs()->GetBoolean(
1502 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401503#else
1504 *visible = browser->window()->IsBookmarkBarVisible();
1505#endif
[email protected]c3240722010-03-05 21:52:581506 *animating = browser->window()->IsBookmarkBarAnimating();
1507 }
1508 }
1509}
1510
[email protected]6d8ffc9f2010-03-12 18:27:531511void AutomationProvider::GetBookmarksAsJSON(int handle,
1512 std::string* bookmarks_as_json,
1513 bool *success) {
1514 *success = false;
1515 if (browser_tracker_->ContainsHandle(handle)) {
1516 Browser* browser = browser_tracker_->GetResource(handle);
1517 if (browser) {
1518 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1519 return;
1520 }
1521 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1522 browser->profile(),
1523 browser->profile()->GetBookmarkModel());
1524 *success = storage->SerializeData(bookmarks_as_json);
1525 }
1526 }
1527}
1528
1529void AutomationProvider::WaitForBookmarkModelToLoad(
1530 int handle,
1531 IPC::Message* reply_message) {
1532 if (browser_tracker_->ContainsHandle(handle)) {
1533 Browser* browser = browser_tracker_->GetResource(handle);
1534 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1535 if (model->IsLoaded()) {
1536 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1537 reply_message, true);
1538 Send(reply_message);
1539 } else {
1540 // The observer will delete itself when done.
1541 new AutomationProviderBookmarkModelObserver(this, reply_message,
1542 model);
1543 }
1544 }
1545}
1546
1547void AutomationProvider::AddBookmarkGroup(int handle,
1548 int64 parent_id, int index,
1549 std::wstring title,
1550 bool* success) {
1551 if (browser_tracker_->ContainsHandle(handle)) {
1552 Browser* browser = browser_tracker_->GetResource(handle);
1553 if (browser) {
1554 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1555 if (!model->IsLoaded()) {
1556 *success = false;
1557 return;
1558 }
1559 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1560 DCHECK(parent);
1561 if (parent) {
1562 const BookmarkNode* child = model->AddGroup(parent, index,
1563 WideToUTF16(title));
1564 DCHECK(child);
1565 if (child)
1566 *success = true;
1567 }
1568 }
1569 }
1570 *success = false;
1571}
1572
1573void AutomationProvider::AddBookmarkURL(int handle,
1574 int64 parent_id, int index,
1575 std::wstring title, const GURL& url,
1576 bool* success) {
1577 if (browser_tracker_->ContainsHandle(handle)) {
1578 Browser* browser = browser_tracker_->GetResource(handle);
1579 if (browser) {
1580 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1581 if (!model->IsLoaded()) {
1582 *success = false;
1583 return;
1584 }
1585 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1586 DCHECK(parent);
1587 if (parent) {
1588 const BookmarkNode* child = model->AddURL(parent, index,
1589 WideToUTF16(title), url);
1590 DCHECK(child);
1591 if (child)
1592 *success = true;
1593 }
1594 }
1595 }
1596 *success = false;
1597}
1598
1599void AutomationProvider::ReparentBookmark(int handle,
1600 int64 id, int64 new_parent_id,
1601 int index,
1602 bool* success) {
1603 if (browser_tracker_->ContainsHandle(handle)) {
1604 Browser* browser = browser_tracker_->GetResource(handle);
1605 if (browser) {
1606 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1607 if (!model->IsLoaded()) {
1608 *success = false;
1609 return;
1610 }
1611 const BookmarkNode* node = model->GetNodeByID(id);
1612 DCHECK(node);
1613 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1614 DCHECK(new_parent);
1615 if (node && new_parent) {
1616 model->Move(node, new_parent, index);
1617 *success = true;
1618 }
1619 }
1620 }
1621 *success = false;
1622}
1623
1624void AutomationProvider::SetBookmarkTitle(int handle,
1625 int64 id, std::wstring title,
1626 bool* success) {
1627 if (browser_tracker_->ContainsHandle(handle)) {
1628 Browser* browser = browser_tracker_->GetResource(handle);
1629 if (browser) {
1630 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1631 if (!model->IsLoaded()) {
1632 *success = false;
1633 return;
1634 }
1635 const BookmarkNode* node = model->GetNodeByID(id);
1636 DCHECK(node);
1637 if (node) {
1638 model->SetTitle(node, WideToUTF16(title));
1639 *success = true;
1640 }
1641 }
1642 }
1643 *success = false;
1644}
1645
1646void AutomationProvider::SetBookmarkURL(int handle,
1647 int64 id, const GURL& url,
1648 bool* success) {
1649 if (browser_tracker_->ContainsHandle(handle)) {
1650 Browser* browser = browser_tracker_->GetResource(handle);
1651 if (browser) {
1652 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1653 if (!model->IsLoaded()) {
1654 *success = false;
1655 return;
1656 }
1657 const BookmarkNode* node = model->GetNodeByID(id);
1658 DCHECK(node);
1659 if (node) {
1660 model->SetURL(node, url);
1661 *success = true;
1662 }
1663 }
1664 }
1665 *success = false;
1666}
1667
1668void AutomationProvider::RemoveBookmark(int handle,
1669 int64 id,
1670 bool* success) {
1671 if (browser_tracker_->ContainsHandle(handle)) {
1672 Browser* browser = browser_tracker_->GetResource(handle);
1673 if (browser) {
1674 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1675 if (!model->IsLoaded()) {
1676 *success = false;
1677 return;
1678 }
1679 const BookmarkNode* node = model->GetNodeByID(id);
1680 DCHECK(node);
1681 if (node) {
1682 const BookmarkNode* parent = node->GetParent();
1683 DCHECK(parent);
1684 model->Remove(parent, parent->IndexOfChild(node));
1685 *success = true;
1686 }
1687 }
1688 }
1689 *success = false;
1690}
1691
[email protected]ef413ca2010-05-25 21:09:141692// Sample json input: { "command": "SetWindowDimensions",
1693// "x": 20, # optional
1694// "y": 20, # optional
1695// "width": 800, # optional
1696// "height": 600 } # optional
1697void AutomationProvider::SetWindowDimensions(Browser* browser,
1698 DictionaryValue* args,
1699 IPC::Message* reply_message) {
1700 gfx::Rect rect = browser->window()->GetRestoredBounds();
1701 int x, y, width, height;
1702 if (args->GetInteger(L"x", &x))
1703 rect.set_x(x);
1704 if (args->GetInteger(L"y", &y))
1705 rect.set_y(y);
1706 if (args->GetInteger(L"width", &width))
1707 rect.set_width(width);
1708 if (args->GetInteger(L"height", &height))
1709 rect.set_height(height);
1710 browser->window()->SetBounds(rect);
1711 AutomationMsg_SendJSONRequest::WriteReplyParams(
1712 reply_message, std::string("{}"), true);
1713 Send(reply_message);
1714}
1715
[email protected]a9ff2c02010-05-13 17:33:051716// Sample json input: { "command": "GetBrowserInfo" }
1717// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1718// sample json output.
[email protected]53329582010-05-14 21:10:581719void AutomationProvider::GetBrowserInfo(Browser* browser,
1720 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051721 IPC::Message* reply_message) {
1722 std::string json_return;
1723 bool reply_return = true;
1724
1725 DictionaryValue* properties = new DictionaryValue;
1726 properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
1727 properties->SetString(L"BrowserProcessExecutableName",
1728 chrome::kBrowserProcessExecutableName);
1729 properties->SetString(L"HelperProcessExecutableName",
1730 chrome::kHelperProcessExecutableName);
1731 properties->SetString(L"BrowserProcessExecutablePath",
1732 chrome::kBrowserProcessExecutablePath);
1733 properties->SetString(L"HelperProcessExecutablePath",
1734 chrome::kHelperProcessExecutablePath);
[email protected]a9ff2c02010-05-13 17:33:051735 properties->SetString(L"command_line_string",
1736 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001737
1738 std::string branding;
1739#if defined(GOOGLE_CHROME_BUILD)
1740 branding = "Google Chrome";
1741#elif defined(CHROMIUM_BUILD)
1742 branding = "Chromium";
1743#else
1744 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051745#endif
[email protected]44eed9f2010-06-28 22:04:001746 properties->SetString(L"branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051747
1748 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1749 return_value->Set(L"properties", properties);
1750
[email protected]ef413ca2010-05-25 21:09:141751 return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
1752 // Add info about all windows in a list of dictionaries, one dictionary
1753 // item per window.
1754 ListValue* windows = new ListValue;
1755 int windex = 0;
1756 for (BrowserList::const_iterator it = BrowserList::begin();
1757 it != BrowserList::end();
1758 ++it, ++windex) {
1759 DictionaryValue* browser_item = new DictionaryValue;
1760 browser = *it;
1761 browser_item->SetInteger(L"index", windex);
1762 // Window properties
1763 gfx::Rect rect = browser->window()->GetRestoredBounds();
1764 browser_item->SetInteger(L"x", rect.x());
1765 browser_item->SetInteger(L"y", rect.y());
1766 browser_item->SetInteger(L"width", rect.width());
1767 browser_item->SetInteger(L"height", rect.height());
1768 browser_item->SetBoolean(L"fullscreen",
1769 browser->window()->IsFullscreen());
1770 browser_item->SetInteger(L"selected_tab", browser->selected_index());
1771 browser_item->SetBoolean(L"incognito",
1772 browser->profile()->IsOffTheRecord());
1773 // For each window, add info about all tabs in a list of dictionaries,
1774 // one dictionary item per tab.
1775 ListValue* tabs = new ListValue;
1776 for (int i = 0; i < browser->tab_count(); ++i) {
1777 TabContents* tc = browser->GetTabContentsAt(i);
1778 DictionaryValue* tab = new DictionaryValue;
1779 tab->SetInteger(L"index", i);
1780 tab->SetString(L"url", tc->GetURL().spec());
1781 tab->SetInteger(L"renderer_pid",
1782 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
1783 tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
1784 tabs->Append(tab);
1785 }
1786 browser_item->Set(L"tabs", tabs);
1787
1788 windows->Append(browser_item);
1789 }
1790 return_value->Set(L"windows", windows);
1791
1792 return_value->SetString(L"child_process_path",
1793 ChildProcessHost::GetChildPath(true).value());
1794 // Child processes are the processes for plugins and other workers.
1795 // Add all child processes in a list of dictionaries, one dictionary item
1796 // per child process.
1797 ListValue* child_processes = new ListValue;
1798 for (ChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1799 // Only add processes which are already started, since we need their handle.
1800 if ((*iter)->handle() != base::kNullProcessHandle) {
1801 ChildProcessInfo* info = *iter;
1802 DictionaryValue* item = new DictionaryValue;
1803 item->SetString(L"name", info->name());
1804 item->SetString(L"type",
1805 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
1806 item->SetInteger(L"pid", base::GetProcId(info->handle()));
1807 child_processes->Append(item);
1808 }
1809 }
1810 return_value->Set(L"child_processes", child_processes);
1811
1812 // Add all extension processes in a list of dictionaries, one dictionary
1813 // item per extension process.
1814 ListValue* extension_processes = new ListValue;
1815 ProfileManager* profile_manager = g_browser_process->profile_manager();
1816 for (ProfileManager::const_iterator it = profile_manager->begin();
1817 it != profile_manager->end(); ++it) {
1818 ExtensionProcessManager* process_manager =
1819 (*it)->GetExtensionProcessManager();
1820 ExtensionProcessManager::const_iterator jt;
1821 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1822 ExtensionHost* ex_host = *jt;
1823 // Don't add dead extension processes.
1824 if (!ex_host->IsRenderViewLive())
1825 continue;
1826 DictionaryValue* item = new DictionaryValue;
1827 item->SetString(L"name", ex_host->extension()->name());
1828 item->SetInteger(
1829 L"pid",
1830 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1831 extension_processes->Append(item);
1832 }
1833 }
1834 return_value->Set(L"extension_processes", extension_processes);
1835
[email protected]a9ff2c02010-05-13 17:33:051836 base::JSONWriter::Write(return_value.get(), false, &json_return);
1837 AutomationMsg_SendJSONRequest::WriteReplyParams(
1838 reply_message, json_return, reply_return);
1839 Send(reply_message);
1840}
1841
[email protected]24e2b102010-04-29 17:56:471842// Sample json input: { "command": "GetHistoryInfo",
1843// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361844// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581845void AutomationProvider::GetHistoryInfo(Browser* browser,
1846 DictionaryValue* args,
1847 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361848 consumer_.CancelAllRequests();
1849
[email protected]e53668962010-06-23 15:35:251850 string16 search_text;
1851 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:361852
1853 // Fetch history.
1854 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1855 history::QueryOptions options;
1856 // The observer owns itself. It deletes itself after it fetches history.
1857 AutomationProviderHistoryObserver* history_observer =
1858 new AutomationProviderHistoryObserver(this, reply_message);
1859 hs->QueryHistory(
1860 search_text,
1861 options,
1862 &consumer_,
1863 NewCallback(history_observer,
1864 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1865}
1866
[email protected]bbe6aa02010-05-07 17:27:291867// Sample json input: { "command": "AddHistoryItem",
1868// "item": { "URL": "http://www.google.com",
1869// "title": "Google", # optional
1870// "time": 12345 # optional (time_t)
1871// } }
1872// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581873void AutomationProvider::AddHistoryItem(Browser* browser,
1874 DictionaryValue* args,
1875 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:291876 bool reply_return = true;
1877 std::string json_return = "{}";
1878
1879 DictionaryValue* item = NULL;
1880 args->GetDictionary(L"item", &item);
1881 string16 url_text;
[email protected]e53668962010-06-23 15:35:251882 string16 title;
[email protected]bbe6aa02010-05-07 17:27:291883 base::Time time = base::Time::Now();
1884
1885 if (item->GetString("url", &url_text)) {
1886 GURL gurl(url_text);
[email protected]e53668962010-06-23 15:35:251887 item->GetString("title", &title); // Don't care if it fails.
[email protected]bbe6aa02010-05-07 17:27:291888 int it;
1889 double dt;
1890 if (item->GetInteger(L"time", &it))
1891 time = base::Time::FromTimeT(it);
1892 else if (item->GetReal(L"time", &dt))
1893 time = base::Time::FromDoubleT(dt);
1894
1895 // Ideas for "dummy" values (e.g. id_scope) came from
1896 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1897 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1898 const void* id_scope = reinterpret_cast<void*>(1);
1899 hs->AddPage(gurl, time,
1900 id_scope,
1901 0,
1902 GURL(),
1903 PageTransition::LINK,
1904 history::RedirectList(),
1905 false);
[email protected]e53668962010-06-23 15:35:251906 if (title.length())
[email protected]bbe6aa02010-05-07 17:27:291907 hs->SetPageTitle(gurl, title);
[email protected]bbe6aa02010-05-07 17:27:291908 } else {
[email protected]7060bb292010-06-24 00:52:491909 json_return = JSONErrorString("bad args (no URL in dict?)");
[email protected]bbe6aa02010-05-07 17:27:291910 reply_return = false;
1911 }
1912
1913 AutomationMsg_SendJSONRequest::WriteReplyParams(
1914 reply_message, json_return, reply_return);
1915 Send(reply_message);
1916}
1917
[email protected]24e2b102010-04-29 17:56:471918// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361919// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581920void AutomationProvider::GetDownloadsInfo(Browser* browser,
1921 DictionaryValue* args,
1922 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:391923 std::string json_return;
1924 bool reply_return = true;
1925 AutomationProviderDownloadManagerObserver observer;
1926 std::vector<DownloadItem*> downloads;
1927 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1928
1929 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7060bb292010-06-24 00:52:491930 json_return = JSONErrorString("no download manager");
[email protected]d4adc292010-04-15 18:06:391931 reply_return = false;
1932 } else {
1933 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1934 // since that would be transient; a download might enter and empty out
1935 // the current download queue too soon to be noticed.
1936 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1937 downloads = observer.Downloads();
1938 }
1939
1940 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1941 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1942 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1943 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1944 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1945
1946 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1947 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1948 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1949 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1950 std::string("DANGEROUS_BUT_VALIDATED");
1951
1952 ListValue* list_of_downloads = new ListValue;
1953 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1954 it != downloads.end();
1955 it++) { // Fill info about each download item.
1956 DictionaryValue* dl_item_value = new DictionaryValue;
1957 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1958 dl_item_value->SetString(L"url", (*it)->url().spec());
1959 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1960 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1961 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
1962 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
1963 dl_item_value->SetBoolean(L"open_when_complete",
1964 (*it)->open_when_complete());
1965 dl_item_value->SetBoolean(L"is_extension_install",
1966 (*it)->is_extension_install());
1967 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
1968 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
1969 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
1970 dl_item_value->SetString(L"safety_state",
1971 safety_state_to_string[(*it)->safety_state()]);
1972 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
1973 list_of_downloads->Append(dl_item_value);
1974 }
1975 return_value->Set(L"downloads", list_of_downloads);
1976 base::JSONWriter::Write(return_value.get(), false, &json_return);
1977
1978 AutomationMsg_SendJSONRequest::WriteReplyParams(
1979 reply_message, json_return, reply_return);
1980 Send(reply_message);
1981 // All value objects allocated above are owned by |return_value|
1982 // and get freed by it.
1983}
1984
[email protected]59a611242010-04-02 02:24:041985void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:581986 Browser* browser,
[email protected]59a611242010-04-02 02:24:041987 DictionaryValue* args,
1988 IPC::Message* reply_message) {
1989 std::string json_return;
1990 bool reply_return = true;
1991 AutomationProviderDownloadManagerObserver observer;
1992 std::vector<DownloadItem*> downloads;
1993
1994 // Look for a quick return.
1995 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7060bb292010-06-24 00:52:491996 json_return = JSONErrorString("no download manager");
[email protected]59a611242010-04-02 02:24:041997 reply_return = false;
1998 } else {
1999 profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
2000 FilePath());
2001 downloads = observer.Downloads();
2002 if (downloads.size() == 0) {
2003 json_return = "{}";
2004 }
2005 }
2006 if (!json_return.empty()) {
2007 AutomationMsg_SendJSONRequest::WriteReplyParams(
2008 reply_message, json_return, reply_return);
2009 Send(reply_message);
2010 }
2011
2012 // The observer owns itself. When the last observed item pings, it
2013 // deletes itself.
2014 AutomationProviderDownloadItemObserver* item_observer =
2015 new AutomationProviderDownloadItemObserver(
2016 this, reply_message, downloads.size());
2017 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2018 i != downloads.end();
2019 i++) {
2020 (*i)->AddObserver(item_observer);
2021 }
2022}
2023
[email protected]24e2b102010-04-29 17:56:472024// Sample json input: { "command": "GetPrefsInfo" }
2025// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582026void AutomationProvider::GetPrefsInfo(Browser* browser,
2027 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472028 IPC::Message* reply_message) {
2029 std::string json_return;
2030 bool reply_return = true;
2031
2032 const PrefService::PreferenceSet& prefs =
2033 profile_->GetPrefs()->preference_set();
2034 DictionaryValue* items = new DictionaryValue;
2035 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
2036 it != prefs.end(); ++it) {
2037 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
2038 }
2039 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2040 return_value->Set(L"prefs", items); // return_value owns items.
2041
2042 base::JSONWriter::Write(return_value.get(), false, &json_return);
2043 AutomationMsg_SendJSONRequest::WriteReplyParams(
2044 reply_message, json_return, reply_return);
2045 Send(reply_message);
2046}
2047
2048// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:582049void AutomationProvider::SetPrefs(Browser* browser,
2050 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472051 IPC::Message* reply_message) {
2052 bool reply_return = true;
2053 std::string json_return = "{}";
2054 std::wstring path;
2055 Value* val;
2056 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
2057 PrefService* pref_service = profile_->GetPrefs();
2058 const PrefService::Preference* pref =
2059 pref_service->FindPreference(path.c_str());
2060 if (!pref) { // Not a registered pref.
[email protected]7060bb292010-06-24 00:52:492061 json_return = JSONErrorString("pref not registered.");
[email protected]24e2b102010-04-29 17:56:472062 reply_return = false;
2063 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7060bb292010-06-24 00:52:492064 json_return = JSONErrorString("pref is managed. cannot be changed.");
[email protected]24e2b102010-04-29 17:56:472065 reply_return = false;
2066 } else { // Set the pref.
2067 pref_service->Set(path.c_str(), *val);
2068 }
2069 } else {
[email protected]7060bb292010-06-24 00:52:492070 json_return = JSONErrorString("no pref path or value given.");
[email protected]24e2b102010-04-29 17:56:472071 reply_return = false;
2072 }
2073
2074 AutomationMsg_SendJSONRequest::WriteReplyParams(
2075 reply_message, json_return, reply_return);
2076 Send(reply_message);
2077}
2078
[email protected]53329582010-05-14 21:10:582079// Sample json input: { "command": "GetOmniboxInfo" }
2080// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
2081void AutomationProvider::GetOmniboxInfo(Browser* browser,
2082 DictionaryValue* args,
2083 IPC::Message* reply_message) {
2084 std::string json_return;
2085 bool reply_return = true;
2086 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2087
2088 LocationBar* loc_bar = browser->window()->GetLocationBar();
2089 AutocompleteEditView* edit_view = loc_bar->location_entry();
2090 AutocompleteEditModel* model = edit_view->model();
2091
2092 // Fill up matches.
2093 ListValue* matches = new ListValue;
2094 const AutocompleteResult& result = model->result();
2095 for (AutocompleteResult::const_iterator i = result.begin();
2096 i != result.end(); ++i) {
2097 const AutocompleteMatch& match = *i;
2098 DictionaryValue* item = new DictionaryValue; // owned by return_value
2099 item->SetString(L"type", AutocompleteMatch::TypeToString(match.type));
2100 item->SetBoolean(L"starred", match.starred);
2101 item->SetString(L"destination_url", match.destination_url.spec());
2102 item->SetString(L"contents", match.contents);
2103 item->SetString(L"description", match.description);
2104 matches->Append(item);
2105 }
2106 return_value->Set(L"matches", matches);
2107
2108 // Fill up other properties.
2109 DictionaryValue* properties = new DictionaryValue; // owned by return_value
2110 properties->SetBoolean(L"has_focus", model->has_focus());
2111 properties->SetBoolean(L"query_in_progress", model->query_in_progress());
2112 properties->SetString(L"keyword", model->keyword());
2113 properties->SetString(L"text", edit_view->GetText());
2114 return_value->Set(L"properties", properties);
2115
2116 base::JSONWriter::Write(return_value.get(), false, &json_return);
2117 AutomationMsg_SendJSONRequest::WriteReplyParams(
2118 reply_message, json_return, reply_return);
2119 Send(reply_message);
2120}
2121
2122// Sample json input: { "command": "SetOmniboxText",
2123// "text": "goog" }
2124void AutomationProvider::SetOmniboxText(Browser* browser,
2125 DictionaryValue* args,
2126 IPC::Message* reply_message) {
2127 std::string json_return = "{}";
2128 bool reply_return = true;
2129 std::wstring text;
2130
2131 if (!args->GetString(L"text", &text)) {
[email protected]7060bb292010-06-24 00:52:492132 json_return = JSONErrorString("text missing");
[email protected]53329582010-05-14 21:10:582133 reply_return = false;
2134 } else {
2135 browser->FocusLocationBar();
2136 LocationBar* loc_bar = browser->window()->GetLocationBar();
2137 AutocompleteEditView* edit_view = loc_bar->location_entry();
2138 edit_view->model()->OnSetFocus(false);
2139 edit_view->SetUserText(text);
2140 }
2141
2142 AutomationMsg_SendJSONRequest::WriteReplyParams(
2143 reply_message, json_return, reply_return);
2144 Send(reply_message);
2145}
2146
2147// Sample json input: { "command": "OmniboxMovePopupSelection",
2148// "count": 1 }
2149// Negative count implies up, positive implies down. Count values will be
2150// capped by the size of the popup list.
2151void AutomationProvider::OmniboxMovePopupSelection(
2152 Browser* browser,
2153 DictionaryValue* args,
2154 IPC::Message* reply_message) {
2155 std::string json_return = "{}";
2156 bool reply_return = true;
2157 int count;
2158
2159 if (!args->GetInteger(L"count", &count)) {
[email protected]7060bb292010-06-24 00:52:492160 json_return = JSONErrorString("count missing");
[email protected]53329582010-05-14 21:10:582161 reply_return = false;
2162 } else {
2163 LocationBar* loc_bar = browser->window()->GetLocationBar();
2164 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2165 model->OnUpOrDownKeyPressed(count);
2166 }
2167
2168 AutomationMsg_SendJSONRequest::WriteReplyParams(
2169 reply_message, json_return, reply_return);
2170 Send(reply_message);
2171}
2172
2173// Sample json input: { "command": "OmniboxAcceptInput" }
2174void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2175 DictionaryValue* args,
2176 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282177 NavigationController& controller =
2178 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122179 // Setup observer to wait until the selected item loads.
2180 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282181 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122182 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582183
2184 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582185}
2186
[email protected]a3cd5022010-06-16 18:25:292187// Sample json input: { "command": "GetInitialLoadTimes" }
2188// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2189void AutomationProvider::GetInitialLoadTimes(
2190 Browser*,
2191 DictionaryValue*,
2192 IPC::Message* reply_message) {
2193 scoped_ptr<DictionaryValue> return_value(
2194 initial_load_observer_->GetTimingInformation());
2195
2196 std::string json_return;
2197 base::JSONWriter::Write(return_value.get(), false, &json_return);
2198 AutomationMsg_SendJSONRequest::WriteReplyParams(
2199 reply_message, json_return, true);
2200 Send(reply_message);
2201}
2202
[email protected]f7d48012010-05-06 08:17:052203// Sample json input: { "command": "GetPluginsInfo" }
2204// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582205void AutomationProvider::GetPluginsInfo(Browser* browser,
2206 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052207 IPC::Message* reply_message) {
2208 std::string json_return;
2209 bool reply_return = true;
2210
2211 std::vector<WebPluginInfo> plugins;
2212 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2213 ListValue* items = new ListValue;
2214 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2215 it != plugins.end();
2216 ++it) {
2217 DictionaryValue* item = new DictionaryValue;
[email protected]c9d811372010-06-23 21:44:572218 item->SetStringFromUTF16(L"name", it->name);
[email protected]f7d48012010-05-06 08:17:052219 item->SetString(L"path", it->path.value());
[email protected]c9d811372010-06-23 21:44:572220 item->SetStringFromUTF16(L"version", it->version);
2221 item->SetStringFromUTF16(L"desc", it->desc);
[email protected]f7d48012010-05-06 08:17:052222 item->SetBoolean(L"enabled", it->enabled);
2223 // Add info about mime types.
2224 ListValue* mime_types = new ListValue();
2225 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2226 it->mime_types.begin();
2227 type_it != it->mime_types.end();
2228 ++type_it) {
2229 DictionaryValue* mime_type = new DictionaryValue();
2230 mime_type->SetString(L"mimeType", type_it->mime_type);
[email protected]c9d811372010-06-23 21:44:572231 mime_type->SetStringFromUTF16(L"description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052232
2233 ListValue* file_extensions = new ListValue();
2234 for (std::vector<std::string>::const_iterator ext_it =
2235 type_it->file_extensions.begin();
2236 ext_it != type_it->file_extensions.end();
2237 ++ext_it) {
2238 file_extensions->Append(new StringValue(*ext_it));
2239 }
2240 mime_type->Set(L"fileExtensions", file_extensions);
2241
2242 mime_types->Append(mime_type);
2243 }
2244 item->Set(L"mimeTypes", mime_types);
2245 items->Append(item);
2246 }
2247 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2248 return_value->Set(L"plugins", items); // return_value owns items.
2249
2250 base::JSONWriter::Write(return_value.get(), false, &json_return);
2251 AutomationMsg_SendJSONRequest::WriteReplyParams(
2252 reply_message, json_return, reply_return);
2253 Send(reply_message);
2254}
2255
2256// Sample json input:
2257// { "command": "EnablePlugin",
2258// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582259void AutomationProvider::EnablePlugin(Browser* browser,
2260 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052261 IPC::Message* reply_message) {
2262 std::string json_return = "{}";
2263 bool reply_return = true;
2264 FilePath::StringType path;
2265 if (!args->GetString(L"path", &path)) {
[email protected]7060bb292010-06-24 00:52:492266 json_return = JSONErrorString("path not specified.");
[email protected]f7d48012010-05-06 08:17:052267 reply_return = false;
2268 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
2269 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2270 " for path %s.\"}", path.c_str());
2271 reply_return = false;
2272 }
2273
2274 AutomationMsg_SendJSONRequest::WriteReplyParams(
2275 reply_message, json_return, reply_return);
2276 Send(reply_message);
2277}
2278
2279// Sample json input:
2280// { "command": "DisablePlugin",
2281// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582282void AutomationProvider::DisablePlugin(Browser* browser,
2283 DictionaryValue* args,
2284 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052285 std::string json_return = "{}";
2286 bool reply_return = true;
2287 FilePath::StringType path;
2288 if (!args->GetString(L"path", &path)) {
[email protected]7060bb292010-06-24 00:52:492289 json_return = JSONErrorString("path not specified.");
[email protected]f7d48012010-05-06 08:17:052290 reply_return = false;
2291 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
2292 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2293 " for path %s.\"}", path.c_str());
2294 reply_return = false;
2295 }
2296
2297 AutomationMsg_SendJSONRequest::WriteReplyParams(
2298 reply_message, json_return, reply_return);
2299 Send(reply_message);
2300}
2301
[email protected]7060bb292010-06-24 00:52:492302// Sample json input:
2303// { "command": "SaveTabContents",
2304// "tab_index": 0,
2305// "filename": <a full pathname> }
2306// Sample json output:
2307// {}
2308void AutomationProvider::SaveTabContents(Browser* browser,
2309 DictionaryValue* args,
2310 IPC::Message* reply_message) {
2311 std::string json_return;
2312 int tab_index = 0;
2313 FilePath::StringType filename;
2314 FilePath::StringType parent_directory;
2315 TabContents* tab_contents = NULL;
2316
2317 if (!args->GetInteger(L"tab_index", &tab_index) ||
2318 !args->GetString(L"filename", &filename)) {
2319 json_return = JSONErrorString("tab_index or filename param missing");
2320 } else {
2321 tab_contents = browser->GetTabContentsAt(tab_index);
2322 if (!tab_contents) {
2323 json_return = JSONErrorString("no tab at tab_index");
2324 }
2325 }
2326 if (tab_contents) {
2327 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2328 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2329 parent_directory = FilePath(filename).DirName().value();
2330 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2331 SavePackage::SAVE_AS_ONLY_HTML)) {
2332 json_return = JSONErrorString("Could not initiate SavePage");
2333 } else {
2334 // The observer will delete itself when done.
2335 new SavePackageNotificationObserver(tab_contents->save_package(),
2336 this, reply_message);
2337 return;
2338 }
2339 }
2340
[email protected]93364da2010-06-29 18:03:442341 // If we get here, error.
[email protected]7060bb292010-06-24 00:52:492342 DCHECK(!json_return.empty());
2343 AutomationMsg_SendJSONRequest::WriteReplyParams(
2344 reply_message, json_return, false);
2345 Send(reply_message);
2346}
2347
[email protected]93364da2010-06-29 18:03:442348/* static */
2349std::string AutomationProvider::JSONErrorString(const std::string& err) {
2350 std::string prefix = "{\"error\": \"";
2351 std::string no_quote_err;
2352 std::string suffix = "\"}";
2353
2354 base::JsonDoubleQuote(err, false, &no_quote_err);
2355 return prefix + no_quote_err + suffix;
2356}
2357
[email protected]53329582010-05-14 21:10:582358void AutomationProvider::SendJSONRequest(int handle,
2359 std::string json_request,
2360 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042361 Browser* browser = NULL;
2362 std::string error_string;
2363 scoped_ptr<Value> values;
2364
2365 // Basic error checking.
2366 if (browser_tracker_->ContainsHandle(handle)) {
2367 browser = browser_tracker_->GetResource(handle);
2368 }
2369 if (!browser) {
2370 error_string = "no browser object";
2371 } else {
2372 base::JSONReader reader;
2373 std::string error;
[email protected]ba399672010-04-06 15:42:392374 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
[email protected]59a611242010-04-02 02:24:042375 if (!error.empty()) {
2376 error_string = error;
2377 }
2378 }
2379
2380 // Make sure input is a dict with a string command.
2381 std::string command;
2382 DictionaryValue* dict_value = NULL;
2383 if (error_string.empty()) {
2384 if (values->GetType() != Value::TYPE_DICTIONARY) {
2385 error_string = "not a dict or no command key in dict";
2386 } else {
2387 // Ownership remains with "values" variable.
2388 dict_value = static_cast<DictionaryValue*>(values.get());
2389 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2390 error_string = "no command key in dict or not a string command";
2391 }
2392 }
2393 }
2394
[email protected]24e2b102010-04-29 17:56:472395 // Map json commands to their handlers.
2396 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052397 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2398 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2399 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2400
[email protected]a9ff2c02010-05-13 17:33:052401 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
2402
[email protected]24e2b102010-04-29 17:56:472403 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292404 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052405
[email protected]53329582010-05-14 21:10:582406 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2407 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2408 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2409 handler_map["OmniboxMovePopupSelection"] =
2410 &AutomationProvider::OmniboxMovePopupSelection;
2411
[email protected]24e2b102010-04-29 17:56:472412 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2413 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052414
[email protected]ef413ca2010-05-25 21:09:142415 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2416
[email protected]f7d48012010-05-06 08:17:052417 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472418 handler_map["WaitForAllDownloadsToComplete"] =
2419 &AutomationProvider::WaitForDownloadsToComplete;
2420
[email protected]a3cd5022010-06-16 18:25:292421 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
2422
[email protected]7060bb292010-06-24 00:52:492423 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
2424
[email protected]59a611242010-04-02 02:24:042425 if (error_string.empty()) {
[email protected]24e2b102010-04-29 17:56:472426 if (handler_map.find(std::string(command)) != handler_map.end()) {
[email protected]53329582010-05-14 21:10:582427 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]59a611242010-04-02 02:24:042428 return;
2429 } else {
[email protected]24e2b102010-04-29 17:56:472430 error_string = "Unknown command. Options: ";
2431 for (std::map<std::string, JsonHandler>::const_iterator it =
2432 handler_map.begin(); it != handler_map.end(); ++it) {
2433 error_string += it->first + ", ";
2434 }
[email protected]59a611242010-04-02 02:24:042435 }
2436 }
2437
2438 // If we hit an error, return info.
[email protected]24e2b102010-04-29 17:56:472439 // Return a dict of {"error", "descriptive_string_for_error"}.
[email protected]59a611242010-04-02 02:24:042440 // Else return an empty dict.
2441 std::string json_string;
2442 bool success = true;
2443 if (!error_string.empty()) {
2444 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
2445 dict->SetString(L"error", error_string);
2446 base::JSONWriter::Write(dict.get(), false, &json_string);
2447 success = false;
2448 } else {
2449 json_string = "{}";
2450 }
2451 AutomationMsg_SendJSONRequest::WriteReplyParams(
2452 reply_message, json_string, success);
2453 Send(reply_message);
2454}
2455
initial.commit09911bf2008-07-26 23:55:292456void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562457 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342458 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2459 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562460 DCHECK(reply_message_ == NULL);
2461 reply_message_ = reply_message;
2462
[email protected]d9f9b792009-06-24 13:17:122463 DevToolsManager::GetInstance()->InspectElement(
2464 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292465 } else {
[email protected]71f65dd2009-02-11 19:14:562466 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2467 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292468 }
2469}
2470
2471void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092472 if (reply_message_) {
2473 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2474 num_resources);
2475 Send(reply_message_);
2476 reply_message_ = NULL;
2477 }
initial.commit09911bf2008-07-26 23:55:292478}
2479
[email protected]a7eee32f2009-05-22 18:08:172480class SetProxyConfigTask : public Task {
2481 public:
[email protected]be180c802009-10-23 06:33:312482 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2483 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252484 : request_context_getter_(request_context_getter),
2485 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172486 virtual void Run() {
2487 // First, deserialize the JSON string. If this fails, log and bail.
2488 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392489 std::string error_msg;
2490 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172491 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2492 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392493 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172494 return;
2495 }
2496
2497 scoped_ptr<DictionaryValue> dict(
2498 static_cast<DictionaryValue*>(root.release()));
2499 // Now put together a proxy configuration from the deserialized string.
2500 net::ProxyConfig pc;
2501 PopulateProxyConfig(*dict.get(), &pc);
2502
[email protected]be180c802009-10-23 06:33:312503 net::ProxyService* proxy_service =
2504 request_context_getter_->GetURLRequestContext()->proxy_service();
2505 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172506 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2507 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312508 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172509 }
2510
2511 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2512 DCHECK(pc);
2513 bool no_proxy = false;
2514 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2515 // Make no changes to the ProxyConfig.
2516 return;
2517 }
2518 bool auto_config;
2519 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482520 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172521 }
2522 std::string pac_url;
2523 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482524 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172525 }
2526 std::string proxy_bypass_list;
2527 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482528 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172529 }
2530 std::string proxy_server;
2531 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482532 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172533 }
2534 }
2535
2536 private:
[email protected]be180c802009-10-23 06:33:312537 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172538 std::string proxy_config_;
2539};
2540
2541
2542void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312543 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2544 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172545 FilePath user_data_dir;
2546 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2547 ProfileManager* profile_manager = g_browser_process->profile_manager();
2548 DCHECK(profile_manager);
2549 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2550 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312551 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172552 }
[email protected]be180c802009-10-23 06:33:312553 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172554
[email protected]fae20792009-10-28 20:31:582555 ChromeThread::PostTask(
2556 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312557 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172558}
2559
[email protected]4f3dc372009-02-24 00:10:292560void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332561 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292562 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292563 if (tab_tracker_->ContainsHandle(handle)) {
2564 NavigationController* tab = tab_tracker_->GetResource(handle);
2565 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2566 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332567 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292568 }
initial.commit09911bf2008-07-26 23:55:292569}
2570
[email protected]6a5670d22009-10-27 16:21:342571void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142572 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532573 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2574 reply_message);
2575}
2576
2577void AutomationProvider::OpenNewBrowserWindowOfType(
2578 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:142579 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292580 // We may have no current browser windows open so don't rely on
2581 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:532582 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
2583 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:052584 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152585 if (show)
[email protected]15952e462008-11-14 00:29:052586 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292587}
2588
[email protected]71f65dd2009-02-11 19:14:562589void AutomationProvider::GetWindowForBrowser(int browser_handle,
2590 bool* success,
2591 int* handle) {
2592 *success = false;
2593 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292594
2595 if (browser_tracker_->ContainsHandle(browser_handle)) {
2596 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202597 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292598 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202599 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562600 *success = true;
initial.commit09911bf2008-07-26 23:55:292601 }
initial.commit09911bf2008-07-26 23:55:292602}
2603
2604void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562605 int browser_handle,
2606 bool* success,
2607 int* autocomplete_edit_handle) {
2608 *success = false;
2609 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292610
2611 if (browser_tracker_->ContainsHandle(browser_handle)) {
2612 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062613 LocationBar* loc_bar = browser->window()->GetLocationBar();
2614 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292615 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562616 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2617 *success = true;
initial.commit09911bf2008-07-26 23:55:292618 }
initial.commit09911bf2008-07-26 23:55:292619}
initial.commit09911bf2008-07-26 23:55:292620
[email protected]71f65dd2009-02-11 19:14:562621void AutomationProvider::ShowInterstitialPage(int tab_handle,
2622 const std::string& html_text,
2623 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292624 if (tab_tracker_->ContainsHandle(tab_handle)) {
2625 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112626 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402627
[email protected]7dad3d5f2010-03-04 00:27:012628 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:402629 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342630 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402631 GURL("about:interstitial"),
2632 html_text);
2633 interstitial->Show();
2634 return;
initial.commit09911bf2008-07-26 23:55:292635 }
[email protected]71f65dd2009-02-11 19:14:562636
[email protected]457f5cf2009-08-18 16:37:522637 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2638 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562639 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292640}
2641
[email protected]71f65dd2009-02-11 19:14:562642void AutomationProvider::HideInterstitialPage(int tab_handle,
2643 bool* success) {
2644 *success = false;
[email protected]57c6a652009-05-04 07:58:342645 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2646 if (tab_contents && tab_contents->interstitial_page()) {
2647 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562648 *success = true;
initial.commit09911bf2008-07-26 23:55:292649 }
initial.commit09911bf2008-07-26 23:55:292650}
2651
[email protected]71f65dd2009-02-11 19:14:562652void AutomationProvider::CloseTab(int tab_handle,
2653 bool wait_until_closed,
2654 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292655 if (tab_tracker_->ContainsHandle(tab_handle)) {
2656 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2657 int index;
2658 Browser* browser = Browser::GetBrowserForController(controller, &index);
2659 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142660 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112661 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452662 return;
initial.commit09911bf2008-07-26 23:55:292663 }
[email protected]de246f52009-02-25 18:25:452664
2665 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:552666 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292667}
2668
[email protected]71f65dd2009-02-11 19:14:562669void AutomationProvider::CloseBrowser(int browser_handle,
2670 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292671 if (browser_tracker_->ContainsHandle(browser_handle)) {
2672 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562673 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562674 reply_message);
[email protected]f3e99e32008-07-30 04:48:392675 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292676 } else {
2677 NOTREACHED();
2678 }
2679}
2680
[email protected]71f65dd2009-02-11 19:14:562681void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2682 if (browser_tracker_->ContainsHandle(browser_handle)) {
2683 Browser* browser = browser_tracker_->GetResource(browser_handle);
2684 browser->window()->Close();
2685 } else {
2686 NOTREACHED();
2687 }
2688}
2689
[email protected]71f65dd2009-02-11 19:14:562690void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2691 IPC::Message* reply_message) {
2692 if (tab_tracker_->ContainsHandle(tab_handle)) {
2693 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2694 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142695 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562696 }
2697}
2698
[email protected]71f65dd2009-02-11 19:14:562699void AutomationProvider::GetSecurityState(int handle, bool* success,
2700 SecurityStyle* security_style,
2701 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:482702 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:292703 if (tab_tracker_->ContainsHandle(handle)) {
2704 NavigationController* tab = tab_tracker_->GetResource(handle);
2705 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562706 *success = true;
2707 *security_style = entry->ssl().security_style();
2708 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:482709 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292710 } else {
[email protected]71f65dd2009-02-11 19:14:562711 *success = false;
2712 *security_style = SECURITY_STYLE_UNKNOWN;
2713 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:482714 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292715 }
2716}
2717
[email protected]71f65dd2009-02-11 19:14:562718void AutomationProvider::GetPageType(int handle, bool* success,
2719 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292720 if (tab_tracker_->ContainsHandle(handle)) {
2721 NavigationController* tab = tab_tracker_->GetResource(handle);
2722 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562723 *page_type = entry->page_type();
2724 *success = true;
initial.commit09911bf2008-07-26 23:55:292725 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342726 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562727 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342728 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562729 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292730 } else {
[email protected]71f65dd2009-02-11 19:14:562731 *success = false;
2732 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292733 }
2734}
2735
[email protected]84abba62009-10-07 17:01:442736void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
2737 int* duration_ms) {
2738 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
2739 event_name);
2740}
2741
[email protected]71f65dd2009-02-11 19:14:562742void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2743 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292744 if (tab_tracker_->ContainsHandle(handle)) {
2745 NavigationController* tab = tab_tracker_->GetResource(handle);
2746 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072747 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402748 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472749 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342750 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292751 if (ssl_blocking_page) {
2752 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:012753 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:562754 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292755 return;
2756 }
2757 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522758 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2759 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562760 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292761 return;
2762 }
2763 }
2764 }
2765 // We failed.
[email protected]457f5cf2009-08-18 16:37:522766 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2767 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562768 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292769}
2770
[email protected]71f65dd2009-02-11 19:14:562771void AutomationProvider::BringBrowserToFront(int browser_handle,
2772 bool* success) {
initial.commit09911bf2008-07-26 23:55:292773 if (browser_tracker_->ContainsHandle(browser_handle)) {
2774 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062775 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562776 *success = true;
initial.commit09911bf2008-07-26 23:55:292777 } else {
[email protected]71f65dd2009-02-11 19:14:562778 *success = false;
initial.commit09911bf2008-07-26 23:55:292779 }
2780}
2781
[email protected]71f65dd2009-02-11 19:14:562782void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2783 int message_num,
2784 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292785 if (browser_tracker_->ContainsHandle(browser_handle)) {
2786 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562787 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142788 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292789 } else {
[email protected]71f65dd2009-02-11 19:14:562790 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292791 }
2792}
2793
[email protected]71f65dd2009-02-11 19:14:562794void AutomationProvider::PrintNow(int tab_handle,
2795 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572796 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342797 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2798 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292799 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572800 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142801 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342802 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572803 return;
initial.commit09911bf2008-07-26 23:55:292804 }
[email protected]71f65dd2009-02-11 19:14:562805 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2806 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292807}
[email protected]d301c952009-07-13 15:02:412808
[email protected]71f65dd2009-02-11 19:14:562809void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:112810 const FilePath& file_name,
2811 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:562812 int type,
2813 bool* success) {
initial.commit09911bf2008-07-26 23:55:292814 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562815 *success = false;
initial.commit09911bf2008-07-26 23:55:292816 return;
2817 }
2818
2819 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2820 Browser* browser = FindAndActivateTab(nav);
2821 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142822 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562823 *success = false;
initial.commit09911bf2008-07-26 23:55:292824 return;
2825 }
2826
initial.commit09911bf2008-07-26 23:55:292827 SavePackage::SavePackageType save_type =
2828 static_cast<SavePackage::SavePackageType>(type);
2829 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2830 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342831 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292832
[email protected]71f65dd2009-02-11 19:14:562833 *success = true;
initial.commit09911bf2008-07-26 23:55:292834}
2835
[email protected]71f65dd2009-02-11 19:14:562836void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2837 bool* success,
2838 std::wstring* text) {
2839 *success = false;
initial.commit09911bf2008-07-26 23:55:292840 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562841 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522842 GetText();
[email protected]71f65dd2009-02-11 19:14:562843 *success = true;
initial.commit09911bf2008-07-26 23:55:292844 }
initial.commit09911bf2008-07-26 23:55:292845}
2846
[email protected]71f65dd2009-02-11 19:14:562847void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2848 const std::wstring& text,
2849 bool* success) {
2850 *success = false;
initial.commit09911bf2008-07-26 23:55:292851 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522852 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2853 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562854 *success = true;
initial.commit09911bf2008-07-26 23:55:292855 }
initial.commit09911bf2008-07-26 23:55:292856}
2857
2858void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562859 int autocomplete_edit_handle,
2860 bool* success,
2861 std::vector<AutocompleteMatchData>* matches) {
2862 *success = false;
initial.commit09911bf2008-07-26 23:55:292863 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272864 const AutocompleteResult& result = autocomplete_edit_tracker_->
2865 GetResource(autocomplete_edit_handle)->model()->result();
2866 for (AutocompleteResult::const_iterator i = result.begin();
2867 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562868 matches->push_back(AutocompleteMatchData(*i));
2869 *success = true;
initial.commit09911bf2008-07-26 23:55:292870 }
initial.commit09911bf2008-07-26 23:55:292871}
2872
2873void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562874 int autocomplete_edit_handle,
2875 bool* success,
2876 bool* query_in_progress) {
2877 *success = false;
2878 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292879 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562880 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522881 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562882 *success = true;
initial.commit09911bf2008-07-26 23:55:292883 }
initial.commit09911bf2008-07-26 23:55:292884}
2885
[email protected]63514af2010-03-30 17:17:232886#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:192887
[email protected]5ae5bed2009-08-21 18:52:442888#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:392889
[email protected]57c6a652009-05-04 07:58:342890TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572891 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572892 if (tab_tracker_->ContainsHandle(handle)) {
2893 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342894 if (tab)
2895 *tab = nav_controller;
2896 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572897 }
[email protected]57c6a652009-05-04 07:58:342898 return NULL;
[email protected]20e93d12008-08-28 16:31:572899}
2900
initial.commit09911bf2008-07-26 23:55:292901TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2902 : AutomationProvider(profile) {
2903 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142904 registrar_.Add(this, NotificationType::SESSION_END,
2905 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292906}
2907
2908TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292909 BrowserList::RemoveObserver(this);
2910}
2911
2912void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:142913 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:292914 AutomationProvider::OnChannelError();
2915}
2916
2917void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2918 // For backwards compatibility with the testing automation interface, we
2919 // want the automation provider (and hence the process) to go away when the
2920 // last browser goes away.
2921 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292922 // If you change this, update Observer for NotificationType::SESSION_END
2923 // below.
[email protected]295039bd2008-08-15 04:32:572924 MessageLoop::current()->PostTask(FROM_HERE,
2925 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292926 }
2927}
2928
2929void TestingAutomationProvider::Observe(NotificationType type,
2930 const NotificationSource& source,
2931 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562932 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292933 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2934 // before the task runs resulting in this object not being deleted. This
2935 // Release balance out the Release scheduled by OnBrowserRemoving.
2936 Release();
2937}
[email protected]295039bd2008-08-15 04:32:572938
2939void TestingAutomationProvider::OnRemoveProvider() {
2940 AutomationProviderList::GetInstance()->RemoveProvider(this);
2941}
[email protected]8a3422c92008-09-24 17:42:422942
[email protected]816633a2009-11-11 21:48:182943void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:562944 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422945 if (tab_tracker_->ContainsHandle(handle)) {
2946 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342947 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112948 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422949 }
[email protected]8a3422c92008-09-24 17:42:422950}
2951
[email protected]816633a2009-11-11 21:48:182952void AutomationProvider::ClickInfoBarAccept(int handle,
2953 int info_bar_index,
2954 bool wait_for_navigation,
2955 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422956 bool success = false;
2957 if (tab_tracker_->ContainsHandle(handle)) {
2958 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2959 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112960 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422961 if (info_bar_index >= 0 && info_bar_index < count) {
2962 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:012963 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:422964 }
[email protected]eb9ba192008-12-02 02:41:342965 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112966 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342967 info_bar_index);
2968 if (delegate->AsConfirmInfoBarDelegate())
2969 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422970 success = true;
2971 }
2972 }
[email protected]4f3dc372009-02-24 00:10:292973 }
[email protected]58f622a62009-10-04 01:17:552974
2975 // This "!wait_for_navigation || !success condition" logic looks suspicious.
2976 // It will send a failure message when success is true but
2977 // |wait_for_navigation| is false.
2978 // TODO(phajdan.jr): investgate whether the reply param (currently
2979 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:422980 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:182981 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:522982 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422983}
2984
[email protected]71f65dd2009-02-11 19:14:562985void AutomationProvider::GetLastNavigationTime(int handle,
2986 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422987 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562988 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422989}
2990
[email protected]71f65dd2009-02-11 19:14:562991void AutomationProvider::WaitForNavigation(int handle,
2992 int64 last_navigation_time,
2993 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:252994 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:422995 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:252996
[email protected]8a3422c92008-09-24 17:42:422997 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562998 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522999 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3000 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553001 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293002 return;
[email protected]8a3422c92008-09-24 17:42:423003 }
3004
[email protected]7dad3d5f2010-03-04 00:27:013005 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423006}
3007
[email protected]71f65dd2009-02-11 19:14:563008void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163009 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563010 int value,
3011 bool* success) {
3012 *success = false;
[email protected]8a3422c92008-09-24 17:42:423013 if (browser_tracker_->ContainsHandle(handle)) {
3014 Browser* browser = browser_tracker_->GetResource(handle);
3015 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563016 *success = true;
[email protected]8a3422c92008-09-24 17:42:423017 }
[email protected]8a3422c92008-09-24 17:42:423018}
[email protected]97fa6ce32008-12-19 01:48:163019
[email protected]71f65dd2009-02-11 19:14:563020void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163021 const std::wstring& name,
[email protected]ddd231e2010-06-29 20:35:193022 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563023 bool* success) {
3024 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163025 if (browser_tracker_->ContainsHandle(handle)) {
3026 Browser* browser = browser_tracker_->GetResource(handle);
3027 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563028 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163029 }
[email protected]97fa6ce32008-12-19 01:48:163030}
3031
[email protected]71f65dd2009-02-11 19:14:563032void AutomationProvider::GetBooleanPreference(int handle,
3033 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:363034 bool* success,
3035 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563036 *success = false;
3037 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163038 if (browser_tracker_->ContainsHandle(handle)) {
3039 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563040 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3041 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163042 }
[email protected]97fa6ce32008-12-19 01:48:163043}
3044
[email protected]71f65dd2009-02-11 19:14:563045void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163046 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563047 bool value,
3048 bool* success) {
3049 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163050 if (browser_tracker_->ContainsHandle(handle)) {
3051 Browser* browser = browser_tracker_->GetResource(handle);
3052 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563053 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163054 }
[email protected]97fa6ce32008-12-19 01:48:163055}
3056
3057// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563058void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403059 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163060 if (tab_tracker_->ContainsHandle(tab_handle)) {
3061 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3062 Browser* browser = FindAndActivateTab(nav);
3063 DCHECK(browser);
3064
[email protected]57c6a652009-05-04 07:58:343065 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3066 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163067 }
[email protected]97fa6ce32008-12-19 01:48:163068}
3069
[email protected]b8f48d12009-11-09 20:14:363070// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563071void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:403072 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:563073 bool* success) {
3074 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163075 if (tab_tracker_->ContainsHandle(tab_handle)) {
3076 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193077 if (!nav)
3078 return;
[email protected]97fa6ce32008-12-19 01:48:163079 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163080
[email protected]2f2afba2010-04-01 01:53:193081 // If the browser has UI, simulate what a user would do.
3082 // Activate the tab and then click the encoding menu.
3083 if (browser &&
3084 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163085 int selected_encoding_id =
3086 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3087 if (selected_encoding_id) {
3088 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563089 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163090 }
[email protected]2f2afba2010-04-01 01:53:193091 } else {
3092 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3093 // Try to get TabContents and call its override_encoding method.
3094 TabContents* contents = nav->tab_contents();
3095 if (!contents)
3096 return;
3097 const std::string selected_encoding =
3098 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
3099 if (selected_encoding.empty())
3100 return;
3101 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163102 }
3103 }
[email protected]97fa6ce32008-12-19 01:48:163104}
[email protected]5bcdb312009-01-07 21:43:203105
[email protected]4d434a1a2009-02-11 21:06:573106void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203107 SavePackage::SetShouldPromptUser(should_prompt);
3108}
[email protected]87eab222009-03-13 00:47:453109
[email protected]66ba4932009-06-04 19:22:133110void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3111 *count = -1; // -1 is the error code
3112 if (tab_tracker_->ContainsHandle(handle)) {
3113 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3114 TabContents* tab_contents = nav_controller->tab_contents();
3115 if (tab_contents) {
3116 BlockedPopupContainer* container =
3117 tab_contents->blocked_popup_container();
3118 if (container) {
3119 *count = static_cast<int>(container->GetBlockedPopupCount());
3120 } else {
3121 // If we don't have a container, we don't have any blocked popups to
3122 // contain!
3123 *count = 0;
3124 }
3125 }
3126 }
3127}
[email protected]f7a68432009-07-29 23:18:193128
3129void AutomationProvider::SelectAll(int tab_handle) {
3130 RenderViewHost* view = GetViewForTab(tab_handle);
3131 if (!view) {
3132 NOTREACHED();
3133 return;
3134 }
3135
3136 view->SelectAll();
3137}
3138
3139void AutomationProvider::Cut(int tab_handle) {
3140 RenderViewHost* view = GetViewForTab(tab_handle);
3141 if (!view) {
3142 NOTREACHED();
3143 return;
3144 }
3145
3146 view->Cut();
3147}
3148
3149void AutomationProvider::Copy(int tab_handle) {
3150 RenderViewHost* view = GetViewForTab(tab_handle);
3151 if (!view) {
3152 NOTREACHED();
3153 return;
3154 }
3155
3156 view->Copy();
3157}
3158
3159void AutomationProvider::Paste(int tab_handle) {
3160 RenderViewHost* view = GetViewForTab(tab_handle);
3161 if (!view) {
3162 NOTREACHED();
3163 return;
3164 }
3165
3166 view->Paste();
3167}
3168
3169void AutomationProvider::ReloadAsync(int tab_handle) {
3170 if (tab_tracker_->ContainsHandle(tab_handle)) {
3171 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3172 if (!tab) {
3173 NOTREACHED();
3174 return;
3175 }
3176
[email protected]106a0812010-03-18 00:15:123177 const bool check_for_repost = true;
3178 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193179 }
3180}
3181
3182void AutomationProvider::StopAsync(int tab_handle) {
3183 RenderViewHost* view = GetViewForTab(tab_handle);
3184 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363185 // We tolerate StopAsync being called even before a view has been created.
3186 // So just log a warning instead of a NOTREACHED().
3187 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193188 return;
3189 }
3190
3191 view->Stop();
3192}
3193
[email protected]1bb5f892009-10-06 01:44:573194void AutomationProvider::OnSetPageFontSize(int tab_handle,
3195 int font_size) {
3196 AutomationPageFontSize automation_font_size =
3197 static_cast<AutomationPageFontSize>(font_size);
3198
3199 if (automation_font_size < SMALLEST_FONT ||
3200 automation_font_size > LARGEST_FONT) {
3201 DLOG(ERROR) << "Invalid font size specified : "
3202 << font_size;
3203 return;
3204 }
3205
3206 if (tab_tracker_->ContainsHandle(tab_handle)) {
3207 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3208 DCHECK(tab != NULL);
3209 if (tab && tab->tab_contents()) {
3210 DCHECK(tab->tab_contents()->profile() != NULL);
3211 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3212 prefs::kWebKitDefaultFontSize, font_size);
3213 }
3214 }
3215}
3216
[email protected]bc73b4e52010-03-26 04:16:203217void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3218 BrowsingDataRemover* remover;
3219 remover = new BrowsingDataRemover(profile(),
3220 BrowsingDataRemover::EVERYTHING, // All time periods.
3221 base::Time());
3222 remover->Remove(remove_mask);
3223 // BrowsingDataRemover deletes itself.
3224}
[email protected]1bb5f892009-10-06 01:44:573225
[email protected]2949e90d2009-08-21 15:32:523226void AutomationProvider::WaitForBrowserWindowCountToBecome(
3227 int target_count, IPC::Message* reply_message) {
3228 if (static_cast<int>(BrowserList::size()) == target_count) {
3229 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3230 reply_message, true);
3231 Send(reply_message);
3232 return;
3233 }
3234
3235 // Set up an observer (it will delete itself).
3236 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3237}
3238
3239void AutomationProvider::WaitForAppModalDialogToBeShown(
3240 IPC::Message* reply_message) {
3241 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3242 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3243 reply_message, true);
3244 Send(reply_message);
3245 return;
3246 }
3247
3248 // Set up an observer (it will delete itself).
3249 new AppModalDialogShownObserver(this, reply_message);
3250}
3251
[email protected]1126a1d32009-08-26 15:39:263252void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3253 int handle, int number_of_navigations, IPC::Message* reply_message) {
3254 if (tab_tracker_->ContainsHandle(handle)) {
3255 NavigationController* tab = tab_tracker_->GetResource(handle);
3256 Browser* browser = FindAndActivateTab(tab);
3257 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013258 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3259 false);
[email protected]1126a1d32009-08-26 15:39:263260 browser->GoBack(CURRENT_TAB);
3261 return;
3262 }
3263 }
3264
3265 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3266 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3267 Send(reply_message);
3268}
3269
3270void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3271 int handle, int number_of_navigations, IPC::Message* reply_message) {
3272 if (tab_tracker_->ContainsHandle(handle)) {
3273 NavigationController* tab = tab_tracker_->GetResource(handle);
3274 Browser* browser = FindAndActivateTab(tab);
3275 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013276 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3277 false);
[email protected]1126a1d32009-08-26 15:39:263278 browser->GoForward(CURRENT_TAB);
3279 return;
3280 }
3281 }
3282
3283 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3284 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3285 Send(reply_message);
3286}
3287
[email protected]f7a68432009-07-29 23:18:193288RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3289 if (tab_tracker_->ContainsHandle(tab_handle)) {
3290 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3291 if (!tab) {
3292 NOTREACHED();
3293 return NULL;
3294 }
3295
3296 TabContents* tab_contents = tab->tab_contents();
3297 if (!tab_contents) {
3298 NOTREACHED();
3299 return NULL;
3300 }
3301
3302 RenderViewHost* view_host = tab_contents->render_view_host();
3303 return view_host;
3304 }
3305
3306 return NULL;
3307}
[email protected]675595f2009-08-26 22:32:043308
3309void AutomationProvider::GetBrowserForWindow(int window_handle,
3310 bool* success,
3311 int* browser_handle) {
3312 *success = false;
3313 *browser_handle = 0;
3314
3315 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3316 if (!window)
3317 return;
3318
3319 BrowserList::const_iterator iter = BrowserList::begin();
3320 for (;iter != BrowserList::end(); ++iter) {
3321 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3322 if (window == this_window) {
3323 // Add() returns the existing handle for the resource if any.
3324 *browser_handle = browser_tracker_->Add(*iter);
3325 *success = true;
3326 return;
3327 }
3328 }
3329}
[email protected]d11c8e92009-10-20 23:26:403330
3331void AutomationProvider::InstallExtension(const FilePath& crx_path,
3332 IPC::Message* reply_message) {
3333 ExtensionsService* service = profile_->GetExtensionsService();
3334 if (service) {
3335 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193336 new ExtensionInstallNotificationObserver(this,
3337 AutomationMsg_InstallExtension::ID,
3338 reply_message);
[email protected]d11c8e92009-10-20 23:26:403339
3340 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163341 scoped_refptr<CrxInstaller> installer(
3342 new CrxInstaller(install_dir,
3343 service,
3344 NULL)); // silent install, no UI
3345 installer->set_allow_privilege_increase(true);
3346 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403347 } else {
3348 AutomationMsg_InstallExtension::WriteReplyParams(
3349 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3350 Send(reply_message);
3351 }
3352}
3353
3354void AutomationProvider::LoadExpandedExtension(
3355 const FilePath& extension_dir,
3356 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383357 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403358 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193359 new ExtensionInstallNotificationObserver(
3360 this,
3361 AutomationMsg_LoadExpandedExtension::ID,
3362 reply_message);
[email protected]d11c8e92009-10-20 23:26:403363
3364 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403365 } else {
3366 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3367 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3368 Send(reply_message);
3369 }
3370}
[email protected]673fd2c02010-02-04 23:10:003371
[email protected]a1e62d12010-03-16 02:18:433372void AutomationProvider::GetEnabledExtensions(
3373 std::vector<FilePath>* result) {
3374 ExtensionsService* service = profile_->GetExtensionsService();
3375 DCHECK(service);
3376 if (service->extensions_enabled()) {
3377 const ExtensionList* extensions = service->extensions();
3378 DCHECK(extensions);
3379 for (size_t i = 0; i < extensions->size(); ++i) {
3380 Extension* extension = (*extensions)[i];
3381 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123382 if (extension->location() == Extension::INTERNAL ||
3383 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073384 result->push_back(extension->path());
3385 }
[email protected]a1e62d12010-03-16 02:18:433386 }
3387 }
3388}
3389
[email protected]790788ac2010-04-06 17:52:193390void AutomationProvider::WaitForExtensionTestResult(
3391 IPC::Message* reply_message) {
3392 DCHECK(reply_message_ == NULL);
3393 reply_message_ = reply_message;
3394 // Call MaybeSendResult, because the result might have come in before
3395 // we were waiting on it.
3396 extension_test_result_observer_->MaybeSendResult();
3397}
3398
3399void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093400 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193401 ExtensionsService* service = profile_->GetExtensionsService();
3402 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3403 if (service && manager) {
3404 // The observer will delete itself when done.
3405 new ExtensionReadyNotificationObserver(
3406 manager,
3407 this,
3408 AutomationMsg_InstallExtensionAndGetHandle::ID,
3409 reply_message);
3410
[email protected]d7e5525d2010-04-20 14:37:093411 ExtensionInstallUI* client =
3412 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193413 scoped_refptr<CrxInstaller> installer(
3414 new CrxInstaller(service->install_directory(),
3415 service,
[email protected]d7e5525d2010-04-20 14:37:093416 client));
[email protected]790788ac2010-04-06 17:52:193417 installer->set_allow_privilege_increase(true);
3418 installer->InstallCrx(crx_path);
3419 } else {
3420 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3421 reply_message, 0);
3422 Send(reply_message);
3423 }
3424}
3425
3426void AutomationProvider::UninstallExtension(int extension_handle,
3427 bool* success) {
3428 *success = false;
3429 Extension* extension = GetExtension(extension_handle);
3430 ExtensionsService* service = profile_->GetExtensionsService();
3431 if (extension && service) {
3432 ExtensionUnloadNotificationObserver observer;
3433 service->UninstallExtension(extension->id(), false);
3434 // The extension unload notification should have been sent synchronously
3435 // with the uninstall. Just to be safe, check that it was received.
3436 *success = observer.did_receive_unload_notification();
3437 }
3438}
3439
3440void AutomationProvider::EnableExtension(int extension_handle,
3441 IPC::Message* reply_message) {
3442 Extension* extension = GetDisabledExtension(extension_handle);
3443 ExtensionsService* service = profile_->GetExtensionsService();
3444 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3445 // Only enable if this extension is disabled.
3446 if (extension && service && manager) {
3447 // The observer will delete itself when done.
3448 new ExtensionReadyNotificationObserver(
3449 manager,
3450 this,
3451 AutomationMsg_EnableExtension::ID,
3452 reply_message);
3453 service->EnableExtension(extension->id());
3454 } else {
3455 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3456 Send(reply_message);
3457 }
3458}
3459
3460void AutomationProvider::DisableExtension(int extension_handle,
3461 bool* success) {
3462 *success = false;
3463 Extension* extension = GetEnabledExtension(extension_handle);
3464 ExtensionsService* service = profile_->GetExtensionsService();
3465 if (extension && service) {
3466 ExtensionUnloadNotificationObserver observer;
3467 service->DisableExtension(extension->id());
3468 // The extension unload notification should have been sent synchronously
3469 // with the disable. Just to be safe, check that it was received.
3470 *success = observer.did_receive_unload_notification();
3471 }
3472}
3473
3474void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3475 int extension_handle, int browser_handle,
3476 IPC::Message* reply_message) {
3477 bool success = false;
3478 Extension* extension = GetEnabledExtension(extension_handle);
3479 ExtensionsService* service = profile_->GetExtensionsService();
3480 ExtensionMessageService* message_service =
3481 profile_->GetExtensionMessageService();
3482 Browser* browser = browser_tracker_->GetResource(browser_handle);
3483 if (extension && service && message_service && browser) {
3484 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3485 if (extension->page_action()) {
3486 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3487 browser->profile(), extension->id(), "action", tab_id, "", 1);
3488 success = true;
3489 } else if (extension->browser_action()) {
3490 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3491 browser->profile(), extension->id(), browser);
3492 success = true;
3493 }
3494 }
3495 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3496 reply_message, success);
3497 Send(reply_message);
3498}
3499
3500void AutomationProvider::MoveExtensionBrowserAction(
3501 int extension_handle, int index, bool* success) {
3502 *success = false;
3503 Extension* extension = GetEnabledExtension(extension_handle);
3504 ExtensionsService* service = profile_->GetExtensionsService();
3505 if (extension && service) {
3506 ExtensionToolbarModel* toolbar = service->toolbar_model();
3507 if (toolbar) {
3508 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3509 toolbar->MoveBrowserAction(extension, index);
3510 *success = true;
3511 } else {
3512 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3513 }
3514 }
3515 }
3516}
3517
3518void AutomationProvider::GetExtensionProperty(
3519 int extension_handle,
3520 AutomationMsg_ExtensionProperty type,
3521 bool* success,
3522 std::string* value) {
3523 *success = false;
3524 Extension* extension = GetExtension(extension_handle);
3525 ExtensionsService* service = profile_->GetExtensionsService();
3526 if (extension && service) {
3527 ExtensionToolbarModel* toolbar = service->toolbar_model();
3528 int found_index = -1;
3529 int index = 0;
3530 switch (type) {
3531 case AUTOMATION_MSG_EXTENSION_ID:
3532 *value = extension->id();
3533 *success = true;
3534 break;
3535 case AUTOMATION_MSG_EXTENSION_NAME:
3536 *value = extension->name();
3537 *success = true;
3538 break;
3539 case AUTOMATION_MSG_EXTENSION_VERSION:
3540 *value = extension->VersionString();
3541 *success = true;
3542 break;
3543 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3544 if (toolbar) {
3545 for (ExtensionList::const_iterator iter = toolbar->begin();
3546 iter != toolbar->end(); iter++) {
3547 // Skip this extension if we are in incognito mode
3548 // and it is not incognito-enabled.
3549 if (profile_->IsOffTheRecord() &&
3550 !service->IsIncognitoEnabled(*iter))
3551 continue;
3552 if (*iter == extension) {
3553 found_index = index;
3554 break;
3555 }
3556 index++;
3557 }
3558 *value = IntToString(found_index);
3559 *success = true;
3560 }
3561 break;
3562 default:
3563 LOG(WARNING) << "Trying to get undefined extension property";
3564 break;
3565 }
3566 }
3567}
3568
[email protected]673fd2c02010-02-04 23:10:003569void AutomationProvider::SaveAsAsync(int tab_handle) {
3570 NavigationController* tab = NULL;
3571 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3572 if (tab_contents)
3573 tab_contents->OnSavePage();
3574}
[email protected]7dad3d5f2010-03-04 00:27:013575
3576void AutomationProvider::SetContentSetting(
3577 int handle,
3578 const std::string& host,
3579 ContentSettingsType content_type,
3580 ContentSetting setting,
3581 bool* success) {
3582 *success = false;
3583 if (browser_tracker_->ContainsHandle(handle)) {
3584 Browser* browser = browser_tracker_->GetResource(handle);
3585 HostContentSettingsMap* map =
3586 browser->profile()->GetHostContentSettingsMap();
3587 if (host.empty()) {
3588 map->SetDefaultContentSetting(content_type, setting);
3589 } else {
[email protected]0314ae02010-04-08 09:18:293590 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
3591 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:013592 }
3593 *success = true;
3594 }
3595}
[email protected]cc824372010-03-31 15:33:013596
3597#if !defined(TOOLKIT_VIEWS)
3598void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
3599 NOTIMPLEMENTED();
3600};
3601
3602void AutomationProvider::WaitForFocusedViewIDToChange(
3603 int handle, int previous_view_id, IPC::Message* reply_message) {
3604 NOTIMPLEMENTED();
3605}
3606
3607void AutomationProvider::StartTrackingPopupMenus(
3608 int browser_handle, bool* success) {
3609 NOTIMPLEMENTED();
3610}
3611
3612void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
3613 NOTIMPLEMENTED();
3614}
3615#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:093616
3617void AutomationProvider::ResetToDefaultTheme() {
3618 profile_->ClearTheme();
3619}