blob: a4f797c6aa73b90ac2141d6ec36257aa24ff2b4b [file] [log] [blame]
[email protected]4801ecc2009-04-05 04:52:581// Copyright (c) 2006-2009 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]202e7a72009-06-15 03:48:367#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:318#include "app/message_box_flags.h"
[email protected]c6cb1992009-04-13 16:45:299#include "base/file_version_info.h"
[email protected]a9024892009-06-16 23:13:5510#include "base/json_reader.h"
[email protected]5fac9622009-02-04 21:49:3811#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/path_service.h"
[email protected]f44265b2009-05-19 18:52:5013#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2714#include "base/string_util.h"
[email protected]5fac9622009-02-04 21:49:3815#include "base/thread.h"
[email protected]a7eee32f2009-05-22 18:08:1716#include "base/values.h"
[email protected]4f3dc372009-02-24 00:10:2917#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2818#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0919#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]b83e4602009-05-15 22:58:3320#include "chrome/browser/automation/automation_extension_function.h"
initial.commit09911bf2008-07-26 23:55:2921#include "chrome/browser/automation/automation_provider_list.h"
[email protected]a9024892009-06-16 23:13:5522#include "chrome/browser/automation/extension_automation_constants.h"
[email protected]f44265b2009-05-19 18:52:5023#include "chrome/browser/automation/extension_port_container.h"
[email protected]66ba4932009-06-04 19:22:1324#include "chrome/browser/blocked_popup_container.h"
[email protected]5c238752009-06-13 10:29:0725#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3926#include "chrome/browser/browser_window.h"
initial.commit09911bf2008-07-26 23:55:2927#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1228#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5929#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2230#include "chrome/browser/download/download_shelf.h"
[email protected]a9024892009-06-16 23:13:5531#include "chrome/browser/extensions/extension_message_service.h"
[email protected]4801ecc2009-04-05 04:52:5832#include "chrome/browser/find_bar.h"
33#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/browser/find_notification_details.h"
[email protected]13869dd2009-05-05 00:40:0635#include "chrome/browser/location_bar.h"
[email protected]f732c1e2009-07-30 15:48:5336#include "chrome/browser/net/url_request_mock_util.h"
[email protected]a7eee32f2009-05-22 18:08:1737#include "chrome/browser/profile_manager.h"
[email protected]6524b5f92009-01-22 17:48:2538#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0339#include "chrome/browser/ssl/ssl_manager.h"
40#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3441#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4542#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1743#include "chrome/common/automation_constants.h"
initial.commit09911bf2008-07-26 23:55:2944#include "chrome/common/chrome_paths.h"
[email protected]a7eee32f2009-05-22 18:08:1745#include "chrome/common/json_value_serializer.h"
[email protected]1c58a5c2009-05-21 18:47:1446#include "chrome/common/notification_service.h"
[email protected]3753f522009-04-14 23:15:4747#include "chrome/common/platform_util.h"
[email protected]8a3422c92008-09-24 17:42:4248#include "chrome/common/pref_service.h"
[email protected]71f65dd2009-02-11 19:14:5649#include "chrome/test/automation/automation_messages.h"
[email protected]a7eee32f2009-05-22 18:08:1750#include "net/proxy/proxy_service.h"
51#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2152#include "net/url_request/url_request_context.h"
[email protected]9a08bcf2009-08-12 19:56:2853#include "views/event.h"
initial.commit09911bf2008-07-26 23:55:2954
[email protected]de246f52009-02-25 18:25:4555#if defined(OS_WIN)
56// TODO(port): Port these headers.
[email protected]de246f52009-02-25 18:25:4557#include "chrome/browser/character_encoding.h"
58#include "chrome/browser/download/save_package.h"
59#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4560#include "chrome/browser/printing/print_job.h"
[email protected]de246f52009-02-25 18:25:4561#endif // defined(OS_WIN)
62
[email protected]e8382172009-06-19 22:16:2863#if defined(OS_WIN) || defined(OS_LINUX)
64// TODO(port): Port these to the mac.
[email protected]9a08bcf2009-08-12 19:56:2865#include "chrome/browser/automation/ui_controls.h"
[email protected]e8382172009-06-19 22:16:2866#include "chrome/browser/login_prompt.h"
67#endif
68
[email protected]13869dd2009-05-05 00:40:0669#if defined(OS_WIN)
70#include "chrome/browser/views/bookmark_bar_view.h"
[email protected]9095e982009-05-27 17:28:2471#include "views/widget/root_view.h"
[email protected]2362e4f2009-05-08 00:34:0572#include "views/widget/widget_win.h"
73#include "views/window/window.h"
[email protected]13869dd2009-05-05 00:40:0674#endif
75
[email protected]e1acf6f2008-10-27 20:43:3376using base::Time;
77
[email protected]f5446092009-07-30 21:10:0178#if defined(OS_WIN)
79static void MoveMouse(const POINT& point) {
80 SetCursorPos(point.x, point.y);
81
82 // Now, make sure that GetMessagePos returns the values we just set by
83 // simulating a mouse move. The value returned by GetMessagePos is updated
84 // when a mouse move event is removed from the event queue.
85 PostMessage(NULL, WM_MOUSEMOVE, 0, MAKELPARAM(point.x, point.y));
86 MSG msg;
87 while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
88 ;
89
90 // Verify
91#ifndef NDEBUG
92 DWORD pos = GetMessagePos();
93 DCHECK_EQ(point.x, GET_X_LPARAM(pos));
94 DCHECK_EQ(point.y, GET_Y_LPARAM(pos));
95#endif
96}
97#endif
98
initial.commit09911bf2008-07-26 23:55:2999class InitialLoadObserver : public NotificationObserver {
100 public:
101 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
[email protected]66791d22009-02-24 20:11:33102 : automation_(automation),
103 outstanding_tab_count_(tab_count) {
initial.commit09911bf2008-07-26 23:55:29104 if (outstanding_tab_count_ > 0) {
[email protected]bfd04a62009-02-01 18:16:56105 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:03106 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:56107 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:03108 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29109 }
110 }
111
112 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:29113 }
114
115 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:03116 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29117 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
118 }
119
initial.commit09911bf2008-07-26 23:55:29120 virtual void Observe(NotificationType type,
121 const NotificationSource& source,
122 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56123 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29124 if (outstanding_tab_count_ > loading_tabs_.size())
125 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:56126 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29127 if (outstanding_tab_count_ > finished_tabs_.size()) {
128 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
129 finished_tabs_.insert(source.map_key());
130 if (outstanding_tab_count_ == finished_tabs_.size())
131 ConditionMet();
132 }
133 } else {
134 NOTREACHED();
135 }
136 }
137
138 private:
139 typedef std::set<uintptr_t> TabSet;
140
[email protected]6a02963e2009-01-06 16:58:03141 NotificationRegistrar registrar_;
142
initial.commit09911bf2008-07-26 23:55:29143 AutomationProvider* automation_;
144 size_t outstanding_tab_count_;
145 TabSet loading_tabs_;
146 TabSet finished_tabs_;
147};
148
149// Watches for NewTabUI page loads for performance timing purposes.
150class NewTabUILoadObserver : public NotificationObserver {
151 public:
152 explicit NewTabUILoadObserver(AutomationProvider* automation)
153 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14154 registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
155 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29156 }
157
158 ~NewTabUILoadObserver() {
initial.commit09911bf2008-07-26 23:55:29159 }
160
161 virtual void Observe(NotificationType type,
162 const NotificationSource& source,
163 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56164 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29165 Details<int> load_time(details);
166 automation_->Send(
167 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
168 } else {
169 NOTREACHED();
170 }
171 }
172
173 private:
[email protected]1c58a5c2009-05-21 18:47:14174 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29175 AutomationProvider* automation_;
176};
177
178class NavigationControllerRestoredObserver : public NotificationObserver {
179 public:
180 NavigationControllerRestoredObserver(AutomationProvider* automation,
181 NavigationController* controller,
[email protected]71f65dd2009-02-11 19:14:56182 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29183 : automation_(automation),
184 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56185 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29186 if (FinishedRestoring()) {
initial.commit09911bf2008-07-26 23:55:29187 SendDone();
188 } else {
[email protected]1c58a5c2009-05-21 18:47:14189 registrar_.Add(this, NotificationType::LOAD_STOP,
190 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29191 }
192 }
193
194 ~NavigationControllerRestoredObserver() {
initial.commit09911bf2008-07-26 23:55:29195 }
196
197 virtual void Observe(NotificationType type,
198 const NotificationSource& source,
199 const NotificationDetails& details) {
200 if (FinishedRestoring()) {
201 SendDone();
[email protected]1c58a5c2009-05-21 18:47:14202 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29203 }
204 }
205
206 private:
initial.commit09911bf2008-07-26 23:55:29207 bool FinishedRestoring() {
[email protected]7f0005a2009-04-15 03:25:11208 return (!controller_->needs_reload() && !controller_->pending_entry() &&
209 !controller_->tab_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29210 }
211
212 void SendDone() {
[email protected]71f65dd2009-02-11 19:14:56213 DCHECK(reply_message_ != NULL);
214 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29215 }
216
[email protected]1c58a5c2009-05-21 18:47:14217 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29218 AutomationProvider* automation_;
219 NavigationController* controller_;
[email protected]71f65dd2009-02-11 19:14:56220 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29221
[email protected]5a52f162008-08-27 04:15:31222 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29223};
224
[email protected]71f65dd2009-02-11 19:14:56225template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29226class NavigationNotificationObserver : public NotificationObserver {
227 public:
228 NavigationNotificationObserver(NavigationController* controller,
229 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56230 IPC::Message* reply_message,
231 NavigationCodeType success_code,
232 NavigationCodeType auth_needed_code,
233 NavigationCodeType failed_code)
initial.commit09911bf2008-07-26 23:55:29234 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56235 reply_message_(reply_message),
initial.commit09911bf2008-07-26 23:55:29236 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56237 navigation_started_(false),
238 success_code_(success_code),
239 auth_needed_code_(auth_needed_code),
240 failed_code_(failed_code) {
[email protected]1c58a5c2009-05-21 18:47:14241 Source<NavigationController> source(controller_);
242 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
243 registrar_.Add(this, NotificationType::LOAD_START, source);
244 registrar_.Add(this, NotificationType::LOAD_STOP, source);
245 registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
246 registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
initial.commit09911bf2008-07-26 23:55:29247 }
248
249 ~NavigationNotificationObserver() {
[email protected]1c58a5c2009-05-21 18:47:14250 if (reply_message_) {
251 // This means we did not receive a notification for this navigation.
252 // Send over a failed navigation status back to the caller to ensure that
253 // the caller does not hang waiting for the response.
254 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
255 failed_code_);
256 automation_->Send(reply_message_);
257 reply_message_ = NULL;
258 }
259
260 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29261 }
262
[email protected]71f65dd2009-02-11 19:14:56263 void ConditionMet(NavigationCodeType navigation_result) {
264 DCHECK(reply_message_ != NULL);
265
266 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
267 navigation_result);
268 automation_->Send(reply_message_);
269 reply_message_ = NULL;
270
initial.commit09911bf2008-07-26 23:55:29271 delete this;
272 }
273
initial.commit09911bf2008-07-26 23:55:29274 virtual void Observe(NotificationType type,
275 const NotificationSource& source,
276 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42277 // We listen for 2 events to determine when the navigation started because:
278 // - when this is used by the WaitForNavigation method, we might be invoked
279 // afer the load has started (but not after the entry was committed, as
280 // WaitForNavigation compares times of the last navigation).
281 // - when this is used with a page requiring authentication, we will not get
[email protected]4f3dc372009-02-24 00:10:29282 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
283 // we need the NotificationType::LOAD_START.
[email protected]bfd04a62009-02-01 18:16:56284 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
285 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29286 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56287 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29288 if (navigation_started_) {
289 navigation_started_ = false;
[email protected]71f65dd2009-02-11 19:14:56290 ConditionMet(success_code_);
initial.commit09911bf2008-07-26 23:55:29291 }
[email protected]bfd04a62009-02-01 18:16:56292 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29293 // The LoginHandler for this tab is no longer valid.
294 automation_->RemoveLoginHandler(controller_);
295
296 // Treat this as if navigation started again, since load start/stop don't
297 // occur while authentication is ongoing.
298 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56299 } else if (type == NotificationType::AUTH_NEEDED) {
[email protected]de246f52009-02-25 18:25:45300#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29301 if (navigation_started_) {
302 // Remember the login handler that wants authentication.
303 LoginHandler* handler =
304 Details<LoginNotificationDetails>(details)->handler();
305 automation_->AddLoginHandler(controller_, handler);
306
307 // Respond that authentication is needed.
308 navigation_started_ = false;
[email protected]71f65dd2009-02-11 19:14:56309 ConditionMet(auth_needed_code_);
initial.commit09911bf2008-07-26 23:55:29310 } else {
311 NOTREACHED();
312 }
[email protected]de246f52009-02-25 18:25:45313#else
314 // TODO(port): Enable when we have LoginNotificationDetails etc.
315 NOTIMPLEMENTED();
316#endif
initial.commit09911bf2008-07-26 23:55:29317 } else {
318 NOTREACHED();
319 }
320 }
321
322 private:
[email protected]1c58a5c2009-05-21 18:47:14323 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29324 AutomationProvider* automation_;
[email protected]71f65dd2009-02-11 19:14:56325 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29326 NavigationController* controller_;
327 bool navigation_started_;
[email protected]71f65dd2009-02-11 19:14:56328 NavigationCodeType success_code_;
329 NavigationCodeType auth_needed_code_;
330 NavigationCodeType failed_code_;
initial.commit09911bf2008-07-26 23:55:29331};
332
333class TabStripNotificationObserver : public NotificationObserver {
334 public:
[email protected]1c58a5c2009-05-21 18:47:14335 TabStripNotificationObserver(NotificationType notification,
336 AutomationProvider* automation)
337 : automation_(automation),
338 notification_(notification) {
339 registrar_.Add(this, notification_, NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29340 }
341
342 virtual ~TabStripNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29343 }
344
345 virtual void Observe(NotificationType type,
346 const NotificationSource& source,
347 const NotificationDetails& details) {
348 if (type == notification_) {
349 ObserveTab(Source<NavigationController>(source).ptr());
350
351 // If verified, no need to observe anymore
352 automation_->RemoveTabStripObserver(this);
353 delete this;
354 } else {
355 NOTREACHED();
356 }
357 }
358
359 virtual void ObserveTab(NavigationController* controller) = 0;
360
361 protected:
[email protected]1c58a5c2009-05-21 18:47:14362 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29363 AutomationProvider* automation_;
initial.commit09911bf2008-07-26 23:55:29364 NotificationType notification_;
initial.commit09911bf2008-07-26 23:55:29365};
366
367class TabAppendedNotificationObserver : public TabStripNotificationObserver {
368 public:
369 TabAppendedNotificationObserver(Browser* parent,
[email protected]1c58a5c2009-05-21 18:47:14370 AutomationProvider* automation,
371 IPC::Message* reply_message)
372 : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
373 automation),
374 parent_(parent),
[email protected]71f65dd2009-02-11 19:14:56375 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29376 }
377
378 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14379 if (automation_->GetIndexForNavigationController(controller, parent_) ==
380 TabStripModel::kNoTab) {
381 // This tab notification doesn't belong to the parent_.
initial.commit09911bf2008-07-26 23:55:29382 return;
383 }
384
385 // Give the same response even if auth is needed, since it doesn't matter.
[email protected]71f65dd2009-02-11 19:14:56386 automation_->AddNavigationStatusListener<int>(
387 controller, reply_message_, AUTOMATION_MSG_NAVIGATION_SUCCESS,
388 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED, AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:29389 }
[email protected]71f65dd2009-02-11 19:14:56390
391 protected:
[email protected]1c58a5c2009-05-21 18:47:14392 Browser* parent_;
[email protected]71f65dd2009-02-11 19:14:56393 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29394};
395
396class TabClosedNotificationObserver : public TabStripNotificationObserver {
397 public:
[email protected]1c58a5c2009-05-21 18:47:14398 TabClosedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56399 bool wait_until_closed,
400 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:14401 : TabStripNotificationObserver(wait_until_closed ?
402 NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
403 automation),
404 reply_message_(reply_message),
405 for_browser_command_(false) {
initial.commit09911bf2008-07-26 23:55:29406 }
407
408 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14409 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42410 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
411 true);
[email protected]1c58a5c2009-05-21 18:47:14412 } else {
[email protected]d79ffea2009-05-07 20:51:42413 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
[email protected]1c58a5c2009-05-21 18:47:14414 }
[email protected]71f65dd2009-02-11 19:14:56415 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29416 }
[email protected]71f65dd2009-02-11 19:14:56417
[email protected]d79ffea2009-05-07 20:51:42418 void set_for_browser_command(bool for_browser_command) {
419 for_browser_command_ = for_browser_command;
420 }
[email protected]1c58a5c2009-05-21 18:47:14421
[email protected]71f65dd2009-02-11 19:14:56422 protected:
423 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42424 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29425};
426
[email protected]14c0a032009-04-13 18:15:14427class BrowserOpenedNotificationObserver : public NotificationObserver {
428 public:
429 BrowserOpenedNotificationObserver(AutomationProvider* automation,
430 IPC::Message* reply_message)
431 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42432 reply_message_(reply_message),
433 for_browser_command_(false) {
[email protected]14c0a032009-04-13 18:15:14434 registrar_.Add(this, NotificationType::BROWSER_OPENED,
435 NotificationService::AllSources());
436 }
437
438 ~BrowserOpenedNotificationObserver() {
439 }
440
441 virtual void Observe(NotificationType type,
442 const NotificationSource& source,
443 const NotificationDetails& details) {
444 if (type == NotificationType::BROWSER_OPENED) {
[email protected]1c58a5c2009-05-21 18:47:14445 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42446 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
447 true);
[email protected]1c58a5c2009-05-21 18:47:14448 }
[email protected]14c0a032009-04-13 18:15:14449 automation_->Send(reply_message_);
450 delete this;
451 } else {
452 NOTREACHED();
453 }
454 }
455
[email protected]d79ffea2009-05-07 20:51:42456 void set_for_browser_command(bool for_browser_command) {
457 for_browser_command_ = for_browser_command;
458 }
[email protected]1c58a5c2009-05-21 18:47:14459
[email protected]14c0a032009-04-13 18:15:14460 private:
[email protected]1c58a5c2009-05-21 18:47:14461 NotificationRegistrar registrar_;
[email protected]14c0a032009-04-13 18:15:14462 AutomationProvider* automation_;
463 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42464 bool for_browser_command_;
[email protected]14c0a032009-04-13 18:15:14465};
466
initial.commit09911bf2008-07-26 23:55:29467class BrowserClosedNotificationObserver : public NotificationObserver {
468 public:
469 BrowserClosedNotificationObserver(Browser* browser,
470 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56471 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29472 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42473 reply_message_(reply_message),
474 for_browser_command_(false) {
[email protected]c300deb32009-05-08 21:26:07475 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
476 Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29477 }
478
479 virtual void Observe(NotificationType type,
480 const NotificationSource& source,
481 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56482 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29483 Details<bool> close_app(details);
[email protected]71f65dd2009-02-11 19:14:56484 DCHECK(reply_message_ != NULL);
[email protected]1c58a5c2009-05-21 18:47:14485 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42486 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
487 true);
[email protected]1c58a5c2009-05-21 18:47:14488 } else {
[email protected]d79ffea2009-05-07 20:51:42489 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
490 *(close_app.ptr()));
[email protected]1c58a5c2009-05-21 18:47:14491 }
[email protected]71f65dd2009-02-11 19:14:56492 automation_->Send(reply_message_);
493 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29494 delete this;
495 }
496
[email protected]d79ffea2009-05-07 20:51:42497 void set_for_browser_command(bool for_browser_command) {
498 for_browser_command_ = for_browser_command;
499 }
[email protected]1c58a5c2009-05-21 18:47:14500
initial.commit09911bf2008-07-26 23:55:29501 private:
[email protected]c300deb32009-05-08 21:26:07502 NotificationRegistrar registrar_;
[email protected]1c58a5c2009-05-21 18:47:14503 AutomationProvider* automation_;
504 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42505 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29506};
507
[email protected]4e41709d2009-04-08 00:04:27508namespace {
509
510// Define mapping from command to notification
511struct CommandNotification {
512 int command;
513 NotificationType::Type notification_type;
514};
515
516const struct CommandNotification command_notifications[] = {
[email protected]14c0a032009-04-13 18:15:14517 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
[email protected]f8fc5882009-05-06 04:23:43518 {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
[email protected]d79ffea2009-05-07 20:51:42519 // Returns as soon as the restored tab is created. To further wait until
520 // the content page is loaded, use WaitForTabToBeRestored.
[email protected]f8fc5882009-05-06 04:23:43521 {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
[email protected]4e41709d2009-04-08 00:04:27522};
523
524} // namespace
525
[email protected]56e71b7c2009-03-27 03:05:56526class ExecuteBrowserCommandObserver : public NotificationObserver {
527 public:
[email protected]56e71b7c2009-03-27 03:05:56528 ~ExecuteBrowserCommandObserver() {
529 }
530
[email protected]d79ffea2009-05-07 20:51:42531 static bool CreateAndRegisterObserver(AutomationProvider* automation,
532 Browser* browser,
533 int command,
534 IPC::Message* reply_message) {
535 bool result = true;
536 switch (command) {
537 case IDC_NEW_WINDOW:
538 case IDC_NEW_INCOGNITO_WINDOW: {
539 BrowserOpenedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14540 new BrowserOpenedNotificationObserver(automation, reply_message);
[email protected]d79ffea2009-05-07 20:51:42541 observer->set_for_browser_command(true);
542 break;
543 }
544 case IDC_CLOSE_WINDOW: {
545 BrowserClosedNotificationObserver* observer =
546 new BrowserClosedNotificationObserver(browser, automation,
[email protected]d79ffea2009-05-07 20:51:42547 reply_message);
548 observer->set_for_browser_command(true);
549 break;
550 }
551 case IDC_CLOSE_TAB: {
552 TabClosedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14553 new TabClosedNotificationObserver(automation, true, reply_message);
[email protected]d79ffea2009-05-07 20:51:42554 observer->set_for_browser_command(true);
555 break;
556 }
[email protected]27e1c9e02009-05-13 18:41:39557 case IDC_BACK:
558 case IDC_FORWARD:
559 case IDC_RELOAD: {
560 automation->
561 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
562 &browser->GetSelectedTabContents()->controller(),
563 reply_message,
564 AUTOMATION_MSG_NAVIGATION_SUCCESS,
565 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
566 AUTOMATION_MSG_NAVIGATION_ERROR);
567 break;
568 }
[email protected]d79ffea2009-05-07 20:51:42569 default: {
570 ExecuteBrowserCommandObserver* observer =
571 new ExecuteBrowserCommandObserver(automation, reply_message);
572 if (!observer->Register(command)) {
573 delete observer;
574 result = false;
575 }
576 break;
577 }
578 }
579 return result;
[email protected]4e41709d2009-04-08 00:04:27580 }
581
[email protected]56e71b7c2009-03-27 03:05:56582 virtual void Observe(NotificationType type,
583 const NotificationSource& source,
584 const NotificationDetails& details) {
585 if (type == notification_type_) {
[email protected]49a14a82009-03-31 04:16:44586 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
587 true);
[email protected]56e71b7c2009-03-27 03:05:56588 automation_->Send(reply_message_);
589 delete this;
590 } else {
591 NOTREACHED();
592 }
593 }
594
595 private:
[email protected]d79ffea2009-05-07 20:51:42596 ExecuteBrowserCommandObserver(AutomationProvider* automation,
597 IPC::Message* reply_message)
598 : automation_(automation),
599 reply_message_(reply_message) {
600 }
601
602 bool Register(int command) {
603 if (!GetNotificationType(command, &notification_type_))
604 return false;
[email protected]1c58a5c2009-05-21 18:47:14605 registrar_.Add(this, notification_type_, NotificationService::AllSources());
[email protected]d79ffea2009-05-07 20:51:42606 return true;
607 }
608
[email protected]4e41709d2009-04-08 00:04:27609 bool GetNotificationType(int command, NotificationType::Type* type) {
610 if (!type)
611 return false;
612 bool found = false;
613 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
614 if (command_notifications[i].command == command) {
615 *type = command_notifications[i].notification_type;
616 found = true;
617 break;
618 }
619 }
620 return found;
621 }
622
[email protected]1c58a5c2009-05-21 18:47:14623 NotificationRegistrar registrar_;
[email protected]56e71b7c2009-03-27 03:05:56624 AutomationProvider* automation_;
625 NotificationType::Type notification_type_;
626 IPC::Message* reply_message_;
[email protected]56e71b7c2009-03-27 03:05:56627};
628
initial.commit09911bf2008-07-26 23:55:29629class FindInPageNotificationObserver : public NotificationObserver {
630 public:
631 FindInPageNotificationObserver(AutomationProvider* automation,
632 TabContents* parent_tab,
[email protected]71f65dd2009-02-11 19:14:56633 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29634 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56635 active_match_ordinal_(-1),
636 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14637 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
638 Source<TabContents>(parent_tab));
initial.commit09911bf2008-07-26 23:55:29639 }
640
641 ~FindInPageNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29642 }
643
[email protected]1c58a5c2009-05-21 18:47:14644 virtual void Observe(NotificationType type,
645 const NotificationSource& source,
646 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56647 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29648 Details<FindNotificationDetails> find_details(details);
649 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49650 // We get multiple responses and one of those will contain the ordinal.
651 // This message comes to us before the final update is sent.
652 if (find_details->active_match_ordinal() > -1)
653 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29654 if (find_details->final_update()) {
[email protected]d97a5642009-07-16 19:33:26655 if (reply_message_ != NULL) {
656 AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
657 active_match_ordinal_, find_details->number_of_matches());
658 automation_->Send(reply_message_);
659 reply_message_ = NULL;
660 } else {
661 DLOG(WARNING) << "Multiple final Find messages observed.";
662 }
initial.commit09911bf2008-07-26 23:55:29663 } else {
664 DLOG(INFO) << "Ignoring, since we only care about the final message";
665 }
666 }
667 } else {
668 NOTREACHED();
669 }
670 }
671
672 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
673 // we wait for notification to find out what the results are. As the user is
674 // typing, new search requests can be issued and the Request ID helps us make
675 // sense of whether this is the current request or an old one. The unit tests,
676 // however, which uses this constant issues only one search at a time, so we
677 // don't need a rolling id to identify each search. But, we still need to
678 // specify one, so we just use a fixed one - its value does not matter.
679 static const int kFindInPageRequestId;
[email protected]1c58a5c2009-05-21 18:47:14680
initial.commit09911bf2008-07-26 23:55:29681 private:
[email protected]1c58a5c2009-05-21 18:47:14682 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29683 AutomationProvider* automation_;
[email protected]aedd85a2008-12-04 19:32:49684 // We will at some point (before final update) be notified of the ordinal and
685 // we need to preserve it so we can send it later.
686 int active_match_ordinal_;
[email protected]71f65dd2009-02-11 19:14:56687 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29688};
689
690const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
691
692class DomOperationNotificationObserver : public NotificationObserver {
693 public:
694 explicit DomOperationNotificationObserver(AutomationProvider* automation)
695 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14696 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
697 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29698 }
699
700 ~DomOperationNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29701 }
702
[email protected]1c58a5c2009-05-21 18:47:14703 virtual void Observe(NotificationType type,
704 const NotificationSource& source,
705 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56706 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29707 Details<DomOperationNotificationDetails> dom_op_details(details);
[email protected]71f65dd2009-02-11 19:14:56708
709 IPC::Message* reply_message = automation_->reply_message_release();
710 DCHECK(reply_message != NULL);
711
[email protected]1c58a5c2009-05-21 18:47:14712 AutomationMsg_DomOperation::WriteReplyParams(reply_message,
713 dom_op_details->json());
[email protected]71f65dd2009-02-11 19:14:56714 automation_->Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29715 }
716 }
[email protected]1c58a5c2009-05-21 18:47:14717
initial.commit09911bf2008-07-26 23:55:29718 private:
[email protected]1c58a5c2009-05-21 18:47:14719 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29720 AutomationProvider* automation_;
721};
722
[email protected]de246f52009-02-25 18:25:45723#if defined(OS_WIN)
724// TODO(port): Enable when printing is ported.
initial.commit09911bf2008-07-26 23:55:29725class DocumentPrintedNotificationObserver : public NotificationObserver {
726 public:
727 DocumentPrintedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56728 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29729 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56730 success_(false),
731 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14732 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
733 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29734 }
735
736 ~DocumentPrintedNotificationObserver() {
[email protected]71f65dd2009-02-11 19:14:56737 DCHECK(reply_message_ != NULL);
738 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
739 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29740 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29741 }
742
743 virtual void Observe(NotificationType type, const NotificationSource& source,
744 const NotificationDetails& details) {
745 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56746 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29747 switch (Details<JobEventDetails>(details)->type()) {
748 case JobEventDetails::JOB_DONE: {
749 // Succeeded.
750 success_ = true;
751 delete this;
752 break;
753 }
754 case JobEventDetails::USER_INIT_CANCELED:
755 case JobEventDetails::FAILED: {
756 // Failed.
757 delete this;
758 break;
759 }
760 case JobEventDetails::NEW_DOC:
761 case JobEventDetails::USER_INIT_DONE:
762 case JobEventDetails::DEFAULT_INIT_DONE:
763 case JobEventDetails::NEW_PAGE:
764 case JobEventDetails::PAGE_DONE:
765 case JobEventDetails::DOC_DONE:
766 case JobEventDetails::ALL_PAGES_REQUESTED: {
767 // Don't care.
768 break;
769 }
770 default: {
771 NOTREACHED();
772 break;
773 }
774 }
775 }
776
777 private:
[email protected]1c58a5c2009-05-21 18:47:14778 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29779 scoped_refptr<AutomationProvider> automation_;
initial.commit09911bf2008-07-26 23:55:29780 bool success_;
[email protected]71f65dd2009-02-11 19:14:56781 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29782};
[email protected]de246f52009-02-25 18:25:45783#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29784
[email protected]cbab76d2008-10-13 22:42:47785class AutomationInterstitialPage : public InterstitialPage {
786 public:
[email protected]57c6a652009-05-04 07:58:34787 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47788 const GURL& url,
789 const std::string& contents)
790 : InterstitialPage(tab, true, url),
791 contents_(contents) {
792 }
793
794 virtual std::string GetHTMLContents() { return contents_; }
795
796 private:
797 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29798
[email protected]cbab76d2008-10-13 22:42:47799 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
800};
801
initial.commit09911bf2008-07-26 23:55:29802AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57803 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56804 profile_(profile),
805 reply_message_(NULL) {
initial.commit09911bf2008-07-26 23:55:29806 browser_tracker_.reset(new AutomationBrowserTracker(this));
initial.commit09911bf2008-07-26 23:55:29807 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20808 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29809 autocomplete_edit_tracker_.reset(
810 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29811 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
812 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
initial.commit09911bf2008-07-26 23:55:29813}
814
815AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50816 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
817 port_containers_.end());
818 port_containers_.clear();
819
[email protected]0da050b92008-08-19 19:29:47820 // Make sure that any outstanding NotificationObservers also get destroyed.
821 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31822 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47823 while ((observer = it.GetNext()) != NULL)
824 delete observer;
initial.commit09911bf2008-07-26 23:55:29825}
826
[email protected]9a3a293b2009-06-04 22:28:16827void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06828 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57829 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06830 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
831 automation_resource_message_filter_,
832 g_browser_process->io_thread()->message_loop(),
833 true, g_browser_process->shutdown_event()));
[email protected]79e966832009-04-21 14:23:05834 scoped_ptr<FileVersionInfo> file_version_info(
835 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
[email protected]cf620752009-04-24 17:05:40836 std::string version_string;
837 if (file_version_info != NULL) {
838 version_string = WideToASCII(file_version_info->file_version());
839 }
[email protected]c6cb1992009-04-13 16:45:29840
841 // Send a hello message with our current automation protocol version.
842 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29843}
844
845void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
846 if (expected_tabs == 0) {
847 Send(new AutomationMsg_InitialLoadsComplete(0));
848 } else {
849 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
850 }
851}
852
[email protected]71f65dd2009-02-11 19:14:56853template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29854NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]71f65dd2009-02-11 19:14:56855 NavigationController* tab, IPC::Message* reply_message,
856 NavigationCodeType success_code,
857 NavigationCodeType auth_needed_code,
858 NavigationCodeType failed_code) {
initial.commit09911bf2008-07-26 23:55:29859 NotificationObserver* observer =
[email protected]71f65dd2009-02-11 19:14:56860 new NavigationNotificationObserver<NavigationCodeType>(
861 tab, this, reply_message, success_code, auth_needed_code,
862 failed_code);
initial.commit09911bf2008-07-26 23:55:29863
[email protected]71f65dd2009-02-11 19:14:56864 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29865 return observer;
866}
867
868void AutomationProvider::RemoveNavigationStatusListener(
869 NotificationObserver* obs) {
870 notification_observer_list_.RemoveObserver(obs);
871}
872
873NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14874 Browser* parent,
875 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56876 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14877 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29878 notification_observer_list_.AddObserver(observer);
879
880 return observer;
881}
882
883void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
884 notification_observer_list_.RemoveObserver(obs);
885}
886
887void AutomationProvider::AddLoginHandler(NavigationController* tab,
888 LoginHandler* handler) {
889 login_handler_map_[tab] = handler;
890}
891
892void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
893 DCHECK(login_handler_map_[tab]);
894 login_handler_map_.erase(tab);
895}
896
[email protected]f44265b2009-05-19 18:52:50897void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
898 int port_id = port->port_id();
899 DCHECK_NE(-1, port_id);
900 DCHECK(port_containers_.find(port_id) == port_containers_.end());
901
902 port_containers_[port_id] = port;
903}
904
905void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
906 int port_id = port->port_id();
907 DCHECK_NE(-1, port_id);
908
909 PortContainerMap::iterator it = port_containers_.find(port_id);
910 DCHECK(it != port_containers_.end());
911
912 if (it != port_containers_.end()) {
913 delete it->second;
914 port_containers_.erase(it);
915 }
916}
917
918ExtensionPortContainer* AutomationProvider::GetPortContainer(
919 int port_id) const {
920 PortContainerMap::const_iterator it = port_containers_.find(port_id);
921 if (it == port_containers_.end())
922 return NULL;
923
924 return it->second;
925}
926
initial.commit09911bf2008-07-26 23:55:29927int AutomationProvider::GetIndexForNavigationController(
928 const NavigationController* controller, const Browser* parent) const {
929 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12930 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29931}
932
933void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
934 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14935 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56936 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
937 CloseBrowserAsync)
938 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
939 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
940 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
941 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
942 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
943 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]1c58a5c2009-05-21 18:47:14944 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]71f65dd2009-02-11 19:14:56945 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
946 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
947 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
948 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
949 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14950 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56951 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
952 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
953 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14954 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29955 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
956 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56957 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36958 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56959 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29960 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56961 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29962 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
963 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56964 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14965 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]de246f52009-02-25 18:25:45966#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56967 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWND, GetWindowHWND)
[email protected]de246f52009-02-25 18:25:45968#endif // defined(OS_WIN)
[email protected]49a14a82009-03-31 04:16:44969 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33970 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44971 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33972 ExecuteBrowserCommand)
[email protected]1c58a5c2009-05-21 18:47:14973 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8f04ff92009-07-08 02:37:15974 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14975 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]de246f52009-02-25 18:25:45976#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56977 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]9a08bcf2009-08-12 19:56:28978#endif // defined(OS_WIN)
979#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]1c58a5c2009-05-21 18:47:14980 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]9a08bcf2009-08-12 19:56:28981#endif
982#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56983 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
984 WindowSimulateDrag)
[email protected]d7fa7552009-03-20 21:06:37985#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56986 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
987 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37988#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56989 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45990#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56991 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
992 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03993 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56994 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14995 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
initial.commit09911bf2008-07-26 23:55:29996 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14997 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56998 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
999 ExecuteJavascript)
1000 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:291001 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:141002 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
1003 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:561004 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
1005 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:141006 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:171007 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:141008 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:141009 OpenNewBrowserWindow)
1010 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:561011 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:141012 GetAutocompleteEditForBrowser)
1013 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:451014#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291015 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:171016#endif
[email protected]71f65dd2009-02-11 19:14:561017 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:291018 NavigateInExternalTab)
[email protected]71f65dd2009-02-11 19:14:561019 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141020 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:561021 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141022 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:171023#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291024 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
1025 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:171026#endif
[email protected]71f65dd2009-02-11 19:14:561027 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
1028 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:141029 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:171030#if defined(OS_WIN)
[email protected]87eab222009-03-13 00:47:451031 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:391032 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
1033 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:171034#endif
[email protected]1c58a5c2009-05-21 18:47:141035 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
1036 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]71f65dd2009-02-11 19:14:561037 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
1038 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:291039 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
1040 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
1041 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:561042 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:411043 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:561044 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
1045 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:291046 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561047 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:291048 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561049 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:291050 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:561051 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:291052 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:561053 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:451054 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:451055 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
1056 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:141057 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:561058 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:571059 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:561060 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:571061 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:561062 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
1063 GetBookmarkBarVisibility)
[email protected]1c58a5c2009-05-21 18:47:141064 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCount, GetSSLInfoBarCount)
[email protected]71f65dd2009-02-11 19:14:561065 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickSSLInfoBarLink,
1066 ClickSSLInfoBarLink)
1067 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:421068 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:561069 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
1070 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:141071 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:561072 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:441073 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:561074 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:201075 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:141076 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:561077 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161078 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561079 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161080 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561081 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:161082 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:141083 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:201084 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
1085 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:141086 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]b83e4602009-05-15 22:58:331087 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
1088 SetEnableExtensionAutomation)
[email protected]59560e0b2009-06-04 03:30:221089 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:131090 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:191091 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
1092 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
1093 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
1094 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
1095 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
1096 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
initial.commit09911bf2008-07-26 23:55:291097 IPC_END_MESSAGE_MAP()
1098}
1099
[email protected]71f65dd2009-02-11 19:14:561100void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
1101 *status = -1;
initial.commit09911bf2008-07-26 23:55:291102 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
1103 Browser* browser = browser_tracker_->GetResource(handle);
1104 if (at_index >= 0 && at_index < browser->tab_count()) {
1105 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:561106 *status = 0;
initial.commit09911bf2008-07-26 23:55:291107 }
1108 }
initial.commit09911bf2008-07-26 23:55:291109}
1110
[email protected]71f65dd2009-02-11 19:14:561111void AutomationProvider::AppendTab(int handle, const GURL& url,
1112 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291113 int append_tab_response = -1; // -1 is the error code
1114 NotificationObserver* observer = NULL;
1115
1116 if (browser_tracker_->ContainsHandle(handle)) {
1117 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:141118 observer = AddTabStripObserver(browser, reply_message);
[email protected]22735af62009-04-07 21:09:581119 TabContents* tab_contents = browser->AddTabWithURL(url, GURL(),
1120 PageTransition::TYPED,
[email protected]5a4940be2009-05-06 06:44:391121 true, -1, false, NULL);
initial.commit09911bf2008-07-26 23:55:291122 if (tab_contents) {
1123 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:571124 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:291125 }
1126 }
1127
1128 if (append_tab_response < 0) {
1129 // The append tab failed. Remove the TabStripObserver
1130 if (observer) {
1131 RemoveTabStripObserver(observer);
1132 delete observer;
1133 }
1134
[email protected]71f65dd2009-02-11 19:14:561135 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
1136 append_tab_response);
1137 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291138 }
1139}
1140
[email protected]71f65dd2009-02-11 19:14:561141void AutomationProvider::NavigateToURL(int handle, const GURL& url,
1142 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291143 if (tab_tracker_->ContainsHandle(handle)) {
1144 NavigationController* tab = tab_tracker_->GetResource(handle);
1145
1146 // Simulate what a user would do. Activate the tab and then navigate.
1147 // We could allow navigating in a background tab in future.
1148 Browser* browser = FindAndActivateTab(tab);
1149
1150 if (browser) {
[email protected]71f65dd2009-02-11 19:14:561151 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1152 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1153 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1154 AUTOMATION_MSG_NAVIGATION_ERROR);
1155
initial.commit09911bf2008-07-26 23:55:291156 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:501157 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:291158 return;
1159 }
1160 }
[email protected]71f65dd2009-02-11 19:14:561161
1162 AutomationMsg_NavigateToURL::WriteReplyParams(
1163 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1164 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291165}
1166
[email protected]71f65dd2009-02-11 19:14:561167void AutomationProvider::NavigationAsync(int handle, const GURL& url,
1168 bool* status) {
1169 *status = false;
initial.commit09911bf2008-07-26 23:55:291170
1171 if (tab_tracker_->ContainsHandle(handle)) {
1172 NavigationController* tab = tab_tracker_->GetResource(handle);
1173
1174 // Simulate what a user would do. Activate the tab and then navigate.
1175 // We could allow navigating in a background tab in future.
1176 Browser* browser = FindAndActivateTab(tab);
1177
1178 if (browser) {
1179 // Don't add any listener unless a callback mechanism is desired.
1180 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:501181 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:561182 *status = true;
initial.commit09911bf2008-07-26 23:55:291183 }
1184 }
initial.commit09911bf2008-07-26 23:55:291185}
1186
[email protected]71f65dd2009-02-11 19:14:561187void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291188 if (tab_tracker_->ContainsHandle(handle)) {
1189 NavigationController* tab = tab_tracker_->GetResource(handle);
1190 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141191 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]71f65dd2009-02-11 19:14:561192 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1193 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1194 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1195 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291196 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291197 return;
1198 }
1199 }
[email protected]71f65dd2009-02-11 19:14:561200
1201 AutomationMsg_GoBack::WriteReplyParams(
1202 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1203 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291204}
1205
[email protected]71f65dd2009-02-11 19:14:561206void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291207 if (tab_tracker_->ContainsHandle(handle)) {
1208 NavigationController* tab = tab_tracker_->GetResource(handle);
1209 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141210 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]71f65dd2009-02-11 19:14:561211 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1212 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1213 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1214 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291215 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291216 return;
1217 }
1218 }
[email protected]71f65dd2009-02-11 19:14:561219
1220 AutomationMsg_GoForward::WriteReplyParams(
1221 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1222 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291223}
1224
[email protected]71f65dd2009-02-11 19:14:561225void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291226 if (tab_tracker_->ContainsHandle(handle)) {
1227 NavigationController* tab = tab_tracker_->GetResource(handle);
1228 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141229 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]71f65dd2009-02-11 19:14:561230 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1231 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1232 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1233 AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:291234 browser->Reload();
1235 return;
1236 }
1237 }
[email protected]71f65dd2009-02-11 19:14:561238
1239 AutomationMsg_Reload::WriteReplyParams(
1240 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1241 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291242}
1243
[email protected]71f65dd2009-02-11 19:14:561244void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:291245 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:561246 const std::wstring& password,
1247 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291248 int status = -1;
1249
1250 if (tab_tracker_->ContainsHandle(tab_handle)) {
1251 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1252 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1253
1254 if (iter != login_handler_map_.end()) {
1255 // If auth is needed again after this, assume login has failed. This is
1256 // not strictly correct, because a navigation can require both proxy and
1257 // server auth, but it should be OK for now.
1258 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561259 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291260 handler->SetAuth(username, password);
1261 status = 0;
1262 }
1263 }
[email protected]de246f52009-02-25 18:25:451264
initial.commit09911bf2008-07-26 23:55:291265 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561266 AutomationMsg_SetAuth::WriteReplyParams(reply_message, status);
1267 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291268 }
1269}
1270
[email protected]71f65dd2009-02-11 19:14:561271void AutomationProvider::CancelAuth(int tab_handle,
1272 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291273 int status = -1;
1274
1275 if (tab_tracker_->ContainsHandle(tab_handle)) {
1276 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1277 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1278
1279 if (iter != login_handler_map_.end()) {
1280 // If auth is needed again after this, something is screwy.
1281 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561282 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291283 handler->CancelAuth();
1284 status = 0;
1285 }
1286 }
[email protected]de246f52009-02-25 18:25:451287
initial.commit09911bf2008-07-26 23:55:291288 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561289 AutomationMsg_CancelAuth::WriteReplyParams(reply_message, status);
1290 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291291 }
1292}
1293
[email protected]71f65dd2009-02-11 19:14:561294void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
1295 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:291296
1297 if (tab_tracker_->ContainsHandle(tab_handle)) {
1298 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1299 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1300
1301 if (iter != login_handler_map_.end()) {
1302 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:561303 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:291304 }
1305 }
initial.commit09911bf2008-07-26 23:55:291306}
1307
[email protected]71f65dd2009-02-11 19:14:561308void AutomationProvider::GetRedirectsFrom(int tab_handle,
1309 const GURL& source_url,
1310 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291311 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1312 if (tab_tracker_->ContainsHandle(tab_handle)) {
1313 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1314 HistoryService* history_service =
1315 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1316
1317 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1318 "has no history service";
1319 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:561320 DCHECK(reply_message_ == NULL);
1321 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291322 // Schedule a history query for redirects. The response will be sent
1323 // asynchronously from the callback the history system uses to notify us
1324 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:291325 redirect_query_ = history_service->QueryRedirectsFrom(
1326 source_url, &consumer_,
1327 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1328 return; // Response will be sent when query completes.
1329 }
1330 }
1331
1332 // Send failure response.
[email protected]deb57402009-02-06 01:35:301333 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:561334 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
1335 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291336}
1337
[email protected]71f65dd2009-02-11 19:14:561338void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
1339 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291340 if (browser_tracker_->ContainsHandle(handle)) {
1341 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561342 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:291343 }
initial.commit09911bf2008-07-26 23:55:291344}
1345
[email protected]202e7a72009-06-15 03:48:361346void AutomationProvider::GetBrowserLocale(string16* locale) {
1347 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:061348 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:361349}
1350
[email protected]71f65dd2009-02-11 19:14:561351void AutomationProvider::GetBrowserWindowCount(int* window_count) {
1352 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:291353}
1354
[email protected]24497032009-05-01 17:00:291355void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
1356 *window_count = static_cast<int>(
1357 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
1358}
1359
[email protected]71f65dd2009-02-11 19:14:561360void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1361 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:071362 AppModalDialog* dialog_delegate =
1363 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501364 *showing_dialog = (dialog_delegate != NULL);
1365 if (*showing_dialog)
1366 *dialog_button = dialog_delegate->GetDialogButtons();
1367 else
[email protected]478ff2ed2009-04-21 23:49:181368 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:201369}
1370
[email protected]71f65dd2009-02-11 19:14:561371void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
1372 *success = false;
[email protected]fad84eab2008-12-05 00:37:201373
[email protected]1f460072009-05-28 17:02:071374 AppModalDialog* dialog_delegate =
1375 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501376 if (dialog_delegate &&
1377 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:181378 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
1379 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:281380 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:561381 *success = true;
[email protected]fad84eab2008-12-05 00:37:201382 }
[email protected]478ff2ed2009-04-21 23:49:181383 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
1384 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:561385 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:281386 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:561387 *success = true;
[email protected]fad84eab2008-12-05 00:37:201388 }
1389 }
[email protected]c274acc2008-11-11 20:13:441390}
1391
[email protected]71f65dd2009-02-11 19:14:561392void AutomationProvider::GetBrowserWindow(int index, int* handle) {
1393 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291394 if (index >= 0) {
1395 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:291396 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:291397 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:561398 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:291399 }
1400 }
initial.commit09911bf2008-07-26 23:55:291401}
1402
[email protected]24497032009-05-01 17:00:291403void AutomationProvider::FindNormalBrowserWindow(int* handle) {
1404 *handle = 0;
1405 Browser* browser = BrowserList::FindBrowserWithType(profile_,
1406 Browser::TYPE_NORMAL);
1407 if (browser)
1408 *handle = browser_tracker_->Add(browser);
1409}
1410
[email protected]71f65dd2009-02-11 19:14:561411void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
1412 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291413 Browser* browser = BrowserList::GetLastActive();
1414 if (browser)
[email protected]71f65dd2009-02-11 19:14:561415 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:291416}
1417
[email protected]de246f52009-02-25 18:25:451418#if defined(OS_WIN)
1419// TODO(port): Remove windowsisms.
initial.commit09911bf2008-07-26 23:55:291420BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1421 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1422 return FALSE;
1423 }
1424 return TRUE;
1425}
1426
[email protected]71f65dd2009-02-11 19:14:561427void AutomationProvider::GetActiveWindow(int* handle) {
initial.commit09911bf2008-07-26 23:55:291428 HWND window = GetForegroundWindow();
1429
1430 // Let's make sure this window belongs to our process.
1431 if (EnumThreadWindows(::GetCurrentThreadId(),
1432 EnumThreadWndProc,
1433 reinterpret_cast<LPARAM>(window))) {
1434 // We enumerated all the windows and did not find the foreground window,
1435 // it is not our window, ignore it.
[email protected]71f65dd2009-02-11 19:14:561436 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291437 return;
1438 }
1439
[email protected]71f65dd2009-02-11 19:14:561440 *handle = window_tracker_->Add(window);
initial.commit09911bf2008-07-26 23:55:291441}
1442
[email protected]71f65dd2009-02-11 19:14:561443void AutomationProvider::GetWindowHWND(int handle, HWND* win32_handle) {
1444 *win32_handle = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291445}
[email protected]de246f52009-02-25 18:25:451446#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291447
[email protected]9a08bcf2009-08-12 19:56:281448#if defined(OS_LINUX)
1449// TODO(estade): use this implementation for all platforms?
1450void AutomationProvider::GetActiveWindow(int* handle) {
1451 gfx::NativeWindow window =
1452 BrowserList::GetLastActive()->window()->GetNativeHandle();
1453 *handle = window_tracker_->Add(window);
1454}
1455#endif
1456
[email protected]4f6381ee2009-04-16 02:46:331457void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
1458 bool* success) {
[email protected]71f65dd2009-02-11 19:14:561459 *success = false;
[email protected]4ae62752008-08-04 23:28:471460 if (browser_tracker_->ContainsHandle(handle)) {
1461 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141462 if (browser->command_updater()->SupportsCommand(command) &&
1463 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471464 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:561465 *success = true;
[email protected]4ae62752008-08-04 23:28:471466 }
1467 }
[email protected]4ae62752008-08-04 23:28:471468}
1469
[email protected]4f6381ee2009-04-16 02:46:331470void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:561471 int handle, int command, IPC::Message* reply_message) {
1472 if (browser_tracker_->ContainsHandle(handle)) {
1473 Browser* browser = browser_tracker_->GetResource(handle);
1474 if (browser->command_updater()->SupportsCommand(command) &&
1475 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]d79ffea2009-05-07 20:51:421476 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
1477 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:271478 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:421479 return;
1480 }
[email protected]56e71b7c2009-03-27 03:05:561481 }
1482 }
[email protected]49a14a82009-03-31 04:16:441483 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:561484 Send(reply_message);
1485}
1486
[email protected]71f65dd2009-02-11 19:14:561487void AutomationProvider::WindowGetViewBounds(int handle, int view_id,
1488 bool screen_coordinates,
1489 bool* success,
1490 gfx::Rect* bounds) {
1491 *success = false;
initial.commit09911bf2008-07-26 23:55:291492
[email protected]de246f52009-02-25 18:25:451493#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291494 void* iter = NULL;
1495 if (window_tracker_->ContainsHandle(handle)) {
1496 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201497 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291498 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381499 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291500 if (view) {
[email protected]71f65dd2009-02-11 19:14:561501 *success = true;
[email protected]96b667d2008-10-14 20:58:441502 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291503 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381504 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291505 else
[email protected]c2dacc92008-10-16 23:51:381506 views::View::ConvertPointToView(view, root_view, &point);
[email protected]71f65dd2009-02-11 19:14:561507 *bounds = view->GetLocalBounds(false);
1508 bounds->set_origin(point);
initial.commit09911bf2008-07-26 23:55:291509 }
1510 }
1511 }
[email protected]de246f52009-02-25 18:25:451512#else
1513 // TODO(port): Enable when window_tracker is ported.
1514 NOTIMPLEMENTED();
1515#endif
initial.commit09911bf2008-07-26 23:55:291516}
1517
[email protected]1299c6e2009-07-25 00:27:181518#if defined(OS_WIN)
[email protected]de246f52009-02-25 18:25:451519
initial.commit09911bf2008-07-26 23:55:291520// This task enqueues a mouse event on the event loop, so that the view
1521// that it's being sent to can do the requisite post-processing.
1522class MouseEventTask : public Task {
1523 public:
[email protected]c2dacc92008-10-16 23:51:381524 MouseEventTask(views::View* view,
1525 views::Event::EventType type,
[email protected]0e80dfe2009-08-07 01:22:581526 const gfx::Point& point,
initial.commit09911bf2008-07-26 23:55:291527 int flags)
1528 : view_(view), type_(type), point_(point), flags_(flags) {}
1529 virtual ~MouseEventTask() {}
1530
1531 virtual void Run() {
[email protected]0e80dfe2009-08-07 01:22:581532 views::MouseEvent event(type_, point_.x(), point_.y(), flags_);
initial.commit09911bf2008-07-26 23:55:291533 // We need to set the cursor position before we process the event because
1534 // some code (tab dragging, for instance) queries the actual cursor location
1535 // rather than the location of the mouse event. Note that the reason why
1536 // the drag code moved away from using mouse event locations was because
1537 // our conversion to screen location doesn't work well with multiple
1538 // monitors, so this only works reliably in a single monitor setup.
[email protected]0e80dfe2009-08-07 01:22:581539 gfx::Point screen_location(point_.x(), point_.y());
initial.commit09911bf2008-07-26 23:55:291540 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]f5446092009-07-30 21:10:011541 MoveMouse(screen_location.ToPOINT());
initial.commit09911bf2008-07-26 23:55:291542 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381543 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291544 view_->OnMousePressed(event);
1545 break;
1546
[email protected]c2dacc92008-10-16 23:51:381547 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291548 view_->OnMouseDragged(event);
1549 break;
1550
[email protected]c2dacc92008-10-16 23:51:381551 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291552 view_->OnMouseReleased(event, false);
1553 break;
1554
1555 default:
1556 NOTREACHED();
1557 }
1558 }
1559
1560 private:
[email protected]c2dacc92008-10-16 23:51:381561 views::View* view_;
1562 views::Event::EventType type_;
[email protected]0e80dfe2009-08-07 01:22:581563 gfx::Point point_;
initial.commit09911bf2008-07-26 23:55:291564 int flags_;
1565
[email protected]5a52f162008-08-27 04:15:311566 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291567};
1568
[email protected]c2dacc92008-10-16 23:51:381569void AutomationProvider::ScheduleMouseEvent(views::View* view,
1570 views::Event::EventType type,
[email protected]0e80dfe2009-08-07 01:22:581571 const gfx::Point& point,
initial.commit09911bf2008-07-26 23:55:291572 int flags) {
1573 MessageLoop::current()->PostTask(FROM_HERE,
1574 new MouseEventTask(view, type, point, flags));
1575}
[email protected]0e80dfe2009-08-07 01:22:581576
[email protected]1299c6e2009-07-25 00:27:181577#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291578
1579// This task just adds another task to the event queue. This is useful if
1580// you want to ensure that any tasks added to the event queue after this one
1581// have already been processed by the time |task| is run.
1582class InvokeTaskLaterTask : public Task {
1583 public:
1584 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1585 virtual ~InvokeTaskLaterTask() {}
1586
1587 virtual void Run() {
1588 MessageLoop::current()->PostTask(FROM_HERE, task_);
1589 }
1590
1591 private:
1592 Task* task_;
1593
[email protected]5a52f162008-08-27 04:15:311594 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291595};
1596
[email protected]de246f52009-02-25 18:25:451597#if defined(OS_WIN)
1598// TODO(port): Replace POINT and other windowsisms.
1599
initial.commit09911bf2008-07-26 23:55:291600// This task sends a WindowDragResponse message with the appropriate
1601// routing ID to the automation proxy. This is implemented as a task so that
1602// we know that the mouse events (and any tasks that they spawn on the message
1603// loop) have been processed by the time this is sent.
1604class WindowDragResponseTask : public Task {
1605 public:
[email protected]1c58a5c2009-05-21 18:47:141606 WindowDragResponseTask(AutomationProvider* provider,
[email protected]71f65dd2009-02-11 19:14:561607 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:141608 : provider_(provider), reply_message_(reply_message) {}
initial.commit09911bf2008-07-26 23:55:291609 virtual ~WindowDragResponseTask() {}
1610
1611 virtual void Run() {
[email protected]71f65dd2009-02-11 19:14:561612 DCHECK(reply_message_ != NULL);
1613 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
1614 provider_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291615 }
1616
1617 private:
1618 AutomationProvider* provider_;
[email protected]71f65dd2009-02-11 19:14:561619 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:291620
[email protected]5a52f162008-08-27 04:15:311621 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291622};
1623
1624void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1625 int handle,
1626 POINT click,
1627 int flags) {
1628 HWND hwnd = 0;
1629
1630 if (window_tracker_->ContainsHandle(handle)) {
1631 hwnd = window_tracker_->GetResource(handle);
1632
initial.commit09911bf2008-07-26 23:55:291633 ui_controls::SendMouseMove(click.x, click.y);
1634
1635 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381636 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1637 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291638 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381639 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1640 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291641 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381642 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1643 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291644 button = ui_controls::MIDDLE;
1645 } else {
1646 NOTREACHED();
1647 }
1648 ui_controls::SendMouseClick(button);
1649 }
1650}
1651
[email protected]71f65dd2009-02-11 19:14:561652void AutomationProvider::WindowSimulateDrag(int handle,
[email protected]fe92e4e2008-11-18 21:31:321653 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441654 int flags,
[email protected]71f65dd2009-02-11 19:14:561655 bool press_escape_en_route,
1656 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291657 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321658 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1659 succeeded = true;
1660
1661 UINT down_message = 0;
1662 UINT up_message = 0;
1663 WPARAM wparam_flags = 0;
1664 if (flags & views::Event::EF_SHIFT_DOWN)
1665 wparam_flags |= MK_SHIFT;
1666 if (flags & views::Event::EF_CONTROL_DOWN)
1667 wparam_flags |= MK_CONTROL;
1668 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1669 wparam_flags |= MK_LBUTTON;
1670 down_message = WM_LBUTTONDOWN;
1671 up_message = WM_LBUTTONUP;
1672 }
1673 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1674 wparam_flags |= MK_MBUTTON;
1675 down_message = WM_MBUTTONDOWN;
1676 up_message = WM_MBUTTONUP;
1677 }
1678 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1679 wparam_flags |= MK_RBUTTON;
1680 down_message = WM_LBUTTONDOWN;
1681 up_message = WM_LBUTTONUP;
1682 }
1683
initial.commit09911bf2008-07-26 23:55:291684 Browser* browser = browser_tracker_->GetResource(handle);
1685 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551686 HWND top_level_hwnd =
1687 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321688 POINT temp = drag_path[0];
1689 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
[email protected]f5446092009-07-30 21:10:011690 MoveMouse(temp);
[email protected]fe92e4e2008-11-18 21:31:321691 SendMessage(top_level_hwnd, down_message, wparam_flags,
1692 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1693 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1694 temp = drag_path[i];
1695 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
[email protected]f5446092009-07-30 21:10:011696 MoveMouse(temp);
[email protected]fe92e4e2008-11-18 21:31:321697 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1698 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341699 }
[email protected]fe92e4e2008-11-18 21:31:321700 POINT end = drag_path[drag_path.size() - 1];
1701 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
[email protected]f5446092009-07-30 21:10:011702 MoveMouse(end);
[email protected]fe92e4e2008-11-18 21:31:321703
1704 if (press_escape_en_route) {
1705 // Press Escape.
1706 ui_controls::SendKeyPress(VK_ESCAPE,
1707 ((flags & views::Event::EF_CONTROL_DOWN)
1708 == views::Event::EF_CONTROL_DOWN),
1709 ((flags & views::Event::EF_SHIFT_DOWN) ==
1710 views::Event::EF_SHIFT_DOWN),
1711 ((flags & views::Event::EF_ALT_DOWN) ==
1712 views::Event::EF_ALT_DOWN));
1713 }
1714 SendMessage(top_level_hwnd, up_message, wparam_flags,
1715 MAKELPARAM(end.x, end.y));
1716
[email protected]1c58a5c2009-05-21 18:47:141717 MessageLoop::current()->PostTask(FROM_HERE, new InvokeTaskLaterTask(
1718 new WindowDragResponseTask(this, reply_message)));
initial.commit09911bf2008-07-26 23:55:291719 } else {
[email protected]71f65dd2009-02-11 19:14:561720 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, true);
1721 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291722 }
1723}
[email protected]9a08bcf2009-08-12 19:56:281724#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291725
[email protected]9a08bcf2009-08-12 19:56:281726#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:291727void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1728 int handle,
1729 wchar_t key,
1730 int flags) {
1731 if (!window_tracker_->ContainsHandle(handle))
1732 return;
1733
1734 // The key event is sent to whatever window is active.
1735 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381736 ((flags & views::Event::EF_CONTROL_DOWN) ==
1737 views::Event::EF_CONTROL_DOWN),
1738 ((flags & views::Event::EF_SHIFT_DOWN) ==
1739 views::Event::EF_SHIFT_DOWN),
1740 ((flags & views::Event::EF_ALT_DOWN) ==
1741 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291742}
[email protected]9a08bcf2009-08-12 19:56:281743#endif
initial.commit09911bf2008-07-26 23:55:291744
[email protected]9a08bcf2009-08-12 19:56:281745#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561746void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
1747 *view_id = -1;
initial.commit09911bf2008-07-26 23:55:291748 if (window_tracker_->ContainsHandle(handle)) {
1749 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381750 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:001751 views::FocusManager::GetFocusManagerForNativeView(hwnd);
initial.commit09911bf2008-07-26 23:55:291752 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381753 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291754 if (focused_view)
[email protected]71f65dd2009-02-11 19:14:561755 *view_id = focused_view->GetID();
initial.commit09911bf2008-07-26 23:55:291756 }
initial.commit09911bf2008-07-26 23:55:291757}
1758
[email protected]8f04ff92009-07-08 02:37:151759void AutomationProvider::SetWindowBounds(int handle, const gfx::Rect& bounds,
1760 bool* success) {
1761 *success = false;
1762 if (window_tracker_->ContainsHandle(handle)) {
1763 HWND hwnd = window_tracker_->GetResource(handle);
1764 if (::MoveWindow(hwnd, bounds.x(), bounds.y(), bounds.width(),
1765 bounds.height(), true)) {
1766 *success = true;
1767 }
1768 }
1769}
1770
[email protected]71f65dd2009-02-11 19:14:561771void AutomationProvider::SetWindowVisible(int handle, bool visible,
1772 bool* result) {
initial.commit09911bf2008-07-26 23:55:291773 if (window_tracker_->ContainsHandle(handle)) {
1774 HWND hwnd = window_tracker_->GetResource(handle);
1775 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
[email protected]71f65dd2009-02-11 19:14:561776 *result = true;
initial.commit09911bf2008-07-26 23:55:291777 } else {
[email protected]71f65dd2009-02-11 19:14:561778 *result = false;
initial.commit09911bf2008-07-26 23:55:291779 }
1780}
[email protected]d2cc6ed2009-04-24 00:26:171781#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291782
[email protected]71f65dd2009-02-11 19:14:561783void AutomationProvider::IsWindowActive(int handle, bool* success,
1784 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291785 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171786 *is_active =
1787 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561788 *success = true;
initial.commit09911bf2008-07-26 23:55:291789 } else {
[email protected]71f65dd2009-02-11 19:14:561790 *success = false;
1791 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291792 }
1793}
1794
[email protected]d2cc6ed2009-04-24 00:26:171795// TODO(port): port this.
1796#if defined(OS_WIN)
[email protected]659d0e82009-02-13 22:43:281797void AutomationProvider::ActivateWindow(int handle) {
initial.commit09911bf2008-07-26 23:55:291798 if (window_tracker_->ContainsHandle(handle)) {
1799 ::SetActiveWindow(window_tracker_->GetResource(handle));
1800 }
1801}
[email protected]d2cc6ed2009-04-24 00:26:171802#endif
initial.commit09911bf2008-07-26 23:55:291803
[email protected]71f65dd2009-02-11 19:14:561804void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1805 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291806
1807 if (browser_tracker_->ContainsHandle(handle)) {
1808 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561809 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291810 }
initial.commit09911bf2008-07-26 23:55:291811}
1812
[email protected]71f65dd2009-02-11 19:14:561813void AutomationProvider::GetTab(int win_handle, int tab_index,
1814 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561815 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291816 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1817 Browser* browser = browser_tracker_->GetResource(win_handle);
1818 if (tab_index < browser->tab_count()) {
1819 TabContents* tab_contents =
1820 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571821 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291822 }
1823 }
initial.commit09911bf2008-07-26 23:55:291824}
1825
[email protected]71f65dd2009-02-11 19:14:561826void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1827 std::wstring* title) {
1828 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291829 if (tab_tracker_->ContainsHandle(handle)) {
1830 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361831 NavigationEntry* entry = tab->GetActiveEntry();
1832 if (entry != NULL) {
1833 *title = UTF16ToWideHack(entry->title());
1834 } else {
1835 *title = std::wstring();
1836 }
[email protected]71f65dd2009-02-11 19:14:561837 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291838 }
initial.commit09911bf2008-07-26 23:55:291839}
1840
[email protected]77bc6732009-04-20 22:01:031841void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1842 *tabstrip_index = -1; // -1 is the error code
1843
1844 if (tab_tracker_->ContainsHandle(handle)) {
1845 NavigationController* tab = tab_tracker_->GetResource(handle);
1846 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121847 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031848 }
1849}
1850
initial.commit09911bf2008-07-26 23:55:291851void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1852 if (window_tracker_->ContainsHandle(handle)) {
1853 window_tracker_->Remove(window_tracker_->GetResource(handle));
1854 }
1855}
1856
1857void AutomationProvider::OnChannelError() {
1858 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571859 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291860}
1861
1862// TODO(brettw) change this to accept GURLs when history supports it
1863void AutomationProvider::OnRedirectQueryComplete(
1864 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371865 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291866 bool success,
[email protected]379c2b12009-07-01 21:50:331867 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291868 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561869 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291870
[email protected]deb57402009-02-06 01:35:301871 std::vector<GURL> redirects_gurl;
initial.commit09911bf2008-07-26 23:55:291872 if (success) {
[email protected]71f65dd2009-02-11 19:14:561873 reply_message_->WriteBool(true);
initial.commit09911bf2008-07-26 23:55:291874 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301875 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291876 } else {
[email protected]71f65dd2009-02-11 19:14:561877 reply_message_->WriteInt(-1); // Negative count indicates failure.
initial.commit09911bf2008-07-26 23:55:291878 }
1879
[email protected]4f3dc372009-02-24 00:10:291880 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301881
[email protected]71f65dd2009-02-11 19:14:561882 Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291883 redirect_query_ = NULL;
[email protected]71f65dd2009-02-11 19:14:561884 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291885}
1886
1887bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571888 DCHECK(channel_.get());
1889 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291890}
1891
1892Browser* AutomationProvider::FindAndActivateTab(
1893 NavigationController* controller) {
1894 int tab_index;
1895 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1896 if (browser)
1897 browser->SelectTabContentsAt(tab_index, true);
1898
1899 return browser;
1900}
1901
[email protected]71f65dd2009-02-11 19:14:561902void AutomationProvider::GetCookies(const GURL& url, int handle,
1903 int* value_size,
1904 std::string* value) {
1905 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291906 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1907 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561908 *value =
initial.commit09911bf2008-07-26 23:55:291909 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561910 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291911 }
initial.commit09911bf2008-07-26 23:55:291912}
1913
[email protected]71f65dd2009-02-11 19:14:561914void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291915 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561916 int handle,
1917 int* response_value) {
1918 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291919
1920 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1921 NavigationController* tab = tab_tracker_->GetResource(handle);
1922 URLRequestContext* context = tab->profile()->GetRequestContext();
1923 if (context->cookie_store()->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561924 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291925 }
initial.commit09911bf2008-07-26 23:55:291926}
1927
[email protected]71f65dd2009-02-11 19:14:561928void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1929 *success = false;
initial.commit09911bf2008-07-26 23:55:291930 if (tab_tracker_->ContainsHandle(handle)) {
1931 NavigationController* tab = tab_tracker_->GetResource(handle);
1932 // Return what the user would see in the location bar.
[email protected]71f65dd2009-02-11 19:14:561933 *url = tab->GetActiveEntry()->display_url();
1934 *success = true;
initial.commit09911bf2008-07-26 23:55:291935 }
initial.commit09911bf2008-07-26 23:55:291936}
1937
[email protected]de246f52009-02-25 18:25:451938#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561939void AutomationProvider::GetTabHWND(int handle, HWND* tab_hwnd) {
1940 *tab_hwnd = NULL;
initial.commit09911bf2008-07-26 23:55:291941
1942 if (tab_tracker_->ContainsHandle(handle)) {
1943 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111944 *tab_hwnd = tab->tab_contents()->GetNativeView();
initial.commit09911bf2008-07-26 23:55:291945 }
initial.commit09911bf2008-07-26 23:55:291946}
[email protected]de246f52009-02-25 18:25:451947#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291948
[email protected]71f65dd2009-02-11 19:14:561949void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1950 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291951
1952 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561953 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341954 TabContents* tab_contents =
1955 tab_tracker_->GetResource(handle)->tab_contents();
1956 if (tab_contents->process())
1957 *process_id = tab_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291958 }
initial.commit09911bf2008-07-26 23:55:291959}
1960
1961void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331962 NOTREACHED() << "This function has been deprecated. "
1963 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291964}
1965
[email protected]71f65dd2009-02-11 19:14:561966void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291967 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561968 const std::wstring& script,
1969 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291970 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341971 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1972 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571973 // Set the routing id of this message with the controller.
1974 // This routing id needs to be remembered for the reverse
1975 // communication while sending back the response of
1976 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331977 std::wstring set_automation_id;
1978 SStringPrintf(&set_automation_id,
1979 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561980 reply_message->routing_id());
1981
1982 DCHECK(reply_message_ == NULL);
1983 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291984
[email protected]57c6a652009-05-04 07:58:341985 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331986 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341987 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061988 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571989 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291990 }
1991
1992 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561993 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1994 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291995 }
1996}
1997
[email protected]71f65dd2009-02-11 19:14:561998void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1999 *visible = false;
[email protected]20e93d12008-08-28 16:31:572000
[email protected]59560e0b2009-06-04 03:30:222001 if (browser_tracker_->ContainsHandle(handle)) {
2002 Browser* browser = browser_tracker_->GetResource(handle);
2003 if (browser) {
2004 *visible = browser->window()->IsDownloadShelfVisible();
2005 }
2006 }
initial.commit09911bf2008-07-26 23:55:292007}
2008
[email protected]59560e0b2009-06-04 03:30:222009void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
2010 if (browser_tracker_->ContainsHandle(handle)) {
2011 Browser* browser = browser_tracker_->GetResource(handle);
2012 if (browser) {
2013 if (visible)
2014 browser->window()->GetDownloadShelf()->Show();
2015 else
2016 browser->window()->GetDownloadShelf()->Close();
2017 }
2018 }
2019}
2020
2021
[email protected]71f65dd2009-02-11 19:14:562022void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
2023 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:292024 if (tab_tracker_->ContainsHandle(handle)) {
2025 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112026 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:292027 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562028 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:292029 }
2030 }
initial.commit09911bf2008-07-26 23:55:292031}
2032
initial.commit09911bf2008-07-26 23:55:292033void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:562034 int handle, const std::wstring& find_request,
2035 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:312036 NOTREACHED() << "This function has been deprecated."
2037 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:562038 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:312039 return;
2040}
2041
[email protected]4f999132009-03-31 18:08:402042void AutomationProvider::HandleFindRequest(
2043 int handle,
2044 const AutomationMsg_Find_Params& params,
2045 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292046 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:562047 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
2048 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292049 return;
2050 }
2051
2052 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112053 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:292054
2055 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:142056 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:292057
[email protected]57c6a652009-05-04 07:58:342058 tab_contents->set_current_find_request_id(
2059 FindInPageNotificationObserver::kFindInPageRequestId);
2060 tab_contents->render_view_host()->StartFinding(
2061 FindInPageNotificationObserver::kFindInPageRequestId,
2062 params.search_string, params.forward, params.match_case,
2063 params.find_next);
initial.commit09911bf2008-07-26 23:55:292064}
2065
[email protected]5f8af2a2008-08-06 22:49:452066void AutomationProvider::HandleOpenFindInPageRequest(
2067 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:292068 if (browser_tracker_->ContainsHandle(handle)) {
2069 Browser* browser = browser_tracker_->GetResource(handle);
2070 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:452071 }
2072}
2073
[email protected]71f65dd2009-02-11 19:14:562074void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]9e0534b2008-10-21 15:03:012075 gfx::Point position;
[email protected]71f65dd2009-02-11 19:14:562076 *visible = false;
[email protected]4f3dc372009-02-24 00:10:292077 if (browser_tracker_->ContainsHandle(handle)) {
2078 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582079 FindBarTesting* find_bar =
2080 browser->find_bar()->find_bar()->GetFindBarTesting();
2081 find_bar->GetFindBarWindowInfo(&position, visible);
[email protected]4f3dc372009-02-24 00:10:292082 }
[email protected]20e93d12008-08-28 16:31:572083}
2084
[email protected]71f65dd2009-02-11 19:14:562085void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
2086 int* y) {
[email protected]9e0534b2008-10-21 15:03:012087 gfx::Point position(0, 0);
2088 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:292089 if (browser_tracker_->ContainsHandle(handle)) {
2090 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582091 FindBarTesting* find_bar =
2092 browser->find_bar()->find_bar()->GetFindBarTesting();
2093 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:292094 }
[email protected]20e93d12008-08-28 16:31:572095
[email protected]71f65dd2009-02-11 19:14:562096 *x = position.x();
2097 *y = position.y();
[email protected]20e93d12008-08-28 16:31:572098}
2099
[email protected]71f65dd2009-02-11 19:14:562100void AutomationProvider::GetBookmarkBarVisibility(int handle, bool* visible,
2101 bool* animating) {
2102 *visible = false;
2103 *animating = false;
[email protected]c2cbeb92008-09-05 21:36:572104
[email protected]de246f52009-02-25 18:25:452105#if defined(OS_WIN)
[email protected]c2cbeb92008-09-05 21:36:572106 if (browser_tracker_->ContainsHandle(handle)) {
2107 Browser* browser = browser_tracker_->GetResource(handle);
2108 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:522109 BrowserWindowTesting* testing =
2110 browser->window()->GetBrowserWindowTesting();
2111 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:572112 if (bookmark_bar) {
[email protected]71f65dd2009-02-11 19:14:562113 *animating = bookmark_bar->IsAnimating();
2114 *visible = browser->window()->IsBookmarkBarVisible();
[email protected]c2cbeb92008-09-05 21:36:572115 }
2116 }
2117 }
[email protected]de246f52009-02-25 18:25:452118#else
2119 // TODO(port): Enable when bookmarks ui is ported.
2120 NOTIMPLEMENTED();
2121#endif
[email protected]c2cbeb92008-09-05 21:36:572122}
2123
initial.commit09911bf2008-07-26 23:55:292124void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562125 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342126 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2127 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562128 DCHECK(reply_message_ == NULL);
2129 reply_message_ = reply_message;
2130
[email protected]d9f9b792009-06-24 13:17:122131 DevToolsManager::GetInstance()->InspectElement(
2132 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292133 } else {
[email protected]71f65dd2009-02-11 19:14:562134 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2135 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292136 }
2137}
2138
2139void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092140 if (reply_message_) {
2141 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2142 num_resources);
2143 Send(reply_message_);
2144 reply_message_ = NULL;
2145 }
initial.commit09911bf2008-07-26 23:55:292146}
2147
[email protected]a7eee32f2009-05-22 18:08:172148class SetProxyConfigTask : public Task {
2149 public:
2150 explicit SetProxyConfigTask(net::ProxyService* proxy_service,
2151 const std::string& new_proxy_config)
2152 : proxy_service_(proxy_service), proxy_config_(new_proxy_config) {}
2153 virtual void Run() {
2154 // First, deserialize the JSON string. If this fails, log and bail.
2155 JSONStringValueSerializer deserializer(proxy_config_);
2156 std::string error_message;
2157 scoped_ptr<Value> root(deserializer.Deserialize(&error_message));
2158 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2159 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
2160 << error_message;
2161 return;
2162 }
2163
2164 scoped_ptr<DictionaryValue> dict(
2165 static_cast<DictionaryValue*>(root.release()));
2166 // Now put together a proxy configuration from the deserialized string.
2167 net::ProxyConfig pc;
2168 PopulateProxyConfig(*dict.get(), &pc);
2169
2170 DCHECK(proxy_service_);
2171 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2172 new net::ProxyConfigServiceFixed(pc));
2173 proxy_service_->ResetConfigService(proxy_config_service.release());
2174 }
2175
2176 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2177 DCHECK(pc);
2178 bool no_proxy = false;
2179 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2180 // Make no changes to the ProxyConfig.
2181 return;
2182 }
2183 bool auto_config;
2184 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
2185 pc->auto_detect = true;
2186 }
2187 std::string pac_url;
2188 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
2189 pc->pac_url = GURL(pac_url);
2190 }
2191 std::string proxy_bypass_list;
2192 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
2193 pc->ParseNoProxyList(proxy_bypass_list);
2194 }
2195 std::string proxy_server;
2196 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
2197 pc->proxy_rules.ParseFromString(proxy_server);
2198 }
2199 }
2200
2201 private:
2202 net::ProxyService* proxy_service_;
2203 std::string proxy_config_;
2204};
2205
2206
2207void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
2208 URLRequestContext* context = Profile::GetDefaultRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172209 if (!context) {
2210 FilePath user_data_dir;
2211 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2212 ProfileManager* profile_manager = g_browser_process->profile_manager();
2213 DCHECK(profile_manager);
2214 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2215 DCHECK(profile);
2216 context = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172217 }
2218 DCHECK(context);
2219 // Every URLRequestContext should have a proxy service.
2220 net::ProxyService* proxy_service = context->proxy_service();
2221 DCHECK(proxy_service);
2222
[email protected]81ae0a92009-08-06 02:16:162223 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
2224 new SetProxyConfigTask(proxy_service, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172225}
2226
[email protected]4f3dc372009-02-24 00:10:292227void AutomationProvider::GetDownloadDirectory(
2228 int handle, std::wstring* download_directory) {
initial.commit09911bf2008-07-26 23:55:292229 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292230 if (tab_tracker_->ContainsHandle(handle)) {
2231 NavigationController* tab = tab_tracker_->GetResource(handle);
2232 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2233 DCHECK(dlm);
[email protected]71f65dd2009-02-11 19:14:562234 *download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:292235 }
initial.commit09911bf2008-07-26 23:55:292236}
2237
[email protected]14c0a032009-04-13 18:15:142238void AutomationProvider::OpenNewBrowserWindow(bool show,
2239 IPC::Message* reply_message) {
2240 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292241 // We may have no current browser windows open so don't rely on
2242 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:052243 Browser* browser = Browser::Create(profile_);
2244 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152245 if (show)
[email protected]15952e462008-11-14 00:29:052246 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292247}
2248
[email protected]71f65dd2009-02-11 19:14:562249void AutomationProvider::GetWindowForBrowser(int browser_handle,
2250 bool* success,
2251 int* handle) {
2252 *success = false;
2253 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292254
2255 if (browser_tracker_->ContainsHandle(browser_handle)) {
2256 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202257 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292258 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202259 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562260 *success = true;
initial.commit09911bf2008-07-26 23:55:292261 }
initial.commit09911bf2008-07-26 23:55:292262}
2263
[email protected]13869dd2009-05-05 00:40:062264#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292265void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562266 int browser_handle,
2267 bool* success,
2268 int* autocomplete_edit_handle) {
2269 *success = false;
2270 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292271
2272 if (browser_tracker_->ContainsHandle(browser_handle)) {
2273 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062274 LocationBar* loc_bar = browser->window()->GetLocationBar();
2275 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292276 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562277 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2278 *success = true;
initial.commit09911bf2008-07-26 23:55:292279 }
initial.commit09911bf2008-07-26 23:55:292280}
[email protected]13869dd2009-05-05 00:40:062281#endif // defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292282
[email protected]13869dd2009-05-05 00:40:062283#if defined(OS_WIN)
2284// TODO(port): Remove windowsisms.
[email protected]71f65dd2009-02-11 19:14:562285void AutomationProvider::GetBrowserForWindow(int window_handle,
2286 bool* success,
2287 int* browser_handle) {
2288 *success = false;
2289 *browser_handle = 0;
initial.commit09911bf2008-07-26 23:55:292290
2291 if (window_tracker_->ContainsHandle(window_handle)) {
2292 HWND window = window_tracker_->GetResource(window_handle);
2293 BrowserList::const_iterator iter = BrowserList::begin();
2294 Browser* browser = NULL;
2295 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:312296 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
2297 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:292298 browser = *iter;
2299 break;
2300 }
2301 }
2302 if (browser) {
2303 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562304 *browser_handle = browser_tracker_->Add(browser);
2305 *success = true;
initial.commit09911bf2008-07-26 23:55:292306 }
2307 }
initial.commit09911bf2008-07-26 23:55:292308}
[email protected]de246f52009-02-25 18:25:452309#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292310
[email protected]71f65dd2009-02-11 19:14:562311void AutomationProvider::ShowInterstitialPage(int tab_handle,
2312 const std::string& html_text,
2313 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292314 if (tab_tracker_->ContainsHandle(tab_handle)) {
2315 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112316 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402317
2318 AddNavigationStatusListener<bool>(controller, reply_message, true,
2319 false, false);
[email protected]965524b2009-04-04 21:32:402320 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342321 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402322 GURL("about:interstitial"),
2323 html_text);
2324 interstitial->Show();
2325 return;
initial.commit09911bf2008-07-26 23:55:292326 }
[email protected]71f65dd2009-02-11 19:14:562327
2328 AutomationMsg_ShowInterstitialPage::WriteReplyParams(reply_message, false);
2329 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292330}
2331
[email protected]71f65dd2009-02-11 19:14:562332void AutomationProvider::HideInterstitialPage(int tab_handle,
2333 bool* success) {
2334 *success = false;
[email protected]57c6a652009-05-04 07:58:342335 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2336 if (tab_contents && tab_contents->interstitial_page()) {
2337 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562338 *success = true;
initial.commit09911bf2008-07-26 23:55:292339 }
initial.commit09911bf2008-07-26 23:55:292340}
2341
[email protected]71f65dd2009-02-11 19:14:562342void AutomationProvider::CloseTab(int tab_handle,
2343 bool wait_until_closed,
2344 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292345 if (tab_tracker_->ContainsHandle(tab_handle)) {
2346 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2347 int index;
2348 Browser* browser = Browser::GetBrowserForController(controller, &index);
2349 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142350 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112351 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452352 return;
initial.commit09911bf2008-07-26 23:55:292353 }
[email protected]de246f52009-02-25 18:25:452354
2355 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
initial.commit09911bf2008-07-26 23:55:292356}
2357
[email protected]71f65dd2009-02-11 19:14:562358void AutomationProvider::CloseBrowser(int browser_handle,
2359 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292360 if (browser_tracker_->ContainsHandle(browser_handle)) {
2361 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562362 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562363 reply_message);
[email protected]f3e99e32008-07-30 04:48:392364 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292365 } else {
2366 NOTREACHED();
2367 }
2368}
2369
[email protected]71f65dd2009-02-11 19:14:562370void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2371 if (browser_tracker_->ContainsHandle(browser_handle)) {
2372 Browser* browser = browser_tracker_->GetResource(browser_handle);
2373 browser->window()->Close();
2374 } else {
2375 NOTREACHED();
2376 }
2377}
2378
[email protected]de246f52009-02-25 18:25:452379#if defined(OS_WIN)
2380// TODO(port): Remove windowsisms.
[email protected]95c3c592009-07-14 22:09:032381void AutomationProvider::CreateExternalTab(
2382 const IPC::ExternalTabSettings& settings,
2383 gfx::NativeWindow* tab_container_window, gfx::NativeWindow* tab_window,
2384 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:562385 *tab_handle = 0;
2386 *tab_container_window = NULL;
[email protected]c4e944f2009-06-11 18:22:192387 *tab_window = NULL;
[email protected]2e4633c2009-07-09 16:58:062388 ExternalTabContainer* external_tab_container =
2389 new ExternalTabContainer(this, automation_resource_message_filter_);
[email protected]95c3c592009-07-14 22:09:032390 Profile* profile = settings.is_off_the_record ?
2391 profile_->GetOffTheRecordProfile() : profile_;
2392 external_tab_container->Init(profile, settings.parent, settings.dimensions,
[email protected]5f450e52009-07-28 13:28:112393 settings.style, settings.load_requests_via_automation,
2394 settings.handle_top_level_requests);
initial.commit09911bf2008-07-26 23:55:292395 TabContents* tab_contents = external_tab_container->tab_contents();
2396 if (tab_contents) {
[email protected]ce3fa3c2009-04-20 19:55:572397 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
[email protected]eac83f02009-05-08 18:44:442398 external_tab_container->set_tab_handle(*tab_handle);
[email protected]9095e982009-05-27 17:28:242399 *tab_container_window = external_tab_container->GetNativeView();
[email protected]c4e944f2009-06-11 18:22:192400 *tab_window = tab_contents->GetNativeView();
[email protected]31fb110522009-01-28 21:50:392401 } else {
2402 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292403 }
initial.commit09911bf2008-07-26 23:55:292404}
[email protected]d2cc6ed2009-04-24 00:26:172405#endif
initial.commit09911bf2008-07-26 23:55:292406
[email protected]71f65dd2009-02-11 19:14:562407void AutomationProvider::NavigateInExternalTab(
2408 int handle, const GURL& url,
2409 AutomationMsg_NavigationResponseValues* status) {
2410 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292411
2412 if (tab_tracker_->ContainsHandle(handle)) {
2413 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502414 tab->LoadURL(url, GURL(), PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562415 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292416 }
initial.commit09911bf2008-07-26 23:55:292417}
2418
[email protected]d2cc6ed2009-04-24 00:26:172419#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292420void AutomationProvider::ProcessUnhandledAccelerator(
2421 const IPC::Message& message, int handle, const MSG& msg) {
[email protected]b9d227492009-02-10 15:20:272422 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2423 if (external_tab) {
2424 external_tab->ProcessUnhandledAccelerator(msg);
2425 }
2426 // This message expects no response.
2427}
[email protected]d2cc6ed2009-04-24 00:26:172428#endif
[email protected]b9d227492009-02-10 15:20:272429
[email protected]71f65dd2009-02-11 19:14:562430void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2431 IPC::Message* reply_message) {
2432 if (tab_tracker_->ContainsHandle(tab_handle)) {
2433 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2434 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142435 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562436 }
2437}
2438
[email protected]b9d227492009-02-10 15:20:272439void AutomationProvider::SetInitialFocus(const IPC::Message& message,
2440 int handle, bool reverse) {
[email protected]d2cc6ed2009-04-24 00:26:172441#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272442 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2443 if (external_tab) {
[email protected]90daadb42009-06-08 21:27:282444 external_tab->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:292445 }
2446 // This message expects no response.
[email protected]d2cc6ed2009-04-24 00:26:172447#elif defined(OS_POSIX)
2448 // TODO(port) enable this function.
2449 NOTIMPLEMENTED();
2450#endif
initial.commit09911bf2008-07-26 23:55:292451}
2452
[email protected]d2cc6ed2009-04-24 00:26:172453// TODO(port): enable these functions.
2454#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:562455void AutomationProvider::GetSecurityState(int handle, bool* success,
2456 SecurityStyle* security_style,
2457 int* ssl_cert_status,
2458 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292459 if (tab_tracker_->ContainsHandle(handle)) {
2460 NavigationController* tab = tab_tracker_->GetResource(handle);
2461 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562462 *success = true;
2463 *security_style = entry->ssl().security_style();
2464 *ssl_cert_status = entry->ssl().cert_status();
2465 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292466 } else {
[email protected]71f65dd2009-02-11 19:14:562467 *success = false;
2468 *security_style = SECURITY_STYLE_UNKNOWN;
2469 *ssl_cert_status = 0;
2470 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292471 }
2472}
2473
[email protected]71f65dd2009-02-11 19:14:562474void AutomationProvider::GetPageType(int handle, bool* success,
2475 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292476 if (tab_tracker_->ContainsHandle(handle)) {
2477 NavigationController* tab = tab_tracker_->GetResource(handle);
2478 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562479 *page_type = entry->page_type();
2480 *success = true;
initial.commit09911bf2008-07-26 23:55:292481 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342482 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562483 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342484 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562485 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292486 } else {
[email protected]71f65dd2009-02-11 19:14:562487 *success = false;
2488 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292489 }
2490}
2491
[email protected]71f65dd2009-02-11 19:14:562492void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2493 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292494 if (tab_tracker_->ContainsHandle(handle)) {
2495 NavigationController* tab = tab_tracker_->GetResource(handle);
2496 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072497 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402498 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472499 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342500 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292501 if (ssl_blocking_page) {
2502 if (proceed) {
[email protected]71f65dd2009-02-11 19:14:562503 AddNavigationStatusListener<bool>(tab, reply_message, true, true,
2504 false);
2505 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292506 return;
2507 }
2508 ssl_blocking_page->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562509 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2510 true);
2511 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292512 return;
2513 }
2514 }
2515 }
2516 // We failed.
[email protected]71f65dd2009-02-11 19:14:562517 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2518 false);
2519 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292520}
[email protected]de246f52009-02-25 18:25:452521#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292522
[email protected]71f65dd2009-02-11 19:14:562523void AutomationProvider::BringBrowserToFront(int browser_handle,
2524 bool* success) {
initial.commit09911bf2008-07-26 23:55:292525 if (browser_tracker_->ContainsHandle(browser_handle)) {
2526 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062527 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562528 *success = true;
initial.commit09911bf2008-07-26 23:55:292529 } else {
[email protected]71f65dd2009-02-11 19:14:562530 *success = false;
initial.commit09911bf2008-07-26 23:55:292531 }
2532}
2533
[email protected]71f65dd2009-02-11 19:14:562534void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2535 int message_num,
2536 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292537 if (browser_tracker_->ContainsHandle(browser_handle)) {
2538 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562539 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142540 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292541 } else {
[email protected]71f65dd2009-02-11 19:14:562542 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292543 }
2544}
2545
[email protected]de246f52009-02-25 18:25:452546#if defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472547// TODO(port): Enable this.
[email protected]71f65dd2009-02-11 19:14:562548void AutomationProvider::PrintNow(int tab_handle,
2549 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572550 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342551 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2552 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292553 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572554 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142555 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342556 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572557 return;
initial.commit09911bf2008-07-26 23:55:292558 }
[email protected]71f65dd2009-02-11 19:14:562559 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2560 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292561}
[email protected]d301c952009-07-13 15:02:412562
2563void AutomationProvider::PrintAsync(int tab_handle) {
2564 NavigationController* tab = NULL;
2565 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2566 if (tab_contents) {
2567 if (tab_contents->PrintNow())
2568 return;
2569 }
2570}
[email protected]3753f522009-04-14 23:15:472571#endif
initial.commit09911bf2008-07-26 23:55:292572
[email protected]71f65dd2009-02-11 19:14:562573void AutomationProvider::SavePage(int tab_handle,
initial.commit09911bf2008-07-26 23:55:292574 const std::wstring& file_name,
2575 const std::wstring& dir_path,
[email protected]71f65dd2009-02-11 19:14:562576 int type,
2577 bool* success) {
initial.commit09911bf2008-07-26 23:55:292578 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562579 *success = false;
initial.commit09911bf2008-07-26 23:55:292580 return;
2581 }
2582
2583 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2584 Browser* browser = FindAndActivateTab(nav);
2585 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142586 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562587 *success = false;
initial.commit09911bf2008-07-26 23:55:292588 return;
2589 }
2590
initial.commit09911bf2008-07-26 23:55:292591 SavePackage::SavePackageType save_type =
2592 static_cast<SavePackage::SavePackageType>(type);
2593 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2594 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342595 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292596
[email protected]71f65dd2009-02-11 19:14:562597 *success = true;
initial.commit09911bf2008-07-26 23:55:292598}
2599
[email protected]13869dd2009-05-05 00:40:062600#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]3753f522009-04-14 23:15:472601// TODO(port): Enable these.
[email protected]71f65dd2009-02-11 19:14:562602void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2603 bool* success,
2604 std::wstring* text) {
2605 *success = false;
initial.commit09911bf2008-07-26 23:55:292606 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562607 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522608 GetText();
[email protected]71f65dd2009-02-11 19:14:562609 *success = true;
initial.commit09911bf2008-07-26 23:55:292610 }
initial.commit09911bf2008-07-26 23:55:292611}
2612
[email protected]71f65dd2009-02-11 19:14:562613void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2614 const std::wstring& text,
2615 bool* success) {
2616 *success = false;
initial.commit09911bf2008-07-26 23:55:292617 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522618 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2619 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562620 *success = true;
initial.commit09911bf2008-07-26 23:55:292621 }
initial.commit09911bf2008-07-26 23:55:292622}
2623
2624void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562625 int autocomplete_edit_handle,
2626 bool* success,
2627 std::vector<AutocompleteMatchData>* matches) {
2628 *success = false;
initial.commit09911bf2008-07-26 23:55:292629 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272630 const AutocompleteResult& result = autocomplete_edit_tracker_->
2631 GetResource(autocomplete_edit_handle)->model()->result();
2632 for (AutocompleteResult::const_iterator i = result.begin();
2633 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562634 matches->push_back(AutocompleteMatchData(*i));
2635 *success = true;
initial.commit09911bf2008-07-26 23:55:292636 }
initial.commit09911bf2008-07-26 23:55:292637}
2638
2639void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562640 int autocomplete_edit_handle,
2641 bool* success,
2642 bool* query_in_progress) {
2643 *success = false;
2644 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292645 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562646 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522647 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562648 *success = true;
initial.commit09911bf2008-07-26 23:55:292649 }
initial.commit09911bf2008-07-26 23:55:292650}
2651
[email protected]28790922009-03-09 19:48:372652void AutomationProvider::OnMessageFromExternalHost(int handle,
2653 const std::string& message,
2654 const std::string& origin,
2655 const std::string& target) {
[email protected]f7a68432009-07-29 23:18:192656 RenderViewHost* view_host = GetViewForTab(handle);
2657 if (!view_host) {
2658 return;
[email protected]fa83e762008-08-15 21:41:392659 }
[email protected]f7a68432009-07-29 23:18:192660
2661 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
2662 view_host, message, origin, target)) {
2663 // Message was diverted.
2664 return;
2665 }
2666
2667 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
2668 origin, target, this, view_host, handle)) {
2669 // Message was diverted.
2670 return;
2671 }
2672
2673 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
2674 // Message was diverted.
2675 return;
2676 }
2677
2678 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392679}
[email protected]a9024892009-06-16 23:13:552680
2681bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2682 const std::string& message, const std::string& origin,
2683 const std::string& target) {
2684 if (target !=
2685 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2686 return false;
2687
2688 if (origin != extension_automation_constants::kAutomationOrigin) {
2689 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2690 return false;
2691 }
2692
2693 // The message is a JSON-encoded array with two elements, both strings. The
2694 // first is the name of the event to dispatch. The second is a JSON-encoding
2695 // of the arguments specific to that event.
2696 scoped_ptr<Value> message_value(JSONReader::Read(message, false));
2697 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2698 LOG(WARNING) << "Invalid browser event specified through automation";
2699 return false;
2700 }
2701
2702 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2703
2704 std::string event_name;
2705 if (!args->GetString(0, &event_name)) {
2706 LOG(WARNING) << "No browser event name specified through automation";
2707 return false;
2708 }
2709
2710 std::string json_args;
2711 if (!args->GetString(1, &json_args)) {
2712 LOG(WARNING) << "No browser event args specified through automation";
2713 return false;
2714 }
2715
[email protected]7120f132009-07-20 21:05:372716 if (profile()->GetExtensionMessageService()) {
2717 profile()->GetExtensionMessageService()->
2718 DispatchEventToRenderers(event_name.c_str(), json_args);
2719 }
[email protected]a9024892009-06-16 23:13:552720
2721 return true;
2722}
[email protected]13869dd2009-05-05 00:40:062723#endif // defined(OS_WIN) || defined(OS_LINUX)
[email protected]fa83e762008-08-15 21:41:392724
[email protected]57c6a652009-05-04 07:58:342725TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572726 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572727 if (tab_tracker_->ContainsHandle(handle)) {
2728 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342729 if (tab)
2730 *tab = nav_controller;
2731 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572732 }
[email protected]57c6a652009-05-04 07:58:342733 return NULL;
[email protected]20e93d12008-08-28 16:31:572734}
2735
[email protected]5cc063692009-04-07 23:21:312736#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272737ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
2738 if (tab_tracker_->ContainsHandle(handle)) {
2739 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]965524b2009-04-04 21:32:402740 return ExternalTabContainer::GetContainerForTab(
2741 tab->tab_contents()->GetNativeView());
[email protected]b9d227492009-02-10 15:20:272742 }
2743
2744 return NULL;
2745}
[email protected]de246f52009-02-25 18:25:452746#endif // defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272747
initial.commit09911bf2008-07-26 23:55:292748TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2749 : AutomationProvider(profile) {
2750 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142751 registrar_.Add(this, NotificationType::SESSION_END,
2752 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292753}
2754
2755TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292756 BrowserList::RemoveObserver(this);
2757}
2758
2759void TestingAutomationProvider::OnChannelError() {
2760 BrowserList::CloseAllBrowsers(true);
2761 AutomationProvider::OnChannelError();
2762}
2763
2764void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2765 // For backwards compatibility with the testing automation interface, we
2766 // want the automation provider (and hence the process) to go away when the
2767 // last browser goes away.
2768 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292769 // If you change this, update Observer for NotificationType::SESSION_END
2770 // below.
[email protected]295039bd2008-08-15 04:32:572771 MessageLoop::current()->PostTask(FROM_HERE,
2772 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292773 }
2774}
2775
2776void TestingAutomationProvider::Observe(NotificationType type,
2777 const NotificationSource& source,
2778 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562779 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292780 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2781 // before the task runs resulting in this object not being deleted. This
2782 // Release balance out the Release scheduled by OnBrowserRemoving.
2783 Release();
2784}
[email protected]295039bd2008-08-15 04:32:572785
2786void TestingAutomationProvider::OnRemoveProvider() {
2787 AutomationProviderList::GetInstance()->RemoveProvider(this);
2788}
[email protected]8a3422c92008-09-24 17:42:422789
[email protected]71f65dd2009-02-11 19:14:562790void AutomationProvider::GetSSLInfoBarCount(int handle, int* count) {
2791 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422792 if (tab_tracker_->ContainsHandle(handle)) {
2793 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342794 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112795 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422796 }
[email protected]8a3422c92008-09-24 17:42:422797}
2798
[email protected]71f65dd2009-02-11 19:14:562799void AutomationProvider::ClickSSLInfoBarLink(int handle,
[email protected]8a3422c92008-09-24 17:42:422800 int info_bar_index,
[email protected]71f65dd2009-02-11 19:14:562801 bool wait_for_navigation,
2802 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422803 bool success = false;
2804 if (tab_tracker_->ContainsHandle(handle)) {
2805 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2806 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112807 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422808 if (info_bar_index >= 0 && info_bar_index < count) {
2809 if (wait_for_navigation) {
[email protected]71f65dd2009-02-11 19:14:562810 AddNavigationStatusListener<bool>(nav_controller, reply_message,
2811 true, true, false);
[email protected]8a3422c92008-09-24 17:42:422812 }
[email protected]eb9ba192008-12-02 02:41:342813 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112814 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342815 info_bar_index);
2816 if (delegate->AsConfirmInfoBarDelegate())
2817 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422818 success = true;
2819 }
2820 }
[email protected]4f3dc372009-02-24 00:10:292821 }
[email protected]8a3422c92008-09-24 17:42:422822 if (!wait_for_navigation || !success)
[email protected]71f65dd2009-02-11 19:14:562823 AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(reply_message,
2824 success);
[email protected]8a3422c92008-09-24 17:42:422825}
2826
[email protected]71f65dd2009-02-11 19:14:562827void AutomationProvider::GetLastNavigationTime(int handle,
2828 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422829 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562830 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422831}
2832
[email protected]71f65dd2009-02-11 19:14:562833void AutomationProvider::WaitForNavigation(int handle,
2834 int64 last_navigation_time,
2835 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422836 NavigationController* controller = NULL;
2837 if (tab_tracker_->ContainsHandle(handle))
2838 controller = tab_tracker_->GetResource(handle);
2839
2840 Time time = tab_tracker_->GetLastNavigationTime(handle);
2841 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562842 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
2843 controller != NULL);
[email protected]4f3dc372009-02-24 00:10:292844 return;
[email protected]8a3422c92008-09-24 17:42:422845 }
2846
[email protected]71f65dd2009-02-11 19:14:562847 AddNavigationStatusListener<bool>(controller, reply_message, true, true,
2848 false);
[email protected]8a3422c92008-09-24 17:42:422849}
2850
[email protected]71f65dd2009-02-11 19:14:562851void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162852 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562853 int value,
2854 bool* success) {
2855 *success = false;
[email protected]8a3422c92008-09-24 17:42:422856 if (browser_tracker_->ContainsHandle(handle)) {
2857 Browser* browser = browser_tracker_->GetResource(handle);
2858 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562859 *success = true;
[email protected]8a3422c92008-09-24 17:42:422860 }
[email protected]8a3422c92008-09-24 17:42:422861}
[email protected]97fa6ce32008-12-19 01:48:162862
[email protected]71f65dd2009-02-11 19:14:562863void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162864 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562865 const std::wstring& value,
2866 bool* success) {
2867 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162868 if (browser_tracker_->ContainsHandle(handle)) {
2869 Browser* browser = browser_tracker_->GetResource(handle);
2870 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562871 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162872 }
[email protected]97fa6ce32008-12-19 01:48:162873}
2874
[email protected]71f65dd2009-02-11 19:14:562875void AutomationProvider::GetBooleanPreference(int handle,
2876 const std::wstring& name,
2877 bool* success,
2878 bool* value) {
2879 *success = false;
2880 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162881 if (browser_tracker_->ContainsHandle(handle)) {
2882 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562883 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2884 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162885 }
[email protected]97fa6ce32008-12-19 01:48:162886}
2887
[email protected]71f65dd2009-02-11 19:14:562888void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162889 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562890 bool value,
2891 bool* success) {
2892 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162893 if (browser_tracker_->ContainsHandle(handle)) {
2894 Browser* browser = browser_tracker_->GetResource(handle);
2895 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562896 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162897 }
[email protected]97fa6ce32008-12-19 01:48:162898}
2899
2900// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562901void AutomationProvider::GetPageCurrentEncoding(
2902 int tab_handle, std::wstring* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162903 if (tab_tracker_->ContainsHandle(tab_handle)) {
2904 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2905 Browser* browser = FindAndActivateTab(nav);
2906 DCHECK(browser);
2907
[email protected]57c6a652009-05-04 07:58:342908 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2909 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162910 }
[email protected]97fa6ce32008-12-19 01:48:162911}
2912
2913// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562914void AutomationProvider::OverrideEncoding(int tab_handle,
2915 const std::wstring& encoding_name,
2916 bool* success) {
2917 *success = false;
[email protected]de246f52009-02-25 18:25:452918#if defined(OS_WIN)
[email protected]97fa6ce32008-12-19 01:48:162919 if (tab_tracker_->ContainsHandle(tab_handle)) {
2920 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2921 Browser* browser = FindAndActivateTab(nav);
2922 DCHECK(browser);
2923
[email protected]1fc025202009-01-20 23:03:142924 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:112925 TabContents* tab_contents = nav->tab_contents();
[email protected]97fa6ce32008-12-19 01:48:162926 int selected_encoding_id =
2927 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2928 if (selected_encoding_id) {
2929 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562930 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162931 }
2932 }
2933 }
[email protected]de246f52009-02-25 18:25:452934#else
2935 // TODO(port): Enable when encoding-related parts of Browser are ported.
2936 NOTIMPLEMENTED();
2937#endif
[email protected]97fa6ce32008-12-19 01:48:162938}
[email protected]5bcdb312009-01-07 21:43:202939
[email protected]4d434a1a2009-02-11 21:06:572940void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:202941 SavePackage::SetShouldPromptUser(should_prompt);
2942}
[email protected]87eab222009-03-13 00:47:452943
[email protected]b83e4602009-05-15 22:58:332944void AutomationProvider::SetEnableExtensionAutomation(bool automation_enabled) {
2945 AutomationExtensionFunction::SetEnabled(automation_enabled);
2946}
2947
[email protected]d2cc6ed2009-04-24 00:26:172948#if defined(OS_WIN)
2949// TODO(port): Reposition_Params is win-specific. We'll need to port it.
[email protected]87eab222009-03-13 00:47:452950void AutomationProvider::OnTabReposition(
2951 int tab_handle, const IPC::Reposition_Params& params) {
2952 if (!tab_tracker_->ContainsHandle(tab_handle))
2953 return;
2954
2955 if (!IsWindow(params.window))
2956 return;
2957
2958 unsigned long process_id = 0;
2959 unsigned long thread_id = 0;
2960
2961 thread_id = GetWindowThreadProcessId(params.window, &process_id);
2962
2963 if (thread_id != GetCurrentThreadId()) {
2964 NOTREACHED();
2965 return;
2966 }
2967
[email protected]a9233d0f2009-04-20 05:39:332968 SetWindowPos(params.window, params.window_insert_after, params.left,
2969 params.top, params.width, params.height, params.flags);
2970
[email protected]a2c5a9892009-04-07 16:13:452971 if (params.set_parent) {
2972 if (IsWindow(params.parent_window)) {
2973 if (!SetParent(params.window, params.parent_window))
2974 DLOG(WARNING) << "SetParent failed. Error 0x%x" << GetLastError();
2975 }
2976 }
[email protected]87eab222009-03-13 00:47:452977}
[email protected]e943d6662009-06-12 03:50:392978
2979void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle,
2980 int command) {
2981 if (tab_tracker_->ContainsHandle(tab_handle)) {
2982 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2983 if (!tab) {
2984 NOTREACHED();
2985 return;
2986 }
2987
2988 TabContents* tab_contents = tab->tab_contents();
2989 if (!tab_contents || !tab_contents->delegate()) {
2990 NOTREACHED();
2991 return;
2992 }
2993
2994 tab_contents->delegate()->ExecuteContextMenuCommand(command);
2995 }
2996}
2997
2998#endif // defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472999
3000void AutomationProvider::GetWindowTitle(int handle, string16* text) {
3001 gfx::NativeWindow window = window_tracker_->GetResource(handle);
3002 text->assign(platform_util::GetWindowTitle(window));
3003}
[email protected]66ba4932009-06-04 19:22:133004
3005void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3006 *count = -1; // -1 is the error code
3007 if (tab_tracker_->ContainsHandle(handle)) {
3008 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3009 TabContents* tab_contents = nav_controller->tab_contents();
3010 if (tab_contents) {
3011 BlockedPopupContainer* container =
3012 tab_contents->blocked_popup_container();
3013 if (container) {
3014 *count = static_cast<int>(container->GetBlockedPopupCount());
3015 } else {
3016 // If we don't have a container, we don't have any blocked popups to
3017 // contain!
3018 *count = 0;
3019 }
3020 }
3021 }
3022}
[email protected]f7a68432009-07-29 23:18:193023
3024void AutomationProvider::SelectAll(int tab_handle) {
3025 RenderViewHost* view = GetViewForTab(tab_handle);
3026 if (!view) {
3027 NOTREACHED();
3028 return;
3029 }
3030
3031 view->SelectAll();
3032}
3033
3034void AutomationProvider::Cut(int tab_handle) {
3035 RenderViewHost* view = GetViewForTab(tab_handle);
3036 if (!view) {
3037 NOTREACHED();
3038 return;
3039 }
3040
3041 view->Cut();
3042}
3043
3044void AutomationProvider::Copy(int tab_handle) {
3045 RenderViewHost* view = GetViewForTab(tab_handle);
3046 if (!view) {
3047 NOTREACHED();
3048 return;
3049 }
3050
3051 view->Copy();
3052}
3053
3054void AutomationProvider::Paste(int tab_handle) {
3055 RenderViewHost* view = GetViewForTab(tab_handle);
3056 if (!view) {
3057 NOTREACHED();
3058 return;
3059 }
3060
3061 view->Paste();
3062}
3063
3064void AutomationProvider::ReloadAsync(int tab_handle) {
3065 if (tab_tracker_->ContainsHandle(tab_handle)) {
3066 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3067 if (!tab) {
3068 NOTREACHED();
3069 return;
3070 }
3071
3072 tab->Reload(false);
3073 }
3074}
3075
3076void AutomationProvider::StopAsync(int tab_handle) {
3077 RenderViewHost* view = GetViewForTab(tab_handle);
3078 if (!view) {
3079 NOTREACHED();
3080 return;
3081 }
3082
3083 view->Stop();
3084}
3085
3086RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3087 if (tab_tracker_->ContainsHandle(tab_handle)) {
3088 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3089 if (!tab) {
3090 NOTREACHED();
3091 return NULL;
3092 }
3093
3094 TabContents* tab_contents = tab->tab_contents();
3095 if (!tab_contents) {
3096 NOTREACHED();
3097 return NULL;
3098 }
3099
3100 RenderViewHost* view_host = tab_contents->render_view_host();
3101 return view_host;
3102 }
3103
3104 return NULL;
3105}