blob: df2cf14ec711d8e891b2c396c035dffc821fbd4c [file] [log] [blame]
[email protected]3b5f7022010-03-25 20:37:401// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]202e7a72009-06-15 03:48:369#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3110#include "app/message_box_flags.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]7060bb292010-06-24 00:52:4912#include "base/file_path.h"
[email protected]c6cb1992009-04-13 16:45:2913#include "base/file_version_info.h"
[email protected]93d49d72009-10-23 20:00:2014#include "base/json/json_reader.h"
[email protected]59a611242010-04-02 02:24:0415#include "base/json/json_writer.h"
[email protected]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]5fac9622009-02-04 21:49:3822#include "base/thread.h"
[email protected]6d8ffc9f2010-03-12 18:27:5323#include "base/utf_string_conversions.h"
[email protected]a7eee32f2009-05-22 18:08:1724#include "base/values.h"
[email protected]4f3dc372009-02-24 00:10:2925#include "chrome/app/chrome_dll_resource.h"
[email protected]bcff05a2010-04-14 01:46:4326#include "chrome/app/chrome_version_info.h"
[email protected]0bfa713f2009-04-07 20:18:2827#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0928#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]790788ac2010-04-06 17:52:1929#include "chrome/browser/automation/automation_extension_tracker.h"
initial.commit09911bf2008-07-26 23:55:2930#include "chrome/browser/automation/automation_provider_list.h"
[email protected]e12de87e2009-08-28 00:02:0831#include "chrome/browser/automation/automation_provider_observers.h"
[email protected]f44265b2009-05-19 18:52:5032#include "chrome/browser/automation/extension_port_container.h"
[email protected]66ba4932009-06-04 19:22:1333#include "chrome/browser/blocked_popup_container.h"
[email protected]6d8ffc9f2010-03-12 18:27:5334#include "chrome/browser/bookmarks/bookmark_model.h"
35#include "chrome/browser/bookmarks/bookmark_storage.h"
[email protected]ef413ca2010-05-25 21:09:1436#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0737#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3938#include "chrome/browser/browser_window.h"
[email protected]bc73b4e52010-03-26 04:16:2039#include "chrome/browser/browsing_data_remover.h"
[email protected]f83f9102010-05-04 17:01:0540#include "chrome/browser/character_encoding.h"
[email protected]fae20792009-10-28 20:31:5841#include "chrome/browser/chrome_thread.h"
initial.commit09911bf2008-07-26 23:55:2942#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1243#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5944#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2245#include "chrome/browser/download/download_shelf.h"
[email protected]f83f9102010-05-04 17:01:0546#include "chrome/browser/download/save_package.h"
[email protected]d11c8e92009-10-20 23:26:4047#include "chrome/browser/extensions/crx_installer.h"
[email protected]790788ac2010-04-06 17:52:1948#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]ef413ca2010-05-25 21:09:1449#include "chrome/browser/extensions/extension_host.h"
[email protected]d11c8e92009-10-20 23:26:4050#include "chrome/browser/extensions/extension_install_ui.h"
[email protected]a9024892009-06-16 23:13:5551#include "chrome/browser/extensions/extension_message_service.h"
[email protected]790788ac2010-04-06 17:52:1952#include "chrome/browser/extensions/extension_tabs_module.h"
53#include "chrome/browser/extensions/extension_toolbar_model.h"
54#include "chrome/browser/extensions/extensions_service.h"
[email protected]8cb5d5b2010-02-09 11:36:1655#include "chrome/browser/extensions/user_script_master.h"
[email protected]4801ecc2009-04-05 04:52:5856#include "chrome/browser/find_bar.h"
57#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2958#include "chrome/browser/find_notification_details.h"
[email protected]7dad3d5f2010-03-04 00:27:0159#include "chrome/browser/host_content_settings_map.h"
[email protected]0ac83682010-01-22 17:46:2760#include "chrome/browser/io_thread.h"
[email protected]13869dd2009-05-05 00:40:0661#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0162#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5363#include "chrome/browser/net/url_request_mock_util.h"
[email protected]14a000d2010-04-29 21:44:2464#include "chrome/browser/platform_util.h"
[email protected]052313b2010-02-19 09:43:0865#include "chrome/browser/pref_service.h"
[email protected]f83f9102010-05-04 17:01:0566#include "chrome/browser/printing/print_job.h"
[email protected]a7eee32f2009-05-22 18:08:1767#include "chrome/browser/profile_manager.h"
[email protected]1db6ff152009-10-12 15:32:0768#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]6524b5f92009-01-22 17:48:2569#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0370#include "chrome/browser/ssl/ssl_manager.h"
71#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3472#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4573#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1774#include "chrome/common/automation_constants.h"
[email protected]a9ff2c02010-05-13 17:33:0575#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2976#include "chrome/common/chrome_paths.h"
[email protected]790788ac2010-04-06 17:52:1977#include "chrome/common/extensions/extension.h"
[email protected]a7eee32f2009-05-22 18:08:1778#include "chrome/common/json_value_serializer.h"
[email protected]68d2a05f2010-05-07 21:39:5579#include "chrome/common/net/url_request_context_getter.h"
[email protected]1c58a5c2009-05-21 18:47:1480#include "chrome/common/notification_service.h"
[email protected]1bb5f892009-10-06 01:44:5781#include "chrome/common/pref_names.h"
[email protected]f5bf8ccf2010-02-05 18:19:2582#include "chrome/common/url_constants.h"
[email protected]71f65dd2009-02-11 19:14:5683#include "chrome/test/automation/automation_messages.h"
[email protected]1bb5f892009-10-06 01:44:5784#include "chrome/test/automation/tab_proxy.h"
[email protected]a7eee32f2009-05-22 18:08:1785#include "net/proxy/proxy_service.h"
86#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2187#include "net/url_request/url_request_context.h"
[email protected]1b5a48c2010-04-29 23:08:3088#include "chrome/browser/automation/ui_controls.h"
[email protected]9a08bcf2009-08-12 19:56:2889#include "views/event.h"
[email protected]f7d48012010-05-06 08:17:0590#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2991
[email protected]de246f52009-02-25 18:25:4592#if defined(OS_WIN)
[email protected]4bdde602010-06-16 03:17:3593#include "chrome/browser/external_tab_container_win.h"
[email protected]de246f52009-02-25 18:25:4594#endif // defined(OS_WIN)
95
[email protected]e1acf6f2008-10-27 20:43:3396using base::Time;
97
[email protected]cbab76d2008-10-13 22:42:4798class AutomationInterstitialPage : public InterstitialPage {
99 public:
[email protected]57c6a652009-05-04 07:58:34100 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47101 const GURL& url,
102 const std::string& contents)
103 : InterstitialPage(tab, true, url),
104 contents_(contents) {
105 }
106
107 virtual std::string GetHTMLContents() { return contents_; }
108
109 private:
110 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29111
[email protected]cbab76d2008-10-13 22:42:47112 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
113};
114
[email protected]c2cb8542009-08-20 21:16:51115class ClickTask : public Task {
116 public:
[email protected]fc2e0872009-08-21 22:14:41117 explicit ClickTask(int flags) : flags_(flags) {}
[email protected]c2cb8542009-08-20 21:16:51118 virtual ~ClickTask() {}
119
120 virtual void Run() {
121 ui_controls::MouseButton button = ui_controls::LEFT;
122 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
123 views::Event::EF_LEFT_BUTTON_DOWN) {
124 button = ui_controls::LEFT;
125 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
126 views::Event::EF_RIGHT_BUTTON_DOWN) {
127 button = ui_controls::RIGHT;
128 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
129 views::Event::EF_MIDDLE_BUTTON_DOWN) {
130 button = ui_controls::MIDDLE;
131 } else {
132 NOTREACHED();
133 }
134
[email protected]fc2e0872009-08-21 22:14:41135 ui_controls::SendMouseClick(button);
[email protected]c2cb8542009-08-20 21:16:51136 }
137
138 private:
[email protected]c2cb8542009-08-20 21:16:51139 int flags_;
140
141 DISALLOW_COPY_AND_ASSIGN(ClickTask);
142};
[email protected]c2cb8542009-08-20 21:16:51143
initial.commit09911bf2008-07-26 23:55:29144AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57145 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56146 profile_(profile),
[email protected]cc824372010-03-31 15:33:01147 reply_message_(NULL),
148 popup_menu_waiter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29149 browser_tracker_.reset(new AutomationBrowserTracker(this));
[email protected]790788ac2010-04-06 17:52:19150 extension_tracker_.reset(new AutomationExtensionTracker(this));
initial.commit09911bf2008-07-26 23:55:29151 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20152 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29153 autocomplete_edit_tracker_.reset(
154 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29155 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
156 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
[email protected]84abba62009-10-07 17:01:44157 metric_event_duration_observer_.reset(new MetricEventDurationObserver());
[email protected]790788ac2010-04-06 17:52:19158 extension_test_result_observer_.reset(
159 new ExtensionTestResultNotificationObserver(this));
[email protected]528211a2010-01-14 15:25:13160 g_browser_process->AddRefModule();
initial.commit09911bf2008-07-26 23:55:29161}
162
163AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50164 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
165 port_containers_.end());
166 port_containers_.clear();
167
[email protected]0da050b92008-08-19 19:29:47168 // Make sure that any outstanding NotificationObservers also get destroyed.
169 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31170 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47171 while ((observer = it.GetNext()) != NULL)
172 delete observer;
[email protected]528211a2010-01-14 15:25:13173
174 if (channel_.get()) {
175 channel_->Close();
176 }
177 g_browser_process->ReleaseModule();
initial.commit09911bf2008-07-26 23:55:29178}
179
[email protected]9a3a293b2009-06-04 22:28:16180void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06181 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57182 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06183 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
184 automation_resource_message_filter_,
185 g_browser_process->io_thread()->message_loop(),
186 true, g_browser_process->shutdown_event()));
[email protected]bcff05a2010-04-14 01:46:43187 scoped_ptr<FileVersionInfo> version_info(
188 chrome_app::GetChromeVersionInfo());
[email protected]cf620752009-04-24 17:05:40189 std::string version_string;
[email protected]bcff05a2010-04-14 01:46:43190 if (version_info != NULL) {
191 version_string = WideToASCII(version_info->file_version());
[email protected]cf620752009-04-24 17:05:40192 }
[email protected]c6cb1992009-04-13 16:45:29193
194 // Send a hello message with our current automation protocol version.
195 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29196}
197
198void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
199 if (expected_tabs == 0) {
200 Send(new AutomationMsg_InitialLoadsComplete(0));
201 } else {
202 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
203 }
204}
205
206NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58207 NavigationController* tab, IPC::Message* reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01208 int number_of_navigations, bool include_current_navigation) {
initial.commit09911bf2008-07-26 23:55:29209 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58210 new NavigationNotificationObserver(tab, this, reply_message,
[email protected]7dad3d5f2010-03-04 00:27:01211 number_of_navigations,
212 include_current_navigation);
initial.commit09911bf2008-07-26 23:55:29213
[email protected]71f65dd2009-02-11 19:14:56214 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29215 return observer;
216}
217
[email protected]faf2ee42010-05-11 14:26:17218void AutomationProvider::RemoveNavigationStatusListener(
219 NotificationObserver* obs) {
220 notification_observer_list_.RemoveObserver(obs);
221}
222
initial.commit09911bf2008-07-26 23:55:29223NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14224 Browser* parent,
225 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56226 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14227 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29228 notification_observer_list_.AddObserver(observer);
229
230 return observer;
231}
232
[email protected]faf2ee42010-05-11 14:26:17233void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
initial.commit09911bf2008-07-26 23:55:29234 notification_observer_list_.RemoveObserver(obs);
235}
236
237void AutomationProvider::AddLoginHandler(NavigationController* tab,
238 LoginHandler* handler) {
239 login_handler_map_[tab] = handler;
240}
241
242void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
243 DCHECK(login_handler_map_[tab]);
244 login_handler_map_.erase(tab);
245}
246
[email protected]f44265b2009-05-19 18:52:50247void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
248 int port_id = port->port_id();
249 DCHECK_NE(-1, port_id);
250 DCHECK(port_containers_.find(port_id) == port_containers_.end());
251
252 port_containers_[port_id] = port;
253}
254
255void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
256 int port_id = port->port_id();
257 DCHECK_NE(-1, port_id);
258
259 PortContainerMap::iterator it = port_containers_.find(port_id);
260 DCHECK(it != port_containers_.end());
261
262 if (it != port_containers_.end()) {
263 delete it->second;
264 port_containers_.erase(it);
265 }
266}
267
268ExtensionPortContainer* AutomationProvider::GetPortContainer(
269 int port_id) const {
270 PortContainerMap::const_iterator it = port_containers_.find(port_id);
271 if (it == port_containers_.end())
272 return NULL;
273
274 return it->second;
275}
276
initial.commit09911bf2008-07-26 23:55:29277int AutomationProvider::GetIndexForNavigationController(
278 const NavigationController* controller, const Browser* parent) const {
279 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12280 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29281}
282
[email protected]790788ac2010-04-06 17:52:19283int AutomationProvider::AddExtension(Extension* extension) {
284 DCHECK(extension);
285 return extension_tracker_->Add(extension);
286}
287
288Extension* AutomationProvider::GetExtension(int extension_handle) {
289 return extension_tracker_->GetResource(extension_handle);
290}
291
292Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
293 Extension* extension = extension_tracker_->GetResource(extension_handle);
294 ExtensionsService* service = profile_->GetExtensionsService();
295 if (extension && service &&
296 service->GetExtensionById(extension->id(), false))
297 return extension;
298 return NULL;
299}
300
301Extension* AutomationProvider::GetDisabledExtension(int extension_handle) {
302 Extension* extension = extension_tracker_->GetResource(extension_handle);
303 ExtensionsService* service = profile_->GetExtensionsService();
304 if (extension && service &&
305 service->GetExtensionById(extension->id(), true) &&
306 !service->GetExtensionById(extension->id(), false))
307 return extension;
308 return NULL;
309}
310
initial.commit09911bf2008-07-26 23:55:29311void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
312 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14313 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56314 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
315 CloseBrowserAsync)
316 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
317 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
318 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
319 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
320 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
321 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]5fa57942010-04-21 23:07:22322 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
[email protected]1c58a5c2009-05-21 18:47:14323 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:58324 IPC_MESSAGE_HANDLER_DELAY_REPLY(
325 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
326 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:56327 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
[email protected]c70f9b82010-04-21 07:31:11328 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
329 NavigationAsyncWithDisposition)
[email protected]71f65dd2009-02-11 19:14:56330 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
331 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
332 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
333 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14334 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56335 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
336 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
337 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14338 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29339 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
340 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56341 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36342 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56343 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29344 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56345 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29346 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
347 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56348 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14349 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]8dd404bb2009-09-22 19:57:24350 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
[email protected]49a14a82009-03-31 04:16:44351 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33352 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44353 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33354 ExecuteBrowserCommand)
[email protected]8dd404bb2009-09-22 19:57:24355 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
[email protected]1c58a5c2009-05-21 18:47:14356 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8dd404bb2009-09-22 19:57:24357 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
[email protected]8f04ff92009-07-08 02:37:15358 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14359 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]d1a5941e2009-08-13 23:34:24360 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]60507b12009-11-02 23:51:35361 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
[email protected]1c58a5c2009-05-21 18:47:14362 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]1b5a48c2010-04-29 23:08:30363#if !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56364 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
365 WindowSimulateDrag)
[email protected]1b5a48c2010-04-29 23:08:30366#endif // !defined(OS_MACOSX)
[email protected]71f65dd2009-02-11 19:14:56367 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
[email protected]982921f12009-10-27 21:43:53368 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
[email protected]71f65dd2009-02-11 19:14:56369 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37370#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56371 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45372#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56373 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
374 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03375 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56376 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14377 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
[email protected]34930432009-11-09 00:12:09378 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
379 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
380 GetFullscreenBubbleVisibility)
initial.commit09911bf2008-07-26 23:55:29381 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14382 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56383 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
384 ExecuteJavascript)
385 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29386 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14387 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
388 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56389 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
390 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14391 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17392 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14393 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14394 OpenNewBrowserWindow)
[email protected]982921f12009-10-27 21:43:53395 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
396 OpenNewBrowserWindowOfType)
[email protected]1c58a5c2009-05-21 18:47:14397 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56398 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14399 GetAutocompleteEditForBrowser)
400 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]71f65dd2009-02-11 19:14:56401 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14402 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56403 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14404 HideInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56405 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
406 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:14407 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
408 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]84abba62009-10-07 17:01:44409 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
410 GetMetricEventDuration)
[email protected]71f65dd2009-02-11 19:14:56411 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
412 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29413 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
414 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
415 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56416 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:41417 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:56418 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
419 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29420 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56421 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29422 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56423 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29424 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:56425 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:29426 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:56427 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:45428 HandleOpenFindInPageRequest)
[email protected]1c58a5c2009-05-21 18:47:14429 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:56430 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:57431 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:56432 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:57433 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:56434 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
435 GetBookmarkBarVisibility)
[email protected]6d8ffc9f2010-03-12 18:27:53436 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
437 GetBookmarksAsJSON)
438 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
439 WaitForBookmarkModelToLoad)
440 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
441 AddBookmarkGroup)
442 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
443 AddBookmarkURL)
444 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
445 ReparentBookmark)
446 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
447 SetBookmarkTitle)
448 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
449 SetBookmarkURL)
450 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
451 RemoveBookmark)
[email protected]59a611242010-04-02 02:24:04452 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
453 SendJSONRequest)
[email protected]816633a2009-11-11 21:48:18454 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
455 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
456 ClickInfoBarAccept)
[email protected]71f65dd2009-02-11 19:14:56457 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:42458 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:56459 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
460 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:14461 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:56462 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:44463 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:56464 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:20465 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:14466 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:56467 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16468 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56469 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:16470 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:56471 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:16472 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:14473 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20474 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
475 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:14476 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]59560e0b2009-06-04 03:30:22477 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:13478 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:19479 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
480 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
481 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
482 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
483 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
484 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:52485 IPC_MESSAGE_HANDLER_DELAY_REPLY(
486 AutomationMsg_WaitForBrowserWindowCountToBecome,
487 WaitForBrowserWindowCountToBecome)
488 IPC_MESSAGE_HANDLER_DELAY_REPLY(
489 AutomationMsg_WaitForAppModalDialogToBeShown,
490 WaitForAppModalDialogToBeShown)
[email protected]1126a1d32009-08-26 15:39:26491 IPC_MESSAGE_HANDLER_DELAY_REPLY(
492 AutomationMsg_GoBackBlockUntilNavigationsComplete,
493 GoBackBlockUntilNavigationsComplete)
494 IPC_MESSAGE_HANDLER_DELAY_REPLY(
495 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
496 GoForwardBlockUntilNavigationsComplete)
[email protected]1bb5f892009-10-06 01:44:57497 IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
[email protected]d11c8e92009-10-20 23:26:40498 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
499 InstallExtension)
500 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
501 LoadExpandedExtension)
[email protected]a1e62d12010-03-16 02:18:43502 IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
503 GetEnabledExtensions)
[email protected]790788ac2010-04-06 17:52:19504 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
505 WaitForExtensionTestResult)
506 IPC_MESSAGE_HANDLER_DELAY_REPLY(
507 AutomationMsg_InstallExtensionAndGetHandle,
508 InstallExtensionAndGetHandle)
509 IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
510 UninstallExtension)
511 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
512 EnableExtension)
513 IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
514 DisableExtension)
515 IPC_MESSAGE_HANDLER_DELAY_REPLY(
516 AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
517 ExecuteExtensionActionInActiveTabAsync)
518 IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
519 MoveExtensionBrowserAction)
520 IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
521 GetExtensionProperty)
[email protected]fedaa7d2010-01-26 20:34:57522 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
523 ShutdownSessionService)
[email protected]673fd2c02010-02-04 23:10:00524 IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
[email protected]7dad3d5f2010-03-04 00:27:01525 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
[email protected]bc73b4e52010-03-26 04:16:20526 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
[email protected]bdd5a9c92010-06-14 18:21:00527 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
[email protected]cc824372010-03-31 15:33:01528#if defined(TOOLKIT_VIEWS)
529 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
530 WaitForFocusedViewIDToChange)
531 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
532 StartTrackingPopupMenus)
533 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
534 WaitForPopupMenuToOpen)
[email protected]bdd5a9c92010-06-14 18:21:00535#endif // defined(TOOLKIT_VIEWS)
[email protected]52415f842010-06-10 21:51:52536#if defined(OS_WIN)
537 // These are for use with external tabs.
538 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
539 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
540 ProcessUnhandledAccelerator)
541 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
542 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
543 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
544 OnForwardContextMenuCommandToChrome)
545 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
546 NavigateInExternalTab)
547 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
548 NavigateExternalTabAtIndex)
549 IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
550 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
551 SetEnableExtensionAutomation)
552 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
553 OnMessageFromExternalHost)
[email protected]bdd5a9c92010-06-14 18:21:00554 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
555#endif // defined(OS_WIN)
556#if defined(OS_CHROMEOS)
557 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
558 LoginWithUserAndPass)
559#endif // defined(OS_CHROMEOS)
initial.commit09911bf2008-07-26 23:55:29560 IPC_END_MESSAGE_MAP()
561}
562
[email protected]71f65dd2009-02-11 19:14:56563void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
564 *status = -1;
initial.commit09911bf2008-07-26 23:55:29565 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
566 Browser* browser = browser_tracker_->GetResource(handle);
567 if (at_index >= 0 && at_index < browser->tab_count()) {
568 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:56569 *status = 0;
initial.commit09911bf2008-07-26 23:55:29570 }
571 }
initial.commit09911bf2008-07-26 23:55:29572}
573
[email protected]71f65dd2009-02-11 19:14:56574void AutomationProvider::AppendTab(int handle, const GURL& url,
575 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29576 int append_tab_response = -1; // -1 is the error code
577 NotificationObserver* observer = NULL;
578
579 if (browser_tracker_->ContainsHandle(handle)) {
580 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:14581 observer = AddTabStripObserver(browser, reply_message);
[email protected]715af7e2010-04-29 01:55:38582 TabContents* tab_contents = browser->AddTabWithURL(
[email protected]4a1665442010-06-28 16:09:39583 url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED,
584 NULL, std::string());
initial.commit09911bf2008-07-26 23:55:29585 if (tab_contents) {
586 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:57587 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:29588 }
589 }
590
591 if (append_tab_response < 0) {
592 // The append tab failed. Remove the TabStripObserver
593 if (observer) {
[email protected]faf2ee42010-05-11 14:26:17594 RemoveTabStripObserver(observer);
initial.commit09911bf2008-07-26 23:55:29595 delete observer;
596 }
597
[email protected]71f65dd2009-02-11 19:14:56598 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
599 append_tab_response);
600 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29601 }
602}
603
[email protected]71f65dd2009-02-11 19:14:56604void AutomationProvider::NavigateToURL(int handle, const GURL& url,
605 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:58606 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
607}
608
609void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
610 int handle, const GURL& url, int number_of_navigations,
611 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29612 if (tab_tracker_->ContainsHandle(handle)) {
613 NavigationController* tab = tab_tracker_->GetResource(handle);
614
615 // Simulate what a user would do. Activate the tab and then navigate.
616 // We could allow navigating in a background tab in future.
617 Browser* browser = FindAndActivateTab(tab);
618
619 if (browser) {
[email protected]7dad3d5f2010-03-04 00:27:01620 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
621 false);
[email protected]71f65dd2009-02-11 19:14:56622
initial.commit09911bf2008-07-26 23:55:29623 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50624 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29625 return;
626 }
627 }
[email protected]71f65dd2009-02-11 19:14:56628
629 AutomationMsg_NavigateToURL::WriteReplyParams(
630 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
631 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29632}
[email protected]2949e90d2009-08-21 15:32:52633
[email protected]c70f9b82010-04-21 07:31:11634void AutomationProvider::NavigationAsync(int handle,
635 const GURL& url,
636 bool* status) {
637 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
638}
639
640void AutomationProvider::NavigationAsyncWithDisposition(
641 int handle,
642 const GURL& url,
643 WindowOpenDisposition disposition,
644 bool* status) {
[email protected]71f65dd2009-02-11 19:14:56645 *status = false;
initial.commit09911bf2008-07-26 23:55:29646
647 if (tab_tracker_->ContainsHandle(handle)) {
648 NavigationController* tab = tab_tracker_->GetResource(handle);
649
650 // Simulate what a user would do. Activate the tab and then navigate.
651 // We could allow navigating in a background tab in future.
652 Browser* browser = FindAndActivateTab(tab);
653
654 if (browser) {
655 // Don't add any listener unless a callback mechanism is desired.
656 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c70f9b82010-04-21 07:31:11657 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:56658 *status = true;
initial.commit09911bf2008-07-26 23:55:29659 }
660 }
initial.commit09911bf2008-07-26 23:55:29661}
662
[email protected]71f65dd2009-02-11 19:14:56663void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29664 if (tab_tracker_->ContainsHandle(handle)) {
665 NavigationController* tab = tab_tracker_->GetResource(handle);
666 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14667 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:01668 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29669 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29670 return;
671 }
672 }
[email protected]71f65dd2009-02-11 19:14:56673
674 AutomationMsg_GoBack::WriteReplyParams(
675 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
676 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29677}
678
[email protected]71f65dd2009-02-11 19:14:56679void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29680 if (tab_tracker_->ContainsHandle(handle)) {
681 NavigationController* tab = tab_tracker_->GetResource(handle);
682 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14683 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:01684 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]485fba42009-03-24 23:27:29685 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29686 return;
687 }
688 }
[email protected]71f65dd2009-02-11 19:14:56689
690 AutomationMsg_GoForward::WriteReplyParams(
691 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
692 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29693}
694
[email protected]71f65dd2009-02-11 19:14:56695void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29696 if (tab_tracker_->ContainsHandle(handle)) {
697 NavigationController* tab = tab_tracker_->GetResource(handle);
698 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14699 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]7dad3d5f2010-03-04 00:27:01700 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]cb84d642010-06-10 00:56:28701 browser->Reload(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:29702 return;
703 }
704 }
[email protected]71f65dd2009-02-11 19:14:56705
706 AutomationMsg_Reload::WriteReplyParams(
707 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
708 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29709}
710
[email protected]71f65dd2009-02-11 19:14:56711void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:29712 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:56713 const std::wstring& password,
714 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29715 if (tab_tracker_->ContainsHandle(tab_handle)) {
716 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
717 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
718
719 if (iter != login_handler_map_.end()) {
720 // If auth is needed again after this, assume login has failed. This is
721 // not strictly correct, because a navigation can require both proxy and
722 // server auth, but it should be OK for now.
723 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01724 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29725 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:52726 return;
initial.commit09911bf2008-07-26 23:55:29727 }
728 }
[email protected]de246f52009-02-25 18:25:45729
[email protected]457f5cf2009-08-18 16:37:52730 AutomationMsg_SetAuth::WriteReplyParams(
731 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
732 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29733}
734
[email protected]71f65dd2009-02-11 19:14:56735void AutomationProvider::CancelAuth(int tab_handle,
736 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29737 if (tab_tracker_->ContainsHandle(tab_handle)) {
738 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
739 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
740
741 if (iter != login_handler_map_.end()) {
742 // If auth is needed again after this, something is screwy.
743 LoginHandler* handler = iter->second;
[email protected]7dad3d5f2010-03-04 00:27:01744 AddNavigationStatusListener(tab, reply_message, 1, false);
initial.commit09911bf2008-07-26 23:55:29745 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:52746 return;
initial.commit09911bf2008-07-26 23:55:29747 }
748 }
[email protected]de246f52009-02-25 18:25:45749
[email protected]457f5cf2009-08-18 16:37:52750 AutomationMsg_CancelAuth::WriteReplyParams(
751 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
752 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29753}
754
[email protected]71f65dd2009-02-11 19:14:56755void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
756 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:29757
758 if (tab_tracker_->ContainsHandle(tab_handle)) {
759 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
760 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
761
762 if (iter != login_handler_map_.end()) {
763 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:56764 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:29765 }
766 }
initial.commit09911bf2008-07-26 23:55:29767}
768
[email protected]71f65dd2009-02-11 19:14:56769void AutomationProvider::GetRedirectsFrom(int tab_handle,
770 const GURL& source_url,
771 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:29772 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
773 if (tab_tracker_->ContainsHandle(tab_handle)) {
774 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
775 HistoryService* history_service =
776 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
777
778 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
779 "has no history service";
780 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:56781 DCHECK(reply_message_ == NULL);
782 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:29783 // Schedule a history query for redirects. The response will be sent
784 // asynchronously from the callback the history system uses to notify us
785 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:29786 redirect_query_ = history_service->QueryRedirectsFrom(
787 source_url, &consumer_,
788 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
789 return; // Response will be sent when query completes.
790 }
791 }
792
793 // Send failure response.
[email protected]deb57402009-02-06 01:35:30794 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:56795 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
796 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29797}
798
[email protected]71f65dd2009-02-11 19:14:56799void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
800 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:29801 if (browser_tracker_->ContainsHandle(handle)) {
802 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:56803 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:29804 }
initial.commit09911bf2008-07-26 23:55:29805}
806
[email protected]202e7a72009-06-15 03:48:36807void AutomationProvider::GetBrowserLocale(string16* locale) {
808 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:06809 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:36810}
811
[email protected]71f65dd2009-02-11 19:14:56812void AutomationProvider::GetBrowserWindowCount(int* window_count) {
813 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:29814}
815
[email protected]24497032009-05-01 17:00:29816void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
817 *window_count = static_cast<int>(
818 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
819}
820
[email protected]71f65dd2009-02-11 19:14:56821void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
822 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:07823 AppModalDialog* dialog_delegate =
824 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50825 *showing_dialog = (dialog_delegate != NULL);
826 if (*showing_dialog)
827 *dialog_button = dialog_delegate->GetDialogButtons();
828 else
[email protected]478ff2ed2009-04-21 23:49:18829 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:20830}
831
[email protected]71f65dd2009-02-11 19:14:56832void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
833 *success = false;
[email protected]fad84eab2008-12-05 00:37:20834
[email protected]1f460072009-05-28 17:02:07835 AppModalDialog* dialog_delegate =
836 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:50837 if (dialog_delegate &&
838 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:18839 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
840 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:28841 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:56842 *success = true;
[email protected]fad84eab2008-12-05 00:37:20843 }
[email protected]478ff2ed2009-04-21 23:49:18844 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
845 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:56846 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:28847 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:56848 *success = true;
[email protected]fad84eab2008-12-05 00:37:20849 }
850 }
[email protected]c274acc2008-11-11 20:13:44851}
852
[email protected]fedaa7d2010-01-26 20:34:57853void AutomationProvider::ShutdownSessionService(int handle, bool* result) {
854 if (browser_tracker_->ContainsHandle(handle)) {
855 Browser* browser = browser_tracker_->GetResource(handle);
856 browser->profile()->ShutdownSessionService();
857 *result = true;
858 } else {
859 *result = false;
860 }
861}
862
[email protected]71f65dd2009-02-11 19:14:56863void AutomationProvider::GetBrowserWindow(int index, int* handle) {
864 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29865 if (index >= 0) {
866 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]f07467d2010-06-16 14:28:30867 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
initial.commit09911bf2008-07-26 23:55:29868 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:56869 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:29870 }
871 }
initial.commit09911bf2008-07-26 23:55:29872}
873
[email protected]24497032009-05-01 17:00:29874void AutomationProvider::FindNormalBrowserWindow(int* handle) {
875 *handle = 0;
876 Browser* browser = BrowserList::FindBrowserWithType(profile_,
[email protected]62b0b532010-03-26 22:44:31877 Browser::TYPE_NORMAL,
878 false);
[email protected]24497032009-05-01 17:00:29879 if (browser)
880 *handle = browser_tracker_->Add(browser);
881}
882
[email protected]71f65dd2009-02-11 19:14:56883void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
884 *handle = 0;
initial.commit09911bf2008-07-26 23:55:29885 Browser* browser = BrowserList::GetLastActive();
886 if (browser)
[email protected]71f65dd2009-02-11 19:14:56887 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:29888}
889
[email protected]b2aa3ed72010-02-01 18:37:14890#if defined(OS_POSIX)
[email protected]9a08bcf2009-08-12 19:56:28891// TODO(estade): use this implementation for all platforms?
892void AutomationProvider::GetActiveWindow(int* handle) {
893 gfx::NativeWindow window =
894 BrowserList::GetLastActive()->window()->GetNativeHandle();
895 *handle = window_tracker_->Add(window);
896}
897#endif
898
[email protected]4f6381ee2009-04-16 02:46:33899void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
900 bool* success) {
[email protected]71f65dd2009-02-11 19:14:56901 *success = false;
[email protected]4ae62752008-08-04 23:28:47902 if (browser_tracker_->ContainsHandle(handle)) {
903 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:14904 if (browser->command_updater()->SupportsCommand(command) &&
905 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:47906 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:56907 *success = true;
[email protected]4ae62752008-08-04 23:28:47908 }
909 }
[email protected]4ae62752008-08-04 23:28:47910}
911
[email protected]4f6381ee2009-04-16 02:46:33912void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:56913 int handle, int command, IPC::Message* reply_message) {
[email protected]12887da72009-09-16 19:15:53914 // List of commands which just finish synchronously and don't require
915 // setting up an observer.
916 static const int kSynchronousCommands[] = {
917 IDC_HOME,
918 IDC_SELECT_NEXT_TAB,
919 IDC_SELECT_PREVIOUS_TAB,
[email protected]2aa336e2010-04-06 21:05:25920 IDC_SHOW_BOOKMARK_MANAGER,
[email protected]12887da72009-09-16 19:15:53921 };
[email protected]56e71b7c2009-03-27 03:05:56922 if (browser_tracker_->ContainsHandle(handle)) {
923 Browser* browser = browser_tracker_->GetResource(handle);
924 if (browser->command_updater()->SupportsCommand(command) &&
925 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]12887da72009-09-16 19:15:53926 // First check if we can handle the command without using an observer.
927 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
928 if (command == kSynchronousCommands[i]) {
929 browser->ExecuteCommand(command);
930 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
931 true);
932 Send(reply_message);
933 return;
934 }
935 }
936
937 // Use an observer if we have one, otherwise fail.
[email protected]d79ffea2009-05-07 20:51:42938 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
939 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:27940 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:42941 return;
942 }
[email protected]56e71b7c2009-03-27 03:05:56943 }
944 }
[email protected]49a14a82009-03-31 04:16:44945 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:56946 Send(reply_message);
947}
948
[email protected]fc2e0872009-08-21 22:14:41949// This task just adds another task to the event queue. This is useful if
950// you want to ensure that any tasks added to the event queue after this one
951// have already been processed by the time |task| is run.
952class InvokeTaskLaterTask : public Task {
953 public:
954 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
955 virtual ~InvokeTaskLaterTask() {}
956
957 virtual void Run() {
958 MessageLoop::current()->PostTask(FROM_HERE, task_);
959 }
960
961 private:
962 Task* task_;
963
964 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
965};
966
initial.commit09911bf2008-07-26 23:55:29967void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
968 int handle,
[email protected]d1a5941e2009-08-13 23:34:24969 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:29970 int flags) {
[email protected]b410bc32009-08-14 01:11:14971 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:51972 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
[email protected]fc2e0872009-08-21 22:14:41973 new ClickTask(flags));
initial.commit09911bf2008-07-26 23:55:29974 }
975}
976
[email protected]60507b12009-11-02 23:51:35977void AutomationProvider::WindowSimulateMouseMove(const IPC::Message& message,
978 int handle,
979 const gfx::Point& location) {
980 if (window_tracker_->ContainsHandle(handle))
981 ui_controls::SendMouseMove(location.x(), location.y());
982}
983
initial.commit09911bf2008-07-26 23:55:29984void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
985 int handle,
[email protected]bc1407f2009-09-29 00:33:35986 int key,
initial.commit09911bf2008-07-26 23:55:29987 int flags) {
[email protected]b410bc32009-08-14 01:11:14988 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:29989 return;
990
[email protected]b410bc32009-08-14 01:11:14991 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:29992 // The key event is sent to whatever window is active.
[email protected]bc1407f2009-09-29 00:33:35993 ui_controls::SendKeyPress(window, static_cast<base::KeyboardCode>(key),
[email protected]c2dacc92008-10-16 23:51:38994 ((flags & views::Event::EF_CONTROL_DOWN) ==
995 views::Event::EF_CONTROL_DOWN),
996 ((flags & views::Event::EF_SHIFT_DOWN) ==
997 views::Event::EF_SHIFT_DOWN),
998 ((flags & views::Event::EF_ALT_DOWN) ==
[email protected]1b5a48c2010-04-29 23:08:30999 views::Event::EF_ALT_DOWN),
1000 ((flags & views::Event::EF_COMMAND_DOWN) ==
1001 views::Event::EF_COMMAND_DOWN));
initial.commit09911bf2008-07-26 23:55:291002}
initial.commit09911bf2008-07-26 23:55:291003
[email protected]71f65dd2009-02-11 19:14:561004void AutomationProvider::IsWindowActive(int handle, bool* success,
1005 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291006 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171007 *is_active =
1008 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561009 *success = true;
initial.commit09911bf2008-07-26 23:55:291010 } else {
[email protected]71f65dd2009-02-11 19:14:561011 *success = false;
1012 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291013 }
1014}
1015
[email protected]71f65dd2009-02-11 19:14:561016void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1017 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291018
1019 if (browser_tracker_->ContainsHandle(handle)) {
1020 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561021 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291022 }
initial.commit09911bf2008-07-26 23:55:291023}
1024
[email protected]982921f12009-10-27 21:43:531025void AutomationProvider::GetType(int handle, int* type_as_int) {
1026 *type_as_int = -1; // -1 is the error code
1027
1028 if (browser_tracker_->ContainsHandle(handle)) {
1029 Browser* browser = browser_tracker_->GetResource(handle);
1030 *type_as_int = static_cast<int>(browser->type());
1031 }
1032}
1033
[email protected]71f65dd2009-02-11 19:14:561034void AutomationProvider::GetTab(int win_handle, int tab_index,
1035 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561036 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291037 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1038 Browser* browser = browser_tracker_->GetResource(win_handle);
1039 if (tab_index < browser->tab_count()) {
1040 TabContents* tab_contents =
1041 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571042 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291043 }
1044 }
initial.commit09911bf2008-07-26 23:55:291045}
1046
[email protected]71f65dd2009-02-11 19:14:561047void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1048 std::wstring* title) {
1049 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291050 if (tab_tracker_->ContainsHandle(handle)) {
1051 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361052 NavigationEntry* entry = tab->GetActiveEntry();
1053 if (entry != NULL) {
1054 *title = UTF16ToWideHack(entry->title());
1055 } else {
1056 *title = std::wstring();
1057 }
[email protected]71f65dd2009-02-11 19:14:561058 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291059 }
initial.commit09911bf2008-07-26 23:55:291060}
1061
[email protected]77bc6732009-04-20 22:01:031062void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1063 *tabstrip_index = -1; // -1 is the error code
1064
1065 if (tab_tracker_->ContainsHandle(handle)) {
1066 NavigationController* tab = tab_tracker_->GetResource(handle);
1067 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121068 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031069 }
1070}
1071
initial.commit09911bf2008-07-26 23:55:291072void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1073 if (window_tracker_->ContainsHandle(handle)) {
1074 window_tracker_->Remove(window_tracker_->GetResource(handle));
1075 }
1076}
1077
1078void AutomationProvider::OnChannelError() {
[email protected]2947cdcd2009-12-03 21:05:161079 LOG(INFO) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571080 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291081}
1082
1083// TODO(brettw) change this to accept GURLs when history supports it
1084void AutomationProvider::OnRedirectQueryComplete(
1085 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371086 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291087 bool success,
[email protected]379c2b12009-07-01 21:50:331088 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291089 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561090 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291091
[email protected]deb57402009-02-06 01:35:301092 std::vector<GURL> redirects_gurl;
[email protected]0bc24482010-03-05 00:33:101093 reply_message_->WriteBool(success);
initial.commit09911bf2008-07-26 23:55:291094 if (success) {
initial.commit09911bf2008-07-26 23:55:291095 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301096 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291097 }
1098
[email protected]4f3dc372009-02-24 00:10:291099 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301100
[email protected]71f65dd2009-02-11 19:14:561101 Send(reply_message_);
[email protected]6a329462010-05-06 19:22:231102 redirect_query_ = 0;
[email protected]71f65dd2009-02-11 19:14:561103 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291104}
1105
1106bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571107 DCHECK(channel_.get());
1108 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291109}
1110
1111Browser* AutomationProvider::FindAndActivateTab(
1112 NavigationController* controller) {
1113 int tab_index;
1114 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1115 if (browser)
1116 browser->SelectTabContentsAt(tab_index, true);
1117
1118 return browser;
1119}
1120
[email protected]71f65dd2009-02-11 19:14:561121void AutomationProvider::GetCookies(const GURL& url, int handle,
1122 int* value_size,
1123 std::string* value) {
1124 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291125 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1126 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311127
1128 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]70daf0b2010-03-02 19:13:001129 scoped_refptr<URLRequestContextGetter> request_context =
1130 tab->tab_contents()->request_context();
1131 if (!request_context.get())
1132 request_context = tab->profile()->GetRequestContext();
1133
[email protected]34d18e42010-06-21 16:04:501134 net::CookieStore* cookie_store = request_context->GetCookieStore();
1135
1136 *value = cookie_store->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561137 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291138 }
initial.commit09911bf2008-07-26 23:55:291139}
1140
[email protected]71f65dd2009-02-11 19:14:561141void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291142 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561143 int handle,
1144 int* response_value) {
1145 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291146
1147 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1148 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]be180c802009-10-23 06:33:311149
[email protected]dfa46e5f2009-11-17 18:48:431150 scoped_refptr<URLRequestContextGetter> request_context =
1151 tab->tab_contents()->request_context();
1152 if (!request_context.get())
1153 request_context = tab->profile()->GetRequestContext();
1154
[email protected]34d18e42010-06-21 16:04:501155 // Since we are running on the UI thread don't call GetURLRequestContext().
1156 scoped_refptr<net::CookieStore> cookie_store =
1157 request_context->GetCookieStore();
1158
1159 if (cookie_store->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561160 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291161 }
initial.commit09911bf2008-07-26 23:55:291162}
1163
[email protected]5fa57942010-04-21 23:07:221164void AutomationProvider::DeleteCookie(const GURL& url,
1165 const std::string& cookie_name,
1166 int handle, bool* success) {
1167 *success = false;
1168 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1169 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]34d18e42010-06-21 16:04:501170 net::CookieStore* cookie_store =
1171 tab->profile()->GetRequestContext()->GetCookieStore();
1172 cookie_store->DeleteCookie(url, cookie_name);
[email protected]5fa57942010-04-21 23:07:221173 *success = true;
1174 }
1175}
1176
[email protected]71f65dd2009-02-11 19:14:561177void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1178 *success = false;
initial.commit09911bf2008-07-26 23:55:291179 if (tab_tracker_->ContainsHandle(handle)) {
1180 NavigationController* tab = tab_tracker_->GetResource(handle);
1181 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541182 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561183 *success = true;
initial.commit09911bf2008-07-26 23:55:291184 }
initial.commit09911bf2008-07-26 23:55:291185}
1186
[email protected]71f65dd2009-02-11 19:14:561187void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1188 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291189
1190 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561191 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341192 TabContents* tab_contents =
1193 tab_tracker_->GetResource(handle)->tab_contents();
[email protected]8cb5d5b2010-02-09 11:36:161194 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1195 if (rph)
1196 *process_id = base::GetProcId(rph->GetHandle());
initial.commit09911bf2008-07-26 23:55:291197 }
initial.commit09911bf2008-07-26 23:55:291198}
1199
1200void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331201 NOTREACHED() << "This function has been deprecated. "
1202 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291203}
1204
[email protected]71f65dd2009-02-11 19:14:561205void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291206 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561207 const std::wstring& script,
1208 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291209 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341210 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1211 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571212 // Set the routing id of this message with the controller.
1213 // This routing id needs to be remembered for the reverse
1214 // communication while sending back the response of
1215 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331216 std::wstring set_automation_id;
1217 SStringPrintf(&set_automation_id,
1218 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561219 reply_message->routing_id());
1220
1221 DCHECK(reply_message_ == NULL);
1222 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291223
[email protected]57c6a652009-05-04 07:58:341224 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331225 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341226 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061227 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571228 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291229 }
1230
1231 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561232 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1233 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291234 }
1235}
1236
[email protected]71f65dd2009-02-11 19:14:561237void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1238 *visible = false;
[email protected]20e93d12008-08-28 16:31:571239
[email protected]59560e0b2009-06-04 03:30:221240 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]f5bf8ccf2010-02-05 18:19:251241#if defined(OS_CHROMEOS)
1242 // Chromium OS shows FileBrowse ui rather than download shelf. So we
1243 // enumerate all browsers and look for a chrome://filebrowse... pop up.
1244 for (BrowserList::const_iterator it = BrowserList::begin();
1245 it != BrowserList::end(); ++it) {
1246 if ((*it)->type() == Browser::TYPE_POPUP) {
1247 const GURL& url =
1248 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
1249
1250 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1251 url.host() == chrome::kChromeUIFileBrowseHost) {
1252 *visible = true;
1253 break;
1254 }
1255 }
1256 }
1257#else
[email protected]59560e0b2009-06-04 03:30:221258 Browser* browser = browser_tracker_->GetResource(handle);
1259 if (browser) {
1260 *visible = browser->window()->IsDownloadShelfVisible();
1261 }
[email protected]f5bf8ccf2010-02-05 18:19:251262#endif
[email protected]59560e0b2009-06-04 03:30:221263 }
initial.commit09911bf2008-07-26 23:55:291264}
1265
[email protected]59560e0b2009-06-04 03:30:221266void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1267 if (browser_tracker_->ContainsHandle(handle)) {
1268 Browser* browser = browser_tracker_->GetResource(handle);
1269 if (browser) {
1270 if (visible)
1271 browser->window()->GetDownloadShelf()->Show();
1272 else
1273 browser->window()->GetDownloadShelf()->Close();
1274 }
1275 }
1276}
1277
[email protected]34930432009-11-09 00:12:091278void AutomationProvider::IsFullscreen(int handle, bool* visible) {
1279 *visible = false;
1280
1281 if (browser_tracker_->ContainsHandle(handle)) {
1282 Browser* browser = browser_tracker_->GetResource(handle);
1283 if (browser)
1284 *visible = browser->window()->IsFullscreen();
1285 }
1286}
1287
1288void AutomationProvider::GetFullscreenBubbleVisibility(int handle,
1289 bool* visible) {
1290 *visible = false;
1291
1292 if (browser_tracker_->ContainsHandle(handle)) {
1293 Browser* browser = browser_tracker_->GetResource(handle);
1294 if (browser)
1295 *visible = browser->window()->IsFullscreenBubbleVisible();
1296 }
1297}
[email protected]59560e0b2009-06-04 03:30:221298
[email protected]71f65dd2009-02-11 19:14:561299void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1300 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291301 if (tab_tracker_->ContainsHandle(handle)) {
1302 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111303 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291304 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561305 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291306 }
1307 }
initial.commit09911bf2008-07-26 23:55:291308}
1309
initial.commit09911bf2008-07-26 23:55:291310void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561311 int handle, const std::wstring& find_request,
1312 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311313 NOTREACHED() << "This function has been deprecated."
1314 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561315 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311316 return;
1317}
1318
[email protected]4f999132009-03-31 18:08:401319void AutomationProvider::HandleFindRequest(
1320 int handle,
1321 const AutomationMsg_Find_Params& params,
1322 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291323 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561324 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1325 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291326 return;
1327 }
1328
1329 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111330 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291331
1332 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141333 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291334
[email protected]57c6a652009-05-04 07:58:341335 tab_contents->set_current_find_request_id(
1336 FindInPageNotificationObserver::kFindInPageRequestId);
1337 tab_contents->render_view_host()->StartFinding(
1338 FindInPageNotificationObserver::kFindInPageRequestId,
1339 params.search_string, params.forward, params.match_case,
1340 params.find_next);
initial.commit09911bf2008-07-26 23:55:291341}
1342
[email protected]5f8af2a2008-08-06 22:49:451343void AutomationProvider::HandleOpenFindInPageRequest(
1344 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291345 if (browser_tracker_->ContainsHandle(handle)) {
1346 Browser* browser = browser_tracker_->GetResource(handle);
1347 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451348 }
1349}
1350
[email protected]71f65dd2009-02-11 19:14:561351void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]71f65dd2009-02-11 19:14:561352 *visible = false;
[email protected]855c0142009-09-28 22:35:241353 Browser* browser = browser_tracker_->GetResource(handle);
1354 if (browser) {
[email protected]4801ecc2009-04-05 04:52:581355 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171356 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]855c0142009-09-28 22:35:241357 find_bar->GetFindBarWindowInfo(NULL, visible);
[email protected]4f3dc372009-02-24 00:10:291358 }
[email protected]20e93d12008-08-28 16:31:571359}
1360
[email protected]71f65dd2009-02-11 19:14:561361void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1362 int* y) {
[email protected]9e0534b2008-10-21 15:03:011363 gfx::Point position(0, 0);
1364 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291365 if (browser_tracker_->ContainsHandle(handle)) {
1366 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581367 FindBarTesting* find_bar =
[email protected]b77cb302009-10-29 04:09:171368 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
[email protected]4801ecc2009-04-05 04:52:581369 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291370 }
[email protected]20e93d12008-08-28 16:31:571371
[email protected]71f65dd2009-02-11 19:14:561372 *x = position.x();
1373 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571374}
1375
[email protected]4512cb52010-04-05 19:50:251376// Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1377// Presence in the NTP is NOT considered visible by this call.
[email protected]c3240722010-03-05 21:52:581378void AutomationProvider::GetBookmarkBarVisibility(int handle,
1379 bool* visible,
1380 bool* animating) {
1381 *visible = false;
1382 *animating = false;
1383
1384 if (browser_tracker_->ContainsHandle(handle)) {
1385 Browser* browser = browser_tracker_->GetResource(handle);
1386 if (browser) {
[email protected]472f099b2010-05-27 17:07:121387#if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1388 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1389
[email protected]ab6ca392010-04-07 00:44:131390 // IsBookmarkBarVisible() line looks correct but is not
1391 // consistent across platforms. Specifically, on Mac/Linux, it
1392 // returns false if the bar is hidden in a pref (even if visible
1393 // on the NTP). On ChromeOS, it returned true if on NTP
1394 // independent of the pref. Making the code more consistent
1395 // caused a perf bot regression on Windows (which shares views).
1396 // See http://crbug.com/40225
[email protected]4512cb52010-04-05 19:50:251397 *visible = browser->profile()->GetPrefs()->GetBoolean(
1398 prefs::kShowBookmarkBar);
[email protected]7e4cd4e82010-04-05 20:59:401399#else
1400 *visible = browser->window()->IsBookmarkBarVisible();
1401#endif
[email protected]c3240722010-03-05 21:52:581402 *animating = browser->window()->IsBookmarkBarAnimating();
1403 }
1404 }
1405}
1406
[email protected]6d8ffc9f2010-03-12 18:27:531407void AutomationProvider::GetBookmarksAsJSON(int handle,
1408 std::string* bookmarks_as_json,
1409 bool *success) {
1410 *success = false;
1411 if (browser_tracker_->ContainsHandle(handle)) {
1412 Browser* browser = browser_tracker_->GetResource(handle);
1413 if (browser) {
1414 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1415 return;
1416 }
1417 scoped_refptr<BookmarkStorage> storage = new BookmarkStorage(
1418 browser->profile(),
1419 browser->profile()->GetBookmarkModel());
1420 *success = storage->SerializeData(bookmarks_as_json);
1421 }
1422 }
1423}
1424
1425void AutomationProvider::WaitForBookmarkModelToLoad(
1426 int handle,
1427 IPC::Message* reply_message) {
1428 if (browser_tracker_->ContainsHandle(handle)) {
1429 Browser* browser = browser_tracker_->GetResource(handle);
1430 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1431 if (model->IsLoaded()) {
1432 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1433 reply_message, true);
1434 Send(reply_message);
1435 } else {
1436 // The observer will delete itself when done.
1437 new AutomationProviderBookmarkModelObserver(this, reply_message,
1438 model);
1439 }
1440 }
1441}
1442
1443void AutomationProvider::AddBookmarkGroup(int handle,
1444 int64 parent_id, int index,
1445 std::wstring title,
1446 bool* success) {
1447 if (browser_tracker_->ContainsHandle(handle)) {
1448 Browser* browser = browser_tracker_->GetResource(handle);
1449 if (browser) {
1450 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1451 if (!model->IsLoaded()) {
1452 *success = false;
1453 return;
1454 }
1455 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1456 DCHECK(parent);
1457 if (parent) {
1458 const BookmarkNode* child = model->AddGroup(parent, index,
1459 WideToUTF16(title));
1460 DCHECK(child);
1461 if (child)
1462 *success = true;
1463 }
1464 }
1465 }
1466 *success = false;
1467}
1468
1469void AutomationProvider::AddBookmarkURL(int handle,
1470 int64 parent_id, int index,
1471 std::wstring title, const GURL& url,
1472 bool* success) {
1473 if (browser_tracker_->ContainsHandle(handle)) {
1474 Browser* browser = browser_tracker_->GetResource(handle);
1475 if (browser) {
1476 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1477 if (!model->IsLoaded()) {
1478 *success = false;
1479 return;
1480 }
1481 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1482 DCHECK(parent);
1483 if (parent) {
1484 const BookmarkNode* child = model->AddURL(parent, index,
1485 WideToUTF16(title), url);
1486 DCHECK(child);
1487 if (child)
1488 *success = true;
1489 }
1490 }
1491 }
1492 *success = false;
1493}
1494
1495void AutomationProvider::ReparentBookmark(int handle,
1496 int64 id, int64 new_parent_id,
1497 int index,
1498 bool* success) {
1499 if (browser_tracker_->ContainsHandle(handle)) {
1500 Browser* browser = browser_tracker_->GetResource(handle);
1501 if (browser) {
1502 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1503 if (!model->IsLoaded()) {
1504 *success = false;
1505 return;
1506 }
1507 const BookmarkNode* node = model->GetNodeByID(id);
1508 DCHECK(node);
1509 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1510 DCHECK(new_parent);
1511 if (node && new_parent) {
1512 model->Move(node, new_parent, index);
1513 *success = true;
1514 }
1515 }
1516 }
1517 *success = false;
1518}
1519
1520void AutomationProvider::SetBookmarkTitle(int handle,
1521 int64 id, std::wstring title,
1522 bool* success) {
1523 if (browser_tracker_->ContainsHandle(handle)) {
1524 Browser* browser = browser_tracker_->GetResource(handle);
1525 if (browser) {
1526 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1527 if (!model->IsLoaded()) {
1528 *success = false;
1529 return;
1530 }
1531 const BookmarkNode* node = model->GetNodeByID(id);
1532 DCHECK(node);
1533 if (node) {
1534 model->SetTitle(node, WideToUTF16(title));
1535 *success = true;
1536 }
1537 }
1538 }
1539 *success = false;
1540}
1541
1542void AutomationProvider::SetBookmarkURL(int handle,
1543 int64 id, const GURL& url,
1544 bool* success) {
1545 if (browser_tracker_->ContainsHandle(handle)) {
1546 Browser* browser = browser_tracker_->GetResource(handle);
1547 if (browser) {
1548 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1549 if (!model->IsLoaded()) {
1550 *success = false;
1551 return;
1552 }
1553 const BookmarkNode* node = model->GetNodeByID(id);
1554 DCHECK(node);
1555 if (node) {
1556 model->SetURL(node, url);
1557 *success = true;
1558 }
1559 }
1560 }
1561 *success = false;
1562}
1563
1564void AutomationProvider::RemoveBookmark(int handle,
1565 int64 id,
1566 bool* success) {
1567 if (browser_tracker_->ContainsHandle(handle)) {
1568 Browser* browser = browser_tracker_->GetResource(handle);
1569 if (browser) {
1570 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1571 if (!model->IsLoaded()) {
1572 *success = false;
1573 return;
1574 }
1575 const BookmarkNode* node = model->GetNodeByID(id);
1576 DCHECK(node);
1577 if (node) {
1578 const BookmarkNode* parent = node->GetParent();
1579 DCHECK(parent);
1580 model->Remove(parent, parent->IndexOfChild(node));
1581 *success = true;
1582 }
1583 }
1584 }
1585 *success = false;
1586}
1587
[email protected]ef413ca2010-05-25 21:09:141588// Sample json input: { "command": "SetWindowDimensions",
1589// "x": 20, # optional
1590// "y": 20, # optional
1591// "width": 800, # optional
1592// "height": 600 } # optional
1593void AutomationProvider::SetWindowDimensions(Browser* browser,
1594 DictionaryValue* args,
1595 IPC::Message* reply_message) {
1596 gfx::Rect rect = browser->window()->GetRestoredBounds();
1597 int x, y, width, height;
1598 if (args->GetInteger(L"x", &x))
1599 rect.set_x(x);
1600 if (args->GetInteger(L"y", &y))
1601 rect.set_y(y);
1602 if (args->GetInteger(L"width", &width))
1603 rect.set_width(width);
1604 if (args->GetInteger(L"height", &height))
1605 rect.set_height(height);
1606 browser->window()->SetBounds(rect);
1607 AutomationMsg_SendJSONRequest::WriteReplyParams(
1608 reply_message, std::string("{}"), true);
1609 Send(reply_message);
1610}
1611
[email protected]7060bb292010-06-24 00:52:491612std::string AutomationProvider::JSONErrorString(std::string err) {
1613 std::string prefix = "{\"error\": \"";
1614 std::string no_quote_err = err;
1615 std::string suffix = "\"}";
1616
1617 // Don't allow input string to break JSON by embedding quotes.
1618 // Try and make sure the input string won't break json quoting rules.
1619 if (no_quote_err.find("\"") != std::string::npos)
1620 no_quote_err = "unhappy about embedded quote in error string";
1621
1622 return prefix + no_quote_err + suffix;
1623}
1624
[email protected]a9ff2c02010-05-13 17:33:051625// Sample json input: { "command": "GetBrowserInfo" }
1626// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
1627// sample json output.
[email protected]53329582010-05-14 21:10:581628void AutomationProvider::GetBrowserInfo(Browser* browser,
1629 DictionaryValue* args,
[email protected]a9ff2c02010-05-13 17:33:051630 IPC::Message* reply_message) {
1631 std::string json_return;
1632 bool reply_return = true;
1633
1634 DictionaryValue* properties = new DictionaryValue;
1635 properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
1636 properties->SetString(L"BrowserProcessExecutableName",
1637 chrome::kBrowserProcessExecutableName);
1638 properties->SetString(L"HelperProcessExecutableName",
1639 chrome::kHelperProcessExecutableName);
1640 properties->SetString(L"BrowserProcessExecutablePath",
1641 chrome::kBrowserProcessExecutablePath);
1642 properties->SetString(L"HelperProcessExecutablePath",
1643 chrome::kHelperProcessExecutablePath);
[email protected]a9ff2c02010-05-13 17:33:051644 properties->SetString(L"command_line_string",
1645 CommandLine::ForCurrentProcess()->command_line_string());
[email protected]44eed9f2010-06-28 22:04:001646
1647 std::string branding;
1648#if defined(GOOGLE_CHROME_BUILD)
1649 branding = "Google Chrome";
1650#elif defined(CHROMIUM_BUILD)
1651 branding = "Chromium";
1652#else
1653 branding = "Unknown Branding";
[email protected]a9ff2c02010-05-13 17:33:051654#endif
[email protected]44eed9f2010-06-28 22:04:001655 properties->SetString(L"branding", branding);
[email protected]a9ff2c02010-05-13 17:33:051656
1657 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1658 return_value->Set(L"properties", properties);
1659
[email protected]ef413ca2010-05-25 21:09:141660 return_value->SetInteger(L"browser_pid", base::GetCurrentProcId());
1661 // Add info about all windows in a list of dictionaries, one dictionary
1662 // item per window.
1663 ListValue* windows = new ListValue;
1664 int windex = 0;
1665 for (BrowserList::const_iterator it = BrowserList::begin();
1666 it != BrowserList::end();
1667 ++it, ++windex) {
1668 DictionaryValue* browser_item = new DictionaryValue;
1669 browser = *it;
1670 browser_item->SetInteger(L"index", windex);
1671 // Window properties
1672 gfx::Rect rect = browser->window()->GetRestoredBounds();
1673 browser_item->SetInteger(L"x", rect.x());
1674 browser_item->SetInteger(L"y", rect.y());
1675 browser_item->SetInteger(L"width", rect.width());
1676 browser_item->SetInteger(L"height", rect.height());
1677 browser_item->SetBoolean(L"fullscreen",
1678 browser->window()->IsFullscreen());
1679 browser_item->SetInteger(L"selected_tab", browser->selected_index());
1680 browser_item->SetBoolean(L"incognito",
1681 browser->profile()->IsOffTheRecord());
1682 // For each window, add info about all tabs in a list of dictionaries,
1683 // one dictionary item per tab.
1684 ListValue* tabs = new ListValue;
1685 for (int i = 0; i < browser->tab_count(); ++i) {
1686 TabContents* tc = browser->GetTabContentsAt(i);
1687 DictionaryValue* tab = new DictionaryValue;
1688 tab->SetInteger(L"index", i);
1689 tab->SetString(L"url", tc->GetURL().spec());
1690 tab->SetInteger(L"renderer_pid",
1691 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
1692 tab->SetInteger(L"num_infobars", tc->infobar_delegate_count());
1693 tabs->Append(tab);
1694 }
1695 browser_item->Set(L"tabs", tabs);
1696
1697 windows->Append(browser_item);
1698 }
1699 return_value->Set(L"windows", windows);
1700
1701 return_value->SetString(L"child_process_path",
1702 ChildProcessHost::GetChildPath(true).value());
1703 // Child processes are the processes for plugins and other workers.
1704 // Add all child processes in a list of dictionaries, one dictionary item
1705 // per child process.
1706 ListValue* child_processes = new ListValue;
1707 for (ChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
1708 // Only add processes which are already started, since we need their handle.
1709 if ((*iter)->handle() != base::kNullProcessHandle) {
1710 ChildProcessInfo* info = *iter;
1711 DictionaryValue* item = new DictionaryValue;
1712 item->SetString(L"name", info->name());
1713 item->SetString(L"type",
1714 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
1715 item->SetInteger(L"pid", base::GetProcId(info->handle()));
1716 child_processes->Append(item);
1717 }
1718 }
1719 return_value->Set(L"child_processes", child_processes);
1720
1721 // Add all extension processes in a list of dictionaries, one dictionary
1722 // item per extension process.
1723 ListValue* extension_processes = new ListValue;
1724 ProfileManager* profile_manager = g_browser_process->profile_manager();
1725 for (ProfileManager::const_iterator it = profile_manager->begin();
1726 it != profile_manager->end(); ++it) {
1727 ExtensionProcessManager* process_manager =
1728 (*it)->GetExtensionProcessManager();
1729 ExtensionProcessManager::const_iterator jt;
1730 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
1731 ExtensionHost* ex_host = *jt;
1732 // Don't add dead extension processes.
1733 if (!ex_host->IsRenderViewLive())
1734 continue;
1735 DictionaryValue* item = new DictionaryValue;
1736 item->SetString(L"name", ex_host->extension()->name());
1737 item->SetInteger(
1738 L"pid",
1739 base::GetProcId(ex_host->render_process_host()->GetHandle()));
1740 extension_processes->Append(item);
1741 }
1742 }
1743 return_value->Set(L"extension_processes", extension_processes);
1744
[email protected]a9ff2c02010-05-13 17:33:051745 base::JSONWriter::Write(return_value.get(), false, &json_return);
1746 AutomationMsg_SendJSONRequest::WriteReplyParams(
1747 reply_message, json_return, reply_return);
1748 Send(reply_message);
1749}
1750
[email protected]24e2b102010-04-29 17:56:471751// Sample json input: { "command": "GetHistoryInfo",
1752// "search_text": "some text" }
[email protected]e6e376e2010-04-19 21:41:361753// Refer chrome/test/pyautolib/history_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581754void AutomationProvider::GetHistoryInfo(Browser* browser,
1755 DictionaryValue* args,
1756 IPC::Message* reply_message) {
[email protected]e6e376e2010-04-19 21:41:361757 consumer_.CancelAllRequests();
1758
[email protected]e53668962010-06-23 15:35:251759 string16 search_text;
1760 args->GetString("search_text", &search_text);
[email protected]e6e376e2010-04-19 21:41:361761
1762 // Fetch history.
1763 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1764 history::QueryOptions options;
1765 // The observer owns itself. It deletes itself after it fetches history.
1766 AutomationProviderHistoryObserver* history_observer =
1767 new AutomationProviderHistoryObserver(this, reply_message);
1768 hs->QueryHistory(
1769 search_text,
1770 options,
1771 &consumer_,
1772 NewCallback(history_observer,
1773 &AutomationProviderHistoryObserver::HistoryQueryComplete));
1774}
1775
[email protected]bbe6aa02010-05-07 17:27:291776// Sample json input: { "command": "AddHistoryItem",
1777// "item": { "URL": "http://www.google.com",
1778// "title": "Google", # optional
1779// "time": 12345 # optional (time_t)
1780// } }
1781// Refer chrome/test/pyautolib/pyauto.py for details on input.
[email protected]53329582010-05-14 21:10:581782void AutomationProvider::AddHistoryItem(Browser* browser,
1783 DictionaryValue* args,
1784 IPC::Message* reply_message) {
[email protected]bbe6aa02010-05-07 17:27:291785 bool reply_return = true;
1786 std::string json_return = "{}";
1787
1788 DictionaryValue* item = NULL;
1789 args->GetDictionary(L"item", &item);
1790 string16 url_text;
[email protected]e53668962010-06-23 15:35:251791 string16 title;
[email protected]bbe6aa02010-05-07 17:27:291792 base::Time time = base::Time::Now();
1793
1794 if (item->GetString("url", &url_text)) {
1795 GURL gurl(url_text);
[email protected]e53668962010-06-23 15:35:251796 item->GetString("title", &title); // Don't care if it fails.
[email protected]bbe6aa02010-05-07 17:27:291797 int it;
1798 double dt;
1799 if (item->GetInteger(L"time", &it))
1800 time = base::Time::FromTimeT(it);
1801 else if (item->GetReal(L"time", &dt))
1802 time = base::Time::FromDoubleT(dt);
1803
1804 // Ideas for "dummy" values (e.g. id_scope) came from
1805 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
1806 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
1807 const void* id_scope = reinterpret_cast<void*>(1);
1808 hs->AddPage(gurl, time,
1809 id_scope,
1810 0,
1811 GURL(),
1812 PageTransition::LINK,
1813 history::RedirectList(),
1814 false);
[email protected]e53668962010-06-23 15:35:251815 if (title.length())
[email protected]bbe6aa02010-05-07 17:27:291816 hs->SetPageTitle(gurl, title);
[email protected]bbe6aa02010-05-07 17:27:291817 } else {
[email protected]7060bb292010-06-24 00:52:491818 json_return = JSONErrorString("bad args (no URL in dict?)");
[email protected]bbe6aa02010-05-07 17:27:291819 reply_return = false;
1820 }
1821
1822 AutomationMsg_SendJSONRequest::WriteReplyParams(
1823 reply_message, json_return, reply_return);
1824 Send(reply_message);
1825}
1826
[email protected]24e2b102010-04-29 17:56:471827// Sample json input: { "command": "GetDownloadsInfo" }
[email protected]e6e376e2010-04-19 21:41:361828// Refer chrome/test/pyautolib/download_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581829void AutomationProvider::GetDownloadsInfo(Browser* browser,
1830 DictionaryValue* args,
1831 IPC::Message* reply_message) {
[email protected]d4adc292010-04-15 18:06:391832 std::string json_return;
1833 bool reply_return = true;
1834 AutomationProviderDownloadManagerObserver observer;
1835 std::vector<DownloadItem*> downloads;
1836 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1837
1838 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7060bb292010-06-24 00:52:491839 json_return = JSONErrorString("no download manager");
[email protected]d4adc292010-04-15 18:06:391840 reply_return = false;
1841 } else {
1842 // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
1843 // since that would be transient; a download might enter and empty out
1844 // the current download queue too soon to be noticed.
1845 profile_->GetDownloadManager()->GetDownloads(&observer, L"");
1846 downloads = observer.Downloads();
1847 }
1848
1849 std::map<DownloadItem::DownloadState, std::string> state_to_string;
1850 state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
1851 state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
1852 state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
1853 state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
1854
1855 std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
1856 safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
1857 safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
1858 safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
1859 std::string("DANGEROUS_BUT_VALIDATED");
1860
1861 ListValue* list_of_downloads = new ListValue;
1862 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
1863 it != downloads.end();
1864 it++) { // Fill info about each download item.
1865 DictionaryValue* dl_item_value = new DictionaryValue;
1866 dl_item_value->SetInteger(L"id", static_cast<int>((*it)->id()));
1867 dl_item_value->SetString(L"url", (*it)->url().spec());
1868 dl_item_value->SetString(L"referrer_url", (*it)->referrer_url().spec());
1869 dl_item_value->SetString(L"file_name", (*it)->file_name().value());
1870 dl_item_value->SetString(L"full_path", (*it)->full_path().value());
1871 dl_item_value->SetBoolean(L"is_paused", (*it)->is_paused());
1872 dl_item_value->SetBoolean(L"open_when_complete",
1873 (*it)->open_when_complete());
1874 dl_item_value->SetBoolean(L"is_extension_install",
1875 (*it)->is_extension_install());
1876 dl_item_value->SetBoolean(L"is_temporary", (*it)->is_temporary());
1877 dl_item_value->SetBoolean(L"is_otr", (*it)->is_otr()); // off-the-record
1878 dl_item_value->SetString(L"state", state_to_string[(*it)->state()]);
1879 dl_item_value->SetString(L"safety_state",
1880 safety_state_to_string[(*it)->safety_state()]);
1881 dl_item_value->SetInteger(L"PercentComplete", (*it)->PercentComplete());
1882 list_of_downloads->Append(dl_item_value);
1883 }
1884 return_value->Set(L"downloads", list_of_downloads);
1885 base::JSONWriter::Write(return_value.get(), false, &json_return);
1886
1887 AutomationMsg_SendJSONRequest::WriteReplyParams(
1888 reply_message, json_return, reply_return);
1889 Send(reply_message);
1890 // All value objects allocated above are owned by |return_value|
1891 // and get freed by it.
1892}
1893
[email protected]59a611242010-04-02 02:24:041894void AutomationProvider::WaitForDownloadsToComplete(
[email protected]53329582010-05-14 21:10:581895 Browser* browser,
[email protected]59a611242010-04-02 02:24:041896 DictionaryValue* args,
1897 IPC::Message* reply_message) {
1898 std::string json_return;
1899 bool reply_return = true;
1900 AutomationProviderDownloadManagerObserver observer;
1901 std::vector<DownloadItem*> downloads;
1902
1903 // Look for a quick return.
1904 if (!profile_->HasCreatedDownloadManager()) {
[email protected]7060bb292010-06-24 00:52:491905 json_return = JSONErrorString("no download manager");
[email protected]59a611242010-04-02 02:24:041906 reply_return = false;
1907 } else {
1908 profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
1909 FilePath());
1910 downloads = observer.Downloads();
1911 if (downloads.size() == 0) {
1912 json_return = "{}";
1913 }
1914 }
1915 if (!json_return.empty()) {
1916 AutomationMsg_SendJSONRequest::WriteReplyParams(
1917 reply_message, json_return, reply_return);
1918 Send(reply_message);
1919 }
1920
1921 // The observer owns itself. When the last observed item pings, it
1922 // deletes itself.
1923 AutomationProviderDownloadItemObserver* item_observer =
1924 new AutomationProviderDownloadItemObserver(
1925 this, reply_message, downloads.size());
1926 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
1927 i != downloads.end();
1928 i++) {
1929 (*i)->AddObserver(item_observer);
1930 }
1931}
1932
[email protected]24e2b102010-04-29 17:56:471933// Sample json input: { "command": "GetPrefsInfo" }
1934// Refer chrome/test/pyautolib/prefs_info.py for sample json output.
[email protected]53329582010-05-14 21:10:581935void AutomationProvider::GetPrefsInfo(Browser* browser,
1936 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471937 IPC::Message* reply_message) {
1938 std::string json_return;
1939 bool reply_return = true;
1940
1941 const PrefService::PreferenceSet& prefs =
1942 profile_->GetPrefs()->preference_set();
1943 DictionaryValue* items = new DictionaryValue;
1944 for (PrefService::PreferenceSet::const_iterator it = prefs.begin();
1945 it != prefs.end(); ++it) {
1946 items->Set((*it)->name(), (*it)->GetValue()->DeepCopy());
1947 }
1948 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1949 return_value->Set(L"prefs", items); // return_value owns items.
1950
1951 base::JSONWriter::Write(return_value.get(), false, &json_return);
1952 AutomationMsg_SendJSONRequest::WriteReplyParams(
1953 reply_message, json_return, reply_return);
1954 Send(reply_message);
1955}
1956
1957// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
[email protected]53329582010-05-14 21:10:581958void AutomationProvider::SetPrefs(Browser* browser,
1959 DictionaryValue* args,
[email protected]24e2b102010-04-29 17:56:471960 IPC::Message* reply_message) {
1961 bool reply_return = true;
1962 std::string json_return = "{}";
1963 std::wstring path;
1964 Value* val;
1965 if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
1966 PrefService* pref_service = profile_->GetPrefs();
1967 const PrefService::Preference* pref =
1968 pref_service->FindPreference(path.c_str());
1969 if (!pref) { // Not a registered pref.
[email protected]7060bb292010-06-24 00:52:491970 json_return = JSONErrorString("pref not registered.");
[email protected]24e2b102010-04-29 17:56:471971 reply_return = false;
1972 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
[email protected]7060bb292010-06-24 00:52:491973 json_return = JSONErrorString("pref is managed. cannot be changed.");
[email protected]24e2b102010-04-29 17:56:471974 reply_return = false;
1975 } else { // Set the pref.
1976 pref_service->Set(path.c_str(), *val);
1977 }
1978 } else {
[email protected]7060bb292010-06-24 00:52:491979 json_return = JSONErrorString("no pref path or value given.");
[email protected]24e2b102010-04-29 17:56:471980 reply_return = false;
1981 }
1982
1983 AutomationMsg_SendJSONRequest::WriteReplyParams(
1984 reply_message, json_return, reply_return);
1985 Send(reply_message);
1986}
1987
[email protected]53329582010-05-14 21:10:581988// Sample json input: { "command": "GetOmniboxInfo" }
1989// Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
1990void AutomationProvider::GetOmniboxInfo(Browser* browser,
1991 DictionaryValue* args,
1992 IPC::Message* reply_message) {
1993 std::string json_return;
1994 bool reply_return = true;
1995 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
1996
1997 LocationBar* loc_bar = browser->window()->GetLocationBar();
1998 AutocompleteEditView* edit_view = loc_bar->location_entry();
1999 AutocompleteEditModel* model = edit_view->model();
2000
2001 // Fill up matches.
2002 ListValue* matches = new ListValue;
2003 const AutocompleteResult& result = model->result();
2004 for (AutocompleteResult::const_iterator i = result.begin();
2005 i != result.end(); ++i) {
2006 const AutocompleteMatch& match = *i;
2007 DictionaryValue* item = new DictionaryValue; // owned by return_value
2008 item->SetString(L"type", AutocompleteMatch::TypeToString(match.type));
2009 item->SetBoolean(L"starred", match.starred);
2010 item->SetString(L"destination_url", match.destination_url.spec());
2011 item->SetString(L"contents", match.contents);
2012 item->SetString(L"description", match.description);
2013 matches->Append(item);
2014 }
2015 return_value->Set(L"matches", matches);
2016
2017 // Fill up other properties.
2018 DictionaryValue* properties = new DictionaryValue; // owned by return_value
2019 properties->SetBoolean(L"has_focus", model->has_focus());
2020 properties->SetBoolean(L"query_in_progress", model->query_in_progress());
2021 properties->SetString(L"keyword", model->keyword());
2022 properties->SetString(L"text", edit_view->GetText());
2023 return_value->Set(L"properties", properties);
2024
2025 base::JSONWriter::Write(return_value.get(), false, &json_return);
2026 AutomationMsg_SendJSONRequest::WriteReplyParams(
2027 reply_message, json_return, reply_return);
2028 Send(reply_message);
2029}
2030
2031// Sample json input: { "command": "SetOmniboxText",
2032// "text": "goog" }
2033void AutomationProvider::SetOmniboxText(Browser* browser,
2034 DictionaryValue* args,
2035 IPC::Message* reply_message) {
2036 std::string json_return = "{}";
2037 bool reply_return = true;
2038 std::wstring text;
2039
2040 if (!args->GetString(L"text", &text)) {
[email protected]7060bb292010-06-24 00:52:492041 json_return = JSONErrorString("text missing");
[email protected]53329582010-05-14 21:10:582042 reply_return = false;
2043 } else {
2044 browser->FocusLocationBar();
2045 LocationBar* loc_bar = browser->window()->GetLocationBar();
2046 AutocompleteEditView* edit_view = loc_bar->location_entry();
2047 edit_view->model()->OnSetFocus(false);
2048 edit_view->SetUserText(text);
2049 }
2050
2051 AutomationMsg_SendJSONRequest::WriteReplyParams(
2052 reply_message, json_return, reply_return);
2053 Send(reply_message);
2054}
2055
2056// Sample json input: { "command": "OmniboxMovePopupSelection",
2057// "count": 1 }
2058// Negative count implies up, positive implies down. Count values will be
2059// capped by the size of the popup list.
2060void AutomationProvider::OmniboxMovePopupSelection(
2061 Browser* browser,
2062 DictionaryValue* args,
2063 IPC::Message* reply_message) {
2064 std::string json_return = "{}";
2065 bool reply_return = true;
2066 int count;
2067
2068 if (!args->GetInteger(L"count", &count)) {
[email protected]7060bb292010-06-24 00:52:492069 json_return = JSONErrorString("count missing");
[email protected]53329582010-05-14 21:10:582070 reply_return = false;
2071 } else {
2072 LocationBar* loc_bar = browser->window()->GetLocationBar();
2073 AutocompleteEditModel* model = loc_bar->location_entry()->model();
2074 model->OnUpOrDownKeyPressed(count);
2075 }
2076
2077 AutomationMsg_SendJSONRequest::WriteReplyParams(
2078 reply_message, json_return, reply_return);
2079 Send(reply_message);
2080}
2081
2082// Sample json input: { "command": "OmniboxAcceptInput" }
2083void AutomationProvider::OmniboxAcceptInput(Browser* browser,
2084 DictionaryValue* args,
2085 IPC::Message* reply_message) {
[email protected]cb84d642010-06-10 00:56:282086 NavigationController& controller =
2087 browser->GetSelectedTabContents()->controller();
[email protected]c1654832010-05-17 23:22:122088 // Setup observer to wait until the selected item loads.
2089 NotificationObserver* observer =
[email protected]cb84d642010-06-10 00:56:282090 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
[email protected]c1654832010-05-17 23:22:122091 notification_observer_list_.AddObserver(observer);
[email protected]53329582010-05-14 21:10:582092
2093 browser->window()->GetLocationBar()->AcceptInput();
[email protected]53329582010-05-14 21:10:582094}
2095
[email protected]a3cd5022010-06-16 18:25:292096// Sample json input: { "command": "GetInitialLoadTimes" }
2097// Refer to InitialLoadObserver::GetTimingInformation() for sample output.
2098void AutomationProvider::GetInitialLoadTimes(
2099 Browser*,
2100 DictionaryValue*,
2101 IPC::Message* reply_message) {
2102 scoped_ptr<DictionaryValue> return_value(
2103 initial_load_observer_->GetTimingInformation());
2104
2105 std::string json_return;
2106 base::JSONWriter::Write(return_value.get(), false, &json_return);
2107 AutomationMsg_SendJSONRequest::WriteReplyParams(
2108 reply_message, json_return, true);
2109 Send(reply_message);
2110}
2111
[email protected]f7d48012010-05-06 08:17:052112// Sample json input: { "command": "GetPluginsInfo" }
2113// Refer chrome/test/pyautolib/plugins_info.py for sample json output.
[email protected]53329582010-05-14 21:10:582114void AutomationProvider::GetPluginsInfo(Browser* browser,
2115 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052116 IPC::Message* reply_message) {
2117 std::string json_return;
2118 bool reply_return = true;
2119
2120 std::vector<WebPluginInfo> plugins;
2121 NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
2122 ListValue* items = new ListValue;
2123 for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
2124 it != plugins.end();
2125 ++it) {
2126 DictionaryValue* item = new DictionaryValue;
[email protected]c9d811372010-06-23 21:44:572127 item->SetStringFromUTF16(L"name", it->name);
[email protected]f7d48012010-05-06 08:17:052128 item->SetString(L"path", it->path.value());
[email protected]c9d811372010-06-23 21:44:572129 item->SetStringFromUTF16(L"version", it->version);
2130 item->SetStringFromUTF16(L"desc", it->desc);
[email protected]f7d48012010-05-06 08:17:052131 item->SetBoolean(L"enabled", it->enabled);
2132 // Add info about mime types.
2133 ListValue* mime_types = new ListValue();
2134 for (std::vector<WebPluginMimeType>::const_iterator type_it =
2135 it->mime_types.begin();
2136 type_it != it->mime_types.end();
2137 ++type_it) {
2138 DictionaryValue* mime_type = new DictionaryValue();
2139 mime_type->SetString(L"mimeType", type_it->mime_type);
[email protected]c9d811372010-06-23 21:44:572140 mime_type->SetStringFromUTF16(L"description", type_it->description);
[email protected]f7d48012010-05-06 08:17:052141
2142 ListValue* file_extensions = new ListValue();
2143 for (std::vector<std::string>::const_iterator ext_it =
2144 type_it->file_extensions.begin();
2145 ext_it != type_it->file_extensions.end();
2146 ++ext_it) {
2147 file_extensions->Append(new StringValue(*ext_it));
2148 }
2149 mime_type->Set(L"fileExtensions", file_extensions);
2150
2151 mime_types->Append(mime_type);
2152 }
2153 item->Set(L"mimeTypes", mime_types);
2154 items->Append(item);
2155 }
2156 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2157 return_value->Set(L"plugins", items); // return_value owns items.
2158
2159 base::JSONWriter::Write(return_value.get(), false, &json_return);
2160 AutomationMsg_SendJSONRequest::WriteReplyParams(
2161 reply_message, json_return, reply_return);
2162 Send(reply_message);
2163}
2164
2165// Sample json input:
2166// { "command": "EnablePlugin",
2167// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582168void AutomationProvider::EnablePlugin(Browser* browser,
2169 DictionaryValue* args,
[email protected]f7d48012010-05-06 08:17:052170 IPC::Message* reply_message) {
2171 std::string json_return = "{}";
2172 bool reply_return = true;
2173 FilePath::StringType path;
2174 if (!args->GetString(L"path", &path)) {
[email protected]7060bb292010-06-24 00:52:492175 json_return = JSONErrorString("path not specified.");
[email protected]f7d48012010-05-06 08:17:052176 reply_return = false;
2177 } else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
2178 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2179 " for path %s.\"}", path.c_str());
2180 reply_return = false;
2181 }
2182
2183 AutomationMsg_SendJSONRequest::WriteReplyParams(
2184 reply_message, json_return, reply_return);
2185 Send(reply_message);
2186}
2187
2188// Sample json input:
2189// { "command": "DisablePlugin",
2190// "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
[email protected]53329582010-05-14 21:10:582191void AutomationProvider::DisablePlugin(Browser* browser,
2192 DictionaryValue* args,
2193 IPC::Message* reply_message) {
[email protected]f7d48012010-05-06 08:17:052194 std::string json_return = "{}";
2195 bool reply_return = true;
2196 FilePath::StringType path;
2197 if (!args->GetString(L"path", &path)) {
[email protected]7060bb292010-06-24 00:52:492198 json_return = JSONErrorString("path not specified.");
[email protected]f7d48012010-05-06 08:17:052199 reply_return = false;
2200 } else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
2201 json_return = StringPrintf("{\"error\": \"Could not enable plugin"
2202 " for path %s.\"}", path.c_str());
2203 reply_return = false;
2204 }
2205
2206 AutomationMsg_SendJSONRequest::WriteReplyParams(
2207 reply_message, json_return, reply_return);
2208 Send(reply_message);
2209}
2210
[email protected]7060bb292010-06-24 00:52:492211// Sample json input:
2212// { "command": "SaveTabContents",
2213// "tab_index": 0,
2214// "filename": <a full pathname> }
2215// Sample json output:
2216// {}
2217void AutomationProvider::SaveTabContents(Browser* browser,
2218 DictionaryValue* args,
2219 IPC::Message* reply_message) {
2220 std::string json_return;
2221 int tab_index = 0;
2222 FilePath::StringType filename;
2223 FilePath::StringType parent_directory;
2224 TabContents* tab_contents = NULL;
2225
2226 if (!args->GetInteger(L"tab_index", &tab_index) ||
2227 !args->GetString(L"filename", &filename)) {
2228 json_return = JSONErrorString("tab_index or filename param missing");
2229 } else {
2230 tab_contents = browser->GetTabContentsAt(tab_index);
2231 if (!tab_contents) {
2232 json_return = JSONErrorString("no tab at tab_index");
2233 }
2234 }
2235 if (tab_contents) {
2236 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
2237 // used. Nevertheless, SavePackage requires it be valid. Sigh.
2238 parent_directory = FilePath(filename).DirName().value();
2239 if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
2240 SavePackage::SAVE_AS_ONLY_HTML)) {
2241 json_return = JSONErrorString("Could not initiate SavePage");
2242 } else {
2243 // The observer will delete itself when done.
2244 new SavePackageNotificationObserver(tab_contents->save_package(),
2245 this, reply_message);
2246 return;
2247 }
2248 }
2249
2250 // if we get here, error.
2251 DCHECK(!json_return.empty());
2252 AutomationMsg_SendJSONRequest::WriteReplyParams(
2253 reply_message, json_return, false);
2254 Send(reply_message);
2255}
2256
[email protected]53329582010-05-14 21:10:582257void AutomationProvider::SendJSONRequest(int handle,
2258 std::string json_request,
2259 IPC::Message* reply_message) {
[email protected]59a611242010-04-02 02:24:042260 Browser* browser = NULL;
2261 std::string error_string;
2262 scoped_ptr<Value> values;
2263
2264 // Basic error checking.
2265 if (browser_tracker_->ContainsHandle(handle)) {
2266 browser = browser_tracker_->GetResource(handle);
2267 }
2268 if (!browser) {
2269 error_string = "no browser object";
2270 } else {
2271 base::JSONReader reader;
2272 std::string error;
[email protected]ba399672010-04-06 15:42:392273 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
[email protected]59a611242010-04-02 02:24:042274 if (!error.empty()) {
2275 error_string = error;
2276 }
2277 }
2278
2279 // Make sure input is a dict with a string command.
2280 std::string command;
2281 DictionaryValue* dict_value = NULL;
2282 if (error_string.empty()) {
2283 if (values->GetType() != Value::TYPE_DICTIONARY) {
2284 error_string = "not a dict or no command key in dict";
2285 } else {
2286 // Ownership remains with "values" variable.
2287 dict_value = static_cast<DictionaryValue*>(values.get());
2288 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2289 error_string = "no command key in dict or not a string command";
2290 }
2291 }
2292 }
2293
[email protected]24e2b102010-04-29 17:56:472294 // Map json commands to their handlers.
2295 std::map<std::string, JsonHandler> handler_map;
[email protected]f7d48012010-05-06 08:17:052296 handler_map["DisablePlugin"] = &AutomationProvider::DisablePlugin;
2297 handler_map["EnablePlugin"] = &AutomationProvider::EnablePlugin;
2298 handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
2299
[email protected]a9ff2c02010-05-13 17:33:052300 handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
2301
[email protected]24e2b102010-04-29 17:56:472302 handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
[email protected]bbe6aa02010-05-07 17:27:292303 handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
[email protected]f7d48012010-05-06 08:17:052304
[email protected]53329582010-05-14 21:10:582305 handler_map["GetOmniboxInfo"] = &AutomationProvider::GetOmniboxInfo;
2306 handler_map["SetOmniboxText"] = &AutomationProvider::SetOmniboxText;
2307 handler_map["OmniboxAcceptInput"] = &AutomationProvider::OmniboxAcceptInput;
2308 handler_map["OmniboxMovePopupSelection"] =
2309 &AutomationProvider::OmniboxMovePopupSelection;
2310
[email protected]24e2b102010-04-29 17:56:472311 handler_map["GetPrefsInfo"] = &AutomationProvider::GetPrefsInfo;
2312 handler_map["SetPrefs"] = &AutomationProvider::SetPrefs;
[email protected]f7d48012010-05-06 08:17:052313
[email protected]ef413ca2010-05-25 21:09:142314 handler_map["SetWindowDimensions"] = &AutomationProvider::SetWindowDimensions;
2315
[email protected]f7d48012010-05-06 08:17:052316 handler_map["GetDownloadsInfo"] = &AutomationProvider::GetDownloadsInfo;
[email protected]24e2b102010-04-29 17:56:472317 handler_map["WaitForAllDownloadsToComplete"] =
2318 &AutomationProvider::WaitForDownloadsToComplete;
2319
[email protected]a3cd5022010-06-16 18:25:292320 handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
2321
[email protected]7060bb292010-06-24 00:52:492322 handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
2323
[email protected]59a611242010-04-02 02:24:042324 if (error_string.empty()) {
[email protected]24e2b102010-04-29 17:56:472325 if (handler_map.find(std::string(command)) != handler_map.end()) {
[email protected]53329582010-05-14 21:10:582326 (this->*handler_map[command])(browser, dict_value, reply_message);
[email protected]59a611242010-04-02 02:24:042327 return;
2328 } else {
[email protected]24e2b102010-04-29 17:56:472329 error_string = "Unknown command. Options: ";
2330 for (std::map<std::string, JsonHandler>::const_iterator it =
2331 handler_map.begin(); it != handler_map.end(); ++it) {
2332 error_string += it->first + ", ";
2333 }
[email protected]59a611242010-04-02 02:24:042334 }
2335 }
2336
2337 // If we hit an error, return info.
[email protected]24e2b102010-04-29 17:56:472338 // Return a dict of {"error", "descriptive_string_for_error"}.
[email protected]59a611242010-04-02 02:24:042339 // Else return an empty dict.
2340 std::string json_string;
2341 bool success = true;
2342 if (!error_string.empty()) {
2343 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
2344 dict->SetString(L"error", error_string);
2345 base::JSONWriter::Write(dict.get(), false, &json_string);
2346 success = false;
2347 } else {
2348 json_string = "{}";
2349 }
2350 AutomationMsg_SendJSONRequest::WriteReplyParams(
2351 reply_message, json_string, success);
2352 Send(reply_message);
2353}
2354
initial.commit09911bf2008-07-26 23:55:292355void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562356 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342357 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2358 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562359 DCHECK(reply_message_ == NULL);
2360 reply_message_ = reply_message;
2361
[email protected]d9f9b792009-06-24 13:17:122362 DevToolsManager::GetInstance()->InspectElement(
2363 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292364 } else {
[email protected]71f65dd2009-02-11 19:14:562365 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2366 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292367 }
2368}
2369
2370void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092371 if (reply_message_) {
2372 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2373 num_resources);
2374 Send(reply_message_);
2375 reply_message_ = NULL;
2376 }
initial.commit09911bf2008-07-26 23:55:292377}
2378
[email protected]a7eee32f2009-05-22 18:08:172379class SetProxyConfigTask : public Task {
2380 public:
[email protected]be180c802009-10-23 06:33:312381 SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
2382 const std::string& new_proxy_config)
[email protected]2aa336e2010-04-06 21:05:252383 : request_context_getter_(request_context_getter),
2384 proxy_config_(new_proxy_config) {}
[email protected]a7eee32f2009-05-22 18:08:172385 virtual void Run() {
2386 // First, deserialize the JSON string. If this fails, log and bail.
2387 JSONStringValueSerializer deserializer(proxy_config_);
[email protected]ba399672010-04-06 15:42:392388 std::string error_msg;
2389 scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
[email protected]a7eee32f2009-05-22 18:08:172390 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2391 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
[email protected]ba399672010-04-06 15:42:392392 << error_msg;
[email protected]a7eee32f2009-05-22 18:08:172393 return;
2394 }
2395
2396 scoped_ptr<DictionaryValue> dict(
2397 static_cast<DictionaryValue*>(root.release()));
2398 // Now put together a proxy configuration from the deserialized string.
2399 net::ProxyConfig pc;
2400 PopulateProxyConfig(*dict.get(), &pc);
2401
[email protected]be180c802009-10-23 06:33:312402 net::ProxyService* proxy_service =
2403 request_context_getter_->GetURLRequestContext()->proxy_service();
2404 DCHECK(proxy_service);
[email protected]a7eee32f2009-05-22 18:08:172405 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2406 new net::ProxyConfigServiceFixed(pc));
[email protected]be180c802009-10-23 06:33:312407 proxy_service->ResetConfigService(proxy_config_service.release());
[email protected]a7eee32f2009-05-22 18:08:172408 }
2409
2410 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2411 DCHECK(pc);
2412 bool no_proxy = false;
2413 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2414 // Make no changes to the ProxyConfig.
2415 return;
2416 }
2417 bool auto_config;
2418 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
[email protected]ed4ed0f2010-02-24 00:20:482419 pc->set_auto_detect(true);
[email protected]a7eee32f2009-05-22 18:08:172420 }
2421 std::string pac_url;
2422 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
[email protected]ed4ed0f2010-02-24 00:20:482423 pc->set_pac_url(GURL(pac_url));
[email protected]a7eee32f2009-05-22 18:08:172424 }
2425 std::string proxy_bypass_list;
2426 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
[email protected]ed4ed0f2010-02-24 00:20:482427 pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
[email protected]a7eee32f2009-05-22 18:08:172428 }
2429 std::string proxy_server;
2430 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
[email protected]ed4ed0f2010-02-24 00:20:482431 pc->proxy_rules().ParseFromString(proxy_server);
[email protected]a7eee32f2009-05-22 18:08:172432 }
2433 }
2434
2435 private:
[email protected]be180c802009-10-23 06:33:312436 scoped_refptr<URLRequestContextGetter> request_context_getter_;
[email protected]a7eee32f2009-05-22 18:08:172437 std::string proxy_config_;
2438};
2439
2440
2441void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
[email protected]be180c802009-10-23 06:33:312442 URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
2443 if (!context_getter) {
[email protected]a7eee32f2009-05-22 18:08:172444 FilePath user_data_dir;
2445 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2446 ProfileManager* profile_manager = g_browser_process->profile_manager();
2447 DCHECK(profile_manager);
2448 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2449 DCHECK(profile);
[email protected]be180c802009-10-23 06:33:312450 context_getter = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172451 }
[email protected]be180c802009-10-23 06:33:312452 DCHECK(context_getter);
[email protected]a7eee32f2009-05-22 18:08:172453
[email protected]fae20792009-10-28 20:31:582454 ChromeThread::PostTask(
2455 ChromeThread::IO, FROM_HERE,
[email protected]be180c802009-10-23 06:33:312456 new SetProxyConfigTask(context_getter, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172457}
2458
[email protected]4f3dc372009-02-24 00:10:292459void AutomationProvider::GetDownloadDirectory(
[email protected]1f733cf2009-09-30 20:46:332460 int handle, FilePath* download_directory) {
initial.commit09911bf2008-07-26 23:55:292461 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292462 if (tab_tracker_->ContainsHandle(handle)) {
2463 NavigationController* tab = tab_tracker_->GetResource(handle);
2464 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2465 DCHECK(dlm);
[email protected]1f733cf2009-09-30 20:46:332466 *download_directory = dlm->download_path();
initial.commit09911bf2008-07-26 23:55:292467 }
initial.commit09911bf2008-07-26 23:55:292468}
2469
[email protected]6a5670d22009-10-27 16:21:342470void AutomationProvider::OpenNewBrowserWindow(bool show,
[email protected]14c0a032009-04-13 18:15:142471 IPC::Message* reply_message) {
[email protected]982921f12009-10-27 21:43:532472 OpenNewBrowserWindowOfType(static_cast<int>(Browser::TYPE_NORMAL), show,
2473 reply_message);
2474}
2475
2476void AutomationProvider::OpenNewBrowserWindowOfType(
2477 int type, bool show, IPC::Message* reply_message) {
[email protected]14c0a032009-04-13 18:15:142478 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292479 // We may have no current browser windows open so don't rely on
2480 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]982921f12009-10-27 21:43:532481 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
2482 browser->CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:052483 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152484 if (show)
[email protected]15952e462008-11-14 00:29:052485 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292486}
2487
[email protected]71f65dd2009-02-11 19:14:562488void AutomationProvider::GetWindowForBrowser(int browser_handle,
2489 bool* success,
2490 int* handle) {
2491 *success = false;
2492 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292493
2494 if (browser_tracker_->ContainsHandle(browser_handle)) {
2495 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202496 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292497 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202498 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562499 *success = true;
initial.commit09911bf2008-07-26 23:55:292500 }
initial.commit09911bf2008-07-26 23:55:292501}
2502
2503void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562504 int browser_handle,
2505 bool* success,
2506 int* autocomplete_edit_handle) {
2507 *success = false;
2508 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292509
2510 if (browser_tracker_->ContainsHandle(browser_handle)) {
2511 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062512 LocationBar* loc_bar = browser->window()->GetLocationBar();
2513 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292514 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562515 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2516 *success = true;
initial.commit09911bf2008-07-26 23:55:292517 }
initial.commit09911bf2008-07-26 23:55:292518}
initial.commit09911bf2008-07-26 23:55:292519
[email protected]71f65dd2009-02-11 19:14:562520void AutomationProvider::ShowInterstitialPage(int tab_handle,
2521 const std::string& html_text,
2522 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292523 if (tab_tracker_->ContainsHandle(tab_handle)) {
2524 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112525 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402526
[email protected]7dad3d5f2010-03-04 00:27:012527 AddNavigationStatusListener(controller, reply_message, 1, false);
[email protected]965524b2009-04-04 21:32:402528 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342529 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402530 GURL("about:interstitial"),
2531 html_text);
2532 interstitial->Show();
2533 return;
initial.commit09911bf2008-07-26 23:55:292534 }
[email protected]71f65dd2009-02-11 19:14:562535
[email protected]457f5cf2009-08-18 16:37:522536 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2537 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562538 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292539}
2540
[email protected]71f65dd2009-02-11 19:14:562541void AutomationProvider::HideInterstitialPage(int tab_handle,
2542 bool* success) {
2543 *success = false;
[email protected]57c6a652009-05-04 07:58:342544 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2545 if (tab_contents && tab_contents->interstitial_page()) {
2546 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562547 *success = true;
initial.commit09911bf2008-07-26 23:55:292548 }
initial.commit09911bf2008-07-26 23:55:292549}
2550
[email protected]71f65dd2009-02-11 19:14:562551void AutomationProvider::CloseTab(int tab_handle,
2552 bool wait_until_closed,
2553 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292554 if (tab_tracker_->ContainsHandle(tab_handle)) {
2555 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2556 int index;
2557 Browser* browser = Browser::GetBrowserForController(controller, &index);
2558 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142559 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112560 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452561 return;
initial.commit09911bf2008-07-26 23:55:292562 }
[email protected]de246f52009-02-25 18:25:452563
2564 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
[email protected]58f622a62009-10-04 01:17:552565 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292566}
2567
[email protected]71f65dd2009-02-11 19:14:562568void AutomationProvider::CloseBrowser(int browser_handle,
2569 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292570 if (browser_tracker_->ContainsHandle(browser_handle)) {
2571 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562572 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562573 reply_message);
[email protected]f3e99e32008-07-30 04:48:392574 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292575 } else {
2576 NOTREACHED();
2577 }
2578}
2579
[email protected]71f65dd2009-02-11 19:14:562580void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2581 if (browser_tracker_->ContainsHandle(browser_handle)) {
2582 Browser* browser = browser_tracker_->GetResource(browser_handle);
2583 browser->window()->Close();
2584 } else {
2585 NOTREACHED();
2586 }
2587}
2588
[email protected]71f65dd2009-02-11 19:14:562589void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2590 IPC::Message* reply_message) {
2591 if (tab_tracker_->ContainsHandle(tab_handle)) {
2592 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2593 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142594 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562595 }
2596}
2597
[email protected]71f65dd2009-02-11 19:14:562598void AutomationProvider::GetSecurityState(int handle, bool* success,
2599 SecurityStyle* security_style,
2600 int* ssl_cert_status,
[email protected]b4e75c12010-05-18 18:28:482601 int* insecure_content_status) {
initial.commit09911bf2008-07-26 23:55:292602 if (tab_tracker_->ContainsHandle(handle)) {
2603 NavigationController* tab = tab_tracker_->GetResource(handle);
2604 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562605 *success = true;
2606 *security_style = entry->ssl().security_style();
2607 *ssl_cert_status = entry->ssl().cert_status();
[email protected]b4e75c12010-05-18 18:28:482608 *insecure_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292609 } else {
[email protected]71f65dd2009-02-11 19:14:562610 *success = false;
2611 *security_style = SECURITY_STYLE_UNKNOWN;
2612 *ssl_cert_status = 0;
[email protected]b4e75c12010-05-18 18:28:482613 *insecure_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292614 }
2615}
2616
[email protected]71f65dd2009-02-11 19:14:562617void AutomationProvider::GetPageType(int handle, bool* success,
2618 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292619 if (tab_tracker_->ContainsHandle(handle)) {
2620 NavigationController* tab = tab_tracker_->GetResource(handle);
2621 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562622 *page_type = entry->page_type();
2623 *success = true;
initial.commit09911bf2008-07-26 23:55:292624 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342625 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562626 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342627 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562628 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292629 } else {
[email protected]71f65dd2009-02-11 19:14:562630 *success = false;
2631 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292632 }
2633}
2634
[email protected]84abba62009-10-07 17:01:442635void AutomationProvider::GetMetricEventDuration(const std::string& event_name,
2636 int* duration_ms) {
2637 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
2638 event_name);
2639}
2640
[email protected]71f65dd2009-02-11 19:14:562641void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2642 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292643 if (tab_tracker_->ContainsHandle(handle)) {
2644 NavigationController* tab = tab_tracker_->GetResource(handle);
2645 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072646 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402647 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472648 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342649 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292650 if (ssl_blocking_page) {
2651 if (proceed) {
[email protected]7dad3d5f2010-03-04 00:27:012652 AddNavigationStatusListener(tab, reply_message, 1, false);
[email protected]71f65dd2009-02-11 19:14:562653 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292654 return;
2655 }
2656 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522657 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2658 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562659 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292660 return;
2661 }
2662 }
2663 }
2664 // We failed.
[email protected]457f5cf2009-08-18 16:37:522665 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2666 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562667 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292668}
2669
[email protected]71f65dd2009-02-11 19:14:562670void AutomationProvider::BringBrowserToFront(int browser_handle,
2671 bool* success) {
initial.commit09911bf2008-07-26 23:55:292672 if (browser_tracker_->ContainsHandle(browser_handle)) {
2673 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062674 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562675 *success = true;
initial.commit09911bf2008-07-26 23:55:292676 } else {
[email protected]71f65dd2009-02-11 19:14:562677 *success = false;
initial.commit09911bf2008-07-26 23:55:292678 }
2679}
2680
[email protected]71f65dd2009-02-11 19:14:562681void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2682 int message_num,
2683 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292684 if (browser_tracker_->ContainsHandle(browser_handle)) {
2685 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562686 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142687 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292688 } else {
[email protected]71f65dd2009-02-11 19:14:562689 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292690 }
2691}
2692
[email protected]71f65dd2009-02-11 19:14:562693void AutomationProvider::PrintNow(int tab_handle,
2694 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572695 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342696 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2697 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292698 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572699 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142700 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342701 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572702 return;
initial.commit09911bf2008-07-26 23:55:292703 }
[email protected]71f65dd2009-02-11 19:14:562704 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2705 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292706}
[email protected]d301c952009-07-13 15:02:412707
[email protected]71f65dd2009-02-11 19:14:562708void AutomationProvider::SavePage(int tab_handle,
[email protected]828cabe2009-09-26 22:47:112709 const FilePath& file_name,
2710 const FilePath& dir_path,
[email protected]71f65dd2009-02-11 19:14:562711 int type,
2712 bool* success) {
initial.commit09911bf2008-07-26 23:55:292713 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562714 *success = false;
initial.commit09911bf2008-07-26 23:55:292715 return;
2716 }
2717
2718 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2719 Browser* browser = FindAndActivateTab(nav);
2720 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142721 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562722 *success = false;
initial.commit09911bf2008-07-26 23:55:292723 return;
2724 }
2725
initial.commit09911bf2008-07-26 23:55:292726 SavePackage::SavePackageType save_type =
2727 static_cast<SavePackage::SavePackageType>(type);
2728 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2729 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342730 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292731
[email protected]71f65dd2009-02-11 19:14:562732 *success = true;
initial.commit09911bf2008-07-26 23:55:292733}
2734
[email protected]71f65dd2009-02-11 19:14:562735void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2736 bool* success,
2737 std::wstring* text) {
2738 *success = false;
initial.commit09911bf2008-07-26 23:55:292739 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562740 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522741 GetText();
[email protected]71f65dd2009-02-11 19:14:562742 *success = true;
initial.commit09911bf2008-07-26 23:55:292743 }
initial.commit09911bf2008-07-26 23:55:292744}
2745
[email protected]71f65dd2009-02-11 19:14:562746void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2747 const std::wstring& text,
2748 bool* success) {
2749 *success = false;
initial.commit09911bf2008-07-26 23:55:292750 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522751 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2752 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562753 *success = true;
initial.commit09911bf2008-07-26 23:55:292754 }
initial.commit09911bf2008-07-26 23:55:292755}
2756
2757void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562758 int autocomplete_edit_handle,
2759 bool* success,
2760 std::vector<AutocompleteMatchData>* matches) {
2761 *success = false;
initial.commit09911bf2008-07-26 23:55:292762 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272763 const AutocompleteResult& result = autocomplete_edit_tracker_->
2764 GetResource(autocomplete_edit_handle)->model()->result();
2765 for (AutocompleteResult::const_iterator i = result.begin();
2766 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562767 matches->push_back(AutocompleteMatchData(*i));
2768 *success = true;
initial.commit09911bf2008-07-26 23:55:292769 }
initial.commit09911bf2008-07-26 23:55:292770}
2771
2772void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562773 int autocomplete_edit_handle,
2774 bool* success,
2775 bool* query_in_progress) {
2776 *success = false;
2777 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292778 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562779 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522780 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562781 *success = true;
initial.commit09911bf2008-07-26 23:55:292782 }
initial.commit09911bf2008-07-26 23:55:292783}
2784
[email protected]63514af2010-03-30 17:17:232785#if !defined(OS_MACOSX)
[email protected]f7a68432009-07-29 23:18:192786
[email protected]5ae5bed2009-08-21 18:52:442787#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:392788
[email protected]57c6a652009-05-04 07:58:342789TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572790 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572791 if (tab_tracker_->ContainsHandle(handle)) {
2792 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342793 if (tab)
2794 *tab = nav_controller;
2795 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572796 }
[email protected]57c6a652009-05-04 07:58:342797 return NULL;
[email protected]20e93d12008-08-28 16:31:572798}
2799
initial.commit09911bf2008-07-26 23:55:292800TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2801 : AutomationProvider(profile) {
2802 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142803 registrar_.Add(this, NotificationType::SESSION_END,
2804 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292805}
2806
2807TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292808 BrowserList::RemoveObserver(this);
2809}
2810
2811void TestingAutomationProvider::OnChannelError() {
[email protected]a9324442009-10-12 04:32:142812 BrowserList::CloseAllBrowsersAndExit();
initial.commit09911bf2008-07-26 23:55:292813 AutomationProvider::OnChannelError();
2814}
2815
2816void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2817 // For backwards compatibility with the testing automation interface, we
2818 // want the automation provider (and hence the process) to go away when the
2819 // last browser goes away.
2820 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292821 // If you change this, update Observer for NotificationType::SESSION_END
2822 // below.
[email protected]295039bd2008-08-15 04:32:572823 MessageLoop::current()->PostTask(FROM_HERE,
2824 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292825 }
2826}
2827
2828void TestingAutomationProvider::Observe(NotificationType type,
2829 const NotificationSource& source,
2830 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562831 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292832 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2833 // before the task runs resulting in this object not being deleted. This
2834 // Release balance out the Release scheduled by OnBrowserRemoving.
2835 Release();
2836}
[email protected]295039bd2008-08-15 04:32:572837
2838void TestingAutomationProvider::OnRemoveProvider() {
2839 AutomationProviderList::GetInstance()->RemoveProvider(this);
2840}
[email protected]8a3422c92008-09-24 17:42:422841
[email protected]816633a2009-11-11 21:48:182842void AutomationProvider::GetInfoBarCount(int handle, int* count) {
[email protected]71f65dd2009-02-11 19:14:562843 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422844 if (tab_tracker_->ContainsHandle(handle)) {
2845 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342846 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112847 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422848 }
[email protected]8a3422c92008-09-24 17:42:422849}
2850
[email protected]816633a2009-11-11 21:48:182851void AutomationProvider::ClickInfoBarAccept(int handle,
2852 int info_bar_index,
2853 bool wait_for_navigation,
2854 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422855 bool success = false;
2856 if (tab_tracker_->ContainsHandle(handle)) {
2857 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2858 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112859 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422860 if (info_bar_index >= 0 && info_bar_index < count) {
2861 if (wait_for_navigation) {
[email protected]7dad3d5f2010-03-04 00:27:012862 AddNavigationStatusListener(nav_controller, reply_message, 1, false);
[email protected]8a3422c92008-09-24 17:42:422863 }
[email protected]eb9ba192008-12-02 02:41:342864 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112865 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342866 info_bar_index);
2867 if (delegate->AsConfirmInfoBarDelegate())
2868 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422869 success = true;
2870 }
2871 }
[email protected]4f3dc372009-02-24 00:10:292872 }
[email protected]58f622a62009-10-04 01:17:552873
2874 // This "!wait_for_navigation || !success condition" logic looks suspicious.
2875 // It will send a failure message when success is true but
2876 // |wait_for_navigation| is false.
2877 // TODO(phajdan.jr): investgate whether the reply param (currently
2878 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
[email protected]8a3422c92008-09-24 17:42:422879 if (!wait_for_navigation || !success)
[email protected]816633a2009-11-11 21:48:182880 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
[email protected]457f5cf2009-08-18 16:37:522881 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422882}
2883
[email protected]71f65dd2009-02-11 19:14:562884void AutomationProvider::GetLastNavigationTime(int handle,
2885 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422886 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562887 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422888}
2889
[email protected]71f65dd2009-02-11 19:14:562890void AutomationProvider::WaitForNavigation(int handle,
2891 int64 last_navigation_time,
2892 IPC::Message* reply_message) {
[email protected]5fa7acd2009-09-25 20:04:252893 NavigationController* controller = tab_tracker_->GetResource(handle);
[email protected]8a3422c92008-09-24 17:42:422894 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]5fa7acd2009-09-25 20:04:252895
[email protected]8a3422c92008-09-24 17:42:422896 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562897 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522898 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
2899 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]58f622a62009-10-04 01:17:552900 Send(reply_message);
[email protected]4f3dc372009-02-24 00:10:292901 return;
[email protected]8a3422c92008-09-24 17:42:422902 }
2903
[email protected]7dad3d5f2010-03-04 00:27:012904 AddNavigationStatusListener(controller, reply_message, 1, true);
[email protected]8a3422c92008-09-24 17:42:422905}
2906
[email protected]71f65dd2009-02-11 19:14:562907void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162908 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562909 int value,
2910 bool* success) {
2911 *success = false;
[email protected]8a3422c92008-09-24 17:42:422912 if (browser_tracker_->ContainsHandle(handle)) {
2913 Browser* browser = browser_tracker_->GetResource(handle);
2914 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562915 *success = true;
[email protected]8a3422c92008-09-24 17:42:422916 }
[email protected]8a3422c92008-09-24 17:42:422917}
[email protected]97fa6ce32008-12-19 01:48:162918
[email protected]71f65dd2009-02-11 19:14:562919void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162920 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562921 const std::wstring& value,
2922 bool* success) {
2923 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162924 if (browser_tracker_->ContainsHandle(handle)) {
2925 Browser* browser = browser_tracker_->GetResource(handle);
2926 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562927 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162928 }
[email protected]97fa6ce32008-12-19 01:48:162929}
2930
[email protected]71f65dd2009-02-11 19:14:562931void AutomationProvider::GetBooleanPreference(int handle,
2932 const std::wstring& name,
[email protected]b8f48d12009-11-09 20:14:362933 bool* success,
2934 bool* value) {
[email protected]71f65dd2009-02-11 19:14:562935 *success = false;
2936 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162937 if (browser_tracker_->ContainsHandle(handle)) {
2938 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562939 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2940 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162941 }
[email protected]97fa6ce32008-12-19 01:48:162942}
2943
[email protected]71f65dd2009-02-11 19:14:562944void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162945 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562946 bool value,
2947 bool* success) {
2948 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162949 if (browser_tracker_->ContainsHandle(handle)) {
2950 Browser* browser = browser_tracker_->GetResource(handle);
2951 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562952 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162953 }
[email protected]97fa6ce32008-12-19 01:48:162954}
2955
2956// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562957void AutomationProvider::GetPageCurrentEncoding(
[email protected]41fc0322009-09-04 22:23:402958 int tab_handle, std::string* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162959 if (tab_tracker_->ContainsHandle(tab_handle)) {
2960 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2961 Browser* browser = FindAndActivateTab(nav);
2962 DCHECK(browser);
2963
[email protected]57c6a652009-05-04 07:58:342964 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2965 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162966 }
[email protected]97fa6ce32008-12-19 01:48:162967}
2968
[email protected]b8f48d12009-11-09 20:14:362969// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562970void AutomationProvider::OverrideEncoding(int tab_handle,
[email protected]41fc0322009-09-04 22:23:402971 const std::string& encoding_name,
[email protected]71f65dd2009-02-11 19:14:562972 bool* success) {
2973 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162974 if (tab_tracker_->ContainsHandle(tab_handle)) {
2975 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
[email protected]2f2afba2010-04-01 01:53:192976 if (!nav)
2977 return;
[email protected]97fa6ce32008-12-19 01:48:162978 Browser* browser = FindAndActivateTab(nav);
[email protected]97fa6ce32008-12-19 01:48:162979
[email protected]2f2afba2010-04-01 01:53:192980 // If the browser has UI, simulate what a user would do.
2981 // Activate the tab and then click the encoding menu.
2982 if (browser &&
2983 browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162984 int selected_encoding_id =
2985 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2986 if (selected_encoding_id) {
2987 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562988 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162989 }
[email protected]2f2afba2010-04-01 01:53:192990 } else {
2991 // There is no UI, Chrome probably runs as Chrome-Frame mode.
2992 // Try to get TabContents and call its override_encoding method.
2993 TabContents* contents = nav->tab_contents();
2994 if (!contents)
2995 return;
2996 const std::string selected_encoding =
2997 CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
2998 if (selected_encoding.empty())
2999 return;
3000 contents->SetOverrideEncoding(selected_encoding);
[email protected]97fa6ce32008-12-19 01:48:163001 }
3002 }
[email protected]97fa6ce32008-12-19 01:48:163003}
[email protected]5bcdb312009-01-07 21:43:203004
[email protected]4d434a1a2009-02-11 21:06:573005void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203006 SavePackage::SetShouldPromptUser(should_prompt);
3007}
[email protected]87eab222009-03-13 00:47:453008
[email protected]66ba4932009-06-04 19:22:133009void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3010 *count = -1; // -1 is the error code
3011 if (tab_tracker_->ContainsHandle(handle)) {
3012 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3013 TabContents* tab_contents = nav_controller->tab_contents();
3014 if (tab_contents) {
3015 BlockedPopupContainer* container =
3016 tab_contents->blocked_popup_container();
3017 if (container) {
3018 *count = static_cast<int>(container->GetBlockedPopupCount());
3019 } else {
3020 // If we don't have a container, we don't have any blocked popups to
3021 // contain!
3022 *count = 0;
3023 }
3024 }
3025 }
3026}
[email protected]f7a68432009-07-29 23:18:193027
3028void AutomationProvider::SelectAll(int tab_handle) {
3029 RenderViewHost* view = GetViewForTab(tab_handle);
3030 if (!view) {
3031 NOTREACHED();
3032 return;
3033 }
3034
3035 view->SelectAll();
3036}
3037
3038void AutomationProvider::Cut(int tab_handle) {
3039 RenderViewHost* view = GetViewForTab(tab_handle);
3040 if (!view) {
3041 NOTREACHED();
3042 return;
3043 }
3044
3045 view->Cut();
3046}
3047
3048void AutomationProvider::Copy(int tab_handle) {
3049 RenderViewHost* view = GetViewForTab(tab_handle);
3050 if (!view) {
3051 NOTREACHED();
3052 return;
3053 }
3054
3055 view->Copy();
3056}
3057
3058void AutomationProvider::Paste(int tab_handle) {
3059 RenderViewHost* view = GetViewForTab(tab_handle);
3060 if (!view) {
3061 NOTREACHED();
3062 return;
3063 }
3064
3065 view->Paste();
3066}
3067
3068void AutomationProvider::ReloadAsync(int tab_handle) {
3069 if (tab_tracker_->ContainsHandle(tab_handle)) {
3070 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3071 if (!tab) {
3072 NOTREACHED();
3073 return;
3074 }
3075
[email protected]106a0812010-03-18 00:15:123076 const bool check_for_repost = true;
3077 tab->Reload(check_for_repost);
[email protected]f7a68432009-07-29 23:18:193078 }
3079}
3080
3081void AutomationProvider::StopAsync(int tab_handle) {
3082 RenderViewHost* view = GetViewForTab(tab_handle);
3083 if (!view) {
[email protected]8b2b3312009-09-14 18:38:363084 // We tolerate StopAsync being called even before a view has been created.
3085 // So just log a warning instead of a NOTREACHED().
3086 DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
[email protected]f7a68432009-07-29 23:18:193087 return;
3088 }
3089
3090 view->Stop();
3091}
3092
[email protected]1bb5f892009-10-06 01:44:573093void AutomationProvider::OnSetPageFontSize(int tab_handle,
3094 int font_size) {
3095 AutomationPageFontSize automation_font_size =
3096 static_cast<AutomationPageFontSize>(font_size);
3097
3098 if (automation_font_size < SMALLEST_FONT ||
3099 automation_font_size > LARGEST_FONT) {
3100 DLOG(ERROR) << "Invalid font size specified : "
3101 << font_size;
3102 return;
3103 }
3104
3105 if (tab_tracker_->ContainsHandle(tab_handle)) {
3106 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3107 DCHECK(tab != NULL);
3108 if (tab && tab->tab_contents()) {
3109 DCHECK(tab->tab_contents()->profile() != NULL);
3110 tab->tab_contents()->profile()->GetPrefs()->SetInteger(
3111 prefs::kWebKitDefaultFontSize, font_size);
3112 }
3113 }
3114}
3115
[email protected]bc73b4e52010-03-26 04:16:203116void AutomationProvider::RemoveBrowsingData(int remove_mask) {
3117 BrowsingDataRemover* remover;
3118 remover = new BrowsingDataRemover(profile(),
3119 BrowsingDataRemover::EVERYTHING, // All time periods.
3120 base::Time());
3121 remover->Remove(remove_mask);
3122 // BrowsingDataRemover deletes itself.
3123}
[email protected]1bb5f892009-10-06 01:44:573124
[email protected]2949e90d2009-08-21 15:32:523125void AutomationProvider::WaitForBrowserWindowCountToBecome(
3126 int target_count, IPC::Message* reply_message) {
3127 if (static_cast<int>(BrowserList::size()) == target_count) {
3128 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3129 reply_message, true);
3130 Send(reply_message);
3131 return;
3132 }
3133
3134 // Set up an observer (it will delete itself).
3135 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3136}
3137
3138void AutomationProvider::WaitForAppModalDialogToBeShown(
3139 IPC::Message* reply_message) {
3140 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3141 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3142 reply_message, true);
3143 Send(reply_message);
3144 return;
3145 }
3146
3147 // Set up an observer (it will delete itself).
3148 new AppModalDialogShownObserver(this, reply_message);
3149}
3150
[email protected]1126a1d32009-08-26 15:39:263151void AutomationProvider::GoBackBlockUntilNavigationsComplete(
3152 int handle, int number_of_navigations, IPC::Message* reply_message) {
3153 if (tab_tracker_->ContainsHandle(handle)) {
3154 NavigationController* tab = tab_tracker_->GetResource(handle);
3155 Browser* browser = FindAndActivateTab(tab);
3156 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]7dad3d5f2010-03-04 00:27:013157 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3158 false);
[email protected]1126a1d32009-08-26 15:39:263159 browser->GoBack(CURRENT_TAB);
3160 return;
3161 }
3162 }
3163
3164 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
3165 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3166 Send(reply_message);
3167}
3168
3169void AutomationProvider::GoForwardBlockUntilNavigationsComplete(
3170 int handle, int number_of_navigations, IPC::Message* reply_message) {
3171 if (tab_tracker_->ContainsHandle(handle)) {
3172 NavigationController* tab = tab_tracker_->GetResource(handle);
3173 Browser* browser = FindAndActivateTab(tab);
3174 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]7dad3d5f2010-03-04 00:27:013175 AddNavigationStatusListener(tab, reply_message, number_of_navigations,
3176 false);
[email protected]1126a1d32009-08-26 15:39:263177 browser->GoForward(CURRENT_TAB);
3178 return;
3179 }
3180 }
3181
3182 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
3183 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
3184 Send(reply_message);
3185}
3186
[email protected]f7a68432009-07-29 23:18:193187RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3188 if (tab_tracker_->ContainsHandle(tab_handle)) {
3189 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3190 if (!tab) {
3191 NOTREACHED();
3192 return NULL;
3193 }
3194
3195 TabContents* tab_contents = tab->tab_contents();
3196 if (!tab_contents) {
3197 NOTREACHED();
3198 return NULL;
3199 }
3200
3201 RenderViewHost* view_host = tab_contents->render_view_host();
3202 return view_host;
3203 }
3204
3205 return NULL;
3206}
[email protected]675595f2009-08-26 22:32:043207
3208void AutomationProvider::GetBrowserForWindow(int window_handle,
3209 bool* success,
3210 int* browser_handle) {
3211 *success = false;
3212 *browser_handle = 0;
3213
3214 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
3215 if (!window)
3216 return;
3217
3218 BrowserList::const_iterator iter = BrowserList::begin();
3219 for (;iter != BrowserList::end(); ++iter) {
3220 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
3221 if (window == this_window) {
3222 // Add() returns the existing handle for the resource if any.
3223 *browser_handle = browser_tracker_->Add(*iter);
3224 *success = true;
3225 return;
3226 }
3227 }
3228}
[email protected]d11c8e92009-10-20 23:26:403229
3230void AutomationProvider::InstallExtension(const FilePath& crx_path,
3231 IPC::Message* reply_message) {
3232 ExtensionsService* service = profile_->GetExtensionsService();
3233 if (service) {
3234 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193235 new ExtensionInstallNotificationObserver(this,
3236 AutomationMsg_InstallExtension::ID,
3237 reply_message);
[email protected]d11c8e92009-10-20 23:26:403238
3239 const FilePath& install_dir = service->install_directory();
[email protected]6dfbbf82010-03-12 23:09:163240 scoped_refptr<CrxInstaller> installer(
3241 new CrxInstaller(install_dir,
3242 service,
3243 NULL)); // silent install, no UI
3244 installer->set_allow_privilege_increase(true);
3245 installer->InstallCrx(crx_path);
[email protected]d11c8e92009-10-20 23:26:403246 } else {
3247 AutomationMsg_InstallExtension::WriteReplyParams(
3248 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3249 Send(reply_message);
3250 }
3251}
3252
3253void AutomationProvider::LoadExpandedExtension(
3254 const FilePath& extension_dir,
3255 IPC::Message* reply_message) {
[email protected]a4378252010-02-09 08:14:383256 if (profile_->GetExtensionsService()) {
[email protected]d11c8e92009-10-20 23:26:403257 // The observer will delete itself when done.
[email protected]790788ac2010-04-06 17:52:193258 new ExtensionInstallNotificationObserver(
3259 this,
3260 AutomationMsg_LoadExpandedExtension::ID,
3261 reply_message);
[email protected]d11c8e92009-10-20 23:26:403262
3263 profile_->GetExtensionsService()->LoadExtension(extension_dir);
[email protected]d11c8e92009-10-20 23:26:403264 } else {
3265 AutomationMsg_LoadExpandedExtension::WriteReplyParams(
3266 reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
3267 Send(reply_message);
3268 }
3269}
[email protected]673fd2c02010-02-04 23:10:003270
[email protected]a1e62d12010-03-16 02:18:433271void AutomationProvider::GetEnabledExtensions(
3272 std::vector<FilePath>* result) {
3273 ExtensionsService* service = profile_->GetExtensionsService();
3274 DCHECK(service);
3275 if (service->extensions_enabled()) {
3276 const ExtensionList* extensions = service->extensions();
3277 DCHECK(extensions);
3278 for (size_t i = 0; i < extensions->size(); ++i) {
3279 Extension* extension = (*extensions)[i];
3280 DCHECK(extension);
[email protected]472f099b2010-05-27 17:07:123281 if (extension->location() == Extension::INTERNAL ||
3282 extension->location() == Extension::LOAD) {
[email protected]237f281672010-03-20 12:37:073283 result->push_back(extension->path());
3284 }
[email protected]a1e62d12010-03-16 02:18:433285 }
3286 }
3287}
3288
[email protected]790788ac2010-04-06 17:52:193289void AutomationProvider::WaitForExtensionTestResult(
3290 IPC::Message* reply_message) {
3291 DCHECK(reply_message_ == NULL);
3292 reply_message_ = reply_message;
3293 // Call MaybeSendResult, because the result might have come in before
3294 // we were waiting on it.
3295 extension_test_result_observer_->MaybeSendResult();
3296}
3297
3298void AutomationProvider::InstallExtensionAndGetHandle(
[email protected]d7e5525d2010-04-20 14:37:093299 const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
[email protected]790788ac2010-04-06 17:52:193300 ExtensionsService* service = profile_->GetExtensionsService();
3301 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3302 if (service && manager) {
3303 // The observer will delete itself when done.
3304 new ExtensionReadyNotificationObserver(
3305 manager,
3306 this,
3307 AutomationMsg_InstallExtensionAndGetHandle::ID,
3308 reply_message);
3309
[email protected]d7e5525d2010-04-20 14:37:093310 ExtensionInstallUI* client =
3311 (with_ui ? new ExtensionInstallUI(profile_) : NULL);
[email protected]790788ac2010-04-06 17:52:193312 scoped_refptr<CrxInstaller> installer(
3313 new CrxInstaller(service->install_directory(),
3314 service,
[email protected]d7e5525d2010-04-20 14:37:093315 client));
[email protected]790788ac2010-04-06 17:52:193316 installer->set_allow_privilege_increase(true);
3317 installer->InstallCrx(crx_path);
3318 } else {
3319 AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
3320 reply_message, 0);
3321 Send(reply_message);
3322 }
3323}
3324
3325void AutomationProvider::UninstallExtension(int extension_handle,
3326 bool* success) {
3327 *success = false;
3328 Extension* extension = GetExtension(extension_handle);
3329 ExtensionsService* service = profile_->GetExtensionsService();
3330 if (extension && service) {
3331 ExtensionUnloadNotificationObserver observer;
3332 service->UninstallExtension(extension->id(), false);
3333 // The extension unload notification should have been sent synchronously
3334 // with the uninstall. Just to be safe, check that it was received.
3335 *success = observer.did_receive_unload_notification();
3336 }
3337}
3338
3339void AutomationProvider::EnableExtension(int extension_handle,
3340 IPC::Message* reply_message) {
3341 Extension* extension = GetDisabledExtension(extension_handle);
3342 ExtensionsService* service = profile_->GetExtensionsService();
3343 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
3344 // Only enable if this extension is disabled.
3345 if (extension && service && manager) {
3346 // The observer will delete itself when done.
3347 new ExtensionReadyNotificationObserver(
3348 manager,
3349 this,
3350 AutomationMsg_EnableExtension::ID,
3351 reply_message);
3352 service->EnableExtension(extension->id());
3353 } else {
3354 AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
3355 Send(reply_message);
3356 }
3357}
3358
3359void AutomationProvider::DisableExtension(int extension_handle,
3360 bool* success) {
3361 *success = false;
3362 Extension* extension = GetEnabledExtension(extension_handle);
3363 ExtensionsService* service = profile_->GetExtensionsService();
3364 if (extension && service) {
3365 ExtensionUnloadNotificationObserver observer;
3366 service->DisableExtension(extension->id());
3367 // The extension unload notification should have been sent synchronously
3368 // with the disable. Just to be safe, check that it was received.
3369 *success = observer.did_receive_unload_notification();
3370 }
3371}
3372
3373void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
3374 int extension_handle, int browser_handle,
3375 IPC::Message* reply_message) {
3376 bool success = false;
3377 Extension* extension = GetEnabledExtension(extension_handle);
3378 ExtensionsService* service = profile_->GetExtensionsService();
3379 ExtensionMessageService* message_service =
3380 profile_->GetExtensionMessageService();
3381 Browser* browser = browser_tracker_->GetResource(browser_handle);
3382 if (extension && service && message_service && browser) {
3383 int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
3384 if (extension->page_action()) {
3385 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
3386 browser->profile(), extension->id(), "action", tab_id, "", 1);
3387 success = true;
3388 } else if (extension->browser_action()) {
3389 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
3390 browser->profile(), extension->id(), browser);
3391 success = true;
3392 }
3393 }
3394 AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
3395 reply_message, success);
3396 Send(reply_message);
3397}
3398
3399void AutomationProvider::MoveExtensionBrowserAction(
3400 int extension_handle, int index, bool* success) {
3401 *success = false;
3402 Extension* extension = GetEnabledExtension(extension_handle);
3403 ExtensionsService* service = profile_->GetExtensionsService();
3404 if (extension && service) {
3405 ExtensionToolbarModel* toolbar = service->toolbar_model();
3406 if (toolbar) {
3407 if (index >= 0 && index < static_cast<int>(toolbar->size())) {
3408 toolbar->MoveBrowserAction(extension, index);
3409 *success = true;
3410 } else {
3411 DLOG(WARNING) << "Attempted to move browser action to invalid index.";
3412 }
3413 }
3414 }
3415}
3416
3417void AutomationProvider::GetExtensionProperty(
3418 int extension_handle,
3419 AutomationMsg_ExtensionProperty type,
3420 bool* success,
3421 std::string* value) {
3422 *success = false;
3423 Extension* extension = GetExtension(extension_handle);
3424 ExtensionsService* service = profile_->GetExtensionsService();
3425 if (extension && service) {
3426 ExtensionToolbarModel* toolbar = service->toolbar_model();
3427 int found_index = -1;
3428 int index = 0;
3429 switch (type) {
3430 case AUTOMATION_MSG_EXTENSION_ID:
3431 *value = extension->id();
3432 *success = true;
3433 break;
3434 case AUTOMATION_MSG_EXTENSION_NAME:
3435 *value = extension->name();
3436 *success = true;
3437 break;
3438 case AUTOMATION_MSG_EXTENSION_VERSION:
3439 *value = extension->VersionString();
3440 *success = true;
3441 break;
3442 case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
3443 if (toolbar) {
3444 for (ExtensionList::const_iterator iter = toolbar->begin();
3445 iter != toolbar->end(); iter++) {
3446 // Skip this extension if we are in incognito mode
3447 // and it is not incognito-enabled.
3448 if (profile_->IsOffTheRecord() &&
3449 !service->IsIncognitoEnabled(*iter))
3450 continue;
3451 if (*iter == extension) {
3452 found_index = index;
3453 break;
3454 }
3455 index++;
3456 }
3457 *value = IntToString(found_index);
3458 *success = true;
3459 }
3460 break;
3461 default:
3462 LOG(WARNING) << "Trying to get undefined extension property";
3463 break;
3464 }
3465 }
3466}
3467
[email protected]673fd2c02010-02-04 23:10:003468void AutomationProvider::SaveAsAsync(int tab_handle) {
3469 NavigationController* tab = NULL;
3470 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
3471 if (tab_contents)
3472 tab_contents->OnSavePage();
3473}
[email protected]7dad3d5f2010-03-04 00:27:013474
3475void AutomationProvider::SetContentSetting(
3476 int handle,
3477 const std::string& host,
3478 ContentSettingsType content_type,
3479 ContentSetting setting,
3480 bool* success) {
3481 *success = false;
3482 if (browser_tracker_->ContainsHandle(handle)) {
3483 Browser* browser = browser_tracker_->GetResource(handle);
3484 HostContentSettingsMap* map =
3485 browser->profile()->GetHostContentSettingsMap();
3486 if (host.empty()) {
3487 map->SetDefaultContentSetting(content_type, setting);
3488 } else {
[email protected]0314ae02010-04-08 09:18:293489 map->SetContentSetting(HostContentSettingsMap::Pattern(host),
3490 content_type, setting);
[email protected]7dad3d5f2010-03-04 00:27:013491 }
3492 *success = true;
3493 }
3494}
[email protected]cc824372010-03-31 15:33:013495
3496#if !defined(TOOLKIT_VIEWS)
3497void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
3498 NOTIMPLEMENTED();
3499};
3500
3501void AutomationProvider::WaitForFocusedViewIDToChange(
3502 int handle, int previous_view_id, IPC::Message* reply_message) {
3503 NOTIMPLEMENTED();
3504}
3505
3506void AutomationProvider::StartTrackingPopupMenus(
3507 int browser_handle, bool* success) {
3508 NOTIMPLEMENTED();
3509}
3510
3511void AutomationProvider::WaitForPopupMenuToOpen(IPC::Message* reply_message) {
3512 NOTIMPLEMENTED();
3513}
3514#endif // !defined(TOOLKIT_VIEWS)
[email protected]d7e5525d2010-04-20 14:37:093515
3516void AutomationProvider::ResetToDefaultTheme() {
3517 profile_->ClearTheme();
3518}