blob: e59c07a2dcb8ac5f9d42e7ec7a514ee2321ef18c [file] [log] [blame]
[email protected]3b5f7022010-03-25 20:37:401// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]37126212009-05-06 02:23:319#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5910#include "base/callback.h"
[email protected]7060bb292010-06-24 00:52:4911#include "base/file_path.h"
[email protected]c6cb1992009-04-13 16:45:2912#include "base/file_version_info.h"
[email protected]93d49d72009-10-23 20:00:2013#include "base/json/json_reader.h"
[email protected]59a611242010-04-02 02:24:0414#include "base/json/json_writer.h"
[email protected]93364da2010-06-29 18:03:4415#include "base/json/string_escape.h"
[email protected]bc1407f2009-09-29 00:33:3516#include "base/keyboard_codes.h"
[email protected]5fac9622009-02-04 21:49:3817#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/path_service.h"
[email protected]201b2732009-11-13 18:57:4619#include "base/process_util.h"
[email protected]f44265b2009-05-19 18:52:5020#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2721#include "base/string_util.h"
[email protected]9eaa18e2010-06-29 20:51:0122#include "base/task.h"
[email protected]5fac9622009-02-04 21:49:3823#include "base/thread.h"
[email protected]528c56d2010-07-30 19:28:4424#include "base/string_number_conversions.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]0bfa713f2009-04-07 20:18:2829#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0930#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]55846ad842010-07-09 18:22:5631#include "chrome/browser/autofill/autofill_manager.h"
[email protected]679082052010-07-21 21:30:1332#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
33#include "chrome/browser/automation/automation_browser_tracker.h"
[email protected]790788ac2010-04-06 17:52:1934#include "chrome/browser/automation/automation_extension_tracker.h"
[email protected]7c983cc2010-07-16 11:33:3435#include "chrome/browser/automation/automation_provider_json.h"
initial.commit09911bf2008-07-26 23:55:2936#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0837#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]679082052010-07-21 21:30:1338#include "chrome/browser/automation/automation_resource_message_filter.h"
39#include "chrome/browser/automation/automation_tab_tracker.h"
40#include "chrome/browser/automation/automation_window_tracker.h"
[email protected]f44265b2009-05-19 18:52:5041#include "chrome/browser/automation/extension_port_container.h"
[email protected]12802702010-07-09 19:43:0942#include "chrome/browser/autocomplete/autocomplete_edit.h"
[email protected]66ba4932009-06-04 19:22:1343#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5344#include "chrome/browser/bookmarks/bookmark_model.h"
45#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1446#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0747#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3948#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2049#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0550#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5851#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2952#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1253#include "chrome/browser/debugger/devtools_manager.h"
[email protected]6c69796d2010-07-16 21:41:1654#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2255#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0556#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4057#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1958#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1459#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4060#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5561#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1962#include "chrome/browser/extensions/extension_tabs_module.h"
63#include "chrome/browser/extensions/extension_toolbar_model.h"
64#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1665#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5866#include "chrome/browser/find_bar.h"
67#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2968#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0169#include "chrome/browser/host_content_settings_map.h"
[email protected]c5aa5322010-07-15 19:00:0770#include "chrome/browser/importer/importer.h"
71#include "chrome/browser/importer/importer_data_types.h"
[email protected]0ac83682010-01-22 17:46:2772#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0673#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0174#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5375#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2476#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0877#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0578#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1779#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0780#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2581#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0382#include "chrome/browser/ssl/ssl_manager.h"
83#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]b5558cf22010-07-12 17:30:0684#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]57c6a652009-05-04 07:58:3485#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4586#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]38b5a3852010-07-21 06:49:5287#include "chrome/browser/translate/translate_infobar_delegate.h"
[email protected]a7eee32f2009-05-22 18:08:1788#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0589#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2990#include "chrome/common/chrome_paths.h"
[email protected]c984d9f2010-07-20 20:52:2091#include "chrome/common/chrome_switches.h"
[email protected]1eeb5e02010-07-20 23:02:1192#include "chrome/common/chrome_version_info.h"
[email protected]790788ac2010-04-06 17:52:1993#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1794#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5595#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1496#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5797#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2598#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5699#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:57100#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:17101#include "net/proxy/proxy_service.h"
102#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:21103#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:30104#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:28105#include "views/event.h"
[email protected]5bcfe1672010-07-16 20:51:57106#include "webkit/glue/password_form.h"
[email protected]f7d48012010-05-06 08:17:05107#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:29108
[email protected]de246f52009-02-25 18:25:45109#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:35110#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:45111#endif // defined(OS_WIN)
112
[email protected]e1acf6f2008-10-27 20:43:33113using base::Time;
114
[email protected]cbab76d2008-10-13 22:42:47115class AutomationInterstitialPage : public InterstitialPage {
116 public:
[email protected]57c6a652009-05-04 07:58:34117 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47118 const GURL& url,
119 const std::string& contents)
120 : InterstitialPage(tab, true, url),
121 contents_(contents) {
122 }
123
124 virtual std::string GetHTMLContents() { return contents_; }
125
126 private:
127 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29128
[email protected]cbab76d2008-10-13 22:42:47129 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
130};
131
[email protected]c2cb8542009-08-20 21:16:51132class ClickTask : public Task {
133 public:
[email protected]fc2e0872009-08-21 22:14:41134 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51135 virtual ~ClickTask() {}
136
137 virtual void Run() {
138 ui_controls::MouseButton button = ui_controls::LEFT;
139 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
140 views::Event::EF_LEFT_BUTTON_DOWN) {
141 button = ui_controls::LEFT;
142 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
143 views::Event::EF_RIGHT_BUTTON_DOWN) {
144 button = ui_controls::RIGHT;
145 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
146 views::Event::EF_MIDDLE_BUTTON_DOWN) {
147 button = ui_controls::MIDDLE;
148 } else {
149 NOTREACHED();
150 }
151
[email protected]fc2e0872009-08-21 22:14:41152 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51153 }
154
155 private:
[email protected]c2cb8542009-08-20 21:16:51156 int flags_;
157
158 DISALLOW_COPY_AND_ASSIGN(ClickTask);
159};
[email protected]c2cb8542009-08-20 21:16:51160
initial.commit09911bf2008-07-26 23:55:29161AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57162 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56163 profile_(profile),
[email protected]cc824372010-03-31 15:33:01164 reply_message_(NULL),
165 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29166 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19167 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29168 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20169 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29170 autocomplete_edit_tracker_.reset(
171 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29172 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
173 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44174 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19175 extension_test_result_observer_.reset(
176 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13177 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29178}
179
180AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50181 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
182 port_containers_.end());
183 port_containers_.clear();
184
[email protected]0da050b92008-08-19 19:29:47185 // Make sure that any outstanding NotificationObservers also get destroyed.
186 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31187 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47188 while ((observer = it.GetNext()) != NULL)
189 delete observer;
[email protected]528211a2010-01-14 15:25:13190
191 if (channel_.get()) {
192 channel_->Close();
193 }
194 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29195}
196
[email protected]9a3a293b2009-06-04 22:28:16197void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06198 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57199 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06200 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
201 automation_resource_message_filter_,
202 g_browser_process->io_thread()->message_loop(),
203 true, g_browser_process->shutdown_event()));
[email protected]1eeb5e02010-07-20 23:02:11204 scoped_ptr<FileVersionInfo> version_info(chrome::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40205 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43206 if (version_info != NULL) {
207 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40208 }
[email protected]c6cb1992009-04-13 16:45:29209
210 // Send a hello message with our current automation protocol version.
211 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29212}
213
214void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
215 if (expected_tabs == 0) {
216 Send(new AutomationMsg_InitialLoadsComplete(0));
217 } else {
218 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
219 }
220}
221
222NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58223 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01224 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29225 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58226 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01227 number_of_navigations,
228 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29229
[email protected]71f65dd2009-02-11 19:14:56230 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29231 return observer;
232}
233
[email protected]faf2ee42010-05-11 14:26:17234void AutomationProvider::RemoveNavigationStatusListener(
235 NotificationObserver* obs) {
236 notification_observer_list_.RemoveObserver(obs);
237}
238
initial.commit09911bf2008-07-26 23:55:29239NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14240 Browser* parent,
241 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56242 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14243 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29244 notification_observer_list_.AddObserver(observer);
245
246 return observer;
247}
248
[email protected]faf2ee42010-05-11 14:26:17249void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29250 notification_observer_list_.RemoveObserver(obs);
251}
252
253void AutomationProvider::AddLoginHandler(NavigationController* tab,
254 LoginHandler* handler) {
255 login_handler_map_[tab] = handler;
256}
257
258void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
259 DCHECK(login_handler_map_[tab]);
260 login_handler_map_.erase(tab);
261}
262
[email protected]f44265b2009-05-19 18:52:50263void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
264 int port_id = port->port_id();
265 DCHECK_NE(-1, port_id);
266 DCHECK(port_containers_.find(port_id) == port_containers_.end());
267
268 port_containers_[port_id] = port;
269}
270
271void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
272 int port_id = port->port_id();
273 DCHECK_NE(-1, port_id);
274
275 PortContainerMap::iterator it = port_containers_.find(port_id);
276 DCHECK(it != port_containers_.end());
277
278 if (it != port_containers_.end()) {
279 delete it->second;
280 port_containers_.erase(it);
281 }
282}
283
284ExtensionPortContainer* AutomationProvider::GetPortContainer(
285 int port_id) const {
286 PortContainerMap::const_iterator it = port_containers_.find(port_id);
287 if (it == port_containers_.end())
288 return NULL;
289
290 return it->second;
291}
292
initial.commit09911bf2008-07-26 23:55:29293int AutomationProvider::GetIndexForNavigationController(
294 const NavigationController* controller, const Browser* parent) const {
295 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12296 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29297}
298
[email protected]790788ac2010-04-06 17:52:19299int AutomationProvider::AddExtension(Extension* extension) {
300 DCHECK(extension);
301 return extension_tracker_->Add(extension);
302}
303
304Extension* AutomationProvider::GetExtension(int extension_handle) {
305 return extension_tracker_->GetResource(extension_handle);
306}
307
308Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
309 Extension* extension = extension_tracker_->GetResource(extension_handle);
310 ExtensionsService* service = profile_->GetExtensionsService();
311 if (extension && service &&
312 service->GetExtensionById(extension->id(), false))
313 return extension;
314 return NULL;
315}
316
317Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
318 Extension* extension = extension_tracker_->GetResource(extension_handle);
319 ExtensionsService* service = profile_->GetExtensionsService();
320 if (extension && service &&
321 service->GetExtensionById(extension->id(), true) &&
322 !service->GetExtensionById(extension->id(), false))
323 return extension;
324 return NULL;
325}
326
initial.commit09911bf2008-07-26 23:55:29327void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
328 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14329 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56330 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
331 CloseBrowserAsync)
332 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
333 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
334 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
335 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
336 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
337 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22338 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]a503c97c2010-07-16 13:05:48339 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog,
340 ShowCollectedCookiesDialog)
[email protected]1c58a5c2009-05-21 18:47:14341 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58342 IPC_MESSAGE_HANDLER_DELAY_REPLY(
343 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
344 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56345 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11346 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
347 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56348 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
349 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
350 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
351 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14352 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56353 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
354 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
355 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14356 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29357 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
358 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56359 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36360 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56361 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29362 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56363 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29364 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
365 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56366 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14367 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24368 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44369 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33370 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44371 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33372 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24373 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14374 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24375 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15376 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14377 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24378 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35379 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14380 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30381#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56382 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
383 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30384#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56385 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53386 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56387 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37388#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56389 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45390#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56391 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
392 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03393 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56394 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14395 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09396 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
397 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
398 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29399 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14400 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56401 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
402 ExecuteJavascript)
403 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29404 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14405 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
406 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56407 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
408 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14409 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17410 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14411 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14412 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53413 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
414 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14415 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56416 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14417 GetAutocompleteEditForBrowser)
418 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56419 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14420 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56421 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14422 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56423 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
424 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14425 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
426 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44427 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
428 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56429 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
430 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29431 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
[email protected]bdb7ff62010-07-20 01:56:52432 IPC_MESSAGE_HANDLER(AutomationMsg_IsMenuCommandEnabled,
433 IsMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56434 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41435 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56436 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
437 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29438 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56439 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29440 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56441 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29442 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56443 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29444 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56445 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45446 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14447 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56448 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57449 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56450 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57451 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56452 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
453 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53454 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
455 GetBookmarksAsJSON)
456 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
457 WaitForBookmarkModelToLoad)
458 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
459 AddBookmarkGroup)
460 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
461 AddBookmarkURL)
462 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
463 ReparentBookmark)
464 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
465 SetBookmarkTitle)
466 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
467 SetBookmarkURL)
468 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
469 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04470 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
471 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18472 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
473 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
474 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56475 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42476 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56477 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
478 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14479 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56480 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44481 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56482 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20483 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14484 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56485 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16486 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56487 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16488 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56489 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16490 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14491 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20492 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
493 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14494 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22495 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13496 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19497 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
498 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
499 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
500 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
501 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
502 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52503 IPC_MESSAGE_HANDLER_DELAY_REPLY(
504 AutomationMsg_WaitForBrowserWindowCountToBecome,
505 WaitForBrowserWindowCountToBecome)
506 IPC_MESSAGE_HANDLER_DELAY_REPLY(
507 AutomationMsg_WaitForAppModalDialogToBeShown,
508 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26509 IPC_MESSAGE_HANDLER_DELAY_REPLY(
510 AutomationMsg_GoBackBlockUntilNavigationsComplete,
511 GoBackBlockUntilNavigationsComplete)
512 IPC_MESSAGE_HANDLER_DELAY_REPLY(
513 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
514 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57515 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40516 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
517 InstallExtension)
518 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
519 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43520 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
521 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19522 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
523 WaitForExtensionTestResult)
524 IPC_MESSAGE_HANDLER_DELAY_REPLY(
525 AutomationMsg_InstallExtensionAndGetHandle,
526 InstallExtensionAndGetHandle)
527 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
528 UninstallExtension)
529 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
530 EnableExtension)
531 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
532 DisableExtension)
533 IPC_MESSAGE_HANDLER_DELAY_REPLY(
534 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
535 ExecuteExtensionActionInActiveTabAsync)
536 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
537 MoveExtensionBrowserAction)
538 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
539 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57540 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
541 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00542 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01543 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20544 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00545 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01546#if defined(TOOLKIT_VIEWS)
547 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
548 WaitForFocusedViewIDToChange)
549 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
550 StartTrackingPopupMenus)
551 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
552 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00553#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52554#if defined(OS_WIN)
555 // These are for use with external tabs.
556 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
557 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
558 ProcessUnhandledAccelerator)
559 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
560 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
561 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
562 OnForwardContextMenuCommandToChrome)
563 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
564 NavigateInExternalTab)
565 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
566 NavigateExternalTabAtIndex)
567 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
568 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
569 SetEnableExtensionAutomation)
570 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
571 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00572 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
[email protected]1f71d5882010-07-15 20:39:07573 IPC_MESSAGE_HANDLER(AutomationMsg_RunUnloadHandlers, OnRunUnloadHandlers)
[email protected]bdd5a9c92010-06-14 18:21:00574#endif // defined(OS_WIN)
575#if defined(OS_CHROMEOS)
576 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
577 LoginWithUserAndPass)
578#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29579 IPC_END_MESSAGE_MAP()
580}
581
[email protected]71f65dd2009-02-11 19:14:56582void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
583 *status = -1;
initial.commit09911bf2008-07-26 23:55:29584 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
585 Browser* browser = browser_tracker_->GetResource(handle);
586 if (at_index >= 0 && at_index < browser->tab_count()) {
587 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56588 *status = 0;
initial.commit09911bf2008-07-26 23:55:29589 }
590 }
initial.commit09911bf2008-07-26 23:55:29591}
592
[email protected]71f65dd2009-02-11 19:14:56593void AutomationProvider::AppendTab(int handle, const GURL& url,
594 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29595 int append_tab_response = -1; // -1 is the error code
596 NotificationObserver* observer = NULL;
597
598 if (browser_tracker_->ContainsHandle(handle)) {
599 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14600 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38601 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39602 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
603 NULL, std::string());
initial.commit09911bf2008-07-26 23:55:29604 if (tab_contents) {
605 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57606 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29607 }
608 }
609
610 if (append_tab_response < 0) {
611 // The append tab failed. Remove the TabStripObserver
612 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17613 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29614 delete observer;
615 }
616
[email protected]71f65dd2009-02-11 19:14:56617 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
618 append_tab_response);
619 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29620 }
621}
622
[email protected]71f65dd2009-02-11 19:14:56623void AutomationProvider::NavigateToURL(int handle, const GURL& url,
624 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58625 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
626}
627
628void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
629 int handle, const GURL& url, int number_of_navigations,
630 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29631 if (tab_tracker_->ContainsHandle(handle)) {
632 NavigationController* tab = tab_tracker_->GetResource(handle);
633
634 // Simulate what a user would do. Activate the tab and then navigate.
635 // We could allow navigating in a background tab in future.
636 Browser* browser = FindAndActivateTab(tab);
637
638 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01639 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
640 false);
[email protected]71f65dd2009-02-11 19:14:56641
initial.commit09911bf2008-07-26 23:55:29642 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50643 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29644 return;
645 }
646 }
[email protected]71f65dd2009-02-11 19:14:56647
648 AutomationMsg_NavigateToURL::WriteReplyParams(
649 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
650 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29651}
[email protected]2949e90d2009-08-21 15:32:52652
[email protected]c70f9b82010-04-21 07:31:11653void AutomationProvider::NavigationAsync(int handle,
654 const GURL& url,
655 bool* status) {
656 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
657}
658
659void AutomationProvider::NavigationAsyncWithDisposition(
660 int handle,
661 const GURL& url,
662 WindowOpenDisposition disposition,
663 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56664 *status = false;
initial.commit09911bf2008-07-26 23:55:29665
666 if (tab_tracker_->ContainsHandle(handle)) {
667 NavigationController* tab = tab_tracker_->GetResource(handle);
668
669 // Simulate what a user would do. Activate the tab and then navigate.
670 // We could allow navigating in a background tab in future.
671 Browser* browser = FindAndActivateTab(tab);
672
673 if (browser) {
674 // Don't add any listener unless a callback mechanism is desired.
675 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11676 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56677 *status = true;
initial.commit09911bf2008-07-26 23:55:29678 }
679 }
initial.commit09911bf2008-07-26 23:55:29680}
681
[email protected]71f65dd2009-02-11 19:14:56682void AutomationProvider::GoBack(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_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01687 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29688 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29689 return;
690 }
691 }
[email protected]71f65dd2009-02-11 19:14:56692
693 AutomationMsg_GoBack::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::GoForward(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_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01703 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29704 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29705 return;
706 }
707 }
[email protected]71f65dd2009-02-11 19:14:56708
709 AutomationMsg_GoForward::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::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29715 if (tab_tracker_->ContainsHandle(handle)) {
716 NavigationController* tab = tab_tracker_->GetResource(handle);
717 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14718 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01719 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28720 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29721 return;
722 }
723 }
[email protected]71f65dd2009-02-11 19:14:56724
725 AutomationMsg_Reload::WriteReplyParams(
726 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
727 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29728}
729
[email protected]71f65dd2009-02-11 19:14:56730void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29731 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56732 const std::wstring& password,
733 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29734 if (tab_tracker_->ContainsHandle(tab_handle)) {
735 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
736 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
737
738 if (iter != login_handler_map_.end()) {
739 // If auth is needed again after this, assume login has failed. This is
740 // not strictly correct, because a navigation can require both proxy and
741 // server auth, but it should be OK for now.
742 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01743 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29744 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52745 return;
initial.commit09911bf2008-07-26 23:55:29746 }
747 }
[email protected]de246f52009-02-25 18:25:45748
[email protected]457f5cf2009-08-18 16:37:52749 AutomationMsg_SetAuth::WriteReplyParams(
750 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
751 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29752}
753
[email protected]71f65dd2009-02-11 19:14:56754void AutomationProvider::CancelAuth(int tab_handle,
755 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29756 if (tab_tracker_->ContainsHandle(tab_handle)) {
757 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
758 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
759
760 if (iter != login_handler_map_.end()) {
761 // If auth is needed again after this, something is screwy.
762 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01763 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29764 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52765 return;
initial.commit09911bf2008-07-26 23:55:29766 }
767 }
[email protected]de246f52009-02-25 18:25:45768
[email protected]457f5cf2009-08-18 16:37:52769 AutomationMsg_CancelAuth::WriteReplyParams(
770 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
771 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29772}
773
[email protected]71f65dd2009-02-11 19:14:56774void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
775 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29776
777 if (tab_tracker_->ContainsHandle(tab_handle)) {
778 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
779 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
780
781 if (iter != login_handler_map_.end()) {
782 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56783 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29784 }
785 }
initial.commit09911bf2008-07-26 23:55:29786}
787
[email protected]71f65dd2009-02-11 19:14:56788void AutomationProvider::GetRedirectsFrom(int tab_handle,
789 const GURL& source_url,
790 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29791 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
792 if (tab_tracker_->ContainsHandle(tab_handle)) {
793 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
794 HistoryService* history_service =
795 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
796
797 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
798 "has no history service";
799 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56800 DCHECK(reply_message_ == NULL);
801 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29802 // Schedule a history query for redirects. The response will be sent
803 // asynchronously from the callback the history system uses to notify us
804 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29805 redirect_query_ = history_service->QueryRedirectsFrom(
806 source_url, &consumer_,
807 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
808 return; // Response will be sent when query completes.
809 }
810 }
811
812 // Send failure response.
[email protected]deb57402009-02-06 01:35:30813 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56814 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
815 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29816}
817
[email protected]71f65dd2009-02-11 19:14:56818void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
819 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29820 if (browser_tracker_->ContainsHandle(handle)) {
821 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56822 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29823 }
initial.commit09911bf2008-07-26 23:55:29824}
825
[email protected]202e7a72009-06-15 03:48:36826void AutomationProvider::GetBrowserLocale(string16* locale) {
827 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06828 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36829}
830
[email protected]71f65dd2009-02-11 19:14:56831void AutomationProvider::GetBrowserWindowCount(int* window_count) {
832 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29833}
834
[email protected]24497032009-05-01 17:00:29835void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
836 *window_count = static_cast<int>(
837 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
838}
839
[email protected]71f65dd2009-02-11 19:14:56840void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
841 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07842 AppModalDialog* dialog_delegate =
843 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50844 *showing_dialog = (dialog_delegate != NULL);
845 if (*showing_dialog)
846 *dialog_button = dialog_delegate->GetDialogButtons();
847 else
[email protected]478ff2ed2009-04-21 23:49:18848 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20849}
850
[email protected]71f65dd2009-02-11 19:14:56851void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
852 *success = false;
[email protected]fad84eab2008-12-05 00:37:20853
[email protected]1f460072009-05-28 17:02:07854 AppModalDialog* dialog_delegate =
855 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50856 if (dialog_delegate &&
857 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18858 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
859 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28860 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56861 *success = true;
[email protected]fad84eab2008-12-05 00:37:20862 }
[email protected]478ff2ed2009-04-21 23:49:18863 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
864 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56865 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28866 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56867 *success = true;
[email protected]fad84eab2008-12-05 00:37:20868 }
869 }
[email protected]c274acc2008-11-11 20:13:44870}
871
[email protected]fedaa7d2010-01-26 20:34:57872void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
873 if (browser_tracker_->ContainsHandle(handle)) {
874 Browser* browser = browser_tracker_->GetResource(handle);
875 browser->profile()->ShutdownSessionService();
876 *result = true;
877 } else {
878 *result = false;
879 }
880}
881
[email protected]71f65dd2009-02-11 19:14:56882void AutomationProvider::GetBrowserWindow(int index, int* handle) {
883 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29884 if (index >= 0) {
885 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30886 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29887 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56888 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29889 }
890 }
initial.commit09911bf2008-07-26 23:55:29891}
892
[email protected]24497032009-05-01 17:00:29893void AutomationProvider::FindNormalBrowserWindow(int* handle) {
894 *handle = 0;
895 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31896 Browser::TYPE_NORMAL,
897 false);
[email protected]24497032009-05-01 17:00:29898 if (browser)
899 *handle = browser_tracker_->Add(browser);
900}
901
[email protected]71f65dd2009-02-11 19:14:56902void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
903 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29904 Browser* browser = BrowserList::GetLastActive();
905 if (browser)
[email protected]71f65dd2009-02-11 19:14:56906 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29907}
908
[email protected]b2aa3ed72010-02-01 18:37:14909#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28910// TODO(estade): use this implementation for all platforms?
911void AutomationProvider::GetActiveWindow(int* handle) {
912 gfx::NativeWindow window =
913 BrowserList::GetLastActive()->window()->GetNativeHandle();
914 *handle = window_tracker_->Add(window);
915}
916#endif
917
[email protected]4f6381ee2009-04-16 02:46:33918void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
919 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56920 *success = false;
[email protected]4ae62752008-08-04 23:28:47921 if (browser_tracker_->ContainsHandle(handle)) {
922 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14923 if (browser->command_updater()->SupportsCommand(command) &&
924 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47925 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56926 *success = true;
[email protected]4ae62752008-08-04 23:28:47927 }
928 }
[email protected]4ae62752008-08-04 23:28:47929}
930
[email protected]4f6381ee2009-04-16 02:46:33931void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56932 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53933 // List of commands which just finish synchronously and don't require
934 // setting up an observer.
935 static const int kSynchronousCommands[] = {
936 IDC_HOME,
937 IDC_SELECT_NEXT_TAB,
938 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25939 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53940 };
[email protected]56e71b7c2009-03-27 03:05:56941 if (browser_tracker_->ContainsHandle(handle)) {
942 Browser* browser = browser_tracker_->GetResource(handle);
943 if (browser->command_updater()->SupportsCommand(command) &&
944 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53945 // First check if we can handle the command without using an observer.
946 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
947 if (command == kSynchronousCommands[i]) {
948 browser->ExecuteCommand(command);
949 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
950 true);
951 Send(reply_message);
952 return;
953 }
954 }
955
956 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42957 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
958 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27959 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42960 return;
961 }
[email protected]56e71b7c2009-03-27 03:05:56962 }
963 }
[email protected]49a14a82009-03-31 04:16:44964 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56965 Send(reply_message);
966}
967
[email protected]fc2e0872009-08-21 22:14:41968// This task just adds another task to the event queue. This is useful if
969// you want to ensure that any tasks added to the event queue after this one
970// have already been processed by the time |task| is run.
971class InvokeTaskLaterTask : public Task {
972 public:
973 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
974 virtual ~InvokeTaskLaterTask() {}
975
976 virtual void Run() {
977 MessageLoop::current()->PostTask(FROM_HERE, task_);
978 }
979
980 private:
981 Task* task_;
982
983 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
984};
985
initial.commit09911bf2008-07-26 23:55:29986void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
987 int handle,
[email protected]d1a5941e2009-08-13 23:34:24988 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29989 int flags) {
[email protected]b410bc32009-08-14 01:11:14990 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51991 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41992 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29993 }
994}
995
[email protected]60507b12009-11-02 23:51:35996void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
997 int handle,
998 const gfx::Point& location) {
999 if (window_tracker_->ContainsHandle(handle))
1000 ui_controls::SendMouseMove(location.x(), location.y());
1001}
1002
initial.commit09911bf2008-07-26 23:55:291003void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1004 int handle,
[email protected]bc1407f2009-09-29 00:33:351005 int key,
initial.commit09911bf2008-07-26 23:55:291006 int flags) {
[email protected]b410bc32009-08-14 01:11:141007 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291008 return;
1009
[email protected]b410bc32009-08-14 01:11:141010 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291011 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:351012 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:381013 ((flags & views::Event::EF_CONTROL_DOWN) ==
1014 views::Event::EF_CONTROL_DOWN),
1015 ((flags & views::Event::EF_SHIFT_DOWN) ==
1016 views::Event::EF_SHIFT_DOWN),
1017 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:301018 views::Event::EF_ALT_DOWN),
1019 ((flags & views::Event::EF_COMMAND_DOWN) ==
1020 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291021}
initial.commit09911bf2008-07-26 23:55:291022
[email protected]71f65dd2009-02-11 19:14:561023void AutomationProvider::IsWindowActive(int handle, bool* success,
1024 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291025 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171026 *is_active =
1027 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561028 *success = true;
initial.commit09911bf2008-07-26 23:55:291029 } else {
[email protected]71f65dd2009-02-11 19:14:561030 *success = false;
1031 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291032 }
1033}
1034
[email protected]71f65dd2009-02-11 19:14:561035void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1036 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291037
1038 if (browser_tracker_->ContainsHandle(handle)) {
1039 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561040 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291041 }
initial.commit09911bf2008-07-26 23:55:291042}
1043
[email protected]982921f12009-10-27 21:43:531044void AutomationProvider::GetType(int handle, int* type_as_int) {
1045 *type_as_int = -1; // -1 is the error code
1046
1047 if (browser_tracker_->ContainsHandle(handle)) {
1048 Browser* browser = browser_tracker_->GetResource(handle);
1049 *type_as_int = static_cast<int>(browser->type());
1050 }
1051}
1052
[email protected]71f65dd2009-02-11 19:14:561053void AutomationProvider::GetTab(int win_handle, int tab_index,
1054 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561055 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291056 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1057 Browser* browser = browser_tracker_->GetResource(win_handle);
1058 if (tab_index < browser->tab_count()) {
1059 TabContents* tab_contents =
1060 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571061 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291062 }
1063 }
initial.commit09911bf2008-07-26 23:55:291064}
1065
[email protected]71f65dd2009-02-11 19:14:561066void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1067 std::wstring* title) {
1068 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291069 if (tab_tracker_->ContainsHandle(handle)) {
1070 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361071 NavigationEntry* entry = tab->GetActiveEntry();
1072 if (entry != NULL) {
1073 *title = UTF16ToWideHack(entry->title());
1074 } else {
1075 *title = std::wstring();
1076 }
[email protected]71f65dd2009-02-11 19:14:561077 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291078 }
initial.commit09911bf2008-07-26 23:55:291079}
1080
[email protected]77bc6732009-04-20 22:01:031081void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1082 *tabstrip_index = -1; // -1 is the error code
1083
1084 if (tab_tracker_->ContainsHandle(handle)) {
1085 NavigationController* tab = tab_tracker_->GetResource(handle);
1086 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121087 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031088 }
1089}
1090
initial.commit09911bf2008-07-26 23:55:291091void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1092 if (window_tracker_->ContainsHandle(handle)) {
1093 window_tracker_->Remove(window_tracker_->GetResource(handle));
1094 }
1095}
1096
1097void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161098 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571099 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291100}
1101
1102// TODO(brettw) change this to accept GURLs when history supports it
1103void AutomationProvider::OnRedirectQueryComplete(
1104 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371105 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291106 bool success,
[email protected]379c2b12009-07-01 21:50:331107 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291108 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561109 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291110
[email protected]deb57402009-02-06 01:35:301111 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101112 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291113 if (success) {
initial.commit09911bf2008-07-26 23:55:291114 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301115 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291116 }
1117
[email protected]4f3dc372009-02-24 00:10:291118 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301119
[email protected]71f65dd2009-02-11 19:14:561120 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231121 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561122 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291123}
1124
1125bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571126 DCHECK(channel_.get());
1127 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291128}
1129
1130Browser* AutomationProvider::FindAndActivateTab(
1131 NavigationController* controller) {
1132 int tab_index;
1133 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1134 if (browser)
1135 browser->SelectTabContentsAt(tab_index, true);
1136
1137 return browser;
1138}
1139
[email protected]9eaa18e2010-06-29 20:51:011140namespace {
1141
1142class GetCookiesTask : public Task {
1143 public:
1144 GetCookiesTask(const GURL& url,
1145 URLRequestContextGetter* context_getter,
1146 base::WaitableEvent* event,
1147 std::string* cookies)
1148 : url_(url),
1149 context_getter_(context_getter),
1150 event_(event),
1151 cookies_(cookies) {}
1152
1153 virtual void Run() {
1154 *cookies_ = context_getter_->GetCookieStore()->GetCookies(url_);
1155 event_->Signal();
1156 }
1157
1158 private:
1159 const GURL& url_;
1160 URLRequestContextGetter* const context_getter_;
1161 base::WaitableEvent* const event_;
1162 std::string* const cookies_;
1163
1164 DISALLOW_COPY_AND_ASSIGN(GetCookiesTask);
1165};
1166
1167std::string GetCookiesForURL(
1168 const GURL& url,
1169 URLRequestContextGetter* context_getter) {
1170 std::string cookies;
1171 base::WaitableEvent event(true /* manual reset */,
1172 false /* not initially signaled */);
1173 CHECK(ChromeThread::PostTask(
1174 ChromeThread::IO, FROM_HERE,
1175 new GetCookiesTask(url, context_getter, &event, &cookies)));
1176 event.Wait();
1177 return cookies;
1178}
1179
1180class SetCookieTask : public Task {
1181 public:
1182 SetCookieTask(const GURL& url,
1183 const std::string& value,
1184 URLRequestContextGetter* context_getter,
1185 base::WaitableEvent* event,
1186 bool* rv)
1187 : url_(url),
1188 value_(value),
1189 context_getter_(context_getter),
1190 event_(event),
1191 rv_(rv) {}
1192
1193 virtual void Run() {
1194 *rv_ = context_getter_->GetCookieStore()->SetCookie(url_, value_);
1195 event_->Signal();
1196 }
1197
1198 private:
1199 const GURL& url_;
1200 const std::string& value_;
1201 URLRequestContextGetter* const context_getter_;
1202 base::WaitableEvent* const event_;
1203 bool* const rv_;
1204
1205 DISALLOW_COPY_AND_ASSIGN(SetCookieTask);
1206};
1207
1208bool SetCookieForURL(
1209 const GURL& url,
1210 const std::string& value,
1211 URLRequestContextGetter* context_getter) {
1212 base::WaitableEvent event(true /* manual reset */,
1213 false /* not initially signaled */);
1214 bool rv = false;
1215 CHECK(ChromeThread::PostTask(
1216 ChromeThread::IO, FROM_HERE,
1217 new SetCookieTask(url, value, context_getter, &event, &rv)));
1218 event.Wait();
1219 return rv;
1220}
1221
1222class DeleteCookieTask : public Task {
1223 public:
1224 DeleteCookieTask(const GURL& url,
1225 const std::string& name,
1226 const scoped_refptr<URLRequestContextGetter>& context_getter)
1227 : url_(url),
1228 name_(name),
1229 context_getter_(context_getter) {}
1230
1231 virtual void Run() {
1232 net::CookieStore* cookie_store = context_getter_->GetCookieStore();
1233 cookie_store->DeleteCookie(url_, name_);
1234 }
1235
1236 private:
1237 const GURL url_;
1238 const std::string name_;
1239 const scoped_refptr<URLRequestContextGetter> context_getter_;
1240
1241 DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
1242};
1243
1244} // namespace
1245
[email protected]71f65dd2009-02-11 19:14:561246void AutomationProvider::GetCookies(const GURL& url, int handle,
1247 int* value_size,
1248 std::string* value) {
1249 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291250 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1251 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311252
1253 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]674b3822010-08-04 04:02:511254 *value = GetCookiesForURL(url, tab->profile()->GetRequestContext());
[email protected]71f65dd2009-02-11 19:14:561255 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291256 }
initial.commit09911bf2008-07-26 23:55:291257}
1258
[email protected]71f65dd2009-02-11 19:14:561259void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291260 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561261 int handle,
1262 int* response_value) {
1263 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291264
1265 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1266 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311267
[email protected]674b3822010-08-04 04:02:511268 if (SetCookieForURL(url, value, tab->profile()->GetRequestContext()))
[email protected]71f65dd2009-02-11 19:14:561269 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291270 }
initial.commit09911bf2008-07-26 23:55:291271}
1272
[email protected]5fa57942010-04-21 23:07:221273void AutomationProvider::DeleteCookie(const GURL& url,
1274 const std::string& cookie_name,
1275 int handle, bool* success) {
1276 *success = false;
1277 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1278 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]9eaa18e2010-06-29 20:51:011279 ChromeThread::PostTask(
1280 ChromeThread::IO, FROM_HERE,
1281 new DeleteCookieTask(url, cookie_name,
1282 tab->profile()->GetRequestContext()));
[email protected]5fa57942010-04-21 23:07:221283 *success = true;
1284 }
1285}
1286
[email protected]a503c97c2010-07-16 13:05:481287void AutomationProvider::ShowCollectedCookiesDialog(
1288 int handle, bool* success) {
1289 *success = false;
1290 if (tab_tracker_->ContainsHandle(handle)) {
1291 TabContents* tab_contents =
1292 tab_tracker_->GetResource(handle)->tab_contents();
1293 tab_contents->delegate()->ShowCollectedCookiesDialog(tab_contents);
1294 *success = true;
1295 }
1296}
1297
[email protected]71f65dd2009-02-11 19:14:561298void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1299 *success = false;
initial.commit09911bf2008-07-26 23:55:291300 if (tab_tracker_->ContainsHandle(handle)) {
1301 NavigationController* tab = tab_tracker_->GetResource(handle);
1302 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541303 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561304 *success = true;
initial.commit09911bf2008-07-26 23:55:291305 }
initial.commit09911bf2008-07-26 23:55:291306}
1307
[email protected]71f65dd2009-02-11 19:14:561308void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1309 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291310
1311 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561312 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341313 TabContents* tab_contents =
1314 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161315 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1316 if (rph)
1317 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291318 }
initial.commit09911bf2008-07-26 23:55:291319}
1320
1321void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331322 NOTREACHED() << "This function has been deprecated. "
1323 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291324}
1325
[email protected]71f65dd2009-02-11 19:14:561326void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291327 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561328 const std::wstring& script,
1329 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291330 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341331 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1332 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571333 // Set the routing id of this message with the controller.
1334 // This routing id needs to be remembered for the reverse
1335 // communication while sending back the response of
1336 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331337 std::wstring set_automation_id;
1338 SStringPrintf(&set_automation_id,
1339 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561340 reply_message->routing_id());
1341
1342 DCHECK(reply_message_ == NULL);
1343 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291344
[email protected]57c6a652009-05-04 07:58:341345 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331346 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341347 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061348 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571349 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291350 }
1351
1352 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561353 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1354 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291355 }
1356}
1357
[email protected]71f65dd2009-02-11 19:14:561358void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1359 *visible = false;
[email protected]20e93d12008-08-28 16:31:571360
[email protected]59560e0b2009-06-04 03:30:221361 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251362#if defined(OS_CHROMEOS)
1363 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1364 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1365 for (BrowserList::const_iterator it = BrowserList::begin();
1366 it != BrowserList::end(); ++it) {
1367 if ((*it)->type() == Browser::TYPE_POPUP) {
1368 const GURL& url =
1369 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1370
1371 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1372 url.host() == chrome::kChromeUIFileBrowseHost) {
1373 *visible = true;
1374 break;
1375 }
1376 }
1377 }
1378#else
[email protected]59560e0b2009-06-04 03:30:221379 Browser* browser = browser_tracker_->GetResource(handle);
1380 if (browser) {
1381 *visible = browser->window()->IsDownloadShelfVisible();
1382 }
[email protected]f5bf8ccf2010-02-05 18:19:251383#endif
[email protected]59560e0b2009-06-04 03:30:221384 }
initial.commit09911bf2008-07-26 23:55:291385}
1386
[email protected]59560e0b2009-06-04 03:30:221387void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1388 if (browser_tracker_->ContainsHandle(handle)) {
1389 Browser* browser = browser_tracker_->GetResource(handle);
1390 if (browser) {
1391 if (visible)
1392 browser->window()->GetDownloadShelf()->Show();
1393 else
1394 browser->window()->GetDownloadShelf()->Close();
1395 }
1396 }
1397}
1398
[email protected]34930432009-11-09 00:12:091399void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1400 *visible = false;
1401
1402 if (browser_tracker_->ContainsHandle(handle)) {
1403 Browser* browser = browser_tracker_->GetResource(handle);
1404 if (browser)
1405 *visible = browser->window()->IsFullscreen();
1406 }
1407}
1408
1409void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1410 bool* visible) {
1411 *visible = false;
1412
1413 if (browser_tracker_->ContainsHandle(handle)) {
1414 Browser* browser = browser_tracker_->GetResource(handle);
1415 if (browser)
1416 *visible = browser->window()->IsFullscreenBubbleVisible();
1417 }
1418}
[email protected]59560e0b2009-06-04 03:30:221419
[email protected]71f65dd2009-02-11 19:14:561420void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1421 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291422 if (tab_tracker_->ContainsHandle(handle)) {
1423 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111424 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291425 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561426 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291427 }
1428 }
initial.commit09911bf2008-07-26 23:55:291429}
1430
initial.commit09911bf2008-07-26 23:55:291431void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561432 int handle, const std::wstring& find_request,
1433 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311434 NOTREACHED() << "This function has been deprecated."
1435 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561436 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311437 return;
1438}
1439
[email protected]4f999132009-03-31 18:08:401440void AutomationProvider::HandleFindRequest(
1441 int handle,
1442 const AutomationMsg_Find_Params& params,
1443 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291444 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561445 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1446 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291447 return;
1448 }
1449
1450 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111451 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291452
1453 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141454 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291455
[email protected]57c6a652009-05-04 07:58:341456 tab_contents->set_current_find_request_id(
1457 FindInPageNotificationObserver::kFindInPageRequestId);
1458 tab_contents->render_view_host()->StartFinding(
1459 FindInPageNotificationObserver::kFindInPageRequestId,
1460 params.search_string, params.forward, params.match_case,
1461 params.find_next);
initial.commit09911bf2008-07-26 23:55:291462}
1463
[email protected]5f8af2a2008-08-06 22:49:451464void AutomationProvider::HandleOpenFindInPageRequest(
1465 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291466 if (browser_tracker_->ContainsHandle(handle)) {
1467 Browser* browser = browser_tracker_->GetResource(handle);
1468 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451469 }
1470}
1471
[email protected]71f65dd2009-02-11 19:14:561472void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561473 *visible = false;
[email protected]855c0142009-09-28 22:35:241474 Browser* browser = browser_tracker_->GetResource(handle);
1475 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581476 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171477 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241478 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291479 }
[email protected]20e93d12008-08-28 16:31:571480}
1481
[email protected]71f65dd2009-02-11 19:14:561482void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1483 int* y) {
[email protected]9e0534b2008-10-21 15:03:011484 gfx::Point position(0, 0);
1485 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291486 if (browser_tracker_->ContainsHandle(handle)) {
1487 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581488 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171489 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581490 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291491 }
[email protected]20e93d12008-08-28 16:31:571492
[email protected]71f65dd2009-02-11 19:14:561493 *x = position.x();
1494 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571495}
1496
[email protected]4512cb52010-04-05 19:50:251497// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1498// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581499void AutomationProvider::GetBookmarkBarVisibility(int handle,
1500 bool* visible,
1501 bool* animating) {
1502 *visible = false;
1503 *animating = false;
1504
1505 if (browser_tracker_->ContainsHandle(handle)) {
1506 Browser* browser = browser_tracker_->GetResource(handle);
1507 if (browser) {
[email protected]472f099b2010-05-27 17:07:121508#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1509 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1510
[email protected]ab6ca392010-04-07 00:44:131511 // IsBookmarkBarVisible() line looks correct but is not
1512 // consistent across platforms. Specifically, on Mac/Linux, it
1513 // returns false if the bar is hidden in a pref (even if visible
1514 // on the NTP). On ChromeOS, it returned true if on NTP
1515 // independent of the pref. Making the code more consistent
1516 // caused a perf bot regression on Windows (which shares views).
1517 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251518 *visible = browser->profile()->GetPrefs()->GetBoolean(
1519 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401520#else
1521 *visible = browser->window()->IsBookmarkBarVisible();
1522#endif
[email protected]c3240722010-03-05 21:52:581523 *animating = browser->window()->IsBookmarkBarAnimating();
1524 }
1525 }
1526}
1527
[email protected]6d8ffc9f2010-03-12 18:27:531528void AutomationProvider::GetBookmarksAsJSON(int handle,
1529 std::string* bookmarks_as_json,
1530 bool *success) {
1531 *success = false;
1532 if (browser_tracker_->ContainsHandle(handle)) {
1533 Browser* browser = browser_tracker_->GetResource(handle);
1534 if (browser) {
1535 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1536 return;
1537 }
1538 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1539 browser->profile(),
1540 browser->profile()->GetBookmarkModel());
1541 *success = storage->SerializeData(bookmarks_as_json);
1542 }
1543 }
1544}
1545
1546void AutomationProvider::WaitForBookmarkModelToLoad(
1547 int handle,
1548 IPC::Message* reply_message) {
1549 if (browser_tracker_->ContainsHandle(handle)) {
1550 Browser* browser = browser_tracker_->GetResource(handle);
1551 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1552 if (model->IsLoaded()) {
1553 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1554 reply_message, true);
1555 Send(reply_message);
1556 } else {
1557 // The observer will delete itself when done.
1558 new AutomationProviderBookmarkModelObserver(this, reply_message,
1559 model);
1560 }
1561 }
1562}
1563
1564void AutomationProvider::AddBookmarkGroup(int handle,
1565 int64 parent_id, int index,
1566 std::wstring title,
1567 bool* success) {
1568 if (browser_tracker_->ContainsHandle(handle)) {
1569 Browser* browser = browser_tracker_->GetResource(handle);
1570 if (browser) {
1571 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1572 if (!model->IsLoaded()) {
1573 *success = false;
1574 return;
1575 }
1576 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1577 DCHECK(parent);
1578 if (parent) {
1579 const BookmarkNode* child = model->AddGroup(parent, index,
[email protected]ff4c1d82010-08-04 16:58:121580 WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:531581 DCHECK(child);
1582 if (child)
1583 *success = true;
1584 }
1585 }
1586 }
1587 *success = false;
1588}
1589
1590void AutomationProvider::AddBookmarkURL(int handle,
1591 int64 parent_id, int index,
1592 std::wstring title, const GURL& url,
1593 bool* success) {
1594 if (browser_tracker_->ContainsHandle(handle)) {
1595 Browser* browser = browser_tracker_->GetResource(handle);
1596 if (browser) {
1597 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1598 if (!model->IsLoaded()) {
1599 *success = false;
1600 return;
1601 }
1602 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1603 DCHECK(parent);
1604 if (parent) {
1605 const BookmarkNode* child = model->AddURL(parent, index,
[email protected]ff4c1d82010-08-04 16:58:121606 WideToUTF16Hack(title), url);
[email protected]6d8ffc9f2010-03-12 18:27:531607 DCHECK(child);
1608 if (child)
1609 *success = true;
1610 }
1611 }
1612 }
1613 *success = false;
1614}
1615
1616void AutomationProvider::ReparentBookmark(int handle,
1617 int64 id, int64 new_parent_id,
1618 int index,
1619 bool* success) {
1620 if (browser_tracker_->ContainsHandle(handle)) {
1621 Browser* browser = browser_tracker_->GetResource(handle);
1622 if (browser) {
1623 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1624 if (!model->IsLoaded()) {
1625 *success = false;
1626 return;
1627 }
1628 const BookmarkNode* node = model->GetNodeByID(id);
1629 DCHECK(node);
1630 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1631 DCHECK(new_parent);
1632 if (node && new_parent) {
1633 model->Move(node, new_parent, index);
1634 *success = true;
1635 }
1636 }
1637 }
1638 *success = false;
1639}
1640
1641void AutomationProvider::SetBookmarkTitle(int handle,
1642 int64 id, std::wstring title,
1643 bool* success) {
1644 if (browser_tracker_->ContainsHandle(handle)) {
1645 Browser* browser = browser_tracker_->GetResource(handle);
1646 if (browser) {
1647 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1648 if (!model->IsLoaded()) {
1649 *success = false;
1650 return;
1651 }
1652 const BookmarkNode* node = model->GetNodeByID(id);
1653 DCHECK(node);
1654 if (node) {
[email protected]ff4c1d82010-08-04 16:58:121655 model->SetTitle(node, WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:531656 *success = true;
1657 }
1658 }
1659 }
1660 *success = false;
1661}
1662
1663void AutomationProvider::SetBookmarkURL(int handle,
1664 int64 id, const GURL& url,
1665 bool* success) {
1666 if (browser_tracker_->ContainsHandle(handle)) {
1667 Browser* browser = browser_tracker_->GetResource(handle);
1668 if (browser) {
1669 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1670 if (!model->IsLoaded()) {
1671 *success = false;
1672 return;
1673 }
1674 const BookmarkNode* node = model->GetNodeByID(id);
1675 DCHECK(node);
1676 if (node) {
1677 model->SetURL(node, url);
1678 *success = true;
1679 }
1680 }
1681 }
1682 *success = false;
1683}
1684
1685void AutomationProvider::RemoveBookmark(int handle,
1686 int64 id,
1687 bool* success) {
1688 if (browser_tracker_->ContainsHandle(handle)) {
1689 Browser* browser = browser_tracker_->GetResource(handle);
1690 if (browser) {
1691 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1692 if (!model->IsLoaded()) {
1693 *success = false;
1694 return;
1695 }
1696 const BookmarkNode* node = model->GetNodeByID(id);
1697 DCHECK(node);
1698 if (node) {
1699 const BookmarkNode* parent = node->GetParent();
1700 DCHECK(parent);
1701 model->Remove(parent, parent->IndexOfChild(node));
1702 *success = true;
1703 }
1704 }
1705 }
1706 *success = false;
1707}
1708
[email protected]ef413ca2010-05-25 21:09:141709// Sample json input: { "command": "SetWindowDimensions",
1710// "x": 20, # optional
1711// "y": 20, # optional
1712// "width": 800, # optional
1713// "height": 600 } # optional
1714void AutomationProvider::SetWindowDimensions(Browser* browser,
1715 DictionaryValue* args,
1716 IPC::Message* reply_message) {
1717 gfx::Rect rect = browser->window()->GetRestoredBounds();
1718 int x, y, width, height;
[email protected]ff4c1d82010-08-04 16:58:121719 if (args->GetInteger("x", &x))
[email protected]ef413ca2010-05-25 21:09:141720 rect.set_x(x);
[email protected]ff4c1d82010-08-04 16:58:121721 if (args->GetInteger("y", &y))
[email protected]ef413ca2010-05-25 21:09:141722 rect.set_y(y);
[email protected]ff4c1d82010-08-04 16:58:121723 if (args->GetInteger("width", &width))
[email protected]ef413ca2010-05-25 21:09:141724 rect.set_width(width);
[email protected]ff4c1d82010-08-04 16:58:121725 if (args->GetInteger("height", &height))
[email protected]ef413ca2010-05-25 21:09:141726 rect.set_height(height);
1727 browser->window()->SetBounds(rect);
[email protected]7c983cc2010-07-16 11:33:341728 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
[email protected]ef413ca2010-05-25 21:09:141729}
1730
[email protected]38b5a3852010-07-21 06:49:521731ListValue* AutomationProvider::GetInfobarsInfo(TabContents* tc) {
1732 // Each infobar may have different properties depending on the type.
1733 ListValue* infobars = new ListValue;
1734 for (int infobar_index = 0;
1735 infobar_index < tc->infobar_delegate_count();
1736 ++infobar_index) {
1737 DictionaryValue* infobar_item = new DictionaryValue;
1738 InfoBarDelegate* infobar = tc->GetInfoBarDelegateAt(infobar_index);
1739 if (infobar->AsConfirmInfoBarDelegate()) {
1740 // Also covers ThemeInstalledInfoBarDelegate and
1741 // CrashedExtensionInfoBarDelegate.
[email protected]ff4c1d82010-08-04 16:58:121742 infobar_item->SetString("type", "confirm_infobar");
[email protected]38b5a3852010-07-21 06:49:521743 ConfirmInfoBarDelegate* confirm_infobar =
1744 infobar->AsConfirmInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:121745 infobar_item->SetString("text",
1746 WideToUTF16Hack(confirm_infobar->GetMessageText()));
1747 infobar_item->SetString("link_text",
1748 WideToUTF16Hack(confirm_infobar->GetLinkText()));
[email protected]38b5a3852010-07-21 06:49:521749 ListValue* buttons_list = new ListValue;
1750 int buttons = confirm_infobar->GetButtons();
1751 if (ConfirmInfoBarDelegate::BUTTON_OK & buttons) {
1752 StringValue* button_label = new StringValue(
1753 confirm_infobar->GetButtonLabel(
1754 ConfirmInfoBarDelegate::BUTTON_OK));
1755 buttons_list->Append(button_label);
1756 }
1757 if (ConfirmInfoBarDelegate::BUTTON_CANCEL & buttons) {
1758 StringValue* button_label = new StringValue(
1759 confirm_infobar->GetButtonLabel(
1760 ConfirmInfoBarDelegate::BUTTON_CANCEL));
1761 buttons_list->Append(button_label);
1762 }
[email protected]ff4c1d82010-08-04 16:58:121763 infobar_item->Set("buttons", buttons_list);
[email protected]38b5a3852010-07-21 06:49:521764 } else if (infobar->AsAlertInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121765 infobar_item->SetString("type", "alert_infobar");
[email protected]38b5a3852010-07-21 06:49:521766 AlertInfoBarDelegate* alert_infobar =
1767 infobar->AsAlertInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:121768 infobar_item->SetString("text",
1769 WideToUTF16Hack(alert_infobar->GetMessageText()));
[email protected]38b5a3852010-07-21 06:49:521770 } else if (infobar->AsLinkInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121771 infobar_item->SetString("type", "link_infobar");
[email protected]38b5a3852010-07-21 06:49:521772 LinkInfoBarDelegate* link_infobar = infobar->AsLinkInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:121773 infobar_item->SetString("link_text",
1774 WideToUTF16Hack(link_infobar->GetLinkText()));
[email protected]38b5a3852010-07-21 06:49:521775 } else if (infobar->AsTranslateInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121776 infobar_item->SetString("type", "translate_infobar");
[email protected]38b5a3852010-07-21 06:49:521777 TranslateInfoBarDelegate* translate_infobar =
1778 infobar->AsTranslateInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:121779 infobar_item->SetString("original_lang_code",
[email protected]38b5a3852010-07-21 06:49:521780 translate_infobar->GetOriginalLanguageCode());
[email protected]ff4c1d82010-08-04 16:58:121781 infobar_item->SetString("target_lang_code",
[email protected]38b5a3852010-07-21 06:49:521782 translate_infobar->GetTargetLanguageCode());
1783 } else if (infobar->AsExtensionInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:121784 infobar_item->SetString("type", "extension_infobar");
[email protected]38b5a3852010-07-21 06:49:521785 } else {
[email protected]ff4c1d82010-08-04 16:58:121786 infobar_item->SetString("type", "unknown_infobar");
[email protected]38b5a3852010-07-21 06:49:521787 }
1788 infobars->Append(infobar_item);
1789 }
1790 return infobars;
1791}
1792
1793// Sample json input: { "command": "WaitForInfobarCount",
1794// "count": COUNT,
1795// "tab_index": INDEX }
1796// Sample output: {}
1797void AutomationProvider::WaitForInfobarCount(Browser* browser,
1798 DictionaryValue* args,
1799 IPC::Message* reply_message) {
1800 int tab_index;
1801 int count;
[email protected]ff4c1d82010-08-04 16:58:121802 if (!args->GetInteger("count", &count) || count < 0 ||
1803 !args->GetInteger("tab_index", &tab_index) || tab_index < 0) {
[email protected]38b5a3852010-07-21 06:49:521804 AutomationJSONReply(this, reply_message).SendError(
1805 "Missing or invalid args: 'count', 'tab_index'.");
1806 return;
1807 }
1808
1809 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
1810 // Observer deletes itself.
1811 new WaitForInfobarCountObserver(this, reply_message, tab_contents, count);
1812}
1813
[email protected]e004a2d2010-07-22 04:55:281814// Sample json input: { "command": "PerformActionOnInfobar",
1815// "action": "dismiss",
1816// "infobar_index": 0,
1817// "tab_index": 0 }
1818// Sample output: {}
1819void AutomationProvider::PerformActionOnInfobar(Browser* browser,
1820 DictionaryValue* args,
1821 IPC::Message* reply_message) {
1822 AutomationJSONReply reply(this, reply_message);
1823 int tab_index;
1824 int infobar_index;
1825 std::string action;
[email protected]ff4c1d82010-08-04 16:58:121826 if (!args->GetInteger("tab_index", &tab_index) ||
1827 !args->GetInteger("infobar_index", &infobar_index) ||
1828 !args->GetString("action", &action)) {
[email protected]e004a2d2010-07-22 04:55:281829 reply.SendError("Invalid or missing args");
1830 return;
1831 }
1832 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
1833 if (!tab_contents) {
1834 reply.SendError(StringPrintf("No such tab at index %d", tab_index));
1835 return;
1836 }
1837 InfoBarDelegate* infobar = NULL;
1838 if (infobar_index < 0 ||
1839 infobar_index >= tab_contents->infobar_delegate_count() ||
1840 !(infobar = tab_contents->GetInfoBarDelegateAt(infobar_index))) {
1841 reply.SendError(StringPrintf("No such infobar at index %d", infobar_index));
1842 return;
1843 }
1844 if ("dismiss" == action) {
1845 infobar->InfoBarDismissed();
1846 tab_contents->RemoveInfoBar(infobar);
1847 reply.SendSuccess(NULL);
1848 return;
1849 }
1850 if ("accept" == action || "cancel" == action) {
1851 ConfirmInfoBarDelegate* confirm_infobar;
1852 if (!(confirm_infobar = infobar->AsConfirmInfoBarDelegate())) {
1853 reply.SendError("Not a confirm infobar");
1854 return;
1855 }
1856 if ("accept" == action) {
1857 if (confirm_infobar->Accept())
1858 tab_contents->RemoveInfoBar(infobar);
1859 } else if ("cancel" == action) {
1860 if (confirm_infobar->Cancel())
1861 tab_contents->RemoveInfoBar(infobar);
1862 }
1863 reply.SendSuccess(NULL);
1864 return;
1865 }
1866 reply.SendError("Invalid action");
1867}
1868
[email protected]26adfd312010-07-20 01:04:461869namespace {
1870
1871// Task to get info about BrowserChildProcessHost. Must run on IO thread to
1872// honor the semantics of BrowserChildProcessHost.
1873// Used by AutomationProvider::GetBrowserInfo().
1874class GetChildProcessHostInfoTask : public Task {
1875 public:
1876 GetChildProcessHostInfoTask(base::WaitableEvent* event,
1877 ListValue* child_processes)
1878 : event_(event),
1879 child_processes_(child_processes) {}
1880
1881 virtual void Run() {
1882 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
1883 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1884 // Only add processes which are already started,
1885 // since we need their handle.
1886 if ((*iter)->handle() == base::kNullProcessHandle) {
1887 continue;
1888 }
1889 ChildProcessInfo* info = *iter;
1890 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121891 item->SetString("name", WideToUTF16Hack(info->name()));
1892 item->SetString("type",
1893 WideToUTF16Hack(ChildProcessInfo::GetTypeNameInEnglish(
1894 info->type())));
1895 item->SetInteger("pid", base::GetProcId(info->handle()));
[email protected]26adfd312010-07-20 01:04:461896 child_processes_->Append(item);
1897 }
1898 event_->Signal();
1899 }
1900
1901 private:
1902 base::WaitableEvent* const event_; // weak
1903 ListValue* child_processes_;
1904
1905 DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask);
1906};
1907
1908} // namespace
1909
[email protected]a9ff2c02010-05-13 17:33:051910// Sample json input: { "command": "GetBrowserInfo" }
1911// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1912// sample json output.
[email protected]53329582010-05-14 21:10:581913void AutomationProvider::GetBrowserInfo(Browser* browser,
1914 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051915 IPC::Message* reply_message) {
[email protected]a9ff2c02010-05-13 17:33:051916 DictionaryValue* properties = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121917 properties->SetString("ChromeVersion", chrome::kChromeVersion);
1918 properties->SetString("BrowserProcessExecutableName",
1919 WideToUTF16Hack(chrome::kBrowserProcessExecutableName));
1920 properties->SetString("HelperProcessExecutableName",
1921 WideToUTF16Hack(chrome::kHelperProcessExecutableName));
1922 properties->SetString("BrowserProcessExecutablePath",
1923 WideToUTF16Hack(chrome::kBrowserProcessExecutablePath));
1924 properties->SetString("HelperProcessExecutablePath",
[email protected]a9ff2c02010-05-13 17:33:051925 chrome::kHelperProcessExecutablePath);
[email protected]ff4c1d82010-08-04 16:58:121926 properties->SetString("command_line_string",
[email protected]a9ff2c02010-05-13 17:33:051927 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001928
1929 std::string branding;
1930#if defined(GOOGLE_CHROME_BUILD)
1931 branding = "Google Chrome";
1932#elif defined(CHROMIUM_BUILD)
1933 branding = "Chromium";
1934#else
1935 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051936#endif
[email protected]ff4c1d82010-08-04 16:58:121937 properties->SetString("branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051938
1939 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:121940 return_value->Set("properties", properties);
[email protected]a9ff2c02010-05-13 17:33:051941
[email protected]ff4c1d82010-08-04 16:58:121942 return_value->SetInteger("browser_pid", base::GetCurrentProcId());
[email protected]ef413ca2010-05-25 21:09:141943 // Add info about all windows in a list of dictionaries, one dictionary
1944 // item per window.
1945 ListValue* windows = new ListValue;
1946 int windex = 0;
1947 for (BrowserList::const_iterator it = BrowserList::begin();
1948 it != BrowserList::end();
1949 ++it, ++windex) {
1950 DictionaryValue* browser_item = new DictionaryValue;
1951 browser = *it;
[email protected]ff4c1d82010-08-04 16:58:121952 browser_item->SetInteger("index", windex);
[email protected]ef413ca2010-05-25 21:09:141953 // Window properties
1954 gfx::Rect rect = browser->window()->GetRestoredBounds();
[email protected]ff4c1d82010-08-04 16:58:121955 browser_item->SetInteger("x", rect.x());
1956 browser_item->SetInteger("y", rect.y());
1957 browser_item->SetInteger("width", rect.width());
1958 browser_item->SetInteger("height", rect.height());
1959 browser_item->SetBoolean("fullscreen",
[email protected]ef413ca2010-05-25 21:09:141960 browser->window()->IsFullscreen());
[email protected]ff4c1d82010-08-04 16:58:121961 browser_item->SetInteger("selected_tab", browser->selected_index());
1962 browser_item->SetBoolean("incognito",
[email protected]ef413ca2010-05-25 21:09:141963 browser->profile()->IsOffTheRecord());
1964 // For each window, add info about all tabs in a list of dictionaries,
1965 // one dictionary item per tab.
1966 ListValue* tabs = new ListValue;
1967 for (int i = 0; i < browser->tab_count(); ++i) {
1968 TabContents* tc = browser->GetTabContentsAt(i);
1969 DictionaryValue* tab = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121970 tab->SetInteger("index", i);
1971 tab->SetString("url", tc->GetURL().spec());
1972 tab->SetInteger("renderer_pid",
[email protected]ef413ca2010-05-25 21:09:141973 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
[email protected]ff4c1d82010-08-04 16:58:121974 tab->Set("infobars", GetInfobarsInfo(tc));
[email protected]ef413ca2010-05-25 21:09:141975 tabs->Append(tab);
1976 }
[email protected]ff4c1d82010-08-04 16:58:121977 browser_item->Set("tabs", tabs);
[email protected]ef413ca2010-05-25 21:09:141978
1979 windows->Append(browser_item);
1980 }
[email protected]ff4c1d82010-08-04 16:58:121981 return_value->Set("windows", windows);
[email protected]ef413ca2010-05-25 21:09:141982
[email protected]ff4c1d82010-08-04 16:58:121983 return_value->SetString("child_process_path",
[email protected]ef413ca2010-05-25 21:09:141984 ChildProcessHost::GetChildPath(true).value());
1985 // Child processes are the processes for plugins and other workers.
1986 // Add all child processes in a list of dictionaries, one dictionary item
1987 // per child process.
1988 ListValue* child_processes = new ListValue;
[email protected]26adfd312010-07-20 01:04:461989 base::WaitableEvent event(true /* manual reset */,
1990 false /* not initially signaled */);
1991 CHECK(ChromeThread::PostTask(
1992 ChromeThread::IO, FROM_HERE,
1993 new GetChildProcessHostInfoTask(&event, child_processes)));
1994 event.Wait();
[email protected]ff4c1d82010-08-04 16:58:121995 return_value->Set("child_processes", child_processes);
[email protected]ef413ca2010-05-25 21:09:141996
1997 // Add all extension processes in a list of dictionaries, one dictionary
1998 // item per extension process.
1999 ListValue* extension_processes = new ListValue;
2000 ProfileManager* profile_manager = g_browser_process->profile_manager();
2001 for (ProfileManager::const_iterator it = profile_manager->begin();
2002 it != profile_manager->end(); ++it) {
2003 ExtensionProcessManager* process_manager =
2004 (*it)->GetExtensionProcessManager();
2005 ExtensionProcessManager::const_iterator jt;
2006 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
2007 ExtensionHost* ex_host = *jt;
2008 // Don't add dead extension processes.
2009 if (!ex_host->IsRenderViewLive())
2010 continue;
2011 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122012 item->SetString("name", ex_host->extension()->name());
[email protected]ef413ca2010-05-25 21:09:142013 item->SetInteger(
[email protected]ff4c1d82010-08-04 16:58:122014 "pid",
[email protected]ef413ca2010-05-25 21:09:142015 base::GetProcId(ex_host->render_process_host()->GetHandle()));
2016 extension_processes->Append(item);
2017 }
2018 }
[email protected]ff4c1d82010-08-04 16:58:122019 return_value->Set("extension_processes", extension_processes);
[email protected]7c983cc2010-07-16 11:33:342020 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]a9ff2c02010-05-13 17:33:052021}
2022
[email protected]24e2b102010-04-29 17:56:472023// Sample json input: { "command": "GetHistoryInfo",
2024// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:362025// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582026void AutomationProvider::GetHistoryInfo(Browser* browser,
2027 DictionaryValue* args,
2028 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:362029 consumer_.CancelAllRequests();
2030
[email protected]e53668962010-06-23 15:35:252031 string16 search_text;
2032 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:362033
2034 // Fetch history.
2035 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2036 history::QueryOptions options;
2037 // The observer owns itself. It deletes itself after it fetches history.
2038 AutomationProviderHistoryObserver* history_observer =
2039 new AutomationProviderHistoryObserver(this, reply_message);
2040 hs->QueryHistory(
2041 search_text,
2042 options,
2043 &consumer_,
2044 NewCallback(history_observer,
2045 &AutomationProviderHistoryObserver::HistoryQueryComplete));
2046}
2047
[email protected]bbe6aa02010-05-07 17:27:292048// Sample json input: { "command": "AddHistoryItem",
2049// "item": { "URL": "http://www.google.com",
2050// "title": "Google", # optional
2051// "time": 12345 # optional (time_t)
2052// } }
2053// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:582054void AutomationProvider::AddHistoryItem(Browser* browser,
2055 DictionaryValue* args,
2056 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:292057 DictionaryValue* item = NULL;
[email protected]ff4c1d82010-08-04 16:58:122058 args->GetDictionary("item", &item);
[email protected]bbe6aa02010-05-07 17:27:292059 string16 url_text;
[email protected]e53668962010-06-23 15:35:252060 string16 title;
[email protected]bbe6aa02010-05-07 17:27:292061 base::Time time = base::Time::Now();
[email protected]7c983cc2010-07-16 11:33:342062 AutomationJSONReply reply(this, reply_message);
[email protected]bbe6aa02010-05-07 17:27:292063
[email protected]7c983cc2010-07-16 11:33:342064 if (!item->GetString("url", &url_text)) {
2065 reply.SendError("bad args (no URL in dict?)");
2066 return;
[email protected]bbe6aa02010-05-07 17:27:292067 }
[email protected]7c983cc2010-07-16 11:33:342068 GURL gurl(url_text);
2069 item->GetString("title", &title); // Don't care if it fails.
2070 int it;
2071 double dt;
[email protected]ff4c1d82010-08-04 16:58:122072 if (item->GetInteger("time", &it))
[email protected]7c983cc2010-07-16 11:33:342073 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:122074 else if (item->GetReal("time", &dt))
[email protected]7c983cc2010-07-16 11:33:342075 time = base::Time::FromDoubleT(dt);
[email protected]f6ff0df2010-07-11 22:41:432076
[email protected]7c983cc2010-07-16 11:33:342077 // Ideas for "dummy" values (e.g. id_scope) came from
2078 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
2079 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2080 const void* id_scope = reinterpret_cast<void*>(1);
2081 hs->AddPage(gurl, time,
2082 id_scope,
2083 0,
2084 GURL(),
2085 PageTransition::LINK,
2086 history::RedirectList(),
2087 false);
2088 if (title.length())
2089 hs->SetPageTitle(gurl, title);
2090 reply.SendSuccess(NULL);
[email protected]bbe6aa02010-05-07 17:27:292091}
2092
[email protected]24e2b102010-04-29 17:56:472093// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:362094// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582095void AutomationProvider::GetDownloadsInfo(Browser* browser,
2096 DictionaryValue* args,
2097 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:392098 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]7c983cc2010-07-16 11:33:342099 AutomationJSONReply reply(this, reply_message);
[email protected]d4adc292010-04-15 18:06:392100
2101 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:342102 reply.SendError("no download manager");
2103 return;
[email protected]d4adc292010-04-15 18:06:392104 }
[email protected]82f37b02010-07-29 22:04:572105
2106 std::vector<DownloadItem*> downloads;
2107 profile_->GetDownloadManager()->GetAllDownloads(FilePath(), &downloads);
[email protected]d4adc292010-04-15 18:06:392108
2109 std::map<DownloadItem::DownloadState, std::string> state_to_string;
2110 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
2111 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
2112 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
2113 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
2114
2115 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
2116 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
2117 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
2118 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
2119 std::string("DANGEROUS_BUT_VALIDATED");
2120
2121 ListValue* list_of_downloads = new ListValue;
2122 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
2123 it != downloads.end();
2124 it++) { // Fill info about each download item.
2125 DictionaryValue* dl_item_value = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122126 dl_item_value->SetInteger("id", static_cast<int>((*it)->id()));
2127 dl_item_value->SetString("url", (*it)->url().spec());
2128 dl_item_value->SetString("referrer_url", (*it)->referrer_url().spec());
2129 dl_item_value->SetString("file_name", (*it)->GetFileName().value());
2130 dl_item_value->SetString("full_path", (*it)->full_path().value());
2131 dl_item_value->SetBoolean("is_paused", (*it)->is_paused());
2132 dl_item_value->SetBoolean("open_when_complete",
[email protected]d4adc292010-04-15 18:06:392133 (*it)->open_when_complete());
[email protected]ff4c1d82010-08-04 16:58:122134 dl_item_value->SetBoolean("is_extension_install",
[email protected]d4adc292010-04-15 18:06:392135 (*it)->is_extension_install());
[email protected]ff4c1d82010-08-04 16:58:122136 dl_item_value->SetBoolean("is_temporary", (*it)->is_temporary());
2137 dl_item_value->SetBoolean("is_otr", (*it)->is_otr()); // off-the-record
2138 dl_item_value->SetString("state", state_to_string[(*it)->state()]);
2139 dl_item_value->SetString("safety_state",
[email protected]d4adc292010-04-15 18:06:392140 safety_state_to_string[(*it)->safety_state()]);
[email protected]ff4c1d82010-08-04 16:58:122141 dl_item_value->SetInteger("PercentComplete", (*it)->PercentComplete());
[email protected]d4adc292010-04-15 18:06:392142 list_of_downloads->Append(dl_item_value);
2143 }
[email protected]ff4c1d82010-08-04 16:58:122144 return_value->Set("downloads", list_of_downloads);
[email protected]d4adc292010-04-15 18:06:392145
[email protected]7c983cc2010-07-16 11:33:342146 reply.SendSuccess(return_value.get());
[email protected]d4adc292010-04-15 18:06:392147 // All value objects allocated above are owned by |return_value|
2148 // and get freed by it.
2149}
2150
[email protected]59a611242010-04-02 02:24:042151void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:582152 Browser* browser,
[email protected]59a611242010-04-02 02:24:042153 DictionaryValue* args,
2154 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:342155 AutomationJSONReply reply(this, reply_message);
[email protected]59a611242010-04-02 02:24:042156
2157 // Look for a quick return.
2158 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:342159 reply.SendSuccess(NULL); // No download manager.
2160 return;
[email protected]59a611242010-04-02 02:24:042161 }
[email protected]82f37b02010-07-29 22:04:572162 std::vector<DownloadItem*> downloads;
2163 profile_->GetDownloadManager()->GetCurrentDownloads(FilePath(), &downloads);
2164 if (downloads.empty()) {
[email protected]7c983cc2010-07-16 11:33:342165 reply.SendSuccess(NULL);
[email protected]f6ff0df2010-07-11 22:41:432166 return;
2167 }
[email protected]59a611242010-04-02 02:24:042168
2169 // The observer owns itself. When the last observed item pings, it
2170 // deletes itself.
2171 AutomationProviderDownloadItemObserver* item_observer =
2172 new AutomationProviderDownloadItemObserver(
2173 this, reply_message, downloads.size());
2174 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2175 i != downloads.end();
2176 i++) {
2177 (*i)->AddObserver(item_observer);
2178 }
2179}
2180
[email protected]24e2b102010-04-29 17:56:472181// Sample json input: { "command": "GetPrefsInfo" }
2182// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582183void AutomationProvider::GetPrefsInfo(Browser* browser,
2184 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472185 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:472186 const PrefService::PreferenceSet& prefs =
2187 profile_->GetPrefs()->preference_set();
2188 DictionaryValue* items = new DictionaryValue;
2189 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
2190 it != prefs.end(); ++it) {
2191 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
2192 }
2193 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:122194 return_value->Set("prefs", items); // return_value owns items.
[email protected]7c983cc2010-07-16 11:33:342195 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]24e2b102010-04-29 17:56:472196}
2197
2198// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:582199void AutomationProvider::SetPrefs(Browser* browser,
2200 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:472201 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:472202 std::wstring path;
2203 Value* val;
[email protected]7c983cc2010-07-16 11:33:342204 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122205 if (args->GetString(L"path", &path) && args->Get("value", &val)) {
[email protected]24e2b102010-04-29 17:56:472206 PrefService* pref_service = profile_->GetPrefs();
2207 const PrefService::Preference* pref =
2208 pref_service->FindPreference(path.c_str());
2209 if (!pref) { // Not a registered pref.
[email protected]7c983cc2010-07-16 11:33:342210 reply.SendError("pref not registered.");
2211 return;
[email protected]24e2b102010-04-29 17:56:472212 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7c983cc2010-07-16 11:33:342213 reply.SendError("pref is managed. cannot be changed.");
2214 return;
[email protected]24e2b102010-04-29 17:56:472215 } else { // Set the pref.
2216 pref_service->Set(path.c_str(), *val);
2217 }
2218 } else {
[email protected]7c983cc2010-07-16 11:33:342219 reply.SendError("no pref path or value given.");
2220 return;
[email protected]24e2b102010-04-29 17:56:472221 }
2222
[email protected]7c983cc2010-07-16 11:33:342223 reply.SendSuccess(NULL);
[email protected]24e2b102010-04-29 17:56:472224}
2225
[email protected]53329582010-05-14 21:10:582226// Sample json input: { "command": "GetOmniboxInfo" }
2227// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
2228void AutomationProvider::GetOmniboxInfo(Browser* browser,
2229 DictionaryValue* args,
2230 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582231 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2232
2233 LocationBar* loc_bar = browser->window()->GetLocationBar();
2234 AutocompleteEditView* edit_view = loc_bar->location_entry();
2235 AutocompleteEditModel* model = edit_view->model();
2236
2237 // Fill up matches.
2238 ListValue* matches = new ListValue;
2239 const AutocompleteResult& result = model->result();
2240 for (AutocompleteResult::const_iterator i = result.begin();
2241 i != result.end(); ++i) {
2242 const AutocompleteMatch& match = *i;
2243 DictionaryValue* item = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:122244 item->SetString("type", AutocompleteMatch::TypeToString(match.type));
2245 item->SetBoolean("starred", match.starred);
2246 item->SetString("destination_url", match.destination_url.spec());
2247 item->SetString("contents", WideToUTF16Hack(match.contents));
2248 item->SetString("description", WideToUTF16Hack(match.description));
[email protected]53329582010-05-14 21:10:582249 matches->Append(item);
2250 }
[email protected]ff4c1d82010-08-04 16:58:122251 return_value->Set("matches", matches);
[email protected]53329582010-05-14 21:10:582252
2253 // Fill up other properties.
2254 DictionaryValue* properties = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:122255 properties->SetBoolean("has_focus", model->has_focus());
2256 properties->SetBoolean("query_in_progress", model->query_in_progress());
2257 properties->SetString("keyword", WideToUTF16Hack(model->keyword()));
2258 properties->SetString("text", WideToUTF16Hack(edit_view->GetText()));
2259 return_value->Set("properties", properties);
[email protected]53329582010-05-14 21:10:582260
[email protected]7c983cc2010-07-16 11:33:342261 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]53329582010-05-14 21:10:582262}
2263
2264// Sample json input: { "command": "SetOmniboxText",
2265// "text": "goog" }
2266void AutomationProvider::SetOmniboxText(Browser* browser,
2267 DictionaryValue* args,
2268 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582269 std::wstring text;
[email protected]7c983cc2010-07-16 11:33:342270 AutomationJSONReply reply(this, reply_message);
[email protected]53329582010-05-14 21:10:582271 if (!args->GetString(L"text", &text)) {
[email protected]7c983cc2010-07-16 11:33:342272 reply.SendError("text missing");
2273 return;
[email protected]53329582010-05-14 21:10:582274 }
[email protected]7c983cc2010-07-16 11:33:342275 browser->FocusLocationBar();
2276 LocationBar* loc_bar = browser->window()->GetLocationBar();
2277 AutocompleteEditView* edit_view = loc_bar->location_entry();
2278 edit_view->model()->OnSetFocus(false);
2279 edit_view->SetUserText(text);
2280 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:582281}
2282
2283// Sample json input: { "command": "OmniboxMovePopupSelection",
2284// "count": 1 }
2285// Negative count implies up, positive implies down. Count values will be
2286// capped by the size of the popup list.
2287void AutomationProvider::OmniboxMovePopupSelection(
2288 Browser* browser,
2289 DictionaryValue* args,
2290 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:582291 int count;
[email protected]7c983cc2010-07-16 11:33:342292 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122293 if (!args->GetInteger("count", &count)) {
[email protected]7c983cc2010-07-16 11:33:342294 reply.SendError("count missing");
2295 return;
[email protected]53329582010-05-14 21:10:582296 }
[email protected]7c983cc2010-07-16 11:33:342297 LocationBar* loc_bar = browser->window()->GetLocationBar();
2298 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2299 model->OnUpOrDownKeyPressed(count);
2300 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:582301}
2302
2303// Sample json input: { "command": "OmniboxAcceptInput" }
2304void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2305 DictionaryValue* args,
2306 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282307 NavigationController& controller =
2308 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122309 // Setup observer to wait until the selected item loads.
2310 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282311 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122312 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582313
2314 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582315}
2316
[email protected]a3cd5022010-06-16 18:25:292317// Sample json input: { "command": "GetInitialLoadTimes" }
2318// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2319void AutomationProvider::GetInitialLoadTimes(
2320 Browser*,
2321 DictionaryValue*,
2322 IPC::Message* reply_message) {
2323 scoped_ptr<DictionaryValue> return_value(
2324 initial_load_observer_->GetTimingInformation());
[email protected]f6ff0df2010-07-11 22:41:432325
2326 std::string json_return;
2327 base::JSONWriter::Write(return_value.get(), false, &json_return);
2328 AutomationMsg_SendJSONRequest::WriteReplyParams(
2329 reply_message, json_return, true);
2330 Send(reply_message);
[email protected]a3cd5022010-06-16 18:25:292331}
2332
[email protected]f7d48012010-05-06 08:17:052333// Sample json input: { "command": "GetPluginsInfo" }
2334// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582335void AutomationProvider::GetPluginsInfo(Browser* browser,
2336 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052337 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052338 std::vector<WebPluginInfo> plugins;
2339 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2340 ListValue* items = new ListValue;
2341 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2342 it != plugins.end();
2343 ++it) {
2344 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122345 item->SetString("name", it->name);
2346 item->SetString("path", it->path.value());
2347 item->SetString("version", it->version);
2348 item->SetString("desc", it->desc);
2349 item->SetBoolean("enabled", it->enabled);
[email protected]f7d48012010-05-06 08:17:052350 // Add info about mime types.
2351 ListValue* mime_types = new ListValue();
2352 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2353 it->mime_types.begin();
2354 type_it != it->mime_types.end();
2355 ++type_it) {
2356 DictionaryValue* mime_type = new DictionaryValue();
[email protected]ff4c1d82010-08-04 16:58:122357 mime_type->SetString("mimeType", type_it->mime_type);
2358 mime_type->SetString("description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052359
2360 ListValue* file_extensions = new ListValue();
2361 for (std::vector<std::string>::const_iterator ext_it =
2362 type_it->file_extensions.begin();
2363 ext_it != type_it->file_extensions.end();
2364 ++ext_it) {
2365 file_extensions->Append(new StringValue(*ext_it));
2366 }
[email protected]ff4c1d82010-08-04 16:58:122367 mime_type->Set("fileExtensions", file_extensions);
[email protected]f7d48012010-05-06 08:17:052368
2369 mime_types->Append(mime_type);
2370 }
[email protected]ff4c1d82010-08-04 16:58:122371 item->Set("mimeTypes", mime_types);
[email protected]f7d48012010-05-06 08:17:052372 items->Append(item);
2373 }
2374 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:122375 return_value->Set("plugins", items); // return_value owns items.
[email protected]f7d48012010-05-06 08:17:052376
[email protected]7c983cc2010-07-16 11:33:342377 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f7d48012010-05-06 08:17:052378}
2379
2380// Sample json input:
2381// { "command": "EnablePlugin",
2382// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582383void AutomationProvider::EnablePlugin(Browser* browser,
2384 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052385 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052386 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342387 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122388 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342389 reply.SendError("path not specified.");
2390 return;
[email protected]f6ff0df2010-07-11 22:41:432391 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342392 reply.SendError(StringPrintf("Could not enable plugin for path %s.",
2393 path.c_str()));
2394 return;
[email protected]f6ff0df2010-07-11 22:41:432395 }
[email protected]7c983cc2010-07-16 11:33:342396 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052397}
2398
2399// Sample json input:
2400// { "command": "DisablePlugin",
2401// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582402void AutomationProvider::DisablePlugin(Browser* browser,
2403 DictionaryValue* args,
2404 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052405 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:342406 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:122407 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:342408 reply.SendError("path not specified.");
2409 return;
[email protected]f6ff0df2010-07-11 22:41:432410 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:342411 reply.SendError(StringPrintf("Could not disable plugin for path %s.",
2412 path.c_str()));
2413 return;
[email protected]f6ff0df2010-07-11 22:41:432414 }
[email protected]7c983cc2010-07-16 11:33:342415 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:052416}
2417
[email protected]7060bb292010-06-24 00:52:492418// Sample json input:
2419// { "command": "SaveTabContents",
2420// "tab_index": 0,
2421// "filename": <a full pathname> }
2422// Sample json output:
2423// {}
2424void AutomationProvider::SaveTabContents(Browser* browser,
2425 DictionaryValue* args,
2426 IPC::Message* reply_message) {
[email protected]7060bb292010-06-24 00:52:492427 int tab_index = 0;
2428 FilePath::StringType filename;
2429 FilePath::StringType parent_directory;
2430 TabContents* tab_contents = NULL;
2431
[email protected]ff4c1d82010-08-04 16:58:122432 if (!args->GetInteger("tab_index", &tab_index) ||
2433 !args->GetString("filename", &filename)) {
[email protected]26adfd312010-07-20 01:04:462434 AutomationJSONReply(this, reply_message).SendError(
2435 "tab_index or filename param missing");
[email protected]7c983cc2010-07-16 11:33:342436 return;
[email protected]7060bb292010-06-24 00:52:492437 } else {
2438 tab_contents = browser->GetTabContentsAt(tab_index);
2439 if (!tab_contents) {
[email protected]26adfd312010-07-20 01:04:462440 AutomationJSONReply(this, reply_message).SendError(
2441 "no tab at tab_index");
[email protected]7060bb292010-06-24 00:52:492442 return;
2443 }
2444 }
[email protected]7c983cc2010-07-16 11:33:342445 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2446 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2447 parent_directory = FilePath(filename).DirName().value();
2448 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2449 SavePackage::SAVE_AS_ONLY_HTML)) {
[email protected]26adfd312010-07-20 01:04:462450 AutomationJSONReply(this, reply_message).SendError(
2451 "Could not initiate SavePage");
[email protected]7c983cc2010-07-16 11:33:342452 return;
2453 }
2454 // The observer will delete itself when done.
2455 new SavePackageNotificationObserver(tab_contents->save_package(),
2456 this, reply_message);
[email protected]7060bb292010-06-24 00:52:492457}
2458
[email protected]c5aa5322010-07-15 19:00:072459// Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
2460// json input.
2461// Sample json output: "{}"
2462void AutomationProvider::ImportSettings(Browser* browser,
2463 DictionaryValue* args,
2464 IPC::Message* reply_message) {
[email protected]c5aa5322010-07-15 19:00:072465 // Map from the json string passed over to the import item masks.
2466 std::map<std::string, ImportItem> string_to_import_item;
2467 string_to_import_item["HISTORY"] = importer::HISTORY;
2468 string_to_import_item["FAVORITES"] = importer::FAVORITES;
2469 string_to_import_item["COOKIES"] = importer::COOKIES;
2470 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
2471 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
2472 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
2473 string_to_import_item["ALL"] = importer::ALL;
2474
2475 std::wstring browser_name;
2476 int import_items = 0;
2477 ListValue* import_items_list = NULL;
2478 bool first_run;
2479
2480 if (!args->GetString(L"import_from", &browser_name) ||
[email protected]ff4c1d82010-08-04 16:58:122481 !args->GetBoolean("first_run", &first_run) ||
2482 !args->GetList("import_items", &import_items_list)) {
[email protected]7c983cc2010-07-16 11:33:342483 AutomationJSONReply(this, reply_message).SendError(
2484 "Incorrect type for one or more of the arguments.");
[email protected]c5aa5322010-07-15 19:00:072485 return;
2486 }
2487
2488 int num_items = import_items_list->GetSize();
2489 for (int i = 0; i < num_items; i++) {
2490 std::string item;
2491 import_items_list->GetString(i, &item);
2492 // If the provided string is not part of the map, error out.
2493 if (!ContainsKey(string_to_import_item, item)) {
[email protected]7c983cc2010-07-16 11:33:342494 AutomationJSONReply(this, reply_message).SendError(
2495 "Invalid item string found in import_items.");
[email protected]c5aa5322010-07-15 19:00:072496 return;
2497 }
2498 import_items |= string_to_import_item[item];
2499 }
2500
2501 ImporterHost* importer_host = new ImporterHost();
2502 // Get the correct ProfileInfo based on the browser they user provided.
2503 importer::ProfileInfo profile_info;
2504 int num_browsers = importer_host->GetAvailableProfileCount();
2505 int i = 0;
2506 for ( ; i < num_browsers; i++) {
2507 std::wstring name = importer_host->GetSourceProfileNameAt(i);
2508 if (name == browser_name) {
2509 profile_info = importer_host->GetSourceProfileInfoAt(i);
2510 break;
2511 }
2512 }
2513 // If we made it to the end of the loop, then the input was bad.
2514 if (i == num_browsers) {
[email protected]7c983cc2010-07-16 11:33:342515 AutomationJSONReply(this, reply_message).SendError(
2516 "Invalid browser name string found.");
[email protected]c5aa5322010-07-15 19:00:072517 return;
2518 }
2519
2520 Profile* profile = browser->profile();
2521
2522 importer_host->SetObserver(
2523 new AutomationProviderImportSettingsObserver(this, reply_message));
2524 importer_host->StartImportSettings(profile_info, profile, import_items,
2525 new ProfileWriter(profile), first_run);
2526}
2527
[email protected]95222282010-07-26 17:43:022528namespace {
2529
2530// Translates a dictionary password to a PasswordForm struct.
2531webkit_glue::PasswordForm GetPasswordFormFromDict(
2532 const DictionaryValue& password_dict) {
2533
2534 // If the time is specified, change time to the specified time.
2535 base::Time time = base::Time::Now();
2536 int it;
2537 double dt;
[email protected]ff4c1d82010-08-04 16:58:122538 if (password_dict.GetInteger("time", &it))
[email protected]95222282010-07-26 17:43:022539 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:122540 else if (password_dict.GetReal("time", &dt))
[email protected]95222282010-07-26 17:43:022541 time = base::Time::FromDoubleT(dt);
2542
2543 std::string signon_realm;
2544 string16 username_value;
2545 string16 password_value;
2546 string16 origin_url_text;
2547 string16 username_element;
2548 string16 password_element;
2549 string16 submit_element;
2550 string16 action_target_text;
2551 bool blacklist = false;
2552 string16 old_password_element;
2553 string16 old_password_value;
2554
2555 // We don't care if any of these fail - they are either optional or checked
2556 // before this function is called.
[email protected]ff4c1d82010-08-04 16:58:122557 password_dict.GetString("signon_realm", &signon_realm);
[email protected]698f7f42010-08-04 19:35:332558 password_dict.GetString("username_value", &username_value);
2559 password_dict.GetString("password_value", &password_value);
2560 password_dict.GetString("origin_url", &origin_url_text);
2561 password_dict.GetString("username_element", &username_element);
2562 password_dict.GetString("password_element", &password_element);
2563 password_dict.GetString("submit_element", &submit_element);
2564 password_dict.GetString("action_target", &action_target_text);
[email protected]ff4c1d82010-08-04 16:58:122565 password_dict.GetBoolean("blacklist", &blacklist);
[email protected]95222282010-07-26 17:43:022566
2567 GURL origin_gurl(origin_url_text);
2568 GURL action_target(action_target_text);
2569
2570 webkit_glue::PasswordForm password_form;
2571 password_form.signon_realm = signon_realm;
2572 password_form.username_value = username_value;
2573 password_form.password_value = password_value;
2574 password_form.origin = origin_gurl;
2575 password_form.username_element = username_element;
2576 password_form.password_element = password_element;
2577 password_form.submit_element = submit_element;
2578 password_form.action = action_target;
2579 password_form.blacklisted_by_user = blacklist;
2580 password_form.date_created = time;
2581
2582 return password_form;
2583}
2584
2585} // namespace
2586
[email protected]5bcfe1672010-07-16 20:51:572587// See AddSavedPassword() in chrome/test/functional/pyauto.py for sample json
2588// input.
2589// Sample json output: { "password_added": true }
2590void AutomationProvider::AddSavedPassword(Browser* browser,
2591 DictionaryValue* args,
2592 IPC::Message* reply_message) {
[email protected]5bcfe1672010-07-16 20:51:572593 AutomationJSONReply reply(this, reply_message);
[email protected]95222282010-07-26 17:43:022594 DictionaryValue* password_dict = NULL;
[email protected]5bcfe1672010-07-16 20:51:572595
[email protected]ff4c1d82010-08-04 16:58:122596 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:022597 reply.SendError("Password must be a dictionary.");
[email protected]5bcfe1672010-07-16 20:51:572598 return;
2599 }
2600
[email protected]95222282010-07-26 17:43:022601 // The signon realm is effectively the primary key and must be included.
2602 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:122603 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:022604 reply.SendError("Password must include signon_realm.");
2605 return;
2606 }
2607 webkit_glue::PasswordForm new_password =
2608 GetPasswordFormFromDict(*password_dict);
[email protected]5bcfe1672010-07-16 20:51:572609
2610 Profile* profile = browser->profile();
2611 // Use IMPLICIT_ACCESS since new passwords aren't added off the record.
2612 PasswordStore* password_store =
2613 profile->GetPasswordStore(Profile::IMPLICIT_ACCESS);
2614
2615 // Set the return based on whether setting the password succeeded.
2616 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2617
2618 // It will be null if it's accessed in an incognito window.
2619 if (password_store != NULL) {
2620 password_store->AddLogin(new_password);
[email protected]ff4c1d82010-08-04 16:58:122621 return_value->SetBoolean("password_added", true);
[email protected]5bcfe1672010-07-16 20:51:572622 } else {
[email protected]ff4c1d82010-08-04 16:58:122623 return_value->SetBoolean("password_added", false);
[email protected]5bcfe1672010-07-16 20:51:572624 }
2625
2626 reply.SendSuccess(return_value.get());
2627}
2628
[email protected]95222282010-07-26 17:43:022629// See RemoveSavedPassword() in chrome/test/functional/pyauto.py for sample
2630// json input.
2631// Sample json output: {}
2632void AutomationProvider::RemoveSavedPassword(Browser* browser,
2633 DictionaryValue* args,
2634 IPC::Message* reply_message) {
2635 AutomationJSONReply reply(this, reply_message);
2636 DictionaryValue* password_dict = NULL;
2637
[email protected]ff4c1d82010-08-04 16:58:122638 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:022639 reply.SendError("Password must be a dictionary.");
2640 return;
2641 }
2642
2643 // The signon realm is effectively the primary key and must be included.
2644 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:122645 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:022646 reply.SendError("Password must include signon_realm.");
2647 return;
2648 }
2649 webkit_glue::PasswordForm to_remove =
2650 GetPasswordFormFromDict(*password_dict);
2651
2652 Profile* profile = browser->profile();
2653 // Use EXPLICIT_ACCESS since passwords can be removed off the record.
2654 PasswordStore* password_store =
2655 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
2656
2657 password_store->RemoveLogin(to_remove);
2658 reply.SendSuccess(NULL);
2659}
2660
[email protected]5bcfe1672010-07-16 20:51:572661// Sample json input: { "command": "GetSavedPasswords" }
2662// Refer to GetSavedPasswords() in chrome/test/pyautolib/pyauto.py for sample
2663// json output.
2664void AutomationProvider::GetSavedPasswords(Browser* browser,
2665 DictionaryValue* args,
2666 IPC::Message* reply_message) {
2667 Profile* profile = browser->profile();
2668 // Use EXPLICIT_ACCESS since saved passwords can be retreived off the record.
2669 PasswordStore* password_store =
2670 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
2671 password_store->GetAutofillableLogins(
2672 new AutomationProviderGetPasswordsObserver(this, reply_message));
2673 // Observer deletes itself after returning.
2674}
2675
[email protected]a0fc50d72010-07-14 21:14:192676// Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
2677// json input.
2678// Sample json output: {}
2679void AutomationProvider::ClearBrowsingData(Browser* browser,
2680 DictionaryValue* args,
2681 IPC::Message* reply_message) {
[email protected]a0fc50d72010-07-14 21:14:192682 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
2683 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
2684 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
2685 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
2686 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
2687 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
2688
2689 std::map<std::string, int> string_to_mask_value;
2690 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
2691 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
2692 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
2693 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
2694 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
2695 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
2696
2697 std::string time_period;
2698 ListValue* to_remove;
[email protected]ff4c1d82010-08-04 16:58:122699 if (!args->GetString("time_period", &time_period) ||
2700 !args->GetList("to_remove", &to_remove)) {
[email protected]7c983cc2010-07-16 11:33:342701 AutomationJSONReply(this, reply_message).SendError(
2702 "time_period must be a string and to_remove a list.");
[email protected]a0fc50d72010-07-14 21:14:192703 return;
2704 }
2705
2706 int remove_mask = 0;
2707 int num_removals = to_remove->GetSize();
2708 for (int i = 0; i < num_removals; i++) {
2709 std::string removal;
2710 to_remove->GetString(i, &removal);
2711 // If the provided string is not part of the map, then error out.
2712 if (!ContainsKey(string_to_mask_value, removal)) {
[email protected]7c983cc2010-07-16 11:33:342713 AutomationJSONReply(this, reply_message).SendError(
2714 "Invalid browsing data string found in to_remove.");
[email protected]a0fc50d72010-07-14 21:14:192715 return;
2716 }
2717 remove_mask |= string_to_mask_value[removal];
2718 }
2719
2720 if (!ContainsKey(string_to_time_period, time_period)) {
[email protected]7c983cc2010-07-16 11:33:342721 AutomationJSONReply(this, reply_message).SendError(
2722 "Invalid string for time_period.");
[email protected]a0fc50d72010-07-14 21:14:192723 return;
2724 }
2725
2726 BrowsingDataRemover* remover = new BrowsingDataRemover(
2727 profile(), string_to_time_period[time_period], base::Time());
2728
2729 remover->AddObserver(
2730 new AutomationProviderBrowsingDataObserver(this, reply_message));
2731 remover->Remove(remove_mask);
2732 // BrowsingDataRemover deletes itself using DeleteTask.
2733 // The observer also deletes itself after sending the reply.
2734}
2735
[email protected]3dda5b02010-07-27 16:35:422736namespace {
2737
2738 // Get the TabContents from a dictionary of arguments.
2739 TabContents* GetTabContentsFromDict(const Browser* browser,
2740 const DictionaryValue* args,
2741 std::string* error_message) {
2742 int tab_index;
[email protected]ff4c1d82010-08-04 16:58:122743 if (!args->GetInteger("tab_index", &tab_index)) {
[email protected]3dda5b02010-07-27 16:35:422744 *error_message = "Must include tab_index.";
2745 return NULL;
2746 }
2747
2748 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2749 if (!tab_contents) {
2750 *error_message = StringPrintf("No tab at index %d.", tab_index);
2751 return NULL;
2752 }
2753 return tab_contents;
2754 }
2755
2756 // Get the TranslateInfoBarDelegate from TabContents.
2757 TranslateInfoBarDelegate* GetTranslateInfoBarDelegate(
2758 TabContents* tab_contents) {
2759 for (int i = 0; i < tab_contents->infobar_delegate_count(); i++) {
2760 InfoBarDelegate* infobar = tab_contents->GetInfoBarDelegateAt(i);
2761 if (infobar->AsTranslateInfoBarDelegate())
2762 return infobar->AsTranslateInfoBarDelegate();
2763 }
2764 // No translate infobar.
2765 return NULL;
2766 }
2767
2768} // namespace
2769
2770// See GetTranslateInfo() in chrome/test/pyautolib/pyauto.py for sample json
2771// input and output.
2772void AutomationProvider::GetTranslateInfo(Browser* browser,
2773 DictionaryValue* args,
2774 IPC::Message* reply_message) {
2775 std::string error_message;
2776 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2777 &error_message);
2778 if (!tab_contents) {
2779 AutomationJSONReply(this, reply_message).SendError(error_message);
2780 return;
2781 }
2782
2783 // Get the translate bar if there is one and pass it to the observer.
2784 // The observer will check for null and populate the information accordingly.
2785 TranslateInfoBarDelegate* translate_bar =
2786 GetTranslateInfoBarDelegate(tab_contents);
2787
2788 TabLanguageDeterminedObserver* observer = new TabLanguageDeterminedObserver(
2789 this, reply_message, tab_contents, translate_bar);
2790 // If the language for the page hasn't been loaded yet, then just make
2791 // the observer, otherwise call observe directly.
2792 std::string language = tab_contents->language_state().original_language();
2793 if (!language.empty()) {
2794 observer->Observe(NotificationType::TAB_LANGUAGE_DETERMINED,
2795 Source<TabContents>(tab_contents),
2796 Details<std::string>(&language));
2797 }
2798}
2799
2800// See SelectTranslateOption() in chrome/test/pyautolib/pyauto.py for sample
2801// json input.
2802// Sample json output: {}
2803void AutomationProvider::SelectTranslateOption(Browser* browser,
2804 DictionaryValue* args,
2805 IPC::Message* reply_message) {
2806 std::string option;
2807 std::string error_message;
2808 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2809 &error_message);
2810 if (!tab_contents) {
2811 AutomationJSONReply(this, reply_message).SendError(error_message);
2812 return;
2813 }
2814
2815 TranslateInfoBarDelegate* translate_bar =
2816 GetTranslateInfoBarDelegate(tab_contents);
2817 if (!translate_bar) {
2818 AutomationJSONReply(this, reply_message)
2819 .SendError("There is no translate bar open.");
2820 return;
2821 }
2822
[email protected]ff4c1d82010-08-04 16:58:122823 if (!args->GetString("option", &option)) {
[email protected]3dda5b02010-07-27 16:35:422824 AutomationJSONReply(this, reply_message).SendError("Must include option");
2825 return;
2826 }
2827
2828 if (option == "translate_page") {
2829 // Make a new notification observer which will send the reply.
2830 new PageTranslatedObserver(this, reply_message, tab_contents);
2831 translate_bar->Translate();
2832 return;
[email protected]da1913e2010-08-04 23:50:152833 } else if (option == "set_target_language") {
2834 string16 target_language;
2835 if (!args->GetString("target_language", &target_language)) {
2836 AutomationJSONReply(this, reply_message).
2837 SendError("Must include target_language string.");
2838 return;
2839 }
2840 // Get the target language index based off of the language name.
2841 int target_language_index = -1;
2842 for (int i = 0; i < translate_bar->GetLanguageCount(); i++) {
2843 if (translate_bar->GetLanguageDisplayableNameAt(i) == target_language) {
2844 target_language_index = i;
2845 break;
2846 }
2847 }
2848 if (target_language_index == -1) {
2849 AutomationJSONReply(this, reply_message)
2850 .SendError("Invalid target language string.");
2851 return;
2852 }
2853 // If the page has already been translated it will be translated again to
2854 // the new language. The observer will wait until the page has been
2855 // translated to reply.
2856 if (translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE) {
2857 new PageTranslatedObserver(this, reply_message, tab_contents);
2858 translate_bar->SetTargetLanguage(target_language_index);
2859 return;
2860 }
2861 // Otherwise just send the reply back immediately.
2862 translate_bar->SetTargetLanguage(target_language_index);
2863 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2864 return_value->SetBoolean("translation_success", true);
2865 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2866 return;
[email protected]3dda5b02010-07-27 16:35:422867 }
2868
2869 AutomationJSONReply reply(this, reply_message);
2870 if (option == "never_translate_language") {
2871 if (translate_bar->IsLanguageBlacklisted()) {
2872 reply.SendError("The language was already blacklisted.");
2873 return;
2874 }
2875 translate_bar->ToggleLanguageBlacklist();
2876 reply.SendSuccess(NULL);
2877 } else if (option == "never_translate_site") {
2878 if (translate_bar->IsSiteBlacklisted()) {
2879 reply.SendError("The site was already blacklisted.");
2880 return;
2881 }
2882 translate_bar->ToggleSiteBlacklist();
2883 reply.SendSuccess(NULL);
2884 } else if (option == "toggle_always_translate") {
2885 translate_bar->ToggleAlwaysTranslate();
2886 reply.SendSuccess(NULL);
2887 } else if (option == "revert_translation") {
2888 translate_bar->RevertTranslation();
2889 reply.SendSuccess(NULL);
2890 } else {
2891 reply.SendError("Invalid string found for option.");
2892 }
2893}
2894
[email protected]f89ee5d2010-08-02 16:39:122895// See WaitUntilTranslateComplete() in chrome/test/pyautolib/pyauto.py for
2896// sample json input and output.
2897void AutomationProvider::WaitUntilTranslateComplete(
2898 Browser* browser, DictionaryValue* args, IPC::Message* reply_message) {
2899 std::string error_message;
2900 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2901 &error_message);
2902 if (!tab_contents) {
2903 AutomationJSONReply(this, reply_message).SendError(error_message);
2904 return;
2905 }
2906
2907 // If the translation is still pending, the observer will wait
2908 // for it to finish and then reply.
2909 if (tab_contents->language_state().translation_pending()) {
2910 new PageTranslatedObserver(this, reply_message, tab_contents);
2911 return;
2912 }
2913 // Otherwise send back the success or failure of the attempted translation
2914 // based on the translate bar state.
2915 AutomationJSONReply reply(this, reply_message);
2916 TranslateInfoBarDelegate* translate_bar =
2917 GetTranslateInfoBarDelegate(tab_contents);
2918 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2919 if (!translate_bar) {
[email protected]ff4c1d82010-08-04 16:58:122920 return_value->SetBoolean("translation_success", false);
[email protected]f89ee5d2010-08-02 16:39:122921 } else {
2922 return_value->SetBoolean(
[email protected]ff4c1d82010-08-04 16:58:122923 "translation_success",
[email protected]f89ee5d2010-08-02 16:39:122924 translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE);
2925 }
2926 reply.SendSuccess(return_value.get());
2927}
2928
[email protected]4d1929f12010-07-10 00:09:032929// Sample json input: { "command": "GetThemeInfo" }
2930// Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
2931void AutomationProvider::GetThemeInfo(Browser* browser,
2932 DictionaryValue* args,
2933 IPC::Message* reply_message) {
2934 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2935 Extension* theme = browser->profile()->GetTheme();
2936 if (theme) {
[email protected]ff4c1d82010-08-04 16:58:122937 return_value->SetString("name", theme->name());
2938 return_value->Set("images", theme->GetThemeImages()->DeepCopy());
2939 return_value->Set("colors", theme->GetThemeColors()->DeepCopy());
2940 return_value->Set("tints", theme->GetThemeTints()->DeepCopy());
[email protected]4d1929f12010-07-10 00:09:032941 }
[email protected]7c983cc2010-07-16 11:33:342942 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]4d1929f12010-07-10 00:09:032943}
2944
[email protected]32a69cf2010-08-03 16:27:012945// Sample json input: { "command": "GetExtensionsInfo" }
2946// See GetExtensionsInfo() in chrome/test/pyautolib/pyauto.py for sample json
2947// output.
2948void AutomationProvider::GetExtensionsInfo(Browser* browser,
2949 DictionaryValue* args,
2950 IPC::Message* reply_message) {
2951 AutomationJSONReply reply(this, reply_message);
2952 ExtensionsService* service = profile()->GetExtensionsService();
2953 if (!service) {
2954 reply.SendError("No extensions service.");
2955 }
2956 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2957 ListValue* extensions_values = new ListValue;
2958 const ExtensionList* extensions = service->extensions();
2959 for (ExtensionList::const_iterator it = extensions->begin();
2960 it != extensions->end(); ++it) {
2961 const Extension* extension = *it;
2962 DictionaryValue* extension_value = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122963 extension_value->SetString("id", extension->id());
2964 extension_value->SetString("version", extension->VersionString());
2965 extension_value->SetString("name", extension->name());
2966 extension_value->SetString("public_key", extension->public_key());
2967 extension_value->SetString("description", extension->description());
2968 extension_value->SetString("background_url",
[email protected]32a69cf2010-08-03 16:27:012969 extension->background_url().spec());
[email protected]ff4c1d82010-08-04 16:58:122970 extension_value->SetString("options_url",
[email protected]32a69cf2010-08-03 16:27:012971 extension->options_url().spec());
2972 extensions_values->Append(extension_value);
2973 }
[email protected]ff4c1d82010-08-04 16:58:122974 return_value->Set("extensions", extensions_values);
[email protected]32a69cf2010-08-03 16:27:012975 reply.SendSuccess(return_value.get());
2976}
2977
2978// See UninstallExtensionById() in chrome/test/pyautolib/pyauto.py for sample
2979// json input.
2980// Sample json output: {}
2981void AutomationProvider::UninstallExtensionById(Browser* browser,
2982 DictionaryValue* args,
2983 IPC::Message* reply_message) {
2984 AutomationJSONReply reply(this, reply_message);
2985 std::string id;
[email protected]ff4c1d82010-08-04 16:58:122986 if (!args->GetString("id", &id)) {
[email protected]32a69cf2010-08-03 16:27:012987 reply.SendError("Must include string id.");
2988 return;
2989 }
2990 ExtensionsService* service = profile()->GetExtensionsService();
2991 if (!service) {
2992 reply.SendError("No extensions service.");
2993 return;
2994 }
2995 ExtensionUnloadNotificationObserver observer;
2996 service->UninstallExtension(id, false);
2997 reply.SendSuccess(NULL);
2998}
2999
[email protected]55846ad842010-07-09 18:22:563000// Sample json input:
3001// { "command": "GetAutoFillProfile" }
3002// Refer to GetAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
3003// json output.
3004void AutomationProvider::GetAutoFillProfile(Browser* browser,
3005 DictionaryValue* args,
3006 IPC::Message* reply_message) {
[email protected]55846ad842010-07-09 18:22:563007 // Get the AutoFillProfiles currently in the database.
3008 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:123009 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:563010 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
[email protected]7c983cc2010-07-16 11:33:343011 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:563012
3013 if (tab_contents) {
3014 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
3015 ->GetPersonalDataManager();
3016 if (pdm) {
3017 std::vector<AutoFillProfile*> autofill_profiles = pdm->profiles();
3018 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
3019
3020 ListValue* profiles = GetListFromAutoFillProfiles(autofill_profiles);
3021 ListValue* cards = GetListFromCreditCards(credit_cards);
3022
3023 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3024
[email protected]ff4c1d82010-08-04 16:58:123025 return_value->Set("profiles", profiles);
3026 return_value->Set("credit_cards", cards);
[email protected]7c983cc2010-07-16 11:33:343027 reply.SendSuccess(return_value.get());
[email protected]55846ad842010-07-09 18:22:563028 } else {
[email protected]7c983cc2010-07-16 11:33:343029 reply.SendError("No PersonalDataManager.");
3030 return;
[email protected]55846ad842010-07-09 18:22:563031 }
3032 } else {
[email protected]7c983cc2010-07-16 11:33:343033 reply.SendError("No tab at that index.");
3034 return;
[email protected]55846ad842010-07-09 18:22:563035 }
[email protected]55846ad842010-07-09 18:22:563036}
3037
3038// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
3039// json input.
3040// Sample json output: {}
3041void AutomationProvider::FillAutoFillProfile(Browser* browser,
3042 DictionaryValue* args,
3043 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:343044 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:563045 ListValue* profiles = NULL;
3046 ListValue* cards = NULL;
[email protected]ff4c1d82010-08-04 16:58:123047 args->GetList("profiles", &profiles);
3048 args->GetList("credit_cards", &cards);
[email protected]7c983cc2010-07-16 11:33:343049 std::string error_mesg;
[email protected]55846ad842010-07-09 18:22:563050
3051 std::vector<AutoFillProfile> autofill_profiles;
3052 std::vector<CreditCard> credit_cards;
3053 // Create an AutoFillProfile for each of the dictionary profiles.
3054 if (profiles) {
[email protected]7c983cc2010-07-16 11:33:343055 autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg);
[email protected]55846ad842010-07-09 18:22:563056 }
3057 // Create a CreditCard for each of the dictionary values.
3058 if (cards) {
[email protected]7c983cc2010-07-16 11:33:343059 credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
3060 }
3061 if (!error_mesg.empty()) {
3062 reply.SendError(error_mesg);
3063 return;
[email protected]55846ad842010-07-09 18:22:563064 }
3065
3066 // Save the AutoFillProfiles.
3067 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:123068 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:563069 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
3070
3071 if (tab_contents) {
[email protected]ce6b0122010-07-19 19:07:303072 PersonalDataManager* pdm = tab_contents->profile()
[email protected]55846ad842010-07-09 18:22:563073 ->GetPersonalDataManager();
3074 if (pdm) {
3075 pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
3076 cards? &credit_cards : NULL);
3077 } else {
[email protected]7c983cc2010-07-16 11:33:343078 reply.SendError("No PersonalDataManager.");
3079 return;
[email protected]55846ad842010-07-09 18:22:563080 }
3081 } else {
[email protected]7c983cc2010-07-16 11:33:343082 reply.SendError("No tab at that index.");
3083 return;
[email protected]55846ad842010-07-09 18:22:563084 }
[email protected]7c983cc2010-07-16 11:33:343085 reply.SendSuccess(NULL);
[email protected]55846ad842010-07-09 18:22:563086}
3087
3088/* static */
3089ListValue* AutomationProvider::GetListFromAutoFillProfiles(
3090 std::vector<AutoFillProfile*> autofill_profiles) {
3091 ListValue* profiles = new ListValue;
3092
3093 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string
3094 = GetAutoFillFieldToStringMap();
3095
3096 // For each AutoFillProfile, transform it to a dictionary object to return.
3097 for (std::vector<AutoFillProfile*>::iterator it = autofill_profiles.begin();
3098 it != autofill_profiles.end(); ++it) {
3099 AutoFillProfile* profile = *it;
3100 DictionaryValue* profile_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:123101 profile_info->SetString("label", profile->Label());
[email protected]55846ad842010-07-09 18:22:563102 // For each of the types, if it has a value, add it to the dictionary.
3103 for (std::map<AutoFillFieldType, std::wstring>::iterator
3104 type_it = autofill_type_to_string.begin();
3105 type_it != autofill_type_to_string.end(); ++type_it) {
3106 string16 value = profile->GetFieldText(AutoFillType(type_it->first));
3107 if (value.length()) { // If there was something stored for that value.
[email protected]ff4c1d82010-08-04 16:58:123108 profile_info->SetString(type_it->second, value);
[email protected]55846ad842010-07-09 18:22:563109 }
3110 }
3111 profiles->Append(profile_info);
3112 }
3113 return profiles;
3114}
3115
3116/* static */
3117ListValue* AutomationProvider::GetListFromCreditCards(
3118 std::vector<CreditCard*> credit_cards) {
3119 ListValue* cards = new ListValue;
3120
3121 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
3122 GetCreditCardFieldToStringMap();
3123
3124 // For each AutoFillProfile, transform it to a dictionary object to return.
3125 for (std::vector<CreditCard*>::iterator it = credit_cards.begin();
3126 it != credit_cards.end(); ++it) {
3127 CreditCard* card = *it;
3128 DictionaryValue* card_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:123129 card_info->SetString("label", card->Label());
[email protected]55846ad842010-07-09 18:22:563130 // For each of the types, if it has a value, add it to the dictionary.
3131 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3132 credit_card_type_to_string.begin();
3133 type_it != credit_card_type_to_string.end(); ++type_it) {
3134 string16 value = card->GetFieldText(AutoFillType(type_it->first));
3135 // If there was something stored for that value.
3136 if (value.length()) {
[email protected]ff4c1d82010-08-04 16:58:123137 card_info->SetString(type_it->second, value);
[email protected]55846ad842010-07-09 18:22:563138 }
3139 }
3140 cards->Append(card_info);
3141 }
3142 return cards;
3143}
3144
3145/* static */
3146std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
[email protected]7c983cc2010-07-16 11:33:343147 const ListValue& profiles, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:563148 std::vector<AutoFillProfile> autofill_profiles;
3149 DictionaryValue* profile_info = NULL;
3150 string16 profile_label;
3151 string16 current_value;
3152
3153 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string =
3154 GetAutoFillFieldToStringMap();
3155
3156 int num_profiles = profiles.GetSize();
3157 for (int i = 0; i < num_profiles; i++) {
3158 profiles.GetDictionary(i, &profile_info);
3159 profile_info->GetString("label", &profile_label);
3160 // Choose an id of 0 so that a unique id will be created.
3161 AutoFillProfile profile(profile_label, 0);
3162 // Loop through the possible profile types and add those provided.
3163 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3164 autofill_type_to_string.begin();
3165 type_it != autofill_type_to_string.end(); ++type_it) {
3166 if (profile_info->HasKey(type_it->second)) {
[email protected]698f7f42010-08-04 19:35:333167 if (profile_info->GetString(WideToUTF8(type_it->second),
3168 &current_value)) {
[email protected]55846ad842010-07-09 18:22:563169 profile.SetInfo(AutoFillType(type_it->first), current_value);
3170 } else {
[email protected]7c983cc2010-07-16 11:33:343171 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:563172 break;
3173 }
3174 }
3175 }
3176 autofill_profiles.push_back(profile);
3177 }
3178 return autofill_profiles;
3179}
3180
3181/* static */
3182std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
[email protected]7c983cc2010-07-16 11:33:343183 const ListValue& cards, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:563184 std::vector<CreditCard> credit_cards;
3185 DictionaryValue* card_info = NULL;
3186 string16 card_label;
3187 string16 current_value;
3188
3189 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
3190 GetCreditCardFieldToStringMap();
3191
3192 int num_credit_cards = cards.GetSize();
3193 for (int i = 0; i < num_credit_cards; i++) {
3194 cards.GetDictionary(i, &card_info);
3195 card_info->GetString("label", &card_label);
3196 CreditCard card(card_label, 0);
3197 // Loop through the possible credit card fields and add those provided.
3198 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
3199 credit_card_type_to_string.begin();
3200 type_it != credit_card_type_to_string.end(); ++type_it) {
3201 if (card_info->HasKey(type_it->second)) {
[email protected]698f7f42010-08-04 19:35:333202 if (card_info->GetString(WideToUTF8(type_it->second), &current_value)) {
[email protected]55846ad842010-07-09 18:22:563203 card.SetInfo(AutoFillType(type_it->first), current_value);
3204 } else {
[email protected]7c983cc2010-07-16 11:33:343205 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:563206 break;
3207 }
3208 }
3209 }
3210 credit_cards.push_back(card);
3211 }
3212 return credit_cards;
3213}
3214
3215/* static */
3216std::map<AutoFillFieldType, std::wstring>
3217 AutomationProvider::GetAutoFillFieldToStringMap() {
3218 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string;
3219 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
3220 autofill_type_to_string[NAME_MIDDLE] = L"NAME_MIDDLE";
3221 autofill_type_to_string[NAME_LAST] = L"NAME_LAST";
3222 autofill_type_to_string[COMPANY_NAME] = L"COMPANY_NAME";
3223 autofill_type_to_string[EMAIL_ADDRESS] = L"EMAIL_ADDRESS";
3224 autofill_type_to_string[ADDRESS_HOME_LINE1] = L"ADDRESS_HOME_LINE1";
3225 autofill_type_to_string[ADDRESS_HOME_LINE2] = L"ADDRESS_HOME_LINE2";
3226 autofill_type_to_string[ADDRESS_HOME_CITY] = L"ADDRESS_HOME_CITY";
3227 autofill_type_to_string[ADDRESS_HOME_STATE] = L"ADDRESS_HOME_STATE";
3228 autofill_type_to_string[ADDRESS_HOME_ZIP] = L"ADDRESS_HOME_ZIP";
3229 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = L"ADDRESS_HOME_COUNTRY";
3230 autofill_type_to_string[PHONE_HOME_NUMBER] = L"PHONE_HOME_NUMBER";
3231 autofill_type_to_string[PHONE_FAX_NUMBER] = L"PHONE_FAX_NUMBER";
3232 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
3233 return autofill_type_to_string;
3234}
3235
3236/* static */
3237std::map<AutoFillFieldType, std::wstring>
3238 AutomationProvider::GetCreditCardFieldToStringMap() {
3239 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string;
3240 credit_card_type_to_string[CREDIT_CARD_NAME] = L"CREDIT_CARD_NAME";
3241 credit_card_type_to_string[CREDIT_CARD_NUMBER] = L"CREDIT_CARD_NUMBER";
[email protected]55846ad842010-07-09 18:22:563242 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = L"CREDIT_CARD_EXP_MONTH";
3243 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
3244 L"CREDIT_CARD_EXP_4_DIGIT_YEAR";
3245 return credit_card_type_to_string;
3246}
3247
[email protected]53329582010-05-14 21:10:583248void AutomationProvider::SendJSONRequest(int handle,
3249 std::string json_request,
3250 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:043251 Browser* browser = NULL;
[email protected]59a611242010-04-02 02:24:043252 scoped_ptr<Value> values;
3253
3254 // Basic error checking.
3255 if (browser_tracker_->ContainsHandle(handle)) {
3256 browser = browser_tracker_->GetResource(handle);
3257 }
3258 if (!browser) {
[email protected]7c983cc2010-07-16 11:33:343259 AutomationJSONReply(this, reply_message).SendError("no browser object");
3260 return;
3261 }
3262 base::JSONReader reader;
3263 std::string error;
3264 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
3265 if (!error.empty()) {
3266 AutomationJSONReply(this, reply_message).SendError(error);
3267 return;
[email protected]59a611242010-04-02 02:24:043268 }
3269
3270 // Make sure input is a dict with a string command.
3271 std::string command;
3272 DictionaryValue* dict_value = NULL;
[email protected]7c983cc2010-07-16 11:33:343273 if (values->GetType() != Value::TYPE_DICTIONARY) {
3274 AutomationJSONReply(this, reply_message).SendError("not a dict");
3275 return;
3276 }
3277 // Ownership remains with "values" variable.
3278 dict_value = static_cast<DictionaryValue*>(values.get());
3279 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
3280 AutomationJSONReply(this, reply_message).SendError(
3281 "no command key in dict or not a string command");
3282 return;
[email protected]59a611242010-04-02 02:24:043283 }
3284
[email protected]24e2b102010-04-29 17:56:473285 // Map json commands to their handlers.
3286 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:053287 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
3288 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
3289 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
3290
[email protected]a9ff2c02010-05-13 17:33:053291 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
[email protected]7c983cc2010-07-16 11:33:343292
[email protected]38b5a3852010-07-21 06:49:523293 handler_map["WaitForInfobarCount"] = &AutomationProvider::WaitForInfobarCount;
[email protected]e004a2d2010-07-22 04:55:283294 handler_map["PerformActionOnInfobar"] =
3295 &AutomationProvider::PerformActionOnInfobar;
[email protected]38b5a3852010-07-21 06:49:523296
[email protected]24e2b102010-04-29 17:56:473297 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:293298 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:053299
[email protected]53329582010-05-14 21:10:583300 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
3301 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
3302 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
3303 handler_map["OmniboxMovePopupSelection"] =
3304 &AutomationProvider::OmniboxMovePopupSelection;
3305
[email protected]24e2b102010-04-29 17:56:473306 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
3307 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:053308
[email protected]ef413ca2010-05-25 21:09:143309 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
3310
[email protected]f7d48012010-05-06 08:17:053311 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:473312 handler_map["WaitForAllDownloadsToComplete"] =
3313 &AutomationProvider::WaitForDownloadsToComplete;
3314
[email protected]a3cd5022010-06-16 18:25:293315 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
3316
[email protected]7060bb292010-06-24 00:52:493317 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
3318
[email protected]c5aa5322010-07-15 19:00:073319 handler_map["ImportSettings"] = &AutomationProvider::ImportSettings;
3320
[email protected]5bcfe1672010-07-16 20:51:573321 handler_map["AddSavedPassword"] = &AutomationProvider::AddSavedPassword;
[email protected]95222282010-07-26 17:43:023322 handler_map["RemoveSavedPassword"] =
3323 &AutomationProvider::RemoveSavedPassword;
[email protected]5bcfe1672010-07-16 20:51:573324 handler_map["GetSavedPasswords"] = &AutomationProvider::GetSavedPasswords;
3325
[email protected]a0fc50d72010-07-14 21:14:193326 handler_map["ClearBrowsingData"] = &AutomationProvider::ClearBrowsingData;
3327
[email protected]4d1929f12010-07-10 00:09:033328 // SetTheme() implemented using InstallExtension().
3329 handler_map["GetThemeInfo"] = &AutomationProvider::GetThemeInfo;
3330
[email protected]32a69cf2010-08-03 16:27:013331 // InstallExtension() present in pyauto.py.
3332 handler_map["GetExtensionsInfo"] = &AutomationProvider::GetExtensionsInfo;
3333 handler_map["UninstallExtensionById"] =
3334 &AutomationProvider::UninstallExtensionById;
3335
[email protected]3dda5b02010-07-27 16:35:423336 handler_map["SelectTranslateOption"] =
3337 &AutomationProvider::SelectTranslateOption;
3338 handler_map["GetTranslateInfo"] = &AutomationProvider::GetTranslateInfo;
[email protected]f89ee5d2010-08-02 16:39:123339 handler_map["WaitUntilTranslateComplete"] =
3340 &AutomationProvider::WaitUntilTranslateComplete;
[email protected]3dda5b02010-07-27 16:35:423341
[email protected]55846ad842010-07-09 18:22:563342 handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
3343 handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
3344
[email protected]7c983cc2010-07-16 11:33:343345 if (handler_map.find(std::string(command)) != handler_map.end()) {
3346 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]1ac875d22010-07-16 09:57:583347 } else {
[email protected]7c983cc2010-07-16 11:33:343348 std::string error_string = "Unknown command. Options: ";
3349 for (std::map<std::string, JsonHandler>::const_iterator it =
3350 handler_map.begin(); it != handler_map.end(); ++it) {
3351 error_string += it->first + ", ";
3352 }
3353 AutomationJSONReply(this, reply_message).SendError(error_string);
[email protected]1ac875d22010-07-16 09:57:583354 }
[email protected]59a611242010-04-02 02:24:043355}
3356
initial.commit09911bf2008-07-26 23:55:293357void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:563358 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:343359 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
3360 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:563361 DCHECK(reply_message_ == NULL);
3362 reply_message_ = reply_message;
3363
[email protected]d9f9b792009-06-24 13:17:123364 DevToolsManager::GetInstance()->InspectElement(
3365 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:293366 } else {
[email protected]71f65dd2009-02-11 19:14:563367 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
3368 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293369 }
3370}
3371
3372void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:093373 if (reply_message_) {
3374 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
3375 num_resources);
3376 Send(reply_message_);
3377 reply_message_ = NULL;
3378 }
initial.commit09911bf2008-07-26 23:55:293379}
3380
[email protected]a7eee32f2009-05-22 18:08:173381class SetProxyConfigTask : public Task {
3382 public:
[email protected]be180c802009-10-23 06:33:313383 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
3384 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:253385 : request_context_getter_(request_context_getter),
3386 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:173387 virtual void Run() {
3388 // First, deserialize the JSON string. If this fails, log and bail.
3389 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:393390 std::string error_msg;
3391 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:173392 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
3393 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:393394 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:173395 return;
3396 }
3397
3398 scoped_ptr<DictionaryValue> dict(
3399 static_cast<DictionaryValue*>(root.release()));
3400 // Now put together a proxy configuration from the deserialized string.
3401 net::ProxyConfig pc;
3402 PopulateProxyConfig(*dict.get(), &pc);
3403
[email protected]be180c802009-10-23 06:33:313404 net::ProxyService* proxy_service =
3405 request_context_getter_->GetURLRequestContext()->proxy_service();
3406 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:173407 scoped_ptr<net::ProxyConfigService> proxy_config_service(
3408 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:313409 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:173410 }
3411
3412 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
3413 DCHECK(pc);
3414 bool no_proxy = false;
3415 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
3416 // Make no changes to the ProxyConfig.
3417 return;
3418 }
3419 bool auto_config;
3420 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:483421 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:173422 }
3423 std::string pac_url;
3424 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:483425 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:173426 }
3427 std::string proxy_bypass_list;
3428 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:483429 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:173430 }
3431 std::string proxy_server;
3432 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:483433 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:173434 }
3435 }
3436
3437 private:
[email protected]be180c802009-10-23 06:33:313438 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:173439 std::string proxy_config_;
3440};
3441
3442
3443void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:313444 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
3445 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:173446 FilePath user_data_dir;
3447 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
3448 ProfileManager* profile_manager = g_browser_process->profile_manager();
3449 DCHECK(profile_manager);
3450 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
3451 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:313452 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:173453 }
[email protected]be180c802009-10-23 06:33:313454 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:173455
[email protected]fae20792009-10-28 20:31:583456 ChromeThread::PostTask(
3457 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:313458 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:173459}
3460
[email protected]4f3dc372009-02-24 00:10:293461void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:333462 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:293463 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:293464 if (tab_tracker_->ContainsHandle(handle)) {
3465 NavigationController* tab = tab_tracker_->GetResource(handle);
3466 DownloadManager* dlm = tab->profile()->GetDownloadManager();
3467 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:333468 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:293469 }
initial.commit09911bf2008-07-26 23:55:293470}
3471
[email protected]6a5670d22009-10-27 16:21:343472void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:143473 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:533474 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
3475 reply_message);
3476}
3477
3478void AutomationProvider::OpenNewBrowserWindowOfType(
3479 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:143480 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:293481 // We may have no current browser windows open so don't rely on
3482 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:533483 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
3484 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:053485 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:153486 if (show)
[email protected]15952e462008-11-14 00:29:053487 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:293488}
3489
[email protected]71f65dd2009-02-11 19:14:563490void AutomationProvider::GetWindowForBrowser(int browser_handle,
3491 bool* success,
3492 int* handle) {
3493 *success = false;
3494 *handle = 0;
initial.commit09911bf2008-07-26 23:55:293495
3496 if (browser_tracker_->ContainsHandle(browser_handle)) {
3497 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:203498 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:293499 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:203500 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:563501 *success = true;
initial.commit09911bf2008-07-26 23:55:293502 }
initial.commit09911bf2008-07-26 23:55:293503}
3504
3505void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:563506 int browser_handle,
3507 bool* success,
3508 int* autocomplete_edit_handle) {
3509 *success = false;
3510 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:293511
3512 if (browser_tracker_->ContainsHandle(browser_handle)) {
3513 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:063514 LocationBar* loc_bar = browser->window()->GetLocationBar();
3515 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:293516 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:563517 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
3518 *success = true;
initial.commit09911bf2008-07-26 23:55:293519 }
initial.commit09911bf2008-07-26 23:55:293520}
initial.commit09911bf2008-07-26 23:55:293521
[email protected]71f65dd2009-02-11 19:14:563522void AutomationProvider::ShowInterstitialPage(int tab_handle,
3523 const std::string& html_text,
3524 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293525 if (tab_tracker_->ContainsHandle(tab_handle)) {
3526 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:113527 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:403528
[email protected]7dad3d5f2010-03-04 00:27:013529 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:403530 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:343531 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:403532 GURL("about:interstitial"),
3533 html_text);
3534 interstitial->Show();
3535 return;
initial.commit09911bf2008-07-26 23:55:293536 }
[email protected]71f65dd2009-02-11 19:14:563537
[email protected]457f5cf2009-08-18 16:37:523538 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
3539 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563540 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293541}
3542
[email protected]71f65dd2009-02-11 19:14:563543void AutomationProvider::HideInterstitialPage(int tab_handle,
3544 bool* success) {
3545 *success = false;
[email protected]57c6a652009-05-04 07:58:343546 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
3547 if (tab_contents && tab_contents->interstitial_page()) {
3548 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:563549 *success = true;
initial.commit09911bf2008-07-26 23:55:293550 }
initial.commit09911bf2008-07-26 23:55:293551}
3552
[email protected]71f65dd2009-02-11 19:14:563553void AutomationProvider::CloseTab(int tab_handle,
3554 bool wait_until_closed,
3555 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293556 if (tab_tracker_->ContainsHandle(tab_handle)) {
3557 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
3558 int index;
3559 Browser* browser = Browser::GetBrowserForController(controller, &index);
3560 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:143561 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:113562 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:453563 return;
initial.commit09911bf2008-07-26 23:55:293564 }
[email protected]de246f52009-02-25 18:25:453565
3566 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:553567 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293568}
3569
[email protected]71f65dd2009-02-11 19:14:563570void AutomationProvider::CloseBrowser(int browser_handle,
3571 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293572 if (browser_tracker_->ContainsHandle(browser_handle)) {
3573 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563574 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:563575 reply_message);
[email protected]f3e99e32008-07-30 04:48:393576 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:293577 } else {
3578 NOTREACHED();
3579 }
3580}
3581
[email protected]71f65dd2009-02-11 19:14:563582void AutomationProvider::CloseBrowserAsync(int browser_handle) {
3583 if (browser_tracker_->ContainsHandle(browser_handle)) {
3584 Browser* browser = browser_tracker_->GetResource(browser_handle);
3585 browser->window()->Close();
3586 } else {
3587 NOTREACHED();
3588 }
3589}
3590
[email protected]71f65dd2009-02-11 19:14:563591void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
3592 IPC::Message* reply_message) {
3593 if (tab_tracker_->ContainsHandle(tab_handle)) {
3594 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3595 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:143596 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:563597 }
3598}
3599
[email protected]71f65dd2009-02-11 19:14:563600void AutomationProvider::GetSecurityState(int handle, bool* success,
3601 SecurityStyle* security_style,
3602 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:483603 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:293604 if (tab_tracker_->ContainsHandle(handle)) {
3605 NavigationController* tab = tab_tracker_->GetResource(handle);
3606 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563607 *success = true;
3608 *security_style = entry->ssl().security_style();
3609 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:483610 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:293611 } else {
[email protected]71f65dd2009-02-11 19:14:563612 *success = false;
3613 *security_style = SECURITY_STYLE_UNKNOWN;
3614 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:483615 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:293616 }
3617}
3618
[email protected]71f65dd2009-02-11 19:14:563619void AutomationProvider::GetPageType(int handle, bool* success,
3620 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:293621 if (tab_tracker_->ContainsHandle(handle)) {
3622 NavigationController* tab = tab_tracker_->GetResource(handle);
3623 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:563624 *page_type = entry->page_type();
3625 *success = true;
initial.commit09911bf2008-07-26 23:55:293626 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:343627 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:563628 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:343629 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:563630 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293631 } else {
[email protected]71f65dd2009-02-11 19:14:563632 *success = false;
3633 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:293634 }
3635}
3636
[email protected]84abba62009-10-07 17:01:443637void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
3638 int* duration_ms) {
3639 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
3640 event_name);
3641}
3642
[email protected]71f65dd2009-02-11 19:14:563643void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
3644 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:293645 if (tab_tracker_->ContainsHandle(handle)) {
3646 NavigationController* tab = tab_tracker_->GetResource(handle);
3647 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:073648 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:403649 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:473650 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:343651 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:293652 if (ssl_blocking_page) {
3653 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:013654 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:563655 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:293656 return;
3657 }
3658 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:523659 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3660 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:563661 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293662 return;
3663 }
3664 }
3665 }
3666 // We failed.
[email protected]457f5cf2009-08-18 16:37:523667 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
3668 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:563669 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293670}
3671
[email protected]71f65dd2009-02-11 19:14:563672void AutomationProvider::BringBrowserToFront(int browser_handle,
3673 bool* success) {
initial.commit09911bf2008-07-26 23:55:293674 if (browser_tracker_->ContainsHandle(browser_handle)) {
3675 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:063676 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:563677 *success = true;
initial.commit09911bf2008-07-26 23:55:293678 } else {
[email protected]71f65dd2009-02-11 19:14:563679 *success = false;
initial.commit09911bf2008-07-26 23:55:293680 }
3681}
3682
[email protected]bdb7ff62010-07-20 01:56:523683void AutomationProvider::IsMenuCommandEnabled(int browser_handle,
3684 int message_num,
3685 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:293686 if (browser_tracker_->ContainsHandle(browser_handle)) {
3687 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:563688 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:143689 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:293690 } else {
[email protected]71f65dd2009-02-11 19:14:563691 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:293692 }
3693}
3694
[email protected]71f65dd2009-02-11 19:14:563695void AutomationProvider::PrintNow(int tab_handle,
3696 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:573697 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:343698 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3699 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:293700 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:573701 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:143702 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:343703 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:573704 return;
initial.commit09911bf2008-07-26 23:55:293705 }
[email protected]71f65dd2009-02-11 19:14:563706 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
3707 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:293708}
[email protected]d301c952009-07-13 15:02:413709
[email protected]71f65dd2009-02-11 19:14:563710void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:113711 const FilePath& file_name,
3712 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:563713 int type,
3714 bool* success) {
initial.commit09911bf2008-07-26 23:55:293715 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:563716 *success = false;
initial.commit09911bf2008-07-26 23:55:293717 return;
3718 }
3719
3720 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3721 Browser* browser = FindAndActivateTab(nav);
3722 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:143723 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:563724 *success = false;
initial.commit09911bf2008-07-26 23:55:293725 return;
3726 }
3727
initial.commit09911bf2008-07-26 23:55:293728 SavePackage::SavePackageType save_type =
3729 static_cast<SavePackage::SavePackageType>(type);
3730 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
3731 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:343732 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:293733
[email protected]71f65dd2009-02-11 19:14:563734 *success = true;
initial.commit09911bf2008-07-26 23:55:293735}
3736
[email protected]71f65dd2009-02-11 19:14:563737void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
3738 bool* success,
3739 std::wstring* text) {
3740 *success = false;
initial.commit09911bf2008-07-26 23:55:293741 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563742 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:523743 GetText();
[email protected]71f65dd2009-02-11 19:14:563744 *success = true;
initial.commit09911bf2008-07-26 23:55:293745 }
initial.commit09911bf2008-07-26 23:55:293746}
3747
[email protected]71f65dd2009-02-11 19:14:563748void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
3749 const std::wstring& text,
3750 bool* success) {
3751 *success = false;
initial.commit09911bf2008-07-26 23:55:293752 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:523753 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
3754 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:563755 *success = true;
initial.commit09911bf2008-07-26 23:55:293756 }
initial.commit09911bf2008-07-26 23:55:293757}
3758
3759void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:563760 int autocomplete_edit_handle,
3761 bool* success,
3762 std::vector<AutocompleteMatchData>* matches) {
3763 *success = false;
initial.commit09911bf2008-07-26 23:55:293764 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:273765 const AutocompleteResult& result = autocomplete_edit_tracker_->
3766 GetResource(autocomplete_edit_handle)->model()->result();
3767 for (AutocompleteResult::const_iterator i = result.begin();
3768 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:563769 matches->push_back(AutocompleteMatchData(*i));
3770 *success = true;
initial.commit09911bf2008-07-26 23:55:293771 }
initial.commit09911bf2008-07-26 23:55:293772}
3773
3774void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:563775 int autocomplete_edit_handle,
3776 bool* success,
3777 bool* query_in_progress) {
3778 *success = false;
3779 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:293780 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:563781 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:523782 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:563783 *success = true;
initial.commit09911bf2008-07-26 23:55:293784 }
initial.commit09911bf2008-07-26 23:55:293785}
3786
[email protected]63514af2010-03-30 17:17:233787#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:193788
[email protected]5ae5bed2009-08-21 18:52:443789#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:393790
[email protected]57c6a652009-05-04 07:58:343791TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:573792 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:573793 if (tab_tracker_->ContainsHandle(handle)) {
3794 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:343795 if (tab)
3796 *tab = nav_controller;
3797 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:573798 }
[email protected]57c6a652009-05-04 07:58:343799 return NULL;
[email protected]20e93d12008-08-28 16:31:573800}
3801
initial.commit09911bf2008-07-26 23:55:293802TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
3803 : AutomationProvider(profile) {
3804 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:143805 registrar_.Add(this, NotificationType::SESSION_END,
3806 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:293807}
3808
3809TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:293810 BrowserList::RemoveObserver(this);
3811}
3812
3813void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:143814 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:293815 AutomationProvider::OnChannelError();
3816}
3817
[email protected]679082052010-07-21 21:30:133818void TestingAutomationProvider::OnBrowserAdded(const Browser* browser) {
3819}
3820
initial.commit09911bf2008-07-26 23:55:293821void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
3822 // For backwards compatibility with the testing automation interface, we
3823 // want the automation provider (and hence the process) to go away when the
3824 // last browser goes away.
[email protected]c984d9f2010-07-20 20:52:203825 if (BrowserList::size() == 1 && !CommandLine::ForCurrentProcess()->HasSwitch(
3826 switches::kKeepAliveForTest)) {
[email protected]4f3dc372009-02-24 00:10:293827 // If you change this, update Observer for NotificationType::SESSION_END
3828 // below.
[email protected]295039bd2008-08-15 04:32:573829 MessageLoop::current()->PostTask(FROM_HERE,
3830 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:293831 }
3832}
3833
3834void TestingAutomationProvider::Observe(NotificationType type,
3835 const NotificationSource& source,
3836 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563837 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:293838 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
3839 // before the task runs resulting in this object not being deleted. This
3840 // Release balance out the Release scheduled by OnBrowserRemoving.
3841 Release();
3842}
[email protected]295039bd2008-08-15 04:32:573843
3844void TestingAutomationProvider::OnRemoveProvider() {
3845 AutomationProviderList::GetInstance()->RemoveProvider(this);
3846}
[email protected]8a3422c92008-09-24 17:42:423847
[email protected]816633a2009-11-11 21:48:183848void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:563849 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:423850 if (tab_tracker_->ContainsHandle(handle)) {
3851 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:343852 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:113853 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423854 }
[email protected]8a3422c92008-09-24 17:42:423855}
3856
[email protected]816633a2009-11-11 21:48:183857void AutomationProvider::ClickInfoBarAccept(int handle,
3858 int info_bar_index,
3859 bool wait_for_navigation,
3860 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:423861 bool success = false;
3862 if (tab_tracker_->ContainsHandle(handle)) {
3863 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3864 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:113865 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:423866 if (info_bar_index >= 0 && info_bar_index < count) {
3867 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:013868 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:423869 }
[email protected]eb9ba192008-12-02 02:41:343870 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:113871 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:343872 info_bar_index);
3873 if (delegate->AsConfirmInfoBarDelegate())
3874 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:423875 success = true;
3876 }
3877 }
[email protected]4f3dc372009-02-24 00:10:293878 }
[email protected]58f622a62009-10-04 01:17:553879
3880 // This "!wait_for_navigation || !success condition" logic looks suspicious.
3881 // It will send a failure message when success is true but
3882 // |wait_for_navigation| is false.
3883 // TODO(phajdan.jr): investgate whether the reply param (currently
3884 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:423885 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:183886 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:523887 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:423888}
3889
[email protected]71f65dd2009-02-11 19:14:563890void AutomationProvider::GetLastNavigationTime(int handle,
3891 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:423892 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:563893 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:423894}
3895
[email protected]71f65dd2009-02-11 19:14:563896void AutomationProvider::WaitForNavigation(int handle,
3897 int64 last_navigation_time,
3898 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:253899 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:423900 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:253901
[email protected]8a3422c92008-09-24 17:42:423902 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:563903 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:523904 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3905 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553906 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293907 return;
[email protected]8a3422c92008-09-24 17:42:423908 }
3909
[email protected]7dad3d5f2010-03-04 00:27:013910 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423911}
3912
[email protected]71f65dd2009-02-11 19:14:563913void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163914 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563915 int value,
3916 bool* success) {
3917 *success = false;
[email protected]8a3422c92008-09-24 17:42:423918 if (browser_tracker_->ContainsHandle(handle)) {
3919 Browser* browser = browser_tracker_->GetResource(handle);
3920 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563921 *success = true;
[email protected]8a3422c92008-09-24 17:42:423922 }
[email protected]8a3422c92008-09-24 17:42:423923}
[email protected]97fa6ce32008-12-19 01:48:163924
[email protected]71f65dd2009-02-11 19:14:563925void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163926 const std::wstring& name,
[email protected]ddd231e2010-06-29 20:35:193927 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563928 bool* success) {
3929 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163930 if (browser_tracker_->ContainsHandle(handle)) {
3931 Browser* browser = browser_tracker_->GetResource(handle);
3932 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563933 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163934 }
[email protected]97fa6ce32008-12-19 01:48:163935}
3936
[email protected]71f65dd2009-02-11 19:14:563937void AutomationProvider::GetBooleanPreference(int handle,
3938 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:363939 bool* success,
3940 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563941 *success = false;
3942 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163943 if (browser_tracker_->ContainsHandle(handle)) {
3944 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563945 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3946 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163947 }
[email protected]97fa6ce32008-12-19 01:48:163948}
3949
[email protected]71f65dd2009-02-11 19:14:563950void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163951 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563952 bool value,
3953 bool* success) {
3954 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163955 if (browser_tracker_->ContainsHandle(handle)) {
3956 Browser* browser = browser_tracker_->GetResource(handle);
3957 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563958 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163959 }
[email protected]97fa6ce32008-12-19 01:48:163960}
3961
3962// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563963void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403964 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163965 if (tab_tracker_->ContainsHandle(tab_handle)) {
3966 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3967 Browser* browser = FindAndActivateTab(nav);
3968 DCHECK(browser);
3969
[email protected]57c6a652009-05-04 07:58:343970 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3971 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163972 }
[email protected]97fa6ce32008-12-19 01:48:163973}
3974
[email protected]b8f48d12009-11-09 20:14:363975// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563976void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:403977 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:563978 bool* success) {
3979 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163980 if (tab_tracker_->ContainsHandle(tab_handle)) {
3981 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193982 if (!nav)
3983 return;
[email protected]97fa6ce32008-12-19 01:48:163984 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163985
[email protected]2f2afba2010-04-01 01:53:193986 // If the browser has UI, simulate what a user would do.
3987 // Activate the tab and then click the encoding menu.
3988 if (browser &&
3989 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163990 int selected_encoding_id =
3991 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3992 if (selected_encoding_id) {
3993 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563994 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163995 }
[email protected]2f2afba2010-04-01 01:53:193996 } else {
3997 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3998 // Try to get TabContents and call its override_encoding method.
3999 TabContents* contents = nav->tab_contents();
4000 if (!contents)
4001 return;
4002 const std::string selected_encoding =
4003 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
4004 if (selected_encoding.empty())
4005 return;
4006 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:164007 }
4008 }
[email protected]97fa6ce32008-12-19 01:48:164009}
[email protected]5bcdb312009-01-07 21:43:204010
[email protected]4d434a1a2009-02-11 21:06:574011void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:204012 SavePackage::SetShouldPromptUser(should_prompt);
4013}
[email protected]87eab222009-03-13 00:47:454014
[email protected]66ba4932009-06-04 19:22:134015void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
4016 *count = -1; // -1 is the error code
4017 if (tab_tracker_->ContainsHandle(handle)) {
4018 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
4019 TabContents* tab_contents = nav_controller->tab_contents();
4020 if (tab_contents) {
4021 BlockedPopupContainer* container =
4022 tab_contents->blocked_popup_container();
4023 if (container) {
4024 *count = static_cast<int>(container->GetBlockedPopupCount());
4025 } else {
4026 // If we don't have a container, we don't have any blocked popups to
4027 // contain!
4028 *count = 0;
4029 }
4030 }
4031 }
4032}
[email protected]f7a68432009-07-29 23:18:194033
4034void AutomationProvider::SelectAll(int tab_handle) {
4035 RenderViewHost* view = GetViewForTab(tab_handle);
4036 if (!view) {
4037 NOTREACHED();
4038 return;
4039 }
4040
4041 view->SelectAll();
4042}
4043
4044void AutomationProvider::Cut(int tab_handle) {
4045 RenderViewHost* view = GetViewForTab(tab_handle);
4046 if (!view) {
4047 NOTREACHED();
4048 return;
4049 }
4050
4051 view->Cut();
4052}
4053
4054void AutomationProvider::Copy(int tab_handle) {
4055 RenderViewHost* view = GetViewForTab(tab_handle);
4056 if (!view) {
4057 NOTREACHED();
4058 return;
4059 }
4060
4061 view->Copy();
4062}
4063
4064void AutomationProvider::Paste(int tab_handle) {
4065 RenderViewHost* view = GetViewForTab(tab_handle);
4066 if (!view) {
4067 NOTREACHED();
4068 return;
4069 }
4070
4071 view->Paste();
4072}
4073
4074void AutomationProvider::ReloadAsync(int tab_handle) {
4075 if (tab_tracker_->ContainsHandle(tab_handle)) {
4076 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4077 if (!tab) {
4078 NOTREACHED();
4079 return;
4080 }
4081
[email protected]106a0812010-03-18 00:15:124082 const bool check_for_repost = true;
4083 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:194084 }
4085}
4086
4087void AutomationProvider::StopAsync(int tab_handle) {
4088 RenderViewHost* view = GetViewForTab(tab_handle);
4089 if (!view) {
[email protected]8b2b3312009-09-14 18:38:364090 // We tolerate StopAsync being called even before a view has been created.
4091 // So just log a warning instead of a NOTREACHED().
4092 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:194093 return;
4094 }
4095
4096 view->Stop();
4097}
4098
[email protected]1bb5f892009-10-06 01:44:574099void AutomationProvider::OnSetPageFontSize(int tab_handle,
4100 int font_size) {
4101 AutomationPageFontSize automation_font_size =
4102 static_cast<AutomationPageFontSize>(font_size);
4103
4104 if (automation_font_size < SMALLEST_FONT ||
4105 automation_font_size > LARGEST_FONT) {
4106 DLOG(ERROR) << "Invalid font size specified : "
4107 << font_size;
4108 return;
4109 }
4110
4111 if (tab_tracker_->ContainsHandle(tab_handle)) {
4112 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4113 DCHECK(tab != NULL);
4114 if (tab && tab->tab_contents()) {
4115 DCHECK(tab->tab_contents()->profile() != NULL);
4116 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
4117 prefs::kWebKitDefaultFontSize, font_size);
4118 }
4119 }
4120}
4121
[email protected]bc73b4e52010-03-26 04:16:204122void AutomationProvider::RemoveBrowsingData(int remove_mask) {
4123 BrowsingDataRemover* remover;
4124 remover = new BrowsingDataRemover(profile(),
4125 BrowsingDataRemover::EVERYTHING, // All time periods.
4126 base::Time());
4127 remover->Remove(remove_mask);
4128 // BrowsingDataRemover deletes itself.
4129}
[email protected]1bb5f892009-10-06 01:44:574130
[email protected]2949e90d2009-08-21 15:32:524131void AutomationProvider::WaitForBrowserWindowCountToBecome(
4132 int target_count, IPC::Message* reply_message) {
4133 if (static_cast<int>(BrowserList::size()) == target_count) {
4134 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
4135 reply_message, true);
4136 Send(reply_message);
4137 return;
4138 }
4139
4140 // Set up an observer (it will delete itself).
4141 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
4142}
4143
4144void AutomationProvider::WaitForAppModalDialogToBeShown(
4145 IPC::Message* reply_message) {
4146 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
4147 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
4148 reply_message, true);
4149 Send(reply_message);
4150 return;
4151 }
4152
4153 // Set up an observer (it will delete itself).
4154 new AppModalDialogShownObserver(this, reply_message);
4155}
4156
[email protected]1126a1d32009-08-26 15:39:264157void AutomationProvider::GoBackBlockUntilNavigationsComplete(
4158 int handle, int number_of_navigations, IPC::Message* reply_message) {
4159 if (tab_tracker_->ContainsHandle(handle)) {
4160 NavigationController* tab = tab_tracker_->GetResource(handle);
4161 Browser* browser = FindAndActivateTab(tab);
4162 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:014163 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
4164 false);
[email protected]1126a1d32009-08-26 15:39:264165 browser->GoBack(CURRENT_TAB);
4166 return;
4167 }
4168 }
4169
4170 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
4171 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
4172 Send(reply_message);
4173}
4174
4175void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
4176 int handle, int number_of_navigations, IPC::Message* reply_message) {
4177 if (tab_tracker_->ContainsHandle(handle)) {
4178 NavigationController* tab = tab_tracker_->GetResource(handle);
4179 Browser* browser = FindAndActivateTab(tab);
4180 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:014181 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
4182 false);
[email protected]1126a1d32009-08-26 15:39:264183 browser->GoForward(CURRENT_TAB);
4184 return;
4185 }
4186 }
4187
4188 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
4189 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
4190 Send(reply_message);
4191}
4192
[email protected]f7a68432009-07-29 23:18:194193RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
4194 if (tab_tracker_->ContainsHandle(tab_handle)) {
4195 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
4196 if (!tab) {
4197 NOTREACHED();
4198 return NULL;
4199 }
4200
4201 TabContents* tab_contents = tab->tab_contents();
4202 if (!tab_contents) {
4203 NOTREACHED();
4204 return NULL;
4205 }
4206
4207 RenderViewHost* view_host = tab_contents->render_view_host();
4208 return view_host;
4209 }
4210
4211 return NULL;
4212}
[email protected]675595f2009-08-26 22:32:044213
4214void AutomationProvider::GetBrowserForWindow(int window_handle,
4215 bool* success,
4216 int* browser_handle) {
4217 *success = false;
4218 *browser_handle = 0;
4219
4220 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
4221 if (!window)
4222 return;
4223
4224 BrowserList::const_iterator iter = BrowserList::begin();
4225 for (;iter != BrowserList::end(); ++iter) {
4226 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
4227 if (window == this_window) {
4228 // Add() returns the existing handle for the resource if any.
4229 *browser_handle = browser_tracker_->Add(*iter);
4230 *success = true;
4231 return;
4232 }
4233 }
4234}
[email protected]d11c8e92009-10-20 23:26:404235
4236void AutomationProvider::InstallExtension(const FilePath& crx_path,
4237 IPC::Message* reply_message) {
4238 ExtensionsService* service = profile_->GetExtensionsService();
4239 if (service) {
4240 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:194241 new ExtensionInstallNotificationObserver(this,
4242 AutomationMsg_InstallExtension::ID,
4243 reply_message);
[email protected]d11c8e92009-10-20 23:26:404244
4245 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:164246 scoped_refptr<CrxInstaller> installer(
4247 new CrxInstaller(install_dir,
4248 service,
4249 NULL)); // silent install, no UI
4250 installer->set_allow_privilege_increase(true);
4251 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:404252 } else {
4253 AutomationMsg_InstallExtension::WriteReplyParams(
4254 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
4255 Send(reply_message);
4256 }
4257}
4258
4259void AutomationProvider::LoadExpandedExtension(
4260 const FilePath& extension_dir,
4261 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:384262 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:404263 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:194264 new ExtensionInstallNotificationObserver(
4265 this,
4266 AutomationMsg_LoadExpandedExtension::ID,
4267 reply_message);
[email protected]d11c8e92009-10-20 23:26:404268
4269 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:404270 } else {
4271 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
4272 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
4273 Send(reply_message);
4274 }
4275}
[email protected]673fd2c02010-02-04 23:10:004276
[email protected]a1e62d12010-03-16 02:18:434277void AutomationProvider::GetEnabledExtensions(
4278 std::vector<FilePath>* result) {
4279 ExtensionsService* service = profile_->GetExtensionsService();
4280 DCHECK(service);
4281 if (service->extensions_enabled()) {
4282 const ExtensionList* extensions = service->extensions();
4283 DCHECK(extensions);
4284 for (size_t i = 0; i < extensions->size(); ++i) {
4285 Extension* extension = (*extensions)[i];
4286 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:124287 if (extension->location() == Extension::INTERNAL ||
4288 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:074289 result->push_back(extension->path());
4290 }
[email protected]a1e62d12010-03-16 02:18:434291 }
4292 }
4293}
4294
[email protected]790788ac2010-04-06 17:52:194295void AutomationProvider::WaitForExtensionTestResult(
4296 IPC::Message* reply_message) {
4297 DCHECK(reply_message_ == NULL);
4298 reply_message_ = reply_message;
4299 // Call MaybeSendResult, because the result might have come in before
4300 // we were waiting on it.
4301 extension_test_result_observer_->MaybeSendResult();
4302}
4303
4304void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:094305 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:194306 ExtensionsService* service = profile_->GetExtensionsService();
4307 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
4308 if (service && manager) {
4309 // The observer will delete itself when done.
4310 new ExtensionReadyNotificationObserver(
4311 manager,
4312 this,
4313 AutomationMsg_InstallExtensionAndGetHandle::ID,
4314 reply_message);
4315
[email protected]d7e5525d2010-04-20 14:37:094316 ExtensionInstallUI* client =
4317 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:194318 scoped_refptr<CrxInstaller> installer(
4319 new CrxInstaller(service->install_directory(),
4320 service,
[email protected]d7e5525d2010-04-20 14:37:094321 client));
[email protected]790788ac2010-04-06 17:52:194322 installer->set_allow_privilege_increase(true);
4323 installer->InstallCrx(crx_path);
4324 } else {
4325 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
4326 reply_message, 0);
4327 Send(reply_message);
4328 }
4329}
4330
4331void AutomationProvider::UninstallExtension(int extension_handle,
4332 bool* success) {
4333 *success = false;
4334 Extension* extension = GetExtension(extension_handle);
4335 ExtensionsService* service = profile_->GetExtensionsService();
4336 if (extension && service) {
4337 ExtensionUnloadNotificationObserver observer;
4338 service->UninstallExtension(extension->id(), false);
4339 // The extension unload notification should have been sent synchronously
4340 // with the uninstall. Just to be safe, check that it was received.
4341 *success = observer.did_receive_unload_notification();
4342 }
4343}
4344
4345void AutomationProvider::EnableExtension(int extension_handle,
4346 IPC::Message* reply_message) {
4347 Extension* extension = GetDisabledExtension(extension_handle);
4348 ExtensionsService* service = profile_->GetExtensionsService();
4349 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
4350 // Only enable if this extension is disabled.
4351 if (extension && service && manager) {
4352 // The observer will delete itself when done.
4353 new ExtensionReadyNotificationObserver(
4354 manager,
4355 this,
4356 AutomationMsg_EnableExtension::ID,
4357 reply_message);
4358 service->EnableExtension(extension->id());
4359 } else {
4360 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
4361 Send(reply_message);
4362 }
4363}
4364
4365void AutomationProvider::DisableExtension(int extension_handle,
4366 bool* success) {
4367 *success = false;
4368 Extension* extension = GetEnabledExtension(extension_handle);
4369 ExtensionsService* service = profile_->GetExtensionsService();
4370 if (extension && service) {
4371 ExtensionUnloadNotificationObserver observer;
4372 service->DisableExtension(extension->id());
4373 // The extension unload notification should have been sent synchronously
4374 // with the disable. Just to be safe, check that it was received.
4375 *success = observer.did_receive_unload_notification();
4376 }
4377}
4378
4379void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
4380 int extension_handle, int browser_handle,
4381 IPC::Message* reply_message) {
4382 bool success = false;
4383 Extension* extension = GetEnabledExtension(extension_handle);
4384 ExtensionsService* service = profile_->GetExtensionsService();
4385 ExtensionMessageService* message_service =
4386 profile_->GetExtensionMessageService();
4387 Browser* browser = browser_tracker_->GetResource(browser_handle);
4388 if (extension && service && message_service && browser) {
4389 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
4390 if (extension->page_action()) {
4391 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
4392 browser->profile(), extension->id(), "action", tab_id, "", 1);
4393 success = true;
4394 } else if (extension->browser_action()) {
4395 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
4396 browser->profile(), extension->id(), browser);
4397 success = true;
4398 }
4399 }
4400 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
4401 reply_message, success);
4402 Send(reply_message);
4403}
4404
4405void AutomationProvider::MoveExtensionBrowserAction(
4406 int extension_handle, int index, bool* success) {
4407 *success = false;
4408 Extension* extension = GetEnabledExtension(extension_handle);
4409 ExtensionsService* service = profile_->GetExtensionsService();
4410 if (extension && service) {
4411 ExtensionToolbarModel* toolbar = service->toolbar_model();
4412 if (toolbar) {
4413 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
4414 toolbar->MoveBrowserAction(extension, index);
4415 *success = true;
4416 } else {
4417 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
4418 }
4419 }
4420 }
4421}
4422
4423void AutomationProvider::GetExtensionProperty(
4424 int extension_handle,
4425 AutomationMsg_ExtensionProperty type,
4426 bool* success,
4427 std::string* value) {
4428 *success = false;
4429 Extension* extension = GetExtension(extension_handle);
4430 ExtensionsService* service = profile_->GetExtensionsService();
4431 if (extension && service) {
4432 ExtensionToolbarModel* toolbar = service->toolbar_model();
4433 int found_index = -1;
4434 int index = 0;
4435 switch (type) {
4436 case AUTOMATION_MSG_EXTENSION_ID:
4437 *value = extension->id();
4438 *success = true;
4439 break;
4440 case AUTOMATION_MSG_EXTENSION_NAME:
4441 *value = extension->name();
4442 *success = true;
4443 break;
4444 case AUTOMATION_MSG_EXTENSION_VERSION:
4445 *value = extension->VersionString();
4446 *success = true;
4447 break;
4448 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
4449 if (toolbar) {
4450 for (ExtensionList::const_iterator iter = toolbar->begin();
4451 iter != toolbar->end(); iter++) {
4452 // Skip this extension if we are in incognito mode
4453 // and it is not incognito-enabled.
4454 if (profile_->IsOffTheRecord() &&
4455 !service->IsIncognitoEnabled(*iter))
4456 continue;
4457 if (*iter == extension) {
4458 found_index = index;
4459 break;
4460 }
4461 index++;
4462 }
[email protected]528c56d2010-07-30 19:28:444463 *value = base::IntToString(found_index);
[email protected]790788ac2010-04-06 17:52:194464 *success = true;
4465 }
4466 break;
4467 default:
4468 LOG(WARNING) << "Trying to get undefined extension property";
4469 break;
4470 }
4471 }
4472}
4473
[email protected]673fd2c02010-02-04 23:10:004474void AutomationProvider::SaveAsAsync(int tab_handle) {
4475 NavigationController* tab = NULL;
4476 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
4477 if (tab_contents)
4478 tab_contents->OnSavePage();
4479}
[email protected]7dad3d5f2010-03-04 00:27:014480
4481void AutomationProvider::SetContentSetting(
4482 int handle,
4483 const std::string& host,
4484 ContentSettingsType content_type,
4485 ContentSetting setting,
4486 bool* success) {
4487 *success = false;
4488 if (browser_tracker_->ContainsHandle(handle)) {
4489 Browser* browser = browser_tracker_->GetResource(handle);
4490 HostContentSettingsMap* map =
4491 browser->profile()->GetHostContentSettingsMap();
4492 if (host.empty()) {
4493 map->SetDefaultContentSetting(content_type, setting);
4494 } else {
[email protected]0314ae02010-04-08 09:18:294495 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
4496 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:014497 }
4498 *success = true;
4499 }
4500}
[email protected]cc824372010-03-31 15:33:014501
4502#if !defined(TOOLKIT_VIEWS)
4503void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
4504 NOTIMPLEMENTED();
4505};
4506
4507void AutomationProvider::WaitForFocusedViewIDToChange(
4508 int handle, int previous_view_id, IPC::Message* reply_message) {
4509 NOTIMPLEMENTED();
4510}
4511
4512void AutomationProvider::StartTrackingPopupMenus(
4513 int browser_handle, bool* success) {
4514 NOTIMPLEMENTED();
4515}
4516
4517void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
4518 NOTIMPLEMENTED();
4519}
4520#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:094521
4522void AutomationProvider::ResetToDefaultTheme() {
4523 profile_->ClearTheme();
4524}