blob: eee8fbb820ffe738fce1471a6987d6c5427979f0 [file] [log] [blame]
[email protected]3b5f7022010-03-25 20:37:401// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]37126212009-05-06 02:23:319#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5910#include "base/callback.h"
[email protected]7060bb292010-06-24 00:52:4911#include "base/file_path.h"
[email protected]c6cb1992009-04-13 16:45:2912#include "base/file_version_info.h"
[email protected]93d49d72009-10-23 20:00:2013#include "base/json/json_reader.h"
[email protected]59a611242010-04-02 02:24:0414#include "base/json/json_writer.h"
[email protected]93364da2010-06-29 18:03:4415#include "base/json/string_escape.h"
[email protected]bc1407f2009-09-29 00:33:3516#include "base/keyboard_codes.h"
[email protected]5fac9622009-02-04 21:49:3817#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/path_service.h"
[email protected]201b2732009-11-13 18:57:4619#include "base/process_util.h"
[email protected]f44265b2009-05-19 18:52:5020#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2721#include "base/string_util.h"
[email protected]9eaa18e2010-06-29 20:51:0122#include "base/task.h"
[email protected]5fac9622009-02-04 21:49:3823#include "base/thread.h"
[email protected]a872ea1f2010-08-11 04:45:3324#include "base/trace_event.h"
[email protected]528c56d2010-07-30 19:28:4425#include "base/string_number_conversions.h"
[email protected]6d8ffc9f2010-03-12 18:27:5326#include "base/utf_string_conversions.h"
[email protected]a7eee32f2009-05-22 18:08:1727#include "base/values.h"
[email protected]9eaa18e2010-06-29 20:51:0128#include "base/waitable_event.h"
[email protected]4f3dc372009-02-24 00:10:2929#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2830#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0931#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]55846ad842010-07-09 18:22:5632#include "chrome/browser/autofill/autofill_manager.h"
[email protected]679082052010-07-21 21:30:1333#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
34#include "chrome/browser/automation/automation_browser_tracker.h"
[email protected]790788ac2010-04-06 17:52:1935#include "chrome/browser/automation/automation_extension_tracker.h"
[email protected]7c983cc2010-07-16 11:33:3436#include "chrome/browser/automation/automation_provider_json.h"
initial.commit09911bf2008-07-26 23:55:2937#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0838#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]679082052010-07-21 21:30:1339#include "chrome/browser/automation/automation_resource_message_filter.h"
40#include "chrome/browser/automation/automation_tab_tracker.h"
41#include "chrome/browser/automation/automation_window_tracker.h"
[email protected]f44265b2009-05-19 18:52:5042#include "chrome/browser/automation/extension_port_container.h"
[email protected]12802702010-07-09 19:43:0943#include "chrome/browser/autocomplete/autocomplete_edit.h"
[email protected]66ba4932009-06-04 19:22:1344#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5345#include "chrome/browser/bookmarks/bookmark_model.h"
46#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1447#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0748#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3949#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2050#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0551#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5852#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2953#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1254#include "chrome/browser/debugger/devtools_manager.h"
[email protected]6c69796d2010-07-16 21:41:1655#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2256#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0557#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4058#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1959#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1460#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4061#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5562#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1963#include "chrome/browser/extensions/extension_tabs_module.h"
64#include "chrome/browser/extensions/extension_toolbar_model.h"
65#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1666#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5867#include "chrome/browser/find_bar.h"
68#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2969#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0170#include "chrome/browser/host_content_settings_map.h"
[email protected]c5aa5322010-07-15 19:00:0771#include "chrome/browser/importer/importer.h"
72#include "chrome/browser/importer/importer_data_types.h"
[email protected]0ac83682010-01-22 17:46:2773#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0674#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0175#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5376#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2477#include "chrome/browser/platform_util.h"
[email protected]37858e52010-08-26 00:22:0278#include "chrome/browser/prefs/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0579#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1780#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0781#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2582#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0383#include "chrome/browser/ssl/ssl_manager.h"
84#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]b5558cf22010-07-12 17:30:0685#include "chrome/browser/tab_contents/infobar_delegate.h"
[email protected]57c6a652009-05-04 07:58:3486#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4587#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]38b5a3852010-07-21 06:49:5288#include "chrome/browser/translate/translate_infobar_delegate.h"
[email protected]a7eee32f2009-05-22 18:08:1789#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0590#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2991#include "chrome/common/chrome_paths.h"
[email protected]c984d9f2010-07-20 20:52:2092#include "chrome/common/chrome_switches.h"
[email protected]1eeb5e02010-07-20 23:02:1193#include "chrome/common/chrome_version_info.h"
[email protected]790788ac2010-04-06 17:52:1994#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1795#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5596#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1497#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5798#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2599#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:56100#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:57101#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:17102#include "net/proxy/proxy_service.h"
103#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:21104#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:30105#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:28106#include "views/event.h"
[email protected]5bcfe1672010-07-16 20:51:57107#include "webkit/glue/password_form.h"
[email protected]f7d48012010-05-06 08:17:05108#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:29109
[email protected]de246f52009-02-25 18:25:45110#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:35111#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:45112#endif // defined(OS_WIN)
113
[email protected]e1acf6f2008-10-27 20:43:33114using base::Time;
115
[email protected]cbab76d2008-10-13 22:42:47116class AutomationInterstitialPage : public InterstitialPage {
117 public:
[email protected]57c6a652009-05-04 07:58:34118 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47119 const GURL& url,
120 const std::string& contents)
121 : InterstitialPage(tab, true, url),
122 contents_(contents) {
123 }
124
125 virtual std::string GetHTMLContents() { return contents_; }
126
127 private:
128 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29129
[email protected]cbab76d2008-10-13 22:42:47130 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
131};
132
initial.commit09911bf2008-07-26 23:55:29133AutomationProvider::AutomationProvider(Profile* profile)
[email protected]c97080f2010-08-20 20:42:48134 : profile_(profile),
[email protected]4feac662010-08-25 23:29:39135 reply_message_(NULL) {
[email protected]a872ea1f2010-08-11 04:45:33136 TRACE_EVENT_BEGIN("AutomationProvider::AutomationProvider", 0, "");
137
initial.commit09911bf2008-07-26 23:55:29138 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19139 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29140 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20141 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29142 autocomplete_edit_tracker_.reset(
143 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29144 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
145 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44146 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19147 extension_test_result_observer_.reset(
148 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13149 g_browser_process->AddRefModule();
[email protected]a872ea1f2010-08-11 04:45:33150
151 TRACE_EVENT_END("AutomationProvider::AutomationProvider", 0, "");
initial.commit09911bf2008-07-26 23:55:29152}
153
154AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50155 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
156 port_containers_.end());
157 port_containers_.clear();
158
[email protected]0da050b92008-08-19 19:29:47159 // Make sure that any outstanding NotificationObservers also get destroyed.
160 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31161 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47162 while ((observer = it.GetNext()) != NULL)
163 delete observer;
[email protected]528211a2010-01-14 15:25:13164
165 if (channel_.get()) {
166 channel_->Close();
167 }
168 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29169}
170
[email protected]9a3a293b2009-06-04 22:28:16171void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]a872ea1f2010-08-11 04:45:33172 TRACE_EVENT_BEGIN("AutomationProvider::ConnectToChannel", 0, "");
173
[email protected]2e4633c2009-07-09 16:58:06174 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57175 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06176 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
177 automation_resource_message_filter_,
178 g_browser_process->io_thread()->message_loop(),
179 true, g_browser_process->shutdown_event()));
[email protected]1eeb5e02010-07-20 23:02:11180 scoped_ptr<FileVersionInfo> version_info(chrome::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40181 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43182 if (version_info != NULL) {
183 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40184 }
[email protected]c6cb1992009-04-13 16:45:29185
186 // Send a hello message with our current automation protocol version.
187 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
[email protected]a872ea1f2010-08-11 04:45:33188
189 TRACE_EVENT_END("AutomationProvider::ConnectToChannel", 0, "");
initial.commit09911bf2008-07-26 23:55:29190}
191
192void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
193 if (expected_tabs == 0) {
194 Send(new AutomationMsg_InitialLoadsComplete(0));
195 } else {
196 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
197 }
198}
199
200NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58201 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01202 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29203 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58204 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01205 number_of_navigations,
206 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29207
[email protected]71f65dd2009-02-11 19:14:56208 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29209 return observer;
210}
211
[email protected]faf2ee42010-05-11 14:26:17212void AutomationProvider::RemoveNavigationStatusListener(
213 NotificationObserver* obs) {
214 notification_observer_list_.RemoveObserver(obs);
215}
216
initial.commit09911bf2008-07-26 23:55:29217NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14218 Browser* parent,
219 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56220 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14221 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29222 notification_observer_list_.AddObserver(observer);
223
224 return observer;
225}
226
[email protected]faf2ee42010-05-11 14:26:17227void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29228 notification_observer_list_.RemoveObserver(obs);
229}
230
231void AutomationProvider::AddLoginHandler(NavigationController* tab,
232 LoginHandler* handler) {
233 login_handler_map_[tab] = handler;
234}
235
236void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
237 DCHECK(login_handler_map_[tab]);
238 login_handler_map_.erase(tab);
239}
240
[email protected]f44265b2009-05-19 18:52:50241void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
242 int port_id = port->port_id();
243 DCHECK_NE(-1, port_id);
244 DCHECK(port_containers_.find(port_id) == port_containers_.end());
245
246 port_containers_[port_id] = port;
247}
248
249void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
250 int port_id = port->port_id();
251 DCHECK_NE(-1, port_id);
252
253 PortContainerMap::iterator it = port_containers_.find(port_id);
254 DCHECK(it != port_containers_.end());
255
256 if (it != port_containers_.end()) {
257 delete it->second;
258 port_containers_.erase(it);
259 }
260}
261
262ExtensionPortContainer* AutomationProvider::GetPortContainer(
263 int port_id) const {
264 PortContainerMap::const_iterator it = port_containers_.find(port_id);
265 if (it == port_containers_.end())
266 return NULL;
267
268 return it->second;
269}
270
initial.commit09911bf2008-07-26 23:55:29271int AutomationProvider::GetIndexForNavigationController(
272 const NavigationController* controller, const Browser* parent) const {
273 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12274 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29275}
276
[email protected]790788ac2010-04-06 17:52:19277int AutomationProvider::AddExtension(Extension* extension) {
278 DCHECK(extension);
279 return extension_tracker_->Add(extension);
280}
281
282Extension* AutomationProvider::GetExtension(int extension_handle) {
283 return extension_tracker_->GetResource(extension_handle);
284}
285
286Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
287 Extension* extension = extension_tracker_->GetResource(extension_handle);
288 ExtensionsService* service = profile_->GetExtensionsService();
289 if (extension && service &&
290 service->GetExtensionById(extension->id(), false))
291 return extension;
292 return NULL;
293}
294
295Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
296 Extension* extension = extension_tracker_->GetResource(extension_handle);
297 ExtensionsService* service = profile_->GetExtensionsService();
298 if (extension && service &&
299 service->GetExtensionById(extension->id(), true) &&
300 !service->GetExtensionById(extension->id(), false))
301 return extension;
302 return NULL;
303}
304
initial.commit09911bf2008-07-26 23:55:29305void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
306 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1b5a48c2010-04-29 23:08:30307#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56308 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
309 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30310#endif // !defined(OS_MACOSX)
[email protected]d7fa7552009-03-20 21:06:37311#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56312 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45313#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29314 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14315 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17316 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14317 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14318 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53319 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
320 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14321 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]1c58a5c2009-05-21 18:47:14322 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56323 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14324 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56325 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14326 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56327 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
328 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14329 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
330 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44331 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
332 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56333 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
334 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29335 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
[email protected]bdb7ff62010-07-20 01:56:52336 IPC_MESSAGE_HANDLER(AutomationMsg_IsMenuCommandEnabled,
337 IsMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56338 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41339 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56340 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
[email protected]71f65dd2009-02-11 19:14:56341 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45342 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14343 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56344 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57345 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56346 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57347 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56348 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
349 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53350 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
351 GetBookmarksAsJSON)
352 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
353 WaitForBookmarkModelToLoad)
354 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
355 AddBookmarkGroup)
356 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
357 AddBookmarkURL)
358 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
359 ReparentBookmark)
360 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
361 SetBookmarkTitle)
362 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
363 SetBookmarkURL)
364 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
365 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04366 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
367 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18368 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
369 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
370 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56371 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42372 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56373 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
374 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14375 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56376 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44377 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56378 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20379 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14380 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56381 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16382 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56383 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16384 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56385 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16386 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14387 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20388 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
389 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14390 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22391 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13392 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19393 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
394 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
395 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
396 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
397 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
398 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52399 IPC_MESSAGE_HANDLER_DELAY_REPLY(
400 AutomationMsg_WaitForBrowserWindowCountToBecome,
401 WaitForBrowserWindowCountToBecome)
402 IPC_MESSAGE_HANDLER_DELAY_REPLY(
403 AutomationMsg_WaitForAppModalDialogToBeShown,
404 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26405 IPC_MESSAGE_HANDLER_DELAY_REPLY(
406 AutomationMsg_GoBackBlockUntilNavigationsComplete,
407 GoBackBlockUntilNavigationsComplete)
408 IPC_MESSAGE_HANDLER_DELAY_REPLY(
409 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
410 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57411 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40412 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
413 InstallExtension)
414 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
415 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43416 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
417 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19418 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
419 WaitForExtensionTestResult)
420 IPC_MESSAGE_HANDLER_DELAY_REPLY(
421 AutomationMsg_InstallExtensionAndGetHandle,
422 InstallExtensionAndGetHandle)
423 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
424 UninstallExtension)
425 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
426 EnableExtension)
427 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
428 DisableExtension)
429 IPC_MESSAGE_HANDLER_DELAY_REPLY(
430 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
431 ExecuteExtensionActionInActiveTabAsync)
432 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
433 MoveExtensionBrowserAction)
434 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
435 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57436 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
437 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00438 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01439 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20440 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00441 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]52415f842010-06-10 21:51:52442#if defined(OS_WIN)
443 // These are for use with external tabs.
444 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
445 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
446 ProcessUnhandledAccelerator)
447 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
448 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
449 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
450 OnForwardContextMenuCommandToChrome)
451 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
452 NavigateInExternalTab)
453 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
454 NavigateExternalTabAtIndex)
455 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
456 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
457 SetEnableExtensionAutomation)
458 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
459 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00460 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
[email protected]1f71d5882010-07-15 20:39:07461 IPC_MESSAGE_HANDLER(AutomationMsg_RunUnloadHandlers, OnRunUnloadHandlers)
[email protected]7f860dd82010-08-09 23:18:05462 IPC_MESSAGE_HANDLER(AutomationMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]bdd5a9c92010-06-14 18:21:00463#endif // defined(OS_WIN)
464#if defined(OS_CHROMEOS)
465 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
466 LoginWithUserAndPass)
467#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29468 IPC_END_MESSAGE_MAP()
469}
470
[email protected]71f65dd2009-02-11 19:14:56471void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
472 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07473 AppModalDialog* dialog_delegate =
474 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50475 *showing_dialog = (dialog_delegate != NULL);
476 if (*showing_dialog)
477 *dialog_button = dialog_delegate->GetDialogButtons();
478 else
[email protected]478ff2ed2009-04-21 23:49:18479 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20480}
481
[email protected]71f65dd2009-02-11 19:14:56482void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
483 *success = false;
[email protected]fad84eab2008-12-05 00:37:20484
[email protected]1f460072009-05-28 17:02:07485 AppModalDialog* dialog_delegate =
486 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50487 if (dialog_delegate &&
488 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18489 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
490 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28491 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56492 *success = true;
[email protected]fad84eab2008-12-05 00:37:20493 }
[email protected]478ff2ed2009-04-21 23:49:18494 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
495 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56496 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28497 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56498 *success = true;
[email protected]fad84eab2008-12-05 00:37:20499 }
500 }
[email protected]c274acc2008-11-11 20:13:44501}
502
[email protected]fedaa7d2010-01-26 20:34:57503void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
504 if (browser_tracker_->ContainsHandle(handle)) {
505 Browser* browser = browser_tracker_->GetResource(handle);
506 browser->profile()->ShutdownSessionService();
507 *result = true;
508 } else {
509 *result = false;
510 }
511}
512
[email protected]fc2e0872009-08-21 22:14:41513// This task just adds another task to the event queue. This is useful if
514// you want to ensure that any tasks added to the event queue after this one
515// have already been processed by the time |task| is run.
516class InvokeTaskLaterTask : public Task {
517 public:
518 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
519 virtual ~InvokeTaskLaterTask() {}
520
521 virtual void Run() {
522 MessageLoop::current()->PostTask(FROM_HERE, task_);
523 }
524
525 private:
526 Task* task_;
527
528 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
529};
530
initial.commit09911bf2008-07-26 23:55:29531void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
532 if (window_tracker_->ContainsHandle(handle)) {
533 window_tracker_->Remove(window_tracker_->GetResource(handle));
534 }
535}
536
537void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:16538 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:57539 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:29540}
541
initial.commit09911bf2008-07-26 23:55:29542bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:57543 DCHECK(channel_.get());
544 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:29545}
546
547Browser* AutomationProvider::FindAndActivateTab(
548 NavigationController* controller) {
549 int tab_index;
550 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
551 if (browser)
552 browser->SelectTabContentsAt(tab_index, true);
553
554 return browser;
555}
556
[email protected]59560e0b2009-06-04 03:30:22557void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
558 if (browser_tracker_->ContainsHandle(handle)) {
559 Browser* browser = browser_tracker_->GetResource(handle);
560 if (browser) {
561 if (visible)
562 browser->window()->GetDownloadShelf()->Show();
563 else
564 browser->window()->GetDownloadShelf()->Close();
565 }
566 }
567}
568
[email protected]4f999132009-03-31 18:08:40569void AutomationProvider::HandleFindRequest(
570 int handle,
571 const AutomationMsg_Find_Params& params,
572 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29573 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:56574 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
575 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29576 return;
577 }
578
579 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:11580 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:29581
582 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:14583 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:29584
[email protected]57c6a652009-05-04 07:58:34585 tab_contents->set_current_find_request_id(
586 FindInPageNotificationObserver::kFindInPageRequestId);
587 tab_contents->render_view_host()->StartFinding(
588 FindInPageNotificationObserver::kFindInPageRequestId,
589 params.search_string, params.forward, params.match_case,
590 params.find_next);
initial.commit09911bf2008-07-26 23:55:29591}
592
[email protected]5f8af2a2008-08-06 22:49:45593void AutomationProvider::HandleOpenFindInPageRequest(
594 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:29595 if (browser_tracker_->ContainsHandle(handle)) {
596 Browser* browser = browser_tracker_->GetResource(handle);
597 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:45598 }
599}
600
[email protected]71f65dd2009-02-11 19:14:56601void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:56602 *visible = false;
[email protected]855c0142009-09-28 22:35:24603 Browser* browser = browser_tracker_->GetResource(handle);
604 if (browser) {
[email protected]4801ecc2009-04-05 04:52:58605 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:17606 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:24607 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:29608 }
[email protected]20e93d12008-08-28 16:31:57609}
610
[email protected]71f65dd2009-02-11 19:14:56611void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
612 int* y) {
[email protected]9e0534b2008-10-21 15:03:01613 gfx::Point position(0, 0);
614 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:29615 if (browser_tracker_->ContainsHandle(handle)) {
616 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:58617 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:17618 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:58619 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:29620 }
[email protected]20e93d12008-08-28 16:31:57621
[email protected]71f65dd2009-02-11 19:14:56622 *x = position.x();
623 *y = position.y();
[email protected]20e93d12008-08-28 16:31:57624}
625
[email protected]4512cb52010-04-05 19:50:25626// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
627// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:58628void AutomationProvider::GetBookmarkBarVisibility(int handle,
629 bool* visible,
630 bool* animating) {
631 *visible = false;
632 *animating = false;
633
634 if (browser_tracker_->ContainsHandle(handle)) {
635 Browser* browser = browser_tracker_->GetResource(handle);
636 if (browser) {
[email protected]472f099b2010-05-27 17:07:12637#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
638 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
639
[email protected]ab6ca392010-04-07 00:44:13640 // IsBookmarkBarVisible() line looks correct but is not
641 // consistent across platforms. Specifically, on Mac/Linux, it
642 // returns false if the bar is hidden in a pref (even if visible
643 // on the NTP). On ChromeOS, it returned true if on NTP
644 // independent of the pref. Making the code more consistent
645 // caused a perf bot regression on Windows (which shares views).
646 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:25647 *visible = browser->profile()->GetPrefs()->GetBoolean(
648 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:40649#else
650 *visible = browser->window()->IsBookmarkBarVisible();
651#endif
[email protected]c3240722010-03-05 21:52:58652 *animating = browser->window()->IsBookmarkBarAnimating();
653 }
654 }
655}
656
[email protected]6d8ffc9f2010-03-12 18:27:53657void AutomationProvider::GetBookmarksAsJSON(int handle,
658 std::string* bookmarks_as_json,
659 bool *success) {
660 *success = false;
661 if (browser_tracker_->ContainsHandle(handle)) {
662 Browser* browser = browser_tracker_->GetResource(handle);
663 if (browser) {
664 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
665 return;
666 }
667 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
668 browser->profile(),
669 browser->profile()->GetBookmarkModel());
670 *success = storage->SerializeData(bookmarks_as_json);
671 }
672 }
673}
674
675void AutomationProvider::WaitForBookmarkModelToLoad(
676 int handle,
677 IPC::Message* reply_message) {
678 if (browser_tracker_->ContainsHandle(handle)) {
679 Browser* browser = browser_tracker_->GetResource(handle);
680 BookmarkModel* model = browser->profile()->GetBookmarkModel();
681 if (model->IsLoaded()) {
682 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
683 reply_message, true);
684 Send(reply_message);
685 } else {
686 // The observer will delete itself when done.
687 new AutomationProviderBookmarkModelObserver(this, reply_message,
688 model);
689 }
690 }
691}
692
693void AutomationProvider::AddBookmarkGroup(int handle,
694 int64 parent_id, int index,
695 std::wstring title,
696 bool* success) {
697 if (browser_tracker_->ContainsHandle(handle)) {
698 Browser* browser = browser_tracker_->GetResource(handle);
699 if (browser) {
700 BookmarkModel* model = browser->profile()->GetBookmarkModel();
701 if (!model->IsLoaded()) {
702 *success = false;
703 return;
704 }
705 const BookmarkNode* parent = model->GetNodeByID(parent_id);
706 DCHECK(parent);
707 if (parent) {
708 const BookmarkNode* child = model->AddGroup(parent, index,
[email protected]ff4c1d82010-08-04 16:58:12709 WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:53710 DCHECK(child);
711 if (child)
712 *success = true;
713 }
714 }
715 }
716 *success = false;
717}
718
719void AutomationProvider::AddBookmarkURL(int handle,
720 int64 parent_id, int index,
721 std::wstring title, const GURL& url,
722 bool* success) {
723 if (browser_tracker_->ContainsHandle(handle)) {
724 Browser* browser = browser_tracker_->GetResource(handle);
725 if (browser) {
726 BookmarkModel* model = browser->profile()->GetBookmarkModel();
727 if (!model->IsLoaded()) {
728 *success = false;
729 return;
730 }
731 const BookmarkNode* parent = model->GetNodeByID(parent_id);
732 DCHECK(parent);
733 if (parent) {
734 const BookmarkNode* child = model->AddURL(parent, index,
[email protected]ff4c1d82010-08-04 16:58:12735 WideToUTF16Hack(title), url);
[email protected]6d8ffc9f2010-03-12 18:27:53736 DCHECK(child);
737 if (child)
738 *success = true;
739 }
740 }
741 }
742 *success = false;
743}
744
745void AutomationProvider::ReparentBookmark(int handle,
746 int64 id, int64 new_parent_id,
747 int index,
748 bool* success) {
749 if (browser_tracker_->ContainsHandle(handle)) {
750 Browser* browser = browser_tracker_->GetResource(handle);
751 if (browser) {
752 BookmarkModel* model = browser->profile()->GetBookmarkModel();
753 if (!model->IsLoaded()) {
754 *success = false;
755 return;
756 }
757 const BookmarkNode* node = model->GetNodeByID(id);
758 DCHECK(node);
759 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
760 DCHECK(new_parent);
761 if (node && new_parent) {
762 model->Move(node, new_parent, index);
763 *success = true;
764 }
765 }
766 }
767 *success = false;
768}
769
770void AutomationProvider::SetBookmarkTitle(int handle,
771 int64 id, std::wstring title,
772 bool* success) {
773 if (browser_tracker_->ContainsHandle(handle)) {
774 Browser* browser = browser_tracker_->GetResource(handle);
775 if (browser) {
776 BookmarkModel* model = browser->profile()->GetBookmarkModel();
777 if (!model->IsLoaded()) {
778 *success = false;
779 return;
780 }
781 const BookmarkNode* node = model->GetNodeByID(id);
782 DCHECK(node);
783 if (node) {
[email protected]ff4c1d82010-08-04 16:58:12784 model->SetTitle(node, WideToUTF16Hack(title));
[email protected]6d8ffc9f2010-03-12 18:27:53785 *success = true;
786 }
787 }
788 }
789 *success = false;
790}
791
792void AutomationProvider::SetBookmarkURL(int handle,
793 int64 id, const GURL& url,
794 bool* success) {
795 if (browser_tracker_->ContainsHandle(handle)) {
796 Browser* browser = browser_tracker_->GetResource(handle);
797 if (browser) {
798 BookmarkModel* model = browser->profile()->GetBookmarkModel();
799 if (!model->IsLoaded()) {
800 *success = false;
801 return;
802 }
803 const BookmarkNode* node = model->GetNodeByID(id);
804 DCHECK(node);
805 if (node) {
806 model->SetURL(node, url);
807 *success = true;
808 }
809 }
810 }
811 *success = false;
812}
813
814void AutomationProvider::RemoveBookmark(int handle,
815 int64 id,
816 bool* success) {
817 if (browser_tracker_->ContainsHandle(handle)) {
818 Browser* browser = browser_tracker_->GetResource(handle);
819 if (browser) {
820 BookmarkModel* model = browser->profile()->GetBookmarkModel();
821 if (!model->IsLoaded()) {
822 *success = false;
823 return;
824 }
825 const BookmarkNode* node = model->GetNodeByID(id);
826 DCHECK(node);
827 if (node) {
828 const BookmarkNode* parent = node->GetParent();
829 DCHECK(parent);
830 model->Remove(parent, parent->IndexOfChild(node));
831 *success = true;
832 }
833 }
834 }
835 *success = false;
836}
837
[email protected]ef413ca2010-05-25 21:09:14838// Sample json input: { "command": "SetWindowDimensions",
839// "x": 20, # optional
840// "y": 20, # optional
841// "width": 800, # optional
842// "height": 600 } # optional
843void AutomationProvider::SetWindowDimensions(Browser* browser,
844 DictionaryValue* args,
845 IPC::Message* reply_message) {
846 gfx::Rect rect = browser->window()->GetRestoredBounds();
847 int x, y, width, height;
[email protected]ff4c1d82010-08-04 16:58:12848 if (args->GetInteger("x", &x))
[email protected]ef413ca2010-05-25 21:09:14849 rect.set_x(x);
[email protected]ff4c1d82010-08-04 16:58:12850 if (args->GetInteger("y", &y))
[email protected]ef413ca2010-05-25 21:09:14851 rect.set_y(y);
[email protected]ff4c1d82010-08-04 16:58:12852 if (args->GetInteger("width", &width))
[email protected]ef413ca2010-05-25 21:09:14853 rect.set_width(width);
[email protected]ff4c1d82010-08-04 16:58:12854 if (args->GetInteger("height", &height))
[email protected]ef413ca2010-05-25 21:09:14855 rect.set_height(height);
856 browser->window()->SetBounds(rect);
[email protected]7c983cc2010-07-16 11:33:34857 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
[email protected]ef413ca2010-05-25 21:09:14858}
859
[email protected]38b5a3852010-07-21 06:49:52860ListValue* AutomationProvider::GetInfobarsInfo(TabContents* tc) {
861 // Each infobar may have different properties depending on the type.
862 ListValue* infobars = new ListValue;
863 for (int infobar_index = 0;
864 infobar_index < tc->infobar_delegate_count();
865 ++infobar_index) {
866 DictionaryValue* infobar_item = new DictionaryValue;
867 InfoBarDelegate* infobar = tc->GetInfoBarDelegateAt(infobar_index);
868 if (infobar->AsConfirmInfoBarDelegate()) {
869 // Also covers ThemeInstalledInfoBarDelegate and
870 // CrashedExtensionInfoBarDelegate.
[email protected]ff4c1d82010-08-04 16:58:12871 infobar_item->SetString("type", "confirm_infobar");
[email protected]38b5a3852010-07-21 06:49:52872 ConfirmInfoBarDelegate* confirm_infobar =
873 infobar->AsConfirmInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:58874 infobar_item->SetString("text", confirm_infobar->GetMessageText());
875 infobar_item->SetString("link_text", confirm_infobar->GetLinkText());
[email protected]38b5a3852010-07-21 06:49:52876 ListValue* buttons_list = new ListValue;
877 int buttons = confirm_infobar->GetButtons();
878 if (ConfirmInfoBarDelegate::BUTTON_OK & buttons) {
879 StringValue* button_label = new StringValue(
880 confirm_infobar->GetButtonLabel(
881 ConfirmInfoBarDelegate::BUTTON_OK));
882 buttons_list->Append(button_label);
883 }
884 if (ConfirmInfoBarDelegate::BUTTON_CANCEL & buttons) {
885 StringValue* button_label = new StringValue(
886 confirm_infobar->GetButtonLabel(
887 ConfirmInfoBarDelegate::BUTTON_CANCEL));
888 buttons_list->Append(button_label);
889 }
[email protected]ff4c1d82010-08-04 16:58:12890 infobar_item->Set("buttons", buttons_list);
[email protected]38b5a3852010-07-21 06:49:52891 } else if (infobar->AsAlertInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:12892 infobar_item->SetString("type", "alert_infobar");
[email protected]38b5a3852010-07-21 06:49:52893 AlertInfoBarDelegate* alert_infobar =
894 infobar->AsAlertInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:58895 infobar_item->SetString("text", alert_infobar->GetMessageText());
[email protected]38b5a3852010-07-21 06:49:52896 } else if (infobar->AsLinkInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:12897 infobar_item->SetString("type", "link_infobar");
[email protected]38b5a3852010-07-21 06:49:52898 LinkInfoBarDelegate* link_infobar = infobar->AsLinkInfoBarDelegate();
[email protected]e23d3a32010-08-13 19:39:58899 infobar_item->SetString("link_text", link_infobar->GetLinkText());
[email protected]38b5a3852010-07-21 06:49:52900 } else if (infobar->AsTranslateInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:12901 infobar_item->SetString("type", "translate_infobar");
[email protected]38b5a3852010-07-21 06:49:52902 TranslateInfoBarDelegate* translate_infobar =
903 infobar->AsTranslateInfoBarDelegate();
[email protected]ff4c1d82010-08-04 16:58:12904 infobar_item->SetString("original_lang_code",
[email protected]38b5a3852010-07-21 06:49:52905 translate_infobar->GetOriginalLanguageCode());
[email protected]ff4c1d82010-08-04 16:58:12906 infobar_item->SetString("target_lang_code",
[email protected]38b5a3852010-07-21 06:49:52907 translate_infobar->GetTargetLanguageCode());
908 } else if (infobar->AsExtensionInfoBarDelegate()) {
[email protected]ff4c1d82010-08-04 16:58:12909 infobar_item->SetString("type", "extension_infobar");
[email protected]38b5a3852010-07-21 06:49:52910 } else {
[email protected]ff4c1d82010-08-04 16:58:12911 infobar_item->SetString("type", "unknown_infobar");
[email protected]38b5a3852010-07-21 06:49:52912 }
913 infobars->Append(infobar_item);
914 }
915 return infobars;
916}
917
918// Sample json input: { "command": "WaitForInfobarCount",
919// "count": COUNT,
920// "tab_index": INDEX }
921// Sample output: {}
922void AutomationProvider::WaitForInfobarCount(Browser* browser,
923 DictionaryValue* args,
924 IPC::Message* reply_message) {
925 int tab_index;
926 int count;
[email protected]ff4c1d82010-08-04 16:58:12927 if (!args->GetInteger("count", &count) || count < 0 ||
928 !args->GetInteger("tab_index", &tab_index) || tab_index < 0) {
[email protected]38b5a3852010-07-21 06:49:52929 AutomationJSONReply(this, reply_message).SendError(
930 "Missing or invalid args: 'count', 'tab_index'.");
931 return;
932 }
933
934 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
935 // Observer deletes itself.
936 new WaitForInfobarCountObserver(this, reply_message, tab_contents, count);
937}
938
[email protected]e004a2d2010-07-22 04:55:28939// Sample json input: { "command": "PerformActionOnInfobar",
940// "action": "dismiss",
941// "infobar_index": 0,
942// "tab_index": 0 }
943// Sample output: {}
944void AutomationProvider::PerformActionOnInfobar(Browser* browser,
945 DictionaryValue* args,
946 IPC::Message* reply_message) {
947 AutomationJSONReply reply(this, reply_message);
948 int tab_index;
949 int infobar_index;
950 std::string action;
[email protected]ff4c1d82010-08-04 16:58:12951 if (!args->GetInteger("tab_index", &tab_index) ||
952 !args->GetInteger("infobar_index", &infobar_index) ||
953 !args->GetString("action", &action)) {
[email protected]e004a2d2010-07-22 04:55:28954 reply.SendError("Invalid or missing args");
955 return;
956 }
957 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
958 if (!tab_contents) {
959 reply.SendError(StringPrintf("No such tab at index %d", tab_index));
960 return;
961 }
962 InfoBarDelegate* infobar = NULL;
963 if (infobar_index < 0 ||
964 infobar_index >= tab_contents->infobar_delegate_count() ||
965 !(infobar = tab_contents->GetInfoBarDelegateAt(infobar_index))) {
966 reply.SendError(StringPrintf("No such infobar at index %d", infobar_index));
967 return;
968 }
969 if ("dismiss" == action) {
970 infobar->InfoBarDismissed();
971 tab_contents->RemoveInfoBar(infobar);
972 reply.SendSuccess(NULL);
973 return;
974 }
975 if ("accept" == action || "cancel" == action) {
976 ConfirmInfoBarDelegate* confirm_infobar;
977 if (!(confirm_infobar = infobar->AsConfirmInfoBarDelegate())) {
978 reply.SendError("Not a confirm infobar");
979 return;
980 }
981 if ("accept" == action) {
982 if (confirm_infobar->Accept())
983 tab_contents->RemoveInfoBar(infobar);
984 } else if ("cancel" == action) {
985 if (confirm_infobar->Cancel())
986 tab_contents->RemoveInfoBar(infobar);
987 }
988 reply.SendSuccess(NULL);
989 return;
990 }
991 reply.SendError("Invalid action");
992}
993
[email protected]26adfd312010-07-20 01:04:46994namespace {
995
996// Task to get info about BrowserChildProcessHost. Must run on IO thread to
997// honor the semantics of BrowserChildProcessHost.
998// Used by AutomationProvider::GetBrowserInfo().
999class GetChildProcessHostInfoTask : public Task {
1000 public:
1001 GetChildProcessHostInfoTask(base::WaitableEvent* event,
1002 ListValue* child_processes)
1003 : event_(event),
1004 child_processes_(child_processes) {}
1005
1006 virtual void Run() {
1007 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
1008 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1009 // Only add processes which are already started,
1010 // since we need their handle.
1011 if ((*iter)->handle() == base::kNullProcessHandle) {
1012 continue;
1013 }
1014 ChildProcessInfo* info = *iter;
1015 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121016 item->SetString("name", WideToUTF16Hack(info->name()));
1017 item->SetString("type",
[email protected]41b5c202010-08-19 01:11:081018 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
[email protected]ff4c1d82010-08-04 16:58:121019 item->SetInteger("pid", base::GetProcId(info->handle()));
[email protected]26adfd312010-07-20 01:04:461020 child_processes_->Append(item);
1021 }
1022 event_->Signal();
1023 }
1024
1025 private:
1026 base::WaitableEvent* const event_; // weak
1027 ListValue* child_processes_;
1028
1029 DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask);
1030};
1031
1032} // namespace
1033
[email protected]a9ff2c02010-05-13 17:33:051034// Sample json input: { "command": "GetBrowserInfo" }
1035// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1036// sample json output.
[email protected]53329582010-05-14 21:10:581037void AutomationProvider::GetBrowserInfo(Browser* browser,
1038 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051039 IPC::Message* reply_message) {
[email protected]a9ff2c02010-05-13 17:33:051040 DictionaryValue* properties = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121041 properties->SetString("ChromeVersion", chrome::kChromeVersion);
1042 properties->SetString("BrowserProcessExecutableName",
1043 WideToUTF16Hack(chrome::kBrowserProcessExecutableName));
1044 properties->SetString("HelperProcessExecutableName",
1045 WideToUTF16Hack(chrome::kHelperProcessExecutableName));
1046 properties->SetString("BrowserProcessExecutablePath",
1047 WideToUTF16Hack(chrome::kBrowserProcessExecutablePath));
1048 properties->SetString("HelperProcessExecutablePath",
[email protected]a9ff2c02010-05-13 17:33:051049 chrome::kHelperProcessExecutablePath);
[email protected]ff4c1d82010-08-04 16:58:121050 properties->SetString("command_line_string",
[email protected]a9ff2c02010-05-13 17:33:051051 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]9d8fe3b2010-08-20 19:51:241052 FilePath dumps_path;
1053 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
1054 properties->SetString("DIR_CRASH_DUMPS", dumps_path.value());
[email protected]44eed9f2010-06-28 22:04:001055
1056 std::string branding;
1057#if defined(GOOGLE_CHROME_BUILD)
1058 branding = "Google Chrome";
1059#elif defined(CHROMIUM_BUILD)
1060 branding = "Chromium";
1061#else
1062 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051063#endif
[email protected]ff4c1d82010-08-04 16:58:121064 properties->SetString("branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051065
1066 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:121067 return_value->Set("properties", properties);
[email protected]a9ff2c02010-05-13 17:33:051068
[email protected]ff4c1d82010-08-04 16:58:121069 return_value->SetInteger("browser_pid", base::GetCurrentProcId());
[email protected]ef413ca2010-05-25 21:09:141070 // Add info about all windows in a list of dictionaries, one dictionary
1071 // item per window.
1072 ListValue* windows = new ListValue;
1073 int windex = 0;
1074 for (BrowserList::const_iterator it = BrowserList::begin();
1075 it != BrowserList::end();
1076 ++it, ++windex) {
1077 DictionaryValue* browser_item = new DictionaryValue;
1078 browser = *it;
[email protected]ff4c1d82010-08-04 16:58:121079 browser_item->SetInteger("index", windex);
[email protected]ef413ca2010-05-25 21:09:141080 // Window properties
1081 gfx::Rect rect = browser->window()->GetRestoredBounds();
[email protected]ff4c1d82010-08-04 16:58:121082 browser_item->SetInteger("x", rect.x());
1083 browser_item->SetInteger("y", rect.y());
1084 browser_item->SetInteger("width", rect.width());
1085 browser_item->SetInteger("height", rect.height());
1086 browser_item->SetBoolean("fullscreen",
[email protected]ef413ca2010-05-25 21:09:141087 browser->window()->IsFullscreen());
[email protected]ff4c1d82010-08-04 16:58:121088 browser_item->SetInteger("selected_tab", browser->selected_index());
1089 browser_item->SetBoolean("incognito",
[email protected]ef413ca2010-05-25 21:09:141090 browser->profile()->IsOffTheRecord());
1091 // For each window, add info about all tabs in a list of dictionaries,
1092 // one dictionary item per tab.
1093 ListValue* tabs = new ListValue;
1094 for (int i = 0; i < browser->tab_count(); ++i) {
1095 TabContents* tc = browser->GetTabContentsAt(i);
1096 DictionaryValue* tab = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121097 tab->SetInteger("index", i);
1098 tab->SetString("url", tc->GetURL().spec());
1099 tab->SetInteger("renderer_pid",
[email protected]ef413ca2010-05-25 21:09:141100 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
[email protected]ff4c1d82010-08-04 16:58:121101 tab->Set("infobars", GetInfobarsInfo(tc));
[email protected]ef413ca2010-05-25 21:09:141102 tabs->Append(tab);
1103 }
[email protected]ff4c1d82010-08-04 16:58:121104 browser_item->Set("tabs", tabs);
[email protected]ef413ca2010-05-25 21:09:141105
1106 windows->Append(browser_item);
1107 }
[email protected]ff4c1d82010-08-04 16:58:121108 return_value->Set("windows", windows);
[email protected]ef413ca2010-05-25 21:09:141109
[email protected]ff4c1d82010-08-04 16:58:121110 return_value->SetString("child_process_path",
[email protected]ef413ca2010-05-25 21:09:141111 ChildProcessHost::GetChildPath(true).value());
1112 // Child processes are the processes for plugins and other workers.
1113 // Add all child processes in a list of dictionaries, one dictionary item
1114 // per child process.
1115 ListValue* child_processes = new ListValue;
[email protected]26adfd312010-07-20 01:04:461116 base::WaitableEvent event(true /* manual reset */,
1117 false /* not initially signaled */);
1118 CHECK(ChromeThread::PostTask(
1119 ChromeThread::IO, FROM_HERE,
1120 new GetChildProcessHostInfoTask(&event, child_processes)));
1121 event.Wait();
[email protected]ff4c1d82010-08-04 16:58:121122 return_value->Set("child_processes", child_processes);
[email protected]ef413ca2010-05-25 21:09:141123
1124 // Add all extension processes in a list of dictionaries, one dictionary
1125 // item per extension process.
1126 ListValue* extension_processes = new ListValue;
1127 ProfileManager* profile_manager = g_browser_process->profile_manager();
1128 for (ProfileManager::const_iterator it = profile_manager->begin();
1129 it != profile_manager->end(); ++it) {
1130 ExtensionProcessManager* process_manager =
1131 (*it)->GetExtensionProcessManager();
1132 ExtensionProcessManager::const_iterator jt;
1133 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1134 ExtensionHost* ex_host = *jt;
1135 // Don't add dead extension processes.
1136 if (!ex_host->IsRenderViewLive())
1137 continue;
1138 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121139 item->SetString("name", ex_host->extension()->name());
[email protected]ef413ca2010-05-25 21:09:141140 item->SetInteger(
[email protected]ff4c1d82010-08-04 16:58:121141 "pid",
[email protected]ef413ca2010-05-25 21:09:141142 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1143 extension_processes->Append(item);
1144 }
1145 }
[email protected]ff4c1d82010-08-04 16:58:121146 return_value->Set("extension_processes", extension_processes);
[email protected]7c983cc2010-07-16 11:33:341147 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]a9ff2c02010-05-13 17:33:051148}
1149
[email protected]24e2b102010-04-29 17:56:471150// Sample json input: { "command": "GetHistoryInfo",
1151// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361152// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581153void AutomationProvider::GetHistoryInfo(Browser* browser,
1154 DictionaryValue* args,
1155 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361156 consumer_.CancelAllRequests();
1157
[email protected]e53668962010-06-23 15:35:251158 string16 search_text;
1159 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:361160
1161 // Fetch history.
1162 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1163 history::QueryOptions options;
1164 // The observer owns itself. It deletes itself after it fetches history.
1165 AutomationProviderHistoryObserver* history_observer =
1166 new AutomationProviderHistoryObserver(this, reply_message);
1167 hs->QueryHistory(
1168 search_text,
1169 options,
1170 &consumer_,
1171 NewCallback(history_observer,
1172 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1173}
1174
[email protected]bbe6aa02010-05-07 17:27:291175// Sample json input: { "command": "AddHistoryItem",
1176// "item": { "URL": "http://www.google.com",
1177// "title": "Google", # optional
1178// "time": 12345 # optional (time_t)
1179// } }
1180// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581181void AutomationProvider::AddHistoryItem(Browser* browser,
1182 DictionaryValue* args,
1183 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:291184 DictionaryValue* item = NULL;
[email protected]ff4c1d82010-08-04 16:58:121185 args->GetDictionary("item", &item);
[email protected]bbe6aa02010-05-07 17:27:291186 string16 url_text;
[email protected]e53668962010-06-23 15:35:251187 string16 title;
[email protected]bbe6aa02010-05-07 17:27:291188 base::Time time = base::Time::Now();
[email protected]7c983cc2010-07-16 11:33:341189 AutomationJSONReply reply(this, reply_message);
[email protected]bbe6aa02010-05-07 17:27:291190
[email protected]7c983cc2010-07-16 11:33:341191 if (!item->GetString("url", &url_text)) {
1192 reply.SendError("bad args (no URL in dict?)");
1193 return;
[email protected]bbe6aa02010-05-07 17:27:291194 }
[email protected]7c983cc2010-07-16 11:33:341195 GURL gurl(url_text);
1196 item->GetString("title", &title); // Don't care if it fails.
1197 int it;
1198 double dt;
[email protected]ff4c1d82010-08-04 16:58:121199 if (item->GetInteger("time", &it))
[email protected]7c983cc2010-07-16 11:33:341200 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:121201 else if (item->GetReal("time", &dt))
[email protected]7c983cc2010-07-16 11:33:341202 time = base::Time::FromDoubleT(dt);
[email protected]f6ff0df2010-07-11 22:41:431203
[email protected]7c983cc2010-07-16 11:33:341204 // Ideas for "dummy" values (e.g. id_scope) came from
1205 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1206 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1207 const void* id_scope = reinterpret_cast<void*>(1);
1208 hs->AddPage(gurl, time,
1209 id_scope,
1210 0,
1211 GURL(),
1212 PageTransition::LINK,
1213 history::RedirectList(),
[email protected]5989f1a2010-08-21 02:21:111214 history::SOURCE_BROWSED,
[email protected]7c983cc2010-07-16 11:33:341215 false);
1216 if (title.length())
1217 hs->SetPageTitle(gurl, title);
1218 reply.SendSuccess(NULL);
[email protected]bbe6aa02010-05-07 17:27:291219}
1220
[email protected]2d54c4032010-08-20 00:42:281221DictionaryValue* AutomationProvider::GetDictionaryFromDownloadItem(
1222 const DownloadItem* download) {
[email protected]d4adc292010-04-15 18:06:391223 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1224 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1225 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1226 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1227 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1228
1229 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1230 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1231 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1232 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1233 std::string("DANGEROUS_BUT_VALIDATED");
1234
[email protected]2d54c4032010-08-20 00:42:281235 DictionaryValue* dl_item_value = new DictionaryValue;
1236 dl_item_value->SetInteger("id", static_cast<int>(download->id()));
1237 dl_item_value->SetString("url", download->url().spec());
1238 dl_item_value->SetString("referrer_url", download->referrer_url().spec());
1239 dl_item_value->SetString("file_name", download->GetFileName().value());
1240 dl_item_value->SetString("full_path", download->full_path().value());
1241 dl_item_value->SetBoolean("is_paused", download->is_paused());
1242 dl_item_value->SetBoolean("open_when_complete",
1243 download->open_when_complete());
1244 dl_item_value->SetBoolean("is_extension_install",
1245 download->is_extension_install());
1246 dl_item_value->SetBoolean("is_temporary", download->is_temporary());
1247 dl_item_value->SetBoolean("is_otr", download->is_otr()); // off-the-record
1248 dl_item_value->SetString("state", state_to_string[download->state()]);
1249 dl_item_value->SetString("safety_state",
1250 safety_state_to_string[download->safety_state()]);
1251 dl_item_value->SetInteger("PercentComplete", download->PercentComplete());
1252
1253 return dl_item_value;
1254}
1255
1256// Sample json input: { "command": "GetDownloadsInfo" }
1257// Refer chrome/test/pyautolib/download_info.py for sample json output.
1258void AutomationProvider::GetDownloadsInfo(Browser* browser,
1259 DictionaryValue* args,
1260 IPC::Message* reply_message) {
1261 AutomationJSONReply reply(this, reply_message);
1262
1263 if (!profile_->HasCreatedDownloadManager()) {
1264 reply.SendError("no download manager");
1265 return;
1266 }
1267
1268 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1269 std::vector<DownloadItem*> downloads;
1270 profile_->GetDownloadManager()->GetAllDownloads(FilePath(), &downloads);
1271
[email protected]d4adc292010-04-15 18:06:391272 ListValue* list_of_downloads = new ListValue;
1273 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1274 it != downloads.end();
1275 it++) { // Fill info about each download item.
[email protected]2d54c4032010-08-20 00:42:281276 list_of_downloads->Append(GetDictionaryFromDownloadItem(*it));
[email protected]d4adc292010-04-15 18:06:391277 }
[email protected]ff4c1d82010-08-04 16:58:121278 return_value->Set("downloads", list_of_downloads);
[email protected]7c983cc2010-07-16 11:33:341279 reply.SendSuccess(return_value.get());
[email protected]d4adc292010-04-15 18:06:391280 // All value objects allocated above are owned by |return_value|
1281 // and get freed by it.
1282}
1283
[email protected]59a611242010-04-02 02:24:041284void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:581285 Browser* browser,
[email protected]59a611242010-04-02 02:24:041286 DictionaryValue* args,
1287 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:341288 AutomationJSONReply reply(this, reply_message);
[email protected]59a611242010-04-02 02:24:041289
1290 // Look for a quick return.
1291 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7c983cc2010-07-16 11:33:341292 reply.SendSuccess(NULL); // No download manager.
1293 return;
[email protected]59a611242010-04-02 02:24:041294 }
[email protected]82f37b02010-07-29 22:04:571295 std::vector<DownloadItem*> downloads;
1296 profile_->GetDownloadManager()->GetCurrentDownloads(FilePath(), &downloads);
1297 if (downloads.empty()) {
[email protected]7c983cc2010-07-16 11:33:341298 reply.SendSuccess(NULL);
[email protected]f6ff0df2010-07-11 22:41:431299 return;
1300 }
[email protected]59a611242010-04-02 02:24:041301
1302 // The observer owns itself. When the last observed item pings, it
1303 // deletes itself.
1304 AutomationProviderDownloadItemObserver* item_observer =
1305 new AutomationProviderDownloadItemObserver(
1306 this, reply_message, downloads.size());
1307 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
1308 i != downloads.end();
1309 i++) {
1310 (*i)->AddObserver(item_observer);
1311 }
1312}
1313
[email protected]2d54c4032010-08-20 00:42:281314namespace {
1315
1316DownloadItem* GetDownloadItemFromId(int id, DownloadManager* download_manager) {
1317 std::vector<DownloadItem*> downloads;
1318 download_manager->GetAllDownloads(FilePath(), &downloads);
1319 DownloadItem* selected_item = NULL;
1320
1321 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1322 it != downloads.end();
1323 it++) {
1324 DownloadItem* curr_item = *it;
1325 if (curr_item->id() == id) {
1326 selected_item = curr_item;
1327 break;
1328 }
1329 }
1330 return selected_item;
1331}
1332
1333} // namespace
1334
1335// See PerformActionOnDownload() in chrome/test/pyautolib/pyauto.py for sample
1336// json input and output.
1337void AutomationProvider::PerformActionOnDownload(Browser* browser,
1338 DictionaryValue* args,
1339 IPC::Message* reply_message) {
1340 int id;
1341 std::string action;
1342
1343 if (!profile_->HasCreatedDownloadManager()) {
1344 AutomationJSONReply(this, reply_message).SendError("No download manager.");
1345 return;
1346 }
1347 if (!args->GetInteger("id", &id) || !args->GetString("action", &action)) {
1348 AutomationJSONReply(this, reply_message).SendError(
1349 "Must include int id and string action.");
1350 return;
1351 }
1352
1353 DownloadManager* download_manager = profile_->GetDownloadManager();
1354 DownloadItem* selected_item = GetDownloadItemFromId(id, download_manager);
1355 if (!selected_item) {
1356 AutomationJSONReply(this, reply_message).SendError(
1357 StringPrintf("No download with an id of %d\n", id));
1358 return;
1359 }
1360
1361 if (action == "open") {
1362 selected_item->AddObserver(
1363 new AutomationProviderDownloadUpdatedObserver(
1364 this, reply_message, true));
1365 selected_item->OpenDownload();
1366 } else if (action == "toggle_open_files_like_this") {
1367 selected_item->OpenFilesBasedOnExtension(
1368 !selected_item->ShouldOpenFileBasedOnExtension());
1369 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
1370 } else if (action == "remove") {
1371 download_manager->AddObserver(
1372 new AutomationProviderDownloadModelChangedObserver(
1373 this, reply_message, download_manager));
1374 selected_item->Remove(false);
1375 } else if (action == "decline_dangerous_download") {
1376 // This is the same as removing the file with delete_file=true.
1377 download_manager->AddObserver(
1378 new AutomationProviderDownloadModelChangedObserver(
1379 this, reply_message, download_manager));
1380 selected_item->Remove(true);
1381 } else if (action == "save_dangerous_download") {
1382 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
1383 this, reply_message, false));
1384 selected_item->DangerousDownloadValidated();
1385 } else if (action == "toggle_pause") {
1386 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
1387 this, reply_message, false));
1388 // This will still return if download has already completed.
1389 selected_item->TogglePause();
1390 } else if (action == "cancel") {
1391 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
1392 this, reply_message, false));
1393 selected_item->Cancel(true);
1394 } else {
1395 AutomationJSONReply(this, reply_message).SendError(
1396 StringPrintf("Invalid action '%s' given.", action.c_str()));
1397 }
1398}
1399
1400// See WaitForAlwaysOpenDownloadTypeToOpen() in chrome/test/pyautolib/pyauto.py
1401// for sample json input.
1402// Sample json output: {}
1403void AutomationProvider::WaitForAlwaysOpenDownloadTypeToOpen(
1404 Browser* browser, DictionaryValue* args, IPC::Message* reply_message) {
1405 int id;
1406
1407 if (!profile_->HasCreatedDownloadManager()) {
1408 AutomationJSONReply(this, reply_message).SendError("No download manager.");
1409 return;
1410 }
1411 if (!args->GetInteger("id", &id)) {
1412 AutomationJSONReply(this, reply_message).SendError(
1413 "Must include int id.");
1414 return;
1415 }
1416
1417 DownloadItem* selected_item = GetDownloadItemFromId(
1418 id, profile_->GetDownloadManager());
1419 if (!selected_item) {
1420 AutomationJSONReply(this, reply_message).SendError(
1421 StringPrintf("No download with an id of %d\n", id));
1422 return;
1423 }
1424
1425 if (selected_item->auto_opened()) {
1426 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
1427 return;
1428 }
1429 // The observer will reply after the download is opened.
1430 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
1431 this, reply_message, true));
1432}
1433
[email protected]24e2b102010-04-29 17:56:471434// Sample json input: { "command": "GetPrefsInfo" }
1435// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581436void AutomationProvider::GetPrefsInfo(Browser* browser,
1437 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471438 IPC::Message* reply_message) {
[email protected]24e2b102010-04-29 17:56:471439 const PrefService::PreferenceSet& prefs =
1440 profile_->GetPrefs()->preference_set();
1441 DictionaryValue* items = new DictionaryValue;
1442 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
1443 it != prefs.end(); ++it) {
1444 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
1445 }
1446 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:121447 return_value->Set("prefs", items); // return_value owns items.
[email protected]7c983cc2010-07-16 11:33:341448 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]24e2b102010-04-29 17:56:471449}
1450
1451// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:581452void AutomationProvider::SetPrefs(Browser* browser,
1453 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471454 IPC::Message* reply_message) {
[email protected]57ecc4b2010-08-11 03:02:511455 std::string path;
[email protected]24e2b102010-04-29 17:56:471456 Value* val;
[email protected]7c983cc2010-07-16 11:33:341457 AutomationJSONReply reply(this, reply_message);
[email protected]57ecc4b2010-08-11 03:02:511458 if (args->GetString("path", &path) && args->Get("value", &val)) {
[email protected]24e2b102010-04-29 17:56:471459 PrefService* pref_service = profile_->GetPrefs();
1460 const PrefService::Preference* pref =
1461 pref_service->FindPreference(path.c_str());
1462 if (!pref) { // Not a registered pref.
[email protected]7c983cc2010-07-16 11:33:341463 reply.SendError("pref not registered.");
1464 return;
[email protected]24e2b102010-04-29 17:56:471465 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7c983cc2010-07-16 11:33:341466 reply.SendError("pref is managed. cannot be changed.");
1467 return;
[email protected]24e2b102010-04-29 17:56:471468 } else { // Set the pref.
1469 pref_service->Set(path.c_str(), *val);
1470 }
1471 } else {
[email protected]7c983cc2010-07-16 11:33:341472 reply.SendError("no pref path or value given.");
1473 return;
[email protected]24e2b102010-04-29 17:56:471474 }
1475
[email protected]7c983cc2010-07-16 11:33:341476 reply.SendSuccess(NULL);
[email protected]24e2b102010-04-29 17:56:471477}
1478
[email protected]53329582010-05-14 21:10:581479// Sample json input: { "command": "GetOmniboxInfo" }
1480// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
1481void AutomationProvider::GetOmniboxInfo(Browser* browser,
1482 DictionaryValue* args,
1483 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:581484 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1485
1486 LocationBar* loc_bar = browser->window()->GetLocationBar();
1487 AutocompleteEditView* edit_view = loc_bar->location_entry();
1488 AutocompleteEditModel* model = edit_view->model();
1489
1490 // Fill up matches.
1491 ListValue* matches = new ListValue;
1492 const AutocompleteResult& result = model->result();
1493 for (AutocompleteResult::const_iterator i = result.begin();
1494 i != result.end(); ++i) {
1495 const AutocompleteMatch& match = *i;
1496 DictionaryValue* item = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:121497 item->SetString("type", AutocompleteMatch::TypeToString(match.type));
1498 item->SetBoolean("starred", match.starred);
1499 item->SetString("destination_url", match.destination_url.spec());
1500 item->SetString("contents", WideToUTF16Hack(match.contents));
1501 item->SetString("description", WideToUTF16Hack(match.description));
[email protected]53329582010-05-14 21:10:581502 matches->Append(item);
1503 }
[email protected]ff4c1d82010-08-04 16:58:121504 return_value->Set("matches", matches);
[email protected]53329582010-05-14 21:10:581505
1506 // Fill up other properties.
1507 DictionaryValue* properties = new DictionaryValue; // owned by return_value
[email protected]ff4c1d82010-08-04 16:58:121508 properties->SetBoolean("has_focus", model->has_focus());
1509 properties->SetBoolean("query_in_progress", model->query_in_progress());
1510 properties->SetString("keyword", WideToUTF16Hack(model->keyword()));
1511 properties->SetString("text", WideToUTF16Hack(edit_view->GetText()));
1512 return_value->Set("properties", properties);
[email protected]53329582010-05-14 21:10:581513
[email protected]7c983cc2010-07-16 11:33:341514 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]53329582010-05-14 21:10:581515}
1516
1517// Sample json input: { "command": "SetOmniboxText",
1518// "text": "goog" }
1519void AutomationProvider::SetOmniboxText(Browser* browser,
1520 DictionaryValue* args,
1521 IPC::Message* reply_message) {
[email protected]a748ff62010-08-14 17:25:321522 string16 text;
[email protected]7c983cc2010-07-16 11:33:341523 AutomationJSONReply reply(this, reply_message);
[email protected]a748ff62010-08-14 17:25:321524 if (!args->GetString("text", &text)) {
[email protected]7c983cc2010-07-16 11:33:341525 reply.SendError("text missing");
1526 return;
[email protected]53329582010-05-14 21:10:581527 }
[email protected]7c983cc2010-07-16 11:33:341528 browser->FocusLocationBar();
1529 LocationBar* loc_bar = browser->window()->GetLocationBar();
1530 AutocompleteEditView* edit_view = loc_bar->location_entry();
1531 edit_view->model()->OnSetFocus(false);
[email protected]a748ff62010-08-14 17:25:321532 edit_view->SetUserText(UTF16ToWideHack(text));
[email protected]7c983cc2010-07-16 11:33:341533 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:581534}
1535
1536// Sample json input: { "command": "OmniboxMovePopupSelection",
1537// "count": 1 }
1538// Negative count implies up, positive implies down. Count values will be
1539// capped by the size of the popup list.
1540void AutomationProvider::OmniboxMovePopupSelection(
1541 Browser* browser,
1542 DictionaryValue* args,
1543 IPC::Message* reply_message) {
[email protected]53329582010-05-14 21:10:581544 int count;
[email protected]7c983cc2010-07-16 11:33:341545 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:121546 if (!args->GetInteger("count", &count)) {
[email protected]7c983cc2010-07-16 11:33:341547 reply.SendError("count missing");
1548 return;
[email protected]53329582010-05-14 21:10:581549 }
[email protected]7c983cc2010-07-16 11:33:341550 LocationBar* loc_bar = browser->window()->GetLocationBar();
1551 AutocompleteEditModel* model = loc_bar->location_entry()->model();
1552 model->OnUpOrDownKeyPressed(count);
1553 reply.SendSuccess(NULL);
[email protected]53329582010-05-14 21:10:581554}
1555
1556// Sample json input: { "command": "OmniboxAcceptInput" }
1557void AutomationProvider::OmniboxAcceptInput(Browser* browser,
1558 DictionaryValue* args,
1559 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:281560 NavigationController& controller =
1561 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:121562 // Setup observer to wait until the selected item loads.
1563 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:281564 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:121565 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:581566
1567 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:581568}
1569
[email protected]a3cd5022010-06-16 18:25:291570// Sample json input: { "command": "GetInitialLoadTimes" }
1571// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
1572void AutomationProvider::GetInitialLoadTimes(
1573 Browser*,
1574 DictionaryValue*,
1575 IPC::Message* reply_message) {
1576 scoped_ptr<DictionaryValue> return_value(
1577 initial_load_observer_->GetTimingInformation());
[email protected]f6ff0df2010-07-11 22:41:431578
1579 std::string json_return;
1580 base::JSONWriter::Write(return_value.get(), false, &json_return);
1581 AutomationMsg_SendJSONRequest::WriteReplyParams(
1582 reply_message, json_return, true);
1583 Send(reply_message);
[email protected]a3cd5022010-06-16 18:25:291584}
1585
[email protected]f7d48012010-05-06 08:17:051586// Sample json input: { "command": "GetPluginsInfo" }
1587// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581588void AutomationProvider::GetPluginsInfo(Browser* browser,
1589 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:051590 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:051591 std::vector<WebPluginInfo> plugins;
1592 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
1593 ListValue* items = new ListValue;
1594 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
1595 it != plugins.end();
1596 ++it) {
1597 DictionaryValue* item = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:121598 item->SetString("name", it->name);
1599 item->SetString("path", it->path.value());
1600 item->SetString("version", it->version);
1601 item->SetString("desc", it->desc);
1602 item->SetBoolean("enabled", it->enabled);
[email protected]f7d48012010-05-06 08:17:051603 // Add info about mime types.
1604 ListValue* mime_types = new ListValue();
1605 for (std::vector<WebPluginMimeType>::const_iterator type_it =
1606 it->mime_types.begin();
1607 type_it != it->mime_types.end();
1608 ++type_it) {
1609 DictionaryValue* mime_type = new DictionaryValue();
[email protected]ff4c1d82010-08-04 16:58:121610 mime_type->SetString("mimeType", type_it->mime_type);
1611 mime_type->SetString("description", type_it->description);
[email protected]f7d48012010-05-06 08:17:051612
1613 ListValue* file_extensions = new ListValue();
1614 for (std::vector<std::string>::const_iterator ext_it =
1615 type_it->file_extensions.begin();
1616 ext_it != type_it->file_extensions.end();
1617 ++ext_it) {
1618 file_extensions->Append(new StringValue(*ext_it));
1619 }
[email protected]ff4c1d82010-08-04 16:58:121620 mime_type->Set("fileExtensions", file_extensions);
[email protected]f7d48012010-05-06 08:17:051621
1622 mime_types->Append(mime_type);
1623 }
[email protected]ff4c1d82010-08-04 16:58:121624 item->Set("mimeTypes", mime_types);
[email protected]f7d48012010-05-06 08:17:051625 items->Append(item);
1626 }
1627 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]ff4c1d82010-08-04 16:58:121628 return_value->Set("plugins", items); // return_value owns items.
[email protected]f7d48012010-05-06 08:17:051629
[email protected]7c983cc2010-07-16 11:33:341630 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f7d48012010-05-06 08:17:051631}
1632
1633// Sample json input:
1634// { "command": "EnablePlugin",
1635// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:581636void AutomationProvider::EnablePlugin(Browser* browser,
1637 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:051638 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:051639 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:341640 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:121641 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:341642 reply.SendError("path not specified.");
1643 return;
[email protected]f6ff0df2010-07-11 22:41:431644 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:341645 reply.SendError(StringPrintf("Could not enable plugin for path %s.",
1646 path.c_str()));
1647 return;
[email protected]f6ff0df2010-07-11 22:41:431648 }
[email protected]7c983cc2010-07-16 11:33:341649 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:051650}
1651
1652// Sample json input:
1653// { "command": "DisablePlugin",
1654// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:581655void AutomationProvider::DisablePlugin(Browser* browser,
1656 DictionaryValue* args,
1657 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:051658 FilePath::StringType path;
[email protected]7c983cc2010-07-16 11:33:341659 AutomationJSONReply reply(this, reply_message);
[email protected]ff4c1d82010-08-04 16:58:121660 if (!args->GetString("path", &path)) {
[email protected]7c983cc2010-07-16 11:33:341661 reply.SendError("path not specified.");
1662 return;
[email protected]f6ff0df2010-07-11 22:41:431663 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
[email protected]7c983cc2010-07-16 11:33:341664 reply.SendError(StringPrintf("Could not disable plugin for path %s.",
1665 path.c_str()));
1666 return;
[email protected]f6ff0df2010-07-11 22:41:431667 }
[email protected]7c983cc2010-07-16 11:33:341668 reply.SendSuccess(NULL);
[email protected]f7d48012010-05-06 08:17:051669}
1670
[email protected]7060bb292010-06-24 00:52:491671// Sample json input:
1672// { "command": "SaveTabContents",
1673// "tab_index": 0,
1674// "filename": <a full pathname> }
1675// Sample json output:
1676// {}
1677void AutomationProvider::SaveTabContents(Browser* browser,
1678 DictionaryValue* args,
1679 IPC::Message* reply_message) {
[email protected]7060bb292010-06-24 00:52:491680 int tab_index = 0;
1681 FilePath::StringType filename;
1682 FilePath::StringType parent_directory;
1683 TabContents* tab_contents = NULL;
1684
[email protected]ff4c1d82010-08-04 16:58:121685 if (!args->GetInteger("tab_index", &tab_index) ||
1686 !args->GetString("filename", &filename)) {
[email protected]26adfd312010-07-20 01:04:461687 AutomationJSONReply(this, reply_message).SendError(
1688 "tab_index or filename param missing");
[email protected]7c983cc2010-07-16 11:33:341689 return;
[email protected]7060bb292010-06-24 00:52:491690 } else {
1691 tab_contents = browser->GetTabContentsAt(tab_index);
1692 if (!tab_contents) {
[email protected]26adfd312010-07-20 01:04:461693 AutomationJSONReply(this, reply_message).SendError(
1694 "no tab at tab_index");
[email protected]7060bb292010-06-24 00:52:491695 return;
1696 }
1697 }
[email protected]7c983cc2010-07-16 11:33:341698 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
1699 // used. Nevertheless, SavePackage requires it be valid. Sigh.
1700 parent_directory = FilePath(filename).DirName().value();
1701 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
1702 SavePackage::SAVE_AS_ONLY_HTML)) {
[email protected]26adfd312010-07-20 01:04:461703 AutomationJSONReply(this, reply_message).SendError(
1704 "Could not initiate SavePage");
[email protected]7c983cc2010-07-16 11:33:341705 return;
1706 }
1707 // The observer will delete itself when done.
1708 new SavePackageNotificationObserver(tab_contents->save_package(),
1709 this, reply_message);
[email protected]7060bb292010-06-24 00:52:491710}
1711
[email protected]c5aa5322010-07-15 19:00:071712// Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
1713// json input.
1714// Sample json output: "{}"
1715void AutomationProvider::ImportSettings(Browser* browser,
1716 DictionaryValue* args,
1717 IPC::Message* reply_message) {
[email protected]c5aa5322010-07-15 19:00:071718 // Map from the json string passed over to the import item masks.
1719 std::map<std::string, ImportItem> string_to_import_item;
1720 string_to_import_item["HISTORY"] = importer::HISTORY;
1721 string_to_import_item["FAVORITES"] = importer::FAVORITES;
1722 string_to_import_item["COOKIES"] = importer::COOKIES;
1723 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
1724 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
1725 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
1726 string_to_import_item["ALL"] = importer::ALL;
1727
[email protected]a748ff62010-08-14 17:25:321728 string16 browser_name;
[email protected]c5aa5322010-07-15 19:00:071729 int import_items = 0;
1730 ListValue* import_items_list = NULL;
1731 bool first_run;
1732
[email protected]a748ff62010-08-14 17:25:321733 if (!args->GetString("import_from", &browser_name) ||
[email protected]ff4c1d82010-08-04 16:58:121734 !args->GetBoolean("first_run", &first_run) ||
1735 !args->GetList("import_items", &import_items_list)) {
[email protected]7c983cc2010-07-16 11:33:341736 AutomationJSONReply(this, reply_message).SendError(
1737 "Incorrect type for one or more of the arguments.");
[email protected]c5aa5322010-07-15 19:00:071738 return;
1739 }
1740
1741 int num_items = import_items_list->GetSize();
1742 for (int i = 0; i < num_items; i++) {
1743 std::string item;
1744 import_items_list->GetString(i, &item);
1745 // If the provided string is not part of the map, error out.
1746 if (!ContainsKey(string_to_import_item, item)) {
[email protected]7c983cc2010-07-16 11:33:341747 AutomationJSONReply(this, reply_message).SendError(
1748 "Invalid item string found in import_items.");
[email protected]c5aa5322010-07-15 19:00:071749 return;
1750 }
1751 import_items |= string_to_import_item[item];
1752 }
1753
1754 ImporterHost* importer_host = new ImporterHost();
1755 // Get the correct ProfileInfo based on the browser they user provided.
1756 importer::ProfileInfo profile_info;
1757 int num_browsers = importer_host->GetAvailableProfileCount();
1758 int i = 0;
1759 for ( ; i < num_browsers; i++) {
[email protected]a748ff62010-08-14 17:25:321760 string16 name = WideToUTF16Hack(importer_host->GetSourceProfileNameAt(i));
[email protected]c5aa5322010-07-15 19:00:071761 if (name == browser_name) {
1762 profile_info = importer_host->GetSourceProfileInfoAt(i);
1763 break;
1764 }
1765 }
1766 // If we made it to the end of the loop, then the input was bad.
1767 if (i == num_browsers) {
[email protected]7c983cc2010-07-16 11:33:341768 AutomationJSONReply(this, reply_message).SendError(
1769 "Invalid browser name string found.");
[email protected]c5aa5322010-07-15 19:00:071770 return;
1771 }
1772
1773 Profile* profile = browser->profile();
1774
1775 importer_host->SetObserver(
1776 new AutomationProviderImportSettingsObserver(this, reply_message));
1777 importer_host->StartImportSettings(profile_info, profile, import_items,
1778 new ProfileWriter(profile), first_run);
1779}
1780
[email protected]95222282010-07-26 17:43:021781namespace {
1782
1783// Translates a dictionary password to a PasswordForm struct.
1784webkit_glue::PasswordForm GetPasswordFormFromDict(
1785 const DictionaryValue& password_dict) {
1786
1787 // If the time is specified, change time to the specified time.
1788 base::Time time = base::Time::Now();
1789 int it;
1790 double dt;
[email protected]ff4c1d82010-08-04 16:58:121791 if (password_dict.GetInteger("time", &it))
[email protected]95222282010-07-26 17:43:021792 time = base::Time::FromTimeT(it);
[email protected]ff4c1d82010-08-04 16:58:121793 else if (password_dict.GetReal("time", &dt))
[email protected]95222282010-07-26 17:43:021794 time = base::Time::FromDoubleT(dt);
1795
1796 std::string signon_realm;
1797 string16 username_value;
1798 string16 password_value;
1799 string16 origin_url_text;
1800 string16 username_element;
1801 string16 password_element;
1802 string16 submit_element;
1803 string16 action_target_text;
1804 bool blacklist = false;
1805 string16 old_password_element;
1806 string16 old_password_value;
1807
1808 // We don't care if any of these fail - they are either optional or checked
1809 // before this function is called.
[email protected]ff4c1d82010-08-04 16:58:121810 password_dict.GetString("signon_realm", &signon_realm);
[email protected]698f7f42010-08-04 19:35:331811 password_dict.GetString("username_value", &username_value);
1812 password_dict.GetString("password_value", &password_value);
1813 password_dict.GetString("origin_url", &origin_url_text);
1814 password_dict.GetString("username_element", &username_element);
1815 password_dict.GetString("password_element", &password_element);
1816 password_dict.GetString("submit_element", &submit_element);
1817 password_dict.GetString("action_target", &action_target_text);
[email protected]ff4c1d82010-08-04 16:58:121818 password_dict.GetBoolean("blacklist", &blacklist);
[email protected]95222282010-07-26 17:43:021819
1820 GURL origin_gurl(origin_url_text);
1821 GURL action_target(action_target_text);
1822
1823 webkit_glue::PasswordForm password_form;
1824 password_form.signon_realm = signon_realm;
1825 password_form.username_value = username_value;
1826 password_form.password_value = password_value;
1827 password_form.origin = origin_gurl;
1828 password_form.username_element = username_element;
1829 password_form.password_element = password_element;
1830 password_form.submit_element = submit_element;
1831 password_form.action = action_target;
1832 password_form.blacklisted_by_user = blacklist;
1833 password_form.date_created = time;
1834
1835 return password_form;
1836}
1837
1838} // namespace
1839
[email protected]5bcfe1672010-07-16 20:51:571840// See AddSavedPassword() in chrome/test/functional/pyauto.py for sample json
1841// input.
1842// Sample json output: { "password_added": true }
1843void AutomationProvider::AddSavedPassword(Browser* browser,
1844 DictionaryValue* args,
1845 IPC::Message* reply_message) {
[email protected]5bcfe1672010-07-16 20:51:571846 AutomationJSONReply reply(this, reply_message);
[email protected]95222282010-07-26 17:43:021847 DictionaryValue* password_dict = NULL;
[email protected]5bcfe1672010-07-16 20:51:571848
[email protected]ff4c1d82010-08-04 16:58:121849 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:021850 reply.SendError("Password must be a dictionary.");
[email protected]5bcfe1672010-07-16 20:51:571851 return;
1852 }
1853
[email protected]95222282010-07-26 17:43:021854 // The signon realm is effectively the primary key and must be included.
1855 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:121856 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:021857 reply.SendError("Password must include signon_realm.");
1858 return;
1859 }
1860 webkit_glue::PasswordForm new_password =
1861 GetPasswordFormFromDict(*password_dict);
[email protected]5bcfe1672010-07-16 20:51:571862
1863 Profile* profile = browser->profile();
1864 // Use IMPLICIT_ACCESS since new passwords aren't added off the record.
1865 PasswordStore* password_store =
1866 profile->GetPasswordStore(Profile::IMPLICIT_ACCESS);
1867
1868 // Set the return based on whether setting the password succeeded.
1869 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1870
1871 // It will be null if it's accessed in an incognito window.
1872 if (password_store != NULL) {
1873 password_store->AddLogin(new_password);
[email protected]ff4c1d82010-08-04 16:58:121874 return_value->SetBoolean("password_added", true);
[email protected]5bcfe1672010-07-16 20:51:571875 } else {
[email protected]ff4c1d82010-08-04 16:58:121876 return_value->SetBoolean("password_added", false);
[email protected]5bcfe1672010-07-16 20:51:571877 }
1878
1879 reply.SendSuccess(return_value.get());
1880}
1881
[email protected]95222282010-07-26 17:43:021882// See RemoveSavedPassword() in chrome/test/functional/pyauto.py for sample
1883// json input.
1884// Sample json output: {}
1885void AutomationProvider::RemoveSavedPassword(Browser* browser,
1886 DictionaryValue* args,
1887 IPC::Message* reply_message) {
1888 AutomationJSONReply reply(this, reply_message);
1889 DictionaryValue* password_dict = NULL;
1890
[email protected]ff4c1d82010-08-04 16:58:121891 if (!args->GetDictionary("password", &password_dict)) {
[email protected]95222282010-07-26 17:43:021892 reply.SendError("Password must be a dictionary.");
1893 return;
1894 }
1895
1896 // The signon realm is effectively the primary key and must be included.
1897 // Check here before calling GetPasswordFormFromDict.
[email protected]ff4c1d82010-08-04 16:58:121898 if (!password_dict->HasKey("signon_realm")) {
[email protected]95222282010-07-26 17:43:021899 reply.SendError("Password must include signon_realm.");
1900 return;
1901 }
1902 webkit_glue::PasswordForm to_remove =
1903 GetPasswordFormFromDict(*password_dict);
1904
1905 Profile* profile = browser->profile();
1906 // Use EXPLICIT_ACCESS since passwords can be removed off the record.
1907 PasswordStore* password_store =
1908 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
1909
1910 password_store->RemoveLogin(to_remove);
1911 reply.SendSuccess(NULL);
1912}
1913
[email protected]5bcfe1672010-07-16 20:51:571914// Sample json input: { "command": "GetSavedPasswords" }
1915// Refer to GetSavedPasswords() in chrome/test/pyautolib/pyauto.py for sample
1916// json output.
1917void AutomationProvider::GetSavedPasswords(Browser* browser,
1918 DictionaryValue* args,
1919 IPC::Message* reply_message) {
1920 Profile* profile = browser->profile();
1921 // Use EXPLICIT_ACCESS since saved passwords can be retreived off the record.
1922 PasswordStore* password_store =
1923 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
1924 password_store->GetAutofillableLogins(
1925 new AutomationProviderGetPasswordsObserver(this, reply_message));
1926 // Observer deletes itself after returning.
1927}
1928
[email protected]a0fc50d72010-07-14 21:14:191929// Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
1930// json input.
1931// Sample json output: {}
1932void AutomationProvider::ClearBrowsingData(Browser* browser,
1933 DictionaryValue* args,
1934 IPC::Message* reply_message) {
[email protected]a0fc50d72010-07-14 21:14:191935 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
1936 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
1937 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
1938 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
1939 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
1940 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
1941
1942 std::map<std::string, int> string_to_mask_value;
1943 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
1944 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
1945 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
1946 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
1947 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
1948 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
1949
1950 std::string time_period;
1951 ListValue* to_remove;
[email protected]ff4c1d82010-08-04 16:58:121952 if (!args->GetString("time_period", &time_period) ||
1953 !args->GetList("to_remove", &to_remove)) {
[email protected]7c983cc2010-07-16 11:33:341954 AutomationJSONReply(this, reply_message).SendError(
1955 "time_period must be a string and to_remove a list.");
[email protected]a0fc50d72010-07-14 21:14:191956 return;
1957 }
1958
1959 int remove_mask = 0;
1960 int num_removals = to_remove->GetSize();
1961 for (int i = 0; i < num_removals; i++) {
1962 std::string removal;
1963 to_remove->GetString(i, &removal);
1964 // If the provided string is not part of the map, then error out.
1965 if (!ContainsKey(string_to_mask_value, removal)) {
[email protected]7c983cc2010-07-16 11:33:341966 AutomationJSONReply(this, reply_message).SendError(
1967 "Invalid browsing data string found in to_remove.");
[email protected]a0fc50d72010-07-14 21:14:191968 return;
1969 }
1970 remove_mask |= string_to_mask_value[removal];
1971 }
1972
1973 if (!ContainsKey(string_to_time_period, time_period)) {
[email protected]7c983cc2010-07-16 11:33:341974 AutomationJSONReply(this, reply_message).SendError(
1975 "Invalid string for time_period.");
[email protected]a0fc50d72010-07-14 21:14:191976 return;
1977 }
1978
1979 BrowsingDataRemover* remover = new BrowsingDataRemover(
1980 profile(), string_to_time_period[time_period], base::Time());
1981
1982 remover->AddObserver(
1983 new AutomationProviderBrowsingDataObserver(this, reply_message));
1984 remover->Remove(remove_mask);
1985 // BrowsingDataRemover deletes itself using DeleteTask.
1986 // The observer also deletes itself after sending the reply.
1987}
1988
[email protected]3dda5b02010-07-27 16:35:421989namespace {
1990
1991 // Get the TabContents from a dictionary of arguments.
1992 TabContents* GetTabContentsFromDict(const Browser* browser,
1993 const DictionaryValue* args,
1994 std::string* error_message) {
1995 int tab_index;
[email protected]ff4c1d82010-08-04 16:58:121996 if (!args->GetInteger("tab_index", &tab_index)) {
[email protected]3dda5b02010-07-27 16:35:421997 *error_message = "Must include tab_index.";
1998 return NULL;
1999 }
2000
2001 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2002 if (!tab_contents) {
2003 *error_message = StringPrintf("No tab at index %d.", tab_index);
2004 return NULL;
2005 }
2006 return tab_contents;
2007 }
2008
2009 // Get the TranslateInfoBarDelegate from TabContents.
2010 TranslateInfoBarDelegate* GetTranslateInfoBarDelegate(
2011 TabContents* tab_contents) {
2012 for (int i = 0; i < tab_contents->infobar_delegate_count(); i++) {
2013 InfoBarDelegate* infobar = tab_contents->GetInfoBarDelegateAt(i);
2014 if (infobar->AsTranslateInfoBarDelegate())
2015 return infobar->AsTranslateInfoBarDelegate();
2016 }
2017 // No translate infobar.
2018 return NULL;
2019 }
2020
2021} // namespace
2022
2023// See GetTranslateInfo() in chrome/test/pyautolib/pyauto.py for sample json
2024// input and output.
2025void AutomationProvider::GetTranslateInfo(Browser* browser,
2026 DictionaryValue* args,
2027 IPC::Message* reply_message) {
2028 std::string error_message;
2029 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2030 &error_message);
2031 if (!tab_contents) {
2032 AutomationJSONReply(this, reply_message).SendError(error_message);
2033 return;
2034 }
2035
2036 // Get the translate bar if there is one and pass it to the observer.
2037 // The observer will check for null and populate the information accordingly.
2038 TranslateInfoBarDelegate* translate_bar =
2039 GetTranslateInfoBarDelegate(tab_contents);
2040
2041 TabLanguageDeterminedObserver* observer = new TabLanguageDeterminedObserver(
2042 this, reply_message, tab_contents, translate_bar);
2043 // If the language for the page hasn't been loaded yet, then just make
2044 // the observer, otherwise call observe directly.
2045 std::string language = tab_contents->language_state().original_language();
2046 if (!language.empty()) {
2047 observer->Observe(NotificationType::TAB_LANGUAGE_DETERMINED,
2048 Source<TabContents>(tab_contents),
2049 Details<std::string>(&language));
2050 }
2051}
2052
2053// See SelectTranslateOption() in chrome/test/pyautolib/pyauto.py for sample
2054// json input.
2055// Sample json output: {}
2056void AutomationProvider::SelectTranslateOption(Browser* browser,
2057 DictionaryValue* args,
2058 IPC::Message* reply_message) {
2059 std::string option;
2060 std::string error_message;
2061 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2062 &error_message);
2063 if (!tab_contents) {
2064 AutomationJSONReply(this, reply_message).SendError(error_message);
2065 return;
2066 }
2067
2068 TranslateInfoBarDelegate* translate_bar =
2069 GetTranslateInfoBarDelegate(tab_contents);
2070 if (!translate_bar) {
2071 AutomationJSONReply(this, reply_message)
2072 .SendError("There is no translate bar open.");
2073 return;
2074 }
2075
[email protected]ff4c1d82010-08-04 16:58:122076 if (!args->GetString("option", &option)) {
[email protected]3dda5b02010-07-27 16:35:422077 AutomationJSONReply(this, reply_message).SendError("Must include option");
2078 return;
2079 }
2080
2081 if (option == "translate_page") {
2082 // Make a new notification observer which will send the reply.
2083 new PageTranslatedObserver(this, reply_message, tab_contents);
2084 translate_bar->Translate();
2085 return;
[email protected]da1913e2010-08-04 23:50:152086 } else if (option == "set_target_language") {
2087 string16 target_language;
2088 if (!args->GetString("target_language", &target_language)) {
2089 AutomationJSONReply(this, reply_message).
2090 SendError("Must include target_language string.");
2091 return;
2092 }
2093 // Get the target language index based off of the language name.
2094 int target_language_index = -1;
2095 for (int i = 0; i < translate_bar->GetLanguageCount(); i++) {
2096 if (translate_bar->GetLanguageDisplayableNameAt(i) == target_language) {
2097 target_language_index = i;
2098 break;
2099 }
2100 }
2101 if (target_language_index == -1) {
2102 AutomationJSONReply(this, reply_message)
2103 .SendError("Invalid target language string.");
2104 return;
2105 }
2106 // If the page has already been translated it will be translated again to
2107 // the new language. The observer will wait until the page has been
2108 // translated to reply.
2109 if (translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE) {
2110 new PageTranslatedObserver(this, reply_message, tab_contents);
2111 translate_bar->SetTargetLanguage(target_language_index);
2112 return;
2113 }
2114 // Otherwise just send the reply back immediately.
2115 translate_bar->SetTargetLanguage(target_language_index);
2116 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2117 return_value->SetBoolean("translation_success", true);
2118 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2119 return;
[email protected]4a47d76122010-08-10 18:11:162120 } else if (option == "click_always_translate_lang_button") {
2121 if (!translate_bar->ShouldShowAlwaysTranslateButton()) {
2122 AutomationJSONReply(this, reply_message)
2123 .SendError("Always translate button not showing.");
2124 return;
2125 }
2126 // Clicking 'Always Translate' triggers a translation. The observer will
2127 // wait until the translation is complete before sending the reply.
2128 new PageTranslatedObserver(this, reply_message, tab_contents);
2129 translate_bar->AlwaysTranslatePageLanguage();
2130 return;
[email protected]3dda5b02010-07-27 16:35:422131 }
2132
2133 AutomationJSONReply reply(this, reply_message);
2134 if (option == "never_translate_language") {
2135 if (translate_bar->IsLanguageBlacklisted()) {
2136 reply.SendError("The language was already blacklisted.");
2137 return;
2138 }
2139 translate_bar->ToggleLanguageBlacklist();
2140 reply.SendSuccess(NULL);
2141 } else if (option == "never_translate_site") {
2142 if (translate_bar->IsSiteBlacklisted()) {
2143 reply.SendError("The site was already blacklisted.");
2144 return;
2145 }
2146 translate_bar->ToggleSiteBlacklist();
2147 reply.SendSuccess(NULL);
2148 } else if (option == "toggle_always_translate") {
2149 translate_bar->ToggleAlwaysTranslate();
2150 reply.SendSuccess(NULL);
2151 } else if (option == "revert_translation") {
2152 translate_bar->RevertTranslation();
2153 reply.SendSuccess(NULL);
[email protected]4a47d76122010-08-10 18:11:162154 } else if (option == "click_never_translate_lang_button") {
2155 if (!translate_bar->ShouldShowNeverTranslateButton()) {
2156 reply.SendError("Always translate button not showing.");
2157 return;
2158 }
2159 translate_bar->NeverTranslatePageLanguage();
2160 reply.SendSuccess(NULL);
2161 } else if (option == "decline_translation") {
2162 // This is the function called when an infobar is dismissed or when the
2163 // user clicks the 'Nope' translate button.
2164 translate_bar->TranslationDeclined();
[email protected]a9add882010-08-16 20:37:482165 tab_contents->RemoveInfoBar(translate_bar);
[email protected]4a47d76122010-08-10 18:11:162166 reply.SendSuccess(NULL);
[email protected]3dda5b02010-07-27 16:35:422167 } else {
2168 reply.SendError("Invalid string found for option.");
2169 }
2170}
2171
[email protected]f89ee5d2010-08-02 16:39:122172// See WaitUntilTranslateComplete() in chrome/test/pyautolib/pyauto.py for
2173// sample json input and output.
2174void AutomationProvider::WaitUntilTranslateComplete(
2175 Browser* browser, DictionaryValue* args, IPC::Message* reply_message) {
2176 std::string error_message;
2177 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
2178 &error_message);
2179 if (!tab_contents) {
2180 AutomationJSONReply(this, reply_message).SendError(error_message);
2181 return;
2182 }
2183
[email protected]f89ee5d2010-08-02 16:39:122184 TranslateInfoBarDelegate* translate_bar =
2185 GetTranslateInfoBarDelegate(tab_contents);
2186 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
[email protected]14a0aac2010-08-05 15:52:592187
[email protected]f89ee5d2010-08-02 16:39:122188 if (!translate_bar) {
[email protected]57ecc4b2010-08-11 03:02:512189 return_value->SetBoolean("translation_success", false);
[email protected]14a0aac2010-08-05 15:52:592190 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2191 return;
[email protected]f89ee5d2010-08-02 16:39:122192 }
[email protected]14a0aac2010-08-05 15:52:592193
2194 // If the translation is still pending, the observer will wait
2195 // for it to finish and then reply.
2196 if (translate_bar->type() == TranslateInfoBarDelegate::TRANSLATING) {
2197 new PageTranslatedObserver(this, reply_message, tab_contents);
2198 return;
2199 }
2200
2201 // Otherwise send back the success or failure of the attempted translation.
2202 return_value->SetBoolean(
[email protected]57ecc4b2010-08-11 03:02:512203 "translation_success",
[email protected]14a0aac2010-08-05 15:52:592204 translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE);
2205 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]f89ee5d2010-08-02 16:39:122206}
2207
[email protected]4d1929f12010-07-10 00:09:032208// Sample json input: { "command": "GetThemeInfo" }
2209// Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
2210void AutomationProvider::GetThemeInfo(Browser* browser,
2211 DictionaryValue* args,
2212 IPC::Message* reply_message) {
2213 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2214 Extension* theme = browser->profile()->GetTheme();
2215 if (theme) {
[email protected]ff4c1d82010-08-04 16:58:122216 return_value->SetString("name", theme->name());
2217 return_value->Set("images", theme->GetThemeImages()->DeepCopy());
2218 return_value->Set("colors", theme->GetThemeColors()->DeepCopy());
2219 return_value->Set("tints", theme->GetThemeTints()->DeepCopy());
[email protected]4d1929f12010-07-10 00:09:032220 }
[email protected]7c983cc2010-07-16 11:33:342221 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
[email protected]4d1929f12010-07-10 00:09:032222}
2223
[email protected]32a69cf2010-08-03 16:27:012224// Sample json input: { "command": "GetExtensionsInfo" }
2225// See GetExtensionsInfo() in chrome/test/pyautolib/pyauto.py for sample json
2226// output.
2227void AutomationProvider::GetExtensionsInfo(Browser* browser,
2228 DictionaryValue* args,
2229 IPC::Message* reply_message) {
2230 AutomationJSONReply reply(this, reply_message);
2231 ExtensionsService* service = profile()->GetExtensionsService();
2232 if (!service) {
2233 reply.SendError("No extensions service.");
2234 }
2235 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2236 ListValue* extensions_values = new ListValue;
2237 const ExtensionList* extensions = service->extensions();
2238 for (ExtensionList::const_iterator it = extensions->begin();
2239 it != extensions->end(); ++it) {
2240 const Extension* extension = *it;
2241 DictionaryValue* extension_value = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122242 extension_value->SetString("id", extension->id());
2243 extension_value->SetString("version", extension->VersionString());
2244 extension_value->SetString("name", extension->name());
2245 extension_value->SetString("public_key", extension->public_key());
2246 extension_value->SetString("description", extension->description());
2247 extension_value->SetString("background_url",
[email protected]32a69cf2010-08-03 16:27:012248 extension->background_url().spec());
[email protected]ff4c1d82010-08-04 16:58:122249 extension_value->SetString("options_url",
[email protected]32a69cf2010-08-03 16:27:012250 extension->options_url().spec());
2251 extensions_values->Append(extension_value);
2252 }
[email protected]ff4c1d82010-08-04 16:58:122253 return_value->Set("extensions", extensions_values);
[email protected]32a69cf2010-08-03 16:27:012254 reply.SendSuccess(return_value.get());
2255}
2256
2257// See UninstallExtensionById() in chrome/test/pyautolib/pyauto.py for sample
2258// json input.
2259// Sample json output: {}
2260void AutomationProvider::UninstallExtensionById(Browser* browser,
2261 DictionaryValue* args,
2262 IPC::Message* reply_message) {
2263 AutomationJSONReply reply(this, reply_message);
2264 std::string id;
[email protected]ff4c1d82010-08-04 16:58:122265 if (!args->GetString("id", &id)) {
[email protected]32a69cf2010-08-03 16:27:012266 reply.SendError("Must include string id.");
2267 return;
2268 }
2269 ExtensionsService* service = profile()->GetExtensionsService();
2270 if (!service) {
2271 reply.SendError("No extensions service.");
2272 return;
2273 }
2274 ExtensionUnloadNotificationObserver observer;
2275 service->UninstallExtension(id, false);
2276 reply.SendSuccess(NULL);
2277}
2278
[email protected]55846ad842010-07-09 18:22:562279// Sample json input:
2280// { "command": "GetAutoFillProfile" }
2281// Refer to GetAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2282// json output.
2283void AutomationProvider::GetAutoFillProfile(Browser* browser,
2284 DictionaryValue* args,
2285 IPC::Message* reply_message) {
[email protected]55846ad842010-07-09 18:22:562286 // Get the AutoFillProfiles currently in the database.
2287 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:122288 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:562289 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
[email protected]7c983cc2010-07-16 11:33:342290 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:562291
2292 if (tab_contents) {
2293 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
2294 ->GetPersonalDataManager();
2295 if (pdm) {
2296 std::vector<AutoFillProfile*> autofill_profiles = pdm->profiles();
2297 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
2298
2299 ListValue* profiles = GetListFromAutoFillProfiles(autofill_profiles);
2300 ListValue* cards = GetListFromCreditCards(credit_cards);
2301
2302 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2303
[email protected]ff4c1d82010-08-04 16:58:122304 return_value->Set("profiles", profiles);
2305 return_value->Set("credit_cards", cards);
[email protected]7c983cc2010-07-16 11:33:342306 reply.SendSuccess(return_value.get());
[email protected]55846ad842010-07-09 18:22:562307 } else {
[email protected]7c983cc2010-07-16 11:33:342308 reply.SendError("No PersonalDataManager.");
2309 return;
[email protected]55846ad842010-07-09 18:22:562310 }
2311 } else {
[email protected]7c983cc2010-07-16 11:33:342312 reply.SendError("No tab at that index.");
2313 return;
[email protected]55846ad842010-07-09 18:22:562314 }
[email protected]55846ad842010-07-09 18:22:562315}
2316
2317// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
2318// json input.
2319// Sample json output: {}
2320void AutomationProvider::FillAutoFillProfile(Browser* browser,
2321 DictionaryValue* args,
2322 IPC::Message* reply_message) {
[email protected]7c983cc2010-07-16 11:33:342323 AutomationJSONReply reply(this, reply_message);
[email protected]55846ad842010-07-09 18:22:562324 ListValue* profiles = NULL;
2325 ListValue* cards = NULL;
[email protected]ff4c1d82010-08-04 16:58:122326 args->GetList("profiles", &profiles);
2327 args->GetList("credit_cards", &cards);
[email protected]7c983cc2010-07-16 11:33:342328 std::string error_mesg;
[email protected]55846ad842010-07-09 18:22:562329
2330 std::vector<AutoFillProfile> autofill_profiles;
2331 std::vector<CreditCard> credit_cards;
2332 // Create an AutoFillProfile for each of the dictionary profiles.
2333 if (profiles) {
[email protected]7c983cc2010-07-16 11:33:342334 autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg);
[email protected]55846ad842010-07-09 18:22:562335 }
2336 // Create a CreditCard for each of the dictionary values.
2337 if (cards) {
[email protected]7c983cc2010-07-16 11:33:342338 credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
2339 }
2340 if (!error_mesg.empty()) {
2341 reply.SendError(error_mesg);
2342 return;
[email protected]55846ad842010-07-09 18:22:562343 }
2344
2345 // Save the AutoFillProfiles.
2346 int tab_index = 0;
[email protected]ff4c1d82010-08-04 16:58:122347 args->GetInteger("tab_index", &tab_index);
[email protected]55846ad842010-07-09 18:22:562348 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2349
2350 if (tab_contents) {
[email protected]ce6b0122010-07-19 19:07:302351 PersonalDataManager* pdm = tab_contents->profile()
[email protected]55846ad842010-07-09 18:22:562352 ->GetPersonalDataManager();
2353 if (pdm) {
2354 pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
2355 cards? &credit_cards : NULL);
2356 } else {
[email protected]7c983cc2010-07-16 11:33:342357 reply.SendError("No PersonalDataManager.");
2358 return;
[email protected]55846ad842010-07-09 18:22:562359 }
2360 } else {
[email protected]7c983cc2010-07-16 11:33:342361 reply.SendError("No tab at that index.");
2362 return;
[email protected]55846ad842010-07-09 18:22:562363 }
[email protected]7c983cc2010-07-16 11:33:342364 reply.SendSuccess(NULL);
[email protected]55846ad842010-07-09 18:22:562365}
2366
2367/* static */
2368ListValue* AutomationProvider::GetListFromAutoFillProfiles(
2369 std::vector<AutoFillProfile*> autofill_profiles) {
2370 ListValue* profiles = new ListValue;
2371
2372 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string
2373 = GetAutoFillFieldToStringMap();
2374
2375 // For each AutoFillProfile, transform it to a dictionary object to return.
2376 for (std::vector<AutoFillProfile*>::iterator it = autofill_profiles.begin();
2377 it != autofill_profiles.end(); ++it) {
2378 AutoFillProfile* profile = *it;
2379 DictionaryValue* profile_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122380 profile_info->SetString("label", profile->Label());
[email protected]55846ad842010-07-09 18:22:562381 // For each of the types, if it has a value, add it to the dictionary.
2382 for (std::map<AutoFillFieldType, std::wstring>::iterator
2383 type_it = autofill_type_to_string.begin();
2384 type_it != autofill_type_to_string.end(); ++type_it) {
2385 string16 value = profile->GetFieldText(AutoFillType(type_it->first));
2386 if (value.length()) { // If there was something stored for that value.
[email protected]99922662010-08-17 16:24:252387 profile_info->SetString(WideToUTF8(type_it->second), value);
[email protected]55846ad842010-07-09 18:22:562388 }
2389 }
2390 profiles->Append(profile_info);
2391 }
2392 return profiles;
2393}
2394
2395/* static */
2396ListValue* AutomationProvider::GetListFromCreditCards(
2397 std::vector<CreditCard*> credit_cards) {
2398 ListValue* cards = new ListValue;
2399
2400 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2401 GetCreditCardFieldToStringMap();
2402
2403 // For each AutoFillProfile, transform it to a dictionary object to return.
2404 for (std::vector<CreditCard*>::iterator it = credit_cards.begin();
2405 it != credit_cards.end(); ++it) {
2406 CreditCard* card = *it;
2407 DictionaryValue* card_info = new DictionaryValue;
[email protected]ff4c1d82010-08-04 16:58:122408 card_info->SetString("label", card->Label());
[email protected]55846ad842010-07-09 18:22:562409 // For each of the types, if it has a value, add it to the dictionary.
2410 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2411 credit_card_type_to_string.begin();
2412 type_it != credit_card_type_to_string.end(); ++type_it) {
2413 string16 value = card->GetFieldText(AutoFillType(type_it->first));
2414 // If there was something stored for that value.
2415 if (value.length()) {
[email protected]99922662010-08-17 16:24:252416 card_info->SetString(WideToUTF8(type_it->second), value);
[email protected]55846ad842010-07-09 18:22:562417 }
2418 }
2419 cards->Append(card_info);
2420 }
2421 return cards;
2422}
2423
2424/* static */
2425std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
[email protected]7c983cc2010-07-16 11:33:342426 const ListValue& profiles, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:562427 std::vector<AutoFillProfile> autofill_profiles;
2428 DictionaryValue* profile_info = NULL;
2429 string16 profile_label;
2430 string16 current_value;
2431
2432 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string =
2433 GetAutoFillFieldToStringMap();
2434
2435 int num_profiles = profiles.GetSize();
2436 for (int i = 0; i < num_profiles; i++) {
2437 profiles.GetDictionary(i, &profile_info);
2438 profile_info->GetString("label", &profile_label);
2439 // Choose an id of 0 so that a unique id will be created.
2440 AutoFillProfile profile(profile_label, 0);
2441 // Loop through the possible profile types and add those provided.
2442 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2443 autofill_type_to_string.begin();
2444 type_it != autofill_type_to_string.end(); ++type_it) {
[email protected]99922662010-08-17 16:24:252445 if (profile_info->HasKey(WideToUTF8(type_it->second))) {
[email protected]698f7f42010-08-04 19:35:332446 if (profile_info->GetString(WideToUTF8(type_it->second),
2447 &current_value)) {
[email protected]55846ad842010-07-09 18:22:562448 profile.SetInfo(AutoFillType(type_it->first), current_value);
2449 } else {
[email protected]7c983cc2010-07-16 11:33:342450 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:562451 break;
2452 }
2453 }
2454 }
2455 autofill_profiles.push_back(profile);
2456 }
2457 return autofill_profiles;
2458}
2459
2460/* static */
2461std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
[email protected]7c983cc2010-07-16 11:33:342462 const ListValue& cards, std::string* error_message) {
[email protected]55846ad842010-07-09 18:22:562463 std::vector<CreditCard> credit_cards;
2464 DictionaryValue* card_info = NULL;
2465 string16 card_label;
2466 string16 current_value;
2467
2468 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string =
2469 GetCreditCardFieldToStringMap();
2470
2471 int num_credit_cards = cards.GetSize();
2472 for (int i = 0; i < num_credit_cards; i++) {
2473 cards.GetDictionary(i, &card_info);
2474 card_info->GetString("label", &card_label);
2475 CreditCard card(card_label, 0);
2476 // Loop through the possible credit card fields and add those provided.
2477 for (std::map<AutoFillFieldType, std::wstring>::iterator type_it =
2478 credit_card_type_to_string.begin();
2479 type_it != credit_card_type_to_string.end(); ++type_it) {
[email protected]99922662010-08-17 16:24:252480 if (card_info->HasKey(WideToUTF8(type_it->second))) {
[email protected]698f7f42010-08-04 19:35:332481 if (card_info->GetString(WideToUTF8(type_it->second), &current_value)) {
[email protected]55846ad842010-07-09 18:22:562482 card.SetInfo(AutoFillType(type_it->first), current_value);
2483 } else {
[email protected]7c983cc2010-07-16 11:33:342484 *error_message= "All values must be strings";
[email protected]55846ad842010-07-09 18:22:562485 break;
2486 }
2487 }
2488 }
2489 credit_cards.push_back(card);
2490 }
2491 return credit_cards;
2492}
2493
2494/* static */
2495std::map<AutoFillFieldType, std::wstring>
2496 AutomationProvider::GetAutoFillFieldToStringMap() {
2497 std::map<AutoFillFieldType, std::wstring> autofill_type_to_string;
2498 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2499 autofill_type_to_string[NAME_MIDDLE] = L"NAME_MIDDLE";
2500 autofill_type_to_string[NAME_LAST] = L"NAME_LAST";
2501 autofill_type_to_string[COMPANY_NAME] = L"COMPANY_NAME";
2502 autofill_type_to_string[EMAIL_ADDRESS] = L"EMAIL_ADDRESS";
2503 autofill_type_to_string[ADDRESS_HOME_LINE1] = L"ADDRESS_HOME_LINE1";
2504 autofill_type_to_string[ADDRESS_HOME_LINE2] = L"ADDRESS_HOME_LINE2";
2505 autofill_type_to_string[ADDRESS_HOME_CITY] = L"ADDRESS_HOME_CITY";
2506 autofill_type_to_string[ADDRESS_HOME_STATE] = L"ADDRESS_HOME_STATE";
2507 autofill_type_to_string[ADDRESS_HOME_ZIP] = L"ADDRESS_HOME_ZIP";
2508 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = L"ADDRESS_HOME_COUNTRY";
2509 autofill_type_to_string[PHONE_HOME_NUMBER] = L"PHONE_HOME_NUMBER";
2510 autofill_type_to_string[PHONE_FAX_NUMBER] = L"PHONE_FAX_NUMBER";
2511 autofill_type_to_string[NAME_FIRST] = L"NAME_FIRST";
2512 return autofill_type_to_string;
2513}
2514
2515/* static */
2516std::map<AutoFillFieldType, std::wstring>
2517 AutomationProvider::GetCreditCardFieldToStringMap() {
2518 std::map<AutoFillFieldType, std::wstring> credit_card_type_to_string;
2519 credit_card_type_to_string[CREDIT_CARD_NAME] = L"CREDIT_CARD_NAME";
2520 credit_card_type_to_string[CREDIT_CARD_NUMBER] = L"CREDIT_CARD_NUMBER";
[email protected]55846ad842010-07-09 18:22:562521 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = L"CREDIT_CARD_EXP_MONTH";
2522 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
2523 L"CREDIT_CARD_EXP_4_DIGIT_YEAR";
2524 return credit_card_type_to_string;
2525}
2526
[email protected]53329582010-05-14 21:10:582527void AutomationProvider::SendJSONRequest(int handle,
2528 std::string json_request,
2529 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042530 Browser* browser = NULL;
[email protected]59a611242010-04-02 02:24:042531 scoped_ptr<Value> values;
2532
2533 // Basic error checking.
2534 if (browser_tracker_->ContainsHandle(handle)) {
2535 browser = browser_tracker_->GetResource(handle);
2536 }
2537 if (!browser) {
[email protected]7c983cc2010-07-16 11:33:342538 AutomationJSONReply(this, reply_message).SendError("no browser object");
2539 return;
2540 }
2541 base::JSONReader reader;
2542 std::string error;
2543 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
2544 if (!error.empty()) {
2545 AutomationJSONReply(this, reply_message).SendError(error);
2546 return;
[email protected]59a611242010-04-02 02:24:042547 }
2548
2549 // Make sure input is a dict with a string command.
2550 std::string command;
2551 DictionaryValue* dict_value = NULL;
[email protected]7c983cc2010-07-16 11:33:342552 if (values->GetType() != Value::TYPE_DICTIONARY) {
2553 AutomationJSONReply(this, reply_message).SendError("not a dict");
2554 return;
2555 }
2556 // Ownership remains with "values" variable.
2557 dict_value = static_cast<DictionaryValue*>(values.get());
2558 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2559 AutomationJSONReply(this, reply_message).SendError(
2560 "no command key in dict or not a string command");
2561 return;
[email protected]59a611242010-04-02 02:24:042562 }
2563
[email protected]24e2b102010-04-29 17:56:472564 // Map json commands to their handlers.
2565 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052566 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2567 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2568 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2569
[email protected]a9ff2c02010-05-13 17:33:052570 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
[email protected]7c983cc2010-07-16 11:33:342571
[email protected]38b5a3852010-07-21 06:49:522572 handler_map["WaitForInfobarCount"] = &AutomationProvider::WaitForInfobarCount;
[email protected]e004a2d2010-07-22 04:55:282573 handler_map["PerformActionOnInfobar"] =
2574 &AutomationProvider::PerformActionOnInfobar;
[email protected]38b5a3852010-07-21 06:49:522575
[email protected]24e2b102010-04-29 17:56:472576 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292577 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052578
[email protected]53329582010-05-14 21:10:582579 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2580 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2581 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2582 handler_map["OmniboxMovePopupSelection"] =
2583 &AutomationProvider::OmniboxMovePopupSelection;
2584
[email protected]24e2b102010-04-29 17:56:472585 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2586 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052587
[email protected]ef413ca2010-05-25 21:09:142588 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2589
[email protected]f7d48012010-05-06 08:17:052590 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472591 handler_map["WaitForAllDownloadsToComplete"] =
2592 &AutomationProvider::WaitForDownloadsToComplete;
[email protected]2d54c4032010-08-20 00:42:282593 handler_map["PerformActionOnDownload"] =
2594 &AutomationProvider::PerformActionOnDownload;
2595 handler_map["WaitForAlwaysOpenDownloadTypeToOpen"] =
2596 &AutomationProvider::WaitForAlwaysOpenDownloadTypeToOpen;
[email protected]24e2b102010-04-29 17:56:472597
[email protected]a3cd5022010-06-16 18:25:292598 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
2599
[email protected]7060bb292010-06-24 00:52:492600 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
2601
[email protected]c5aa5322010-07-15 19:00:072602 handler_map["ImportSettings"] = &AutomationProvider::ImportSettings;
2603
[email protected]5bcfe1672010-07-16 20:51:572604 handler_map["AddSavedPassword"] = &AutomationProvider::AddSavedPassword;
[email protected]95222282010-07-26 17:43:022605 handler_map["RemoveSavedPassword"] =
2606 &AutomationProvider::RemoveSavedPassword;
[email protected]5bcfe1672010-07-16 20:51:572607 handler_map["GetSavedPasswords"] = &AutomationProvider::GetSavedPasswords;
2608
[email protected]a0fc50d72010-07-14 21:14:192609 handler_map["ClearBrowsingData"] = &AutomationProvider::ClearBrowsingData;
2610
[email protected]4d1929f12010-07-10 00:09:032611 // SetTheme() implemented using InstallExtension().
2612 handler_map["GetThemeInfo"] = &AutomationProvider::GetThemeInfo;
2613
[email protected]32a69cf2010-08-03 16:27:012614 // InstallExtension() present in pyauto.py.
2615 handler_map["GetExtensionsInfo"] = &AutomationProvider::GetExtensionsInfo;
2616 handler_map["UninstallExtensionById"] =
2617 &AutomationProvider::UninstallExtensionById;
2618
[email protected]3dda5b02010-07-27 16:35:422619 handler_map["SelectTranslateOption"] =
2620 &AutomationProvider::SelectTranslateOption;
2621 handler_map["GetTranslateInfo"] = &AutomationProvider::GetTranslateInfo;
[email protected]f89ee5d2010-08-02 16:39:122622 handler_map["WaitUntilTranslateComplete"] =
2623 &AutomationProvider::WaitUntilTranslateComplete;
[email protected]3dda5b02010-07-27 16:35:422624
[email protected]55846ad842010-07-09 18:22:562625 handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
2626 handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
2627
[email protected]7c983cc2010-07-16 11:33:342628 if (handler_map.find(std::string(command)) != handler_map.end()) {
2629 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]1ac875d22010-07-16 09:57:582630 } else {
[email protected]7c983cc2010-07-16 11:33:342631 std::string error_string = "Unknown command. Options: ";
2632 for (std::map<std::string, JsonHandler>::const_iterator it =
2633 handler_map.begin(); it != handler_map.end(); ++it) {
2634 error_string += it->first + ", ";
2635 }
2636 AutomationJSONReply(this, reply_message).SendError(error_string);
[email protected]1ac875d22010-07-16 09:57:582637 }
[email protected]59a611242010-04-02 02:24:042638}
2639
[email protected]a7eee32f2009-05-22 18:08:172640class SetProxyConfigTask : public Task {
2641 public:
[email protected]be180c802009-10-23 06:33:312642 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2643 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252644 : request_context_getter_(request_context_getter),
2645 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172646 virtual void Run() {
2647 // First, deserialize the JSON string. If this fails, log and bail.
2648 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392649 std::string error_msg;
2650 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172651 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2652 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392653 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172654 return;
2655 }
2656
2657 scoped_ptr<DictionaryValue> dict(
2658 static_cast<DictionaryValue*>(root.release()));
2659 // Now put together a proxy configuration from the deserialized string.
2660 net::ProxyConfig pc;
2661 PopulateProxyConfig(*dict.get(), &pc);
2662
[email protected]be180c802009-10-23 06:33:312663 net::ProxyService* proxy_service =
2664 request_context_getter_->GetURLRequestContext()->proxy_service();
2665 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172666 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2667 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312668 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172669 }
2670
2671 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2672 DCHECK(pc);
2673 bool no_proxy = false;
2674 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2675 // Make no changes to the ProxyConfig.
2676 return;
2677 }
2678 bool auto_config;
2679 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482680 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172681 }
2682 std::string pac_url;
2683 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482684 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172685 }
2686 std::string proxy_bypass_list;
2687 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482688 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172689 }
2690 std::string proxy_server;
2691 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482692 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172693 }
2694 }
2695
2696 private:
[email protected]be180c802009-10-23 06:33:312697 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172698 std::string proxy_config_;
2699};
2700
2701
2702void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312703 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2704 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172705 FilePath user_data_dir;
2706 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2707 ProfileManager* profile_manager = g_browser_process->profile_manager();
2708 DCHECK(profile_manager);
2709 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2710 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312711 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172712 }
[email protected]be180c802009-10-23 06:33:312713 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172714
[email protected]fae20792009-10-28 20:31:582715 ChromeThread::PostTask(
2716 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312717 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172718}
2719
[email protected]4f3dc372009-02-24 00:10:292720void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332721 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292722 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292723 if (tab_tracker_->ContainsHandle(handle)) {
2724 NavigationController* tab = tab_tracker_->GetResource(handle);
2725 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2726 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332727 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292728 }
initial.commit09911bf2008-07-26 23:55:292729}
2730
[email protected]6a5670d22009-10-27 16:21:342731void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142732 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532733 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2734 reply_message);
2735}
2736
2737void AutomationProvider::OpenNewBrowserWindowOfType(
2738 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:142739 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292740 // We may have no current browser windows open so don't rely on
2741 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:532742 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
2743 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:052744 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152745 if (show)
[email protected]15952e462008-11-14 00:29:052746 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292747}
2748
[email protected]71f65dd2009-02-11 19:14:562749void AutomationProvider::GetWindowForBrowser(int browser_handle,
2750 bool* success,
2751 int* handle) {
2752 *success = false;
2753 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292754
2755 if (browser_tracker_->ContainsHandle(browser_handle)) {
2756 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202757 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292758 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202759 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562760 *success = true;
initial.commit09911bf2008-07-26 23:55:292761 }
initial.commit09911bf2008-07-26 23:55:292762}
2763
[email protected]71f65dd2009-02-11 19:14:562764void AutomationProvider::ShowInterstitialPage(int tab_handle,
2765 const std::string& html_text,
2766 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292767 if (tab_tracker_->ContainsHandle(tab_handle)) {
2768 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112769 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402770
[email protected]7dad3d5f2010-03-04 00:27:012771 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:402772 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342773 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402774 GURL("about:interstitial"),
2775 html_text);
2776 interstitial->Show();
2777 return;
initial.commit09911bf2008-07-26 23:55:292778 }
[email protected]71f65dd2009-02-11 19:14:562779
[email protected]457f5cf2009-08-18 16:37:522780 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2781 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562782 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292783}
2784
[email protected]71f65dd2009-02-11 19:14:562785void AutomationProvider::HideInterstitialPage(int tab_handle,
2786 bool* success) {
2787 *success = false;
[email protected]57c6a652009-05-04 07:58:342788 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2789 if (tab_contents && tab_contents->interstitial_page()) {
2790 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562791 *success = true;
initial.commit09911bf2008-07-26 23:55:292792 }
initial.commit09911bf2008-07-26 23:55:292793}
2794
[email protected]71f65dd2009-02-11 19:14:562795void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2796 IPC::Message* reply_message) {
2797 if (tab_tracker_->ContainsHandle(tab_handle)) {
2798 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2799 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142800 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562801 }
2802}
2803
[email protected]71f65dd2009-02-11 19:14:562804void AutomationProvider::GetSecurityState(int handle, bool* success,
2805 SecurityStyle* security_style,
2806 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:482807 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:292808 if (tab_tracker_->ContainsHandle(handle)) {
2809 NavigationController* tab = tab_tracker_->GetResource(handle);
2810 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562811 *success = true;
2812 *security_style = entry->ssl().security_style();
2813 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:482814 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292815 } else {
[email protected]71f65dd2009-02-11 19:14:562816 *success = false;
2817 *security_style = SECURITY_STYLE_UNKNOWN;
2818 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:482819 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292820 }
2821}
2822
[email protected]71f65dd2009-02-11 19:14:562823void AutomationProvider::GetPageType(int handle, bool* success,
2824 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292825 if (tab_tracker_->ContainsHandle(handle)) {
2826 NavigationController* tab = tab_tracker_->GetResource(handle);
2827 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562828 *page_type = entry->page_type();
2829 *success = true;
initial.commit09911bf2008-07-26 23:55:292830 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342831 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562832 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342833 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562834 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292835 } else {
[email protected]71f65dd2009-02-11 19:14:562836 *success = false;
2837 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292838 }
2839}
2840
[email protected]84abba62009-10-07 17:01:442841void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
2842 int* duration_ms) {
2843 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
2844 event_name);
2845}
2846
[email protected]71f65dd2009-02-11 19:14:562847void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2848 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292849 if (tab_tracker_->ContainsHandle(handle)) {
2850 NavigationController* tab = tab_tracker_->GetResource(handle);
2851 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072852 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402853 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472854 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342855 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292856 if (ssl_blocking_page) {
2857 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:012858 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:562859 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292860 return;
2861 }
2862 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522863 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2864 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562865 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292866 return;
2867 }
2868 }
2869 }
2870 // We failed.
[email protected]457f5cf2009-08-18 16:37:522871 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2872 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562873 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292874}
2875
[email protected]71f65dd2009-02-11 19:14:562876void AutomationProvider::BringBrowserToFront(int browser_handle,
2877 bool* success) {
initial.commit09911bf2008-07-26 23:55:292878 if (browser_tracker_->ContainsHandle(browser_handle)) {
2879 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062880 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562881 *success = true;
initial.commit09911bf2008-07-26 23:55:292882 } else {
[email protected]71f65dd2009-02-11 19:14:562883 *success = false;
initial.commit09911bf2008-07-26 23:55:292884 }
2885}
2886
[email protected]bdb7ff62010-07-20 01:56:522887void AutomationProvider::IsMenuCommandEnabled(int browser_handle,
2888 int message_num,
2889 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292890 if (browser_tracker_->ContainsHandle(browser_handle)) {
2891 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562892 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142893 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292894 } else {
[email protected]71f65dd2009-02-11 19:14:562895 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292896 }
2897}
2898
[email protected]71f65dd2009-02-11 19:14:562899void AutomationProvider::PrintNow(int tab_handle,
2900 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572901 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342902 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2903 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292904 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572905 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142906 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342907 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572908 return;
initial.commit09911bf2008-07-26 23:55:292909 }
[email protected]71f65dd2009-02-11 19:14:562910 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2911 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292912}
[email protected]d301c952009-07-13 15:02:412913
[email protected]71f65dd2009-02-11 19:14:562914void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:112915 const FilePath& file_name,
2916 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:562917 int type,
2918 bool* success) {
initial.commit09911bf2008-07-26 23:55:292919 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562920 *success = false;
initial.commit09911bf2008-07-26 23:55:292921 return;
2922 }
2923
2924 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2925 Browser* browser = FindAndActivateTab(nav);
2926 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142927 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562928 *success = false;
initial.commit09911bf2008-07-26 23:55:292929 return;
2930 }
2931
initial.commit09911bf2008-07-26 23:55:292932 SavePackage::SavePackageType save_type =
2933 static_cast<SavePackage::SavePackageType>(type);
2934 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2935 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342936 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292937
[email protected]71f65dd2009-02-11 19:14:562938 *success = true;
initial.commit09911bf2008-07-26 23:55:292939}
2940
[email protected]57c6a652009-05-04 07:58:342941TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572942 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572943 if (tab_tracker_->ContainsHandle(handle)) {
2944 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342945 if (tab)
2946 *tab = nav_controller;
2947 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572948 }
[email protected]57c6a652009-05-04 07:58:342949 return NULL;
[email protected]20e93d12008-08-28 16:31:572950}
2951
[email protected]816633a2009-11-11 21:48:182952void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:562953 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422954 if (tab_tracker_->ContainsHandle(handle)) {
2955 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342956 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112957 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422958 }
[email protected]8a3422c92008-09-24 17:42:422959}
2960
[email protected]816633a2009-11-11 21:48:182961void AutomationProvider::ClickInfoBarAccept(int handle,
2962 int info_bar_index,
2963 bool wait_for_navigation,
2964 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422965 bool success = false;
2966 if (tab_tracker_->ContainsHandle(handle)) {
2967 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2968 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112969 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422970 if (info_bar_index >= 0 && info_bar_index < count) {
2971 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:012972 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:422973 }
[email protected]eb9ba192008-12-02 02:41:342974 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112975 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342976 info_bar_index);
2977 if (delegate->AsConfirmInfoBarDelegate())
2978 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422979 success = true;
2980 }
2981 }
[email protected]4f3dc372009-02-24 00:10:292982 }
[email protected]58f622a62009-10-04 01:17:552983
2984 // This "!wait_for_navigation || !success condition" logic looks suspicious.
2985 // It will send a failure message when success is true but
2986 // |wait_for_navigation| is false.
2987 // TODO(phajdan.jr): investgate whether the reply param (currently
2988 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:422989 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:182990 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:522991 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422992}
2993
[email protected]71f65dd2009-02-11 19:14:562994void AutomationProvider::GetLastNavigationTime(int handle,
2995 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422996 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562997 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422998}
2999
[email protected]71f65dd2009-02-11 19:14:563000void AutomationProvider::WaitForNavigation(int handle,
3001 int64 last_navigation_time,
3002 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:253003 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:423004 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:253005
[email protected]8a3422c92008-09-24 17:42:423006 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:563007 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:523008 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
3009 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:553010 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:293011 return;
[email protected]8a3422c92008-09-24 17:42:423012 }
3013
[email protected]7dad3d5f2010-03-04 00:27:013014 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:423015}
3016
[email protected]71f65dd2009-02-11 19:14:563017void AutomationProvider::SetIntPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513018 const std::string& name,
[email protected]71f65dd2009-02-11 19:14:563019 int value,
3020 bool* success) {
3021 *success = false;
[email protected]8a3422c92008-09-24 17:42:423022 if (browser_tracker_->ContainsHandle(handle)) {
3023 Browser* browser = browser_tracker_->GetResource(handle);
3024 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563025 *success = true;
[email protected]8a3422c92008-09-24 17:42:423026 }
[email protected]8a3422c92008-09-24 17:42:423027}
[email protected]97fa6ce32008-12-19 01:48:163028
[email protected]71f65dd2009-02-11 19:14:563029void AutomationProvider::SetStringPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513030 const std::string& name,
[email protected]ddd231e2010-06-29 20:35:193031 const std::string& value,
[email protected]71f65dd2009-02-11 19:14:563032 bool* success) {
3033 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163034 if (browser_tracker_->ContainsHandle(handle)) {
3035 Browser* browser = browser_tracker_->GetResource(handle);
3036 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563037 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163038 }
[email protected]97fa6ce32008-12-19 01:48:163039}
3040
[email protected]71f65dd2009-02-11 19:14:563041void AutomationProvider::GetBooleanPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513042 const std::string& name,
[email protected]b8f48d12009-11-09 20:14:363043 bool* success,
3044 bool* value) {
[email protected]71f65dd2009-02-11 19:14:563045 *success = false;
3046 *value = false;
[email protected]97fa6ce32008-12-19 01:48:163047 if (browser_tracker_->ContainsHandle(handle)) {
3048 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563049 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3050 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163051 }
[email protected]97fa6ce32008-12-19 01:48:163052}
3053
[email protected]71f65dd2009-02-11 19:14:563054void AutomationProvider::SetBooleanPreference(int handle,
[email protected]57ecc4b2010-08-11 03:02:513055 const std::string& name,
[email protected]71f65dd2009-02-11 19:14:563056 bool value,
3057 bool* success) {
3058 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163059 if (browser_tracker_->ContainsHandle(handle)) {
3060 Browser* browser = browser_tracker_->GetResource(handle);
3061 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563062 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163063 }
[email protected]97fa6ce32008-12-19 01:48:163064}
3065
3066// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563067void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:403068 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163069 if (tab_tracker_->ContainsHandle(tab_handle)) {
3070 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3071 Browser* browser = FindAndActivateTab(nav);
3072 DCHECK(browser);
3073
[email protected]57c6a652009-05-04 07:58:343074 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3075 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163076 }
[email protected]97fa6ce32008-12-19 01:48:163077}
3078
[email protected]b8f48d12009-11-09 20:14:363079// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563080void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:403081 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:563082 bool* success) {
3083 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163084 if (tab_tracker_->ContainsHandle(tab_handle)) {
3085 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:193086 if (!nav)
3087 return;
[email protected]97fa6ce32008-12-19 01:48:163088 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:163089
[email protected]2f2afba2010-04-01 01:53:193090 // If the browser has UI, simulate what a user would do.
3091 // Activate the tab and then click the encoding menu.
3092 if (browser &&
3093 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:163094 int selected_encoding_id =
3095 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3096 if (selected_encoding_id) {
3097 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563098 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163099 }
[email protected]2f2afba2010-04-01 01:53:193100 } else {
3101 // There is no UI, Chrome probably runs as Chrome-Frame mode.
3102 // Try to get TabContents and call its override_encoding method.
3103 TabContents* contents = nav->tab_contents();
3104 if (!contents)
3105 return;
3106 const std::string selected_encoding =
3107 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
3108 if (selected_encoding.empty())
3109 return;
3110 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163111 }
3112 }
[email protected]97fa6ce32008-12-19 01:48:163113}
[email protected]5bcdb312009-01-07 21:43:203114
[email protected]4d434a1a2009-02-11 21:06:573115void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203116 SavePackage::SetShouldPromptUser(should_prompt);
3117}
[email protected]87eab222009-03-13 00:47:453118
[email protected]66ba4932009-06-04 19:22:133119void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3120 *count = -1; // -1 is the error code
3121 if (tab_tracker_->ContainsHandle(handle)) {
3122 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3123 TabContents* tab_contents = nav_controller->tab_contents();
3124 if (tab_contents) {
3125 BlockedPopupContainer* container =
3126 tab_contents->blocked_popup_container();
3127 if (container) {
3128 *count = static_cast<int>(container->GetBlockedPopupCount());
3129 } else {
3130 // If we don't have a container, we don't have any blocked popups to
3131 // contain!
3132 *count = 0;
3133 }
3134 }
3135 }
3136}
[email protected]f7a68432009-07-29 23:18:193137
3138void AutomationProvider::SelectAll(int tab_handle) {
3139 RenderViewHost* view = GetViewForTab(tab_handle);
3140 if (!view) {
3141 NOTREACHED();
3142 return;
3143 }
3144
3145 view->SelectAll();
3146}
3147
3148void AutomationProvider::Cut(int tab_handle) {
3149 RenderViewHost* view = GetViewForTab(tab_handle);
3150 if (!view) {
3151 NOTREACHED();
3152 return;
3153 }
3154
3155 view->Cut();
3156}
3157
3158void AutomationProvider::Copy(int tab_handle) {
3159 RenderViewHost* view = GetViewForTab(tab_handle);
3160 if (!view) {
3161 NOTREACHED();
3162 return;
3163 }
3164
3165 view->Copy();
3166}
3167
3168void AutomationProvider::Paste(int tab_handle) {
3169 RenderViewHost* view = GetViewForTab(tab_handle);
3170 if (!view) {
3171 NOTREACHED();
3172 return;
3173 }
3174
3175 view->Paste();
3176}
3177
3178void AutomationProvider::ReloadAsync(int tab_handle) {
3179 if (tab_tracker_->ContainsHandle(tab_handle)) {
3180 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3181 if (!tab) {
3182 NOTREACHED();
3183 return;
3184 }
3185
[email protected]106a0812010-03-18 00:15:123186 const bool check_for_repost = true;
3187 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193188 }
3189}
3190
3191void AutomationProvider::StopAsync(int tab_handle) {
3192 RenderViewHost* view = GetViewForTab(tab_handle);
3193 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363194 // We tolerate StopAsync being called even before a view has been created.
3195 // So just log a warning instead of a NOTREACHED().
3196 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193197 return;
3198 }
3199
3200 view->Stop();
3201}
3202
[email protected]1bb5f892009-10-06 01:44:573203void AutomationProvider::OnSetPageFontSize(int tab_handle,
3204 int font_size) {
3205 AutomationPageFontSize automation_font_size =
3206 static_cast<AutomationPageFontSize>(font_size);
3207
3208 if (automation_font_size < SMALLEST_FONT ||
3209 automation_font_size > LARGEST_FONT) {
3210 DLOG(ERROR) << "Invalid font size specified : "
3211 << font_size;
3212 return;
3213 }
3214
3215 if (tab_tracker_->ContainsHandle(tab_handle)) {
3216 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3217 DCHECK(tab != NULL);
3218 if (tab && tab->tab_contents()) {
3219 DCHECK(tab->tab_contents()->profile() != NULL);
3220 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3221 prefs::kWebKitDefaultFontSize, font_size);
3222 }
3223 }
3224}
3225
[email protected]bc73b4e52010-03-26 04:16:203226void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3227 BrowsingDataRemover* remover;
3228 remover = new BrowsingDataRemover(profile(),
3229 BrowsingDataRemover::EVERYTHING, // All time periods.
3230 base::Time());
3231 remover->Remove(remove_mask);
3232 // BrowsingDataRemover deletes itself.
3233}
[email protected]1bb5f892009-10-06 01:44:573234
[email protected]2949e90d2009-08-21 15:32:523235void AutomationProvider::WaitForBrowserWindowCountToBecome(
3236 int target_count, IPC::Message* reply_message) {
3237 if (static_cast<int>(BrowserList::size()) == target_count) {
3238 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3239 reply_message, true);
3240 Send(reply_message);
3241 return;
3242 }
3243
3244 // Set up an observer (it will delete itself).
3245 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3246}
3247
3248void AutomationProvider::WaitForAppModalDialogToBeShown(
3249 IPC::Message* reply_message) {
3250 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3251 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3252 reply_message, true);
3253 Send(reply_message);
3254 return;
3255 }
3256
3257 // Set up an observer (it will delete itself).
3258 new AppModalDialogShownObserver(this, reply_message);
3259}
3260
[email protected]1126a1d32009-08-26 15:39:263261void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3262 int handle, int number_of_navigations, IPC::Message* reply_message) {
3263 if (tab_tracker_->ContainsHandle(handle)) {
3264 NavigationController* tab = tab_tracker_->GetResource(handle);
3265 Browser* browser = FindAndActivateTab(tab);
3266 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013267 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3268 false);
[email protected]1126a1d32009-08-26 15:39:263269 browser->GoBack(CURRENT_TAB);
3270 return;
3271 }
3272 }
3273
3274 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3275 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3276 Send(reply_message);
3277}
3278
3279void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3280 int handle, int number_of_navigations, IPC::Message* reply_message) {
3281 if (tab_tracker_->ContainsHandle(handle)) {
3282 NavigationController* tab = tab_tracker_->GetResource(handle);
3283 Browser* browser = FindAndActivateTab(tab);
3284 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013285 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3286 false);
[email protected]1126a1d32009-08-26 15:39:263287 browser->GoForward(CURRENT_TAB);
3288 return;
3289 }
3290 }
3291
3292 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3293 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3294 Send(reply_message);
3295}
3296
[email protected]f7a68432009-07-29 23:18:193297RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3298 if (tab_tracker_->ContainsHandle(tab_handle)) {
3299 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3300 if (!tab) {
3301 NOTREACHED();
3302 return NULL;
3303 }
3304
3305 TabContents* tab_contents = tab->tab_contents();
3306 if (!tab_contents) {
3307 NOTREACHED();
3308 return NULL;
3309 }
3310
3311 RenderViewHost* view_host = tab_contents->render_view_host();
3312 return view_host;
3313 }
3314
3315 return NULL;
3316}
[email protected]675595f2009-08-26 22:32:043317
3318void AutomationProvider::GetBrowserForWindow(int window_handle,
3319 bool* success,
3320 int* browser_handle) {
3321 *success = false;
3322 *browser_handle = 0;
3323
3324 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3325 if (!window)
3326 return;
3327
3328 BrowserList::const_iterator iter = BrowserList::begin();
3329 for (;iter != BrowserList::end(); ++iter) {
3330 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3331 if (window == this_window) {
3332 // Add() returns the existing handle for the resource if any.
3333 *browser_handle = browser_tracker_->Add(*iter);
3334 *success = true;
3335 return;
3336 }
3337 }
3338}
[email protected]d11c8e92009-10-20 23:26:403339
3340void AutomationProvider::InstallExtension(const FilePath& crx_path,
3341 IPC::Message* reply_message) {
3342 ExtensionsService* service = profile_->GetExtensionsService();
3343 if (service) {
3344 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193345 new ExtensionInstallNotificationObserver(this,
3346 AutomationMsg_InstallExtension::ID,
3347 reply_message);
[email protected]d11c8e92009-10-20 23:26:403348
3349 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163350 scoped_refptr<CrxInstaller> installer(
3351 new CrxInstaller(install_dir,
3352 service,
3353 NULL)); // silent install, no UI
3354 installer->set_allow_privilege_increase(true);
3355 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403356 } else {
3357 AutomationMsg_InstallExtension::WriteReplyParams(
3358 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3359 Send(reply_message);
3360 }
3361}
3362
3363void AutomationProvider::LoadExpandedExtension(
3364 const FilePath& extension_dir,
3365 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383366 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403367 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193368 new ExtensionInstallNotificationObserver(
3369 this,
3370 AutomationMsg_LoadExpandedExtension::ID,
3371 reply_message);
[email protected]d11c8e92009-10-20 23:26:403372
3373 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403374 } else {
3375 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3376 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3377 Send(reply_message);
3378 }
3379}
[email protected]673fd2c02010-02-04 23:10:003380
[email protected]a1e62d12010-03-16 02:18:433381void AutomationProvider::GetEnabledExtensions(
3382 std::vector<FilePath>* result) {
3383 ExtensionsService* service = profile_->GetExtensionsService();
3384 DCHECK(service);
3385 if (service->extensions_enabled()) {
3386 const ExtensionList* extensions = service->extensions();
3387 DCHECK(extensions);
3388 for (size_t i = 0; i < extensions->size(); ++i) {
3389 Extension* extension = (*extensions)[i];
3390 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123391 if (extension->location() == Extension::INTERNAL ||
3392 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073393 result->push_back(extension->path());
3394 }
[email protected]a1e62d12010-03-16 02:18:433395 }
3396 }
3397}
3398
[email protected]790788ac2010-04-06 17:52:193399void AutomationProvider::WaitForExtensionTestResult(
3400 IPC::Message* reply_message) {
3401 DCHECK(reply_message_ == NULL);
3402 reply_message_ = reply_message;
3403 // Call MaybeSendResult, because the result might have come in before
3404 // we were waiting on it.
3405 extension_test_result_observer_->MaybeSendResult();
3406}
3407
3408void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093409 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193410 ExtensionsService* service = profile_->GetExtensionsService();
3411 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3412 if (service && manager) {
3413 // The observer will delete itself when done.
3414 new ExtensionReadyNotificationObserver(
3415 manager,
3416 this,
3417 AutomationMsg_InstallExtensionAndGetHandle::ID,
3418 reply_message);
3419
[email protected]d7e5525d2010-04-20 14:37:093420 ExtensionInstallUI* client =
3421 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193422 scoped_refptr<CrxInstaller> installer(
3423 new CrxInstaller(service->install_directory(),
3424 service,
[email protected]d7e5525d2010-04-20 14:37:093425 client));
[email protected]790788ac2010-04-06 17:52:193426 installer->set_allow_privilege_increase(true);
3427 installer->InstallCrx(crx_path);
3428 } else {
3429 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3430 reply_message, 0);
3431 Send(reply_message);
3432 }
3433}
3434
3435void AutomationProvider::UninstallExtension(int extension_handle,
3436 bool* success) {
3437 *success = false;
3438 Extension* extension = GetExtension(extension_handle);
3439 ExtensionsService* service = profile_->GetExtensionsService();
3440 if (extension && service) {
3441 ExtensionUnloadNotificationObserver observer;
3442 service->UninstallExtension(extension->id(), false);
3443 // The extension unload notification should have been sent synchronously
3444 // with the uninstall. Just to be safe, check that it was received.
3445 *success = observer.did_receive_unload_notification();
3446 }
3447}
3448
3449void AutomationProvider::EnableExtension(int extension_handle,
3450 IPC::Message* reply_message) {
3451 Extension* extension = GetDisabledExtension(extension_handle);
3452 ExtensionsService* service = profile_->GetExtensionsService();
3453 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3454 // Only enable if this extension is disabled.
3455 if (extension && service && manager) {
3456 // The observer will delete itself when done.
3457 new ExtensionReadyNotificationObserver(
3458 manager,
3459 this,
3460 AutomationMsg_EnableExtension::ID,
3461 reply_message);
3462 service->EnableExtension(extension->id());
3463 } else {
3464 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3465 Send(reply_message);
3466 }
3467}
3468
3469void AutomationProvider::DisableExtension(int extension_handle,
3470 bool* success) {
3471 *success = false;
3472 Extension* extension = GetEnabledExtension(extension_handle);
3473 ExtensionsService* service = profile_->GetExtensionsService();
3474 if (extension && service) {
3475 ExtensionUnloadNotificationObserver observer;
3476 service->DisableExtension(extension->id());
3477 // The extension unload notification should have been sent synchronously
3478 // with the disable. Just to be safe, check that it was received.
3479 *success = observer.did_receive_unload_notification();
3480 }
3481}
3482
3483void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3484 int extension_handle, int browser_handle,
3485 IPC::Message* reply_message) {
3486 bool success = false;
3487 Extension* extension = GetEnabledExtension(extension_handle);
3488 ExtensionsService* service = profile_->GetExtensionsService();
3489 ExtensionMessageService* message_service =
3490 profile_->GetExtensionMessageService();
3491 Browser* browser = browser_tracker_->GetResource(browser_handle);
3492 if (extension && service && message_service && browser) {
3493 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3494 if (extension->page_action()) {
3495 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3496 browser->profile(), extension->id(), "action", tab_id, "", 1);
3497 success = true;
3498 } else if (extension->browser_action()) {
3499 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3500 browser->profile(), extension->id(), browser);
3501 success = true;
3502 }
3503 }
3504 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3505 reply_message, success);
3506 Send(reply_message);
3507}
3508
3509void AutomationProvider::MoveExtensionBrowserAction(
3510 int extension_handle, int index, bool* success) {
3511 *success = false;
3512 Extension* extension = GetEnabledExtension(extension_handle);
3513 ExtensionsService* service = profile_->GetExtensionsService();
3514 if (extension && service) {
3515 ExtensionToolbarModel* toolbar = service->toolbar_model();
3516 if (toolbar) {
3517 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3518 toolbar->MoveBrowserAction(extension, index);
3519 *success = true;
3520 } else {
3521 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3522 }
3523 }
3524 }
3525}
3526
3527void AutomationProvider::GetExtensionProperty(
3528 int extension_handle,
3529 AutomationMsg_ExtensionProperty type,
3530 bool* success,
3531 std::string* value) {
3532 *success = false;
3533 Extension* extension = GetExtension(extension_handle);
3534 ExtensionsService* service = profile_->GetExtensionsService();
3535 if (extension && service) {
3536 ExtensionToolbarModel* toolbar = service->toolbar_model();
3537 int found_index = -1;
3538 int index = 0;
3539 switch (type) {
3540 case AUTOMATION_MSG_EXTENSION_ID:
3541 *value = extension->id();
3542 *success = true;
3543 break;
3544 case AUTOMATION_MSG_EXTENSION_NAME:
3545 *value = extension->name();
3546 *success = true;
3547 break;
3548 case AUTOMATION_MSG_EXTENSION_VERSION:
3549 *value = extension->VersionString();
3550 *success = true;
3551 break;
3552 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3553 if (toolbar) {
3554 for (ExtensionList::const_iterator iter = toolbar->begin();
3555 iter != toolbar->end(); iter++) {
3556 // Skip this extension if we are in incognito mode
3557 // and it is not incognito-enabled.
3558 if (profile_->IsOffTheRecord() &&
3559 !service->IsIncognitoEnabled(*iter))
3560 continue;
3561 if (*iter == extension) {
3562 found_index = index;
3563 break;
3564 }
3565 index++;
3566 }
[email protected]528c56d2010-07-30 19:28:443567 *value = base::IntToString(found_index);
[email protected]790788ac2010-04-06 17:52:193568 *success = true;
3569 }
3570 break;
3571 default:
3572 LOG(WARNING) << "Trying to get undefined extension property";
3573 break;
3574 }
3575 }
3576}
3577
[email protected]673fd2c02010-02-04 23:10:003578void AutomationProvider::SaveAsAsync(int tab_handle) {
3579 NavigationController* tab = NULL;
3580 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3581 if (tab_contents)
3582 tab_contents->OnSavePage();
3583}
[email protected]7dad3d5f2010-03-04 00:27:013584
3585void AutomationProvider::SetContentSetting(
3586 int handle,
3587 const std::string& host,
3588 ContentSettingsType content_type,
3589 ContentSetting setting,
3590 bool* success) {
3591 *success = false;
3592 if (browser_tracker_->ContainsHandle(handle)) {
3593 Browser* browser = browser_tracker_->GetResource(handle);
3594 HostContentSettingsMap* map =
3595 browser->profile()->GetHostContentSettingsMap();
3596 if (host.empty()) {
3597 map->SetDefaultContentSetting(content_type, setting);
3598 } else {
[email protected]0314ae02010-04-08 09:18:293599 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
[email protected]ca352452010-08-06 11:14:093600 content_type, "", setting);
[email protected]7dad3d5f2010-03-04 00:27:013601 }
3602 *success = true;
3603 }
3604}
[email protected]cc824372010-03-31 15:33:013605
[email protected]d7e5525d2010-04-20 14:37:093606void AutomationProvider::ResetToDefaultTheme() {
3607 profile_->ClearTheme();
3608}