blob: 86ccbb9d5c1f9e6aa9b6586407fff4d48af6b554 [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]3fcac682009-08-13 02:28:0136#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5337#include "chrome/browser/net/url_request_mock_util.h"
[email protected]a7eee32f2009-05-22 18:08:1738#include "chrome/browser/profile_manager.h"
[email protected]6524b5f92009-01-22 17:48:2539#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0340#include "chrome/browser/ssl/ssl_manager.h"
41#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3442#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4543#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1744#include "chrome/common/automation_constants.h"
initial.commit09911bf2008-07-26 23:55:2945#include "chrome/common/chrome_paths.h"
[email protected]a7eee32f2009-05-22 18:08:1746#include "chrome/common/json_value_serializer.h"
[email protected]1c58a5c2009-05-21 18:47:1447#include "chrome/common/notification_service.h"
[email protected]3753f522009-04-14 23:15:4748#include "chrome/common/platform_util.h"
[email protected]8a3422c92008-09-24 17:42:4249#include "chrome/common/pref_service.h"
[email protected]71f65dd2009-02-11 19:14:5650#include "chrome/test/automation/automation_messages.h"
[email protected]a7eee32f2009-05-22 18:08:1751#include "net/proxy/proxy_service.h"
52#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2153#include "net/url_request/url_request_context.h"
[email protected]9a08bcf2009-08-12 19:56:2854#include "views/event.h"
initial.commit09911bf2008-07-26 23:55:2955
[email protected]de246f52009-02-25 18:25:4556#if defined(OS_WIN)
57// TODO(port): Port these headers.
[email protected]de246f52009-02-25 18:25:4558#include "chrome/browser/character_encoding.h"
59#include "chrome/browser/download/save_package.h"
60#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4561#include "chrome/browser/printing/print_job.h"
[email protected]de246f52009-02-25 18:25:4562#endif // defined(OS_WIN)
63
[email protected]e8382172009-06-19 22:16:2864#if defined(OS_WIN) || defined(OS_LINUX)
65// TODO(port): Port these to the mac.
[email protected]9a08bcf2009-08-12 19:56:2866#include "chrome/browser/automation/ui_controls.h"
[email protected]e8382172009-06-19 22:16:2867#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]c2cb8542009-08-20 21:16:5174#elif defined(OS_LINUX)
75#include "chrome/browser/gtk/view_id_util.h"
[email protected]13869dd2009-05-05 00:40:0676#endif
77
[email protected]e1acf6f2008-10-27 20:43:3378using base::Time;
79
[email protected]f5446092009-07-30 21:10:0180#if defined(OS_WIN)
81static void MoveMouse(const POINT& point) {
82 SetCursorPos(point.x, point.y);
83
84 // Now, make sure that GetMessagePos returns the values we just set by
85 // simulating a mouse move. The value returned by GetMessagePos is updated
86 // when a mouse move event is removed from the event queue.
87 PostMessage(NULL, WM_MOUSEMOVE, 0, MAKELPARAM(point.x, point.y));
88 MSG msg;
89 while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
90 ;
91
92 // Verify
93#ifndef NDEBUG
94 DWORD pos = GetMessagePos();
95 DCHECK_EQ(point.x, GET_X_LPARAM(pos));
96 DCHECK_EQ(point.y, GET_Y_LPARAM(pos));
97#endif
98}
99#endif
100
initial.commit09911bf2008-07-26 23:55:29101class InitialLoadObserver : public NotificationObserver {
102 public:
103 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
[email protected]66791d22009-02-24 20:11:33104 : automation_(automation),
105 outstanding_tab_count_(tab_count) {
initial.commit09911bf2008-07-26 23:55:29106 if (outstanding_tab_count_ > 0) {
[email protected]bfd04a62009-02-01 18:16:56107 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:03108 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:56109 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:03110 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29111 }
112 }
113
114 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:29115 }
116
117 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:03118 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29119 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
120 }
121
initial.commit09911bf2008-07-26 23:55:29122 virtual void Observe(NotificationType type,
123 const NotificationSource& source,
124 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56125 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29126 if (outstanding_tab_count_ > loading_tabs_.size())
127 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:56128 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29129 if (outstanding_tab_count_ > finished_tabs_.size()) {
130 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
131 finished_tabs_.insert(source.map_key());
132 if (outstanding_tab_count_ == finished_tabs_.size())
133 ConditionMet();
134 }
135 } else {
136 NOTREACHED();
137 }
138 }
139
140 private:
141 typedef std::set<uintptr_t> TabSet;
142
[email protected]6a02963e2009-01-06 16:58:03143 NotificationRegistrar registrar_;
144
initial.commit09911bf2008-07-26 23:55:29145 AutomationProvider* automation_;
146 size_t outstanding_tab_count_;
147 TabSet loading_tabs_;
148 TabSet finished_tabs_;
149};
150
151// Watches for NewTabUI page loads for performance timing purposes.
152class NewTabUILoadObserver : public NotificationObserver {
153 public:
154 explicit NewTabUILoadObserver(AutomationProvider* automation)
155 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14156 registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
157 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29158 }
159
160 ~NewTabUILoadObserver() {
initial.commit09911bf2008-07-26 23:55:29161 }
162
163 virtual void Observe(NotificationType type,
164 const NotificationSource& source,
165 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56166 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29167 Details<int> load_time(details);
168 automation_->Send(
169 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
170 } else {
171 NOTREACHED();
172 }
173 }
174
175 private:
[email protected]1c58a5c2009-05-21 18:47:14176 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29177 AutomationProvider* automation_;
178};
179
180class NavigationControllerRestoredObserver : public NotificationObserver {
181 public:
182 NavigationControllerRestoredObserver(AutomationProvider* automation,
183 NavigationController* controller,
[email protected]71f65dd2009-02-11 19:14:56184 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29185 : automation_(automation),
186 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56187 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29188 if (FinishedRestoring()) {
initial.commit09911bf2008-07-26 23:55:29189 SendDone();
190 } else {
[email protected]1c58a5c2009-05-21 18:47:14191 registrar_.Add(this, NotificationType::LOAD_STOP,
192 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29193 }
194 }
195
196 ~NavigationControllerRestoredObserver() {
initial.commit09911bf2008-07-26 23:55:29197 }
198
199 virtual void Observe(NotificationType type,
200 const NotificationSource& source,
201 const NotificationDetails& details) {
202 if (FinishedRestoring()) {
203 SendDone();
[email protected]1c58a5c2009-05-21 18:47:14204 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29205 }
206 }
207
208 private:
initial.commit09911bf2008-07-26 23:55:29209 bool FinishedRestoring() {
[email protected]7f0005a2009-04-15 03:25:11210 return (!controller_->needs_reload() && !controller_->pending_entry() &&
211 !controller_->tab_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29212 }
213
214 void SendDone() {
[email protected]71f65dd2009-02-11 19:14:56215 DCHECK(reply_message_ != NULL);
216 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29217 }
218
[email protected]1c58a5c2009-05-21 18:47:14219 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29220 AutomationProvider* automation_;
221 NavigationController* controller_;
[email protected]71f65dd2009-02-11 19:14:56222 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29223
[email protected]5a52f162008-08-27 04:15:31224 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29225};
226
initial.commit09911bf2008-07-26 23:55:29227class NavigationNotificationObserver : public NotificationObserver {
228 public:
229 NavigationNotificationObserver(NavigationController* controller,
230 AutomationProvider* automation,
[email protected]2e028a082009-08-19 20:32:58231 IPC::Message* reply_message,
232 int number_of_navigations)
initial.commit09911bf2008-07-26 23:55:29233 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56234 reply_message_(reply_message),
initial.commit09911bf2008-07-26 23:55:29235 controller_(controller),
[email protected]2e028a082009-08-19 20:32:58236 navigations_remaining_(number_of_navigations),
[email protected]457f5cf2009-08-18 16:37:52237 navigation_started_(false) {
[email protected]2e028a082009-08-19 20:32:58238 DCHECK_LT(0, navigations_remaining_);
[email protected]1c58a5c2009-05-21 18:47:14239 Source<NavigationController> source(controller_);
240 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
241 registrar_.Add(this, NotificationType::LOAD_START, source);
242 registrar_.Add(this, NotificationType::LOAD_STOP, source);
243 registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
244 registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
initial.commit09911bf2008-07-26 23:55:29245 }
246
247 ~NavigationNotificationObserver() {
[email protected]1c58a5c2009-05-21 18:47:14248 if (reply_message_) {
249 // This means we did not receive a notification for this navigation.
250 // Send over a failed navigation status back to the caller to ensure that
251 // the caller does not hang waiting for the response.
[email protected]457f5cf2009-08-18 16:37:52252 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
253 reply_message_, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]1c58a5c2009-05-21 18:47:14254 automation_->Send(reply_message_);
255 reply_message_ = NULL;
256 }
257
258 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29259 }
260
[email protected]457f5cf2009-08-18 16:37:52261 void ConditionMet(AutomationMsg_NavigationResponseValues navigation_result) {
[email protected]71f65dd2009-02-11 19:14:56262 DCHECK(reply_message_ != NULL);
263
[email protected]457f5cf2009-08-18 16:37:52264 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
265 reply_message_, navigation_result);
[email protected]71f65dd2009-02-11 19:14:56266 automation_->Send(reply_message_);
267 reply_message_ = NULL;
268
initial.commit09911bf2008-07-26 23:55:29269 delete this;
270 }
271
initial.commit09911bf2008-07-26 23:55:29272 virtual void Observe(NotificationType type,
273 const NotificationSource& source,
274 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42275 // We listen for 2 events to determine when the navigation started because:
276 // - when this is used by the WaitForNavigation method, we might be invoked
277 // afer the load has started (but not after the entry was committed, as
278 // WaitForNavigation compares times of the last navigation).
279 // - when this is used with a page requiring authentication, we will not get
[email protected]4f3dc372009-02-24 00:10:29280 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
281 // we need the NotificationType::LOAD_START.
[email protected]bfd04a62009-02-01 18:16:56282 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
283 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29284 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56285 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29286 if (navigation_started_) {
287 navigation_started_ = false;
[email protected]2e028a082009-08-19 20:32:58288 if (--navigations_remaining_ == 0)
289 ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
initial.commit09911bf2008-07-26 23:55:29290 }
[email protected]bfd04a62009-02-01 18:16:56291 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29292 // The LoginHandler for this tab is no longer valid.
293 automation_->RemoveLoginHandler(controller_);
294
295 // Treat this as if navigation started again, since load start/stop don't
296 // occur while authentication is ongoing.
297 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56298 } else if (type == NotificationType::AUTH_NEEDED) {
[email protected]de246f52009-02-25 18:25:45299#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29300 if (navigation_started_) {
301 // Remember the login handler that wants authentication.
302 LoginHandler* handler =
303 Details<LoginNotificationDetails>(details)->handler();
304 automation_->AddLoginHandler(controller_, handler);
305
306 // Respond that authentication is needed.
307 navigation_started_ = false;
[email protected]457f5cf2009-08-18 16:37:52308 ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
initial.commit09911bf2008-07-26 23:55:29309 } else {
310 NOTREACHED();
311 }
[email protected]de246f52009-02-25 18:25:45312#else
313 // TODO(port): Enable when we have LoginNotificationDetails etc.
314 NOTIMPLEMENTED();
315#endif
initial.commit09911bf2008-07-26 23:55:29316 } else {
317 NOTREACHED();
318 }
319 }
320
321 private:
[email protected]1c58a5c2009-05-21 18:47:14322 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29323 AutomationProvider* automation_;
[email protected]71f65dd2009-02-11 19:14:56324 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29325 NavigationController* controller_;
[email protected]2e028a082009-08-19 20:32:58326 int navigations_remaining_;
initial.commit09911bf2008-07-26 23:55:29327 bool navigation_started_;
initial.commit09911bf2008-07-26 23:55:29328};
329
330class TabStripNotificationObserver : public NotificationObserver {
331 public:
[email protected]1c58a5c2009-05-21 18:47:14332 TabStripNotificationObserver(NotificationType notification,
333 AutomationProvider* automation)
334 : automation_(automation),
335 notification_(notification) {
336 registrar_.Add(this, notification_, NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29337 }
338
339 virtual ~TabStripNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29340 }
341
342 virtual void Observe(NotificationType type,
343 const NotificationSource& source,
344 const NotificationDetails& details) {
345 if (type == notification_) {
346 ObserveTab(Source<NavigationController>(source).ptr());
347
348 // If verified, no need to observe anymore
349 automation_->RemoveTabStripObserver(this);
350 delete this;
351 } else {
352 NOTREACHED();
353 }
354 }
355
356 virtual void ObserveTab(NavigationController* controller) = 0;
357
358 protected:
[email protected]1c58a5c2009-05-21 18:47:14359 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29360 AutomationProvider* automation_;
initial.commit09911bf2008-07-26 23:55:29361 NotificationType notification_;
initial.commit09911bf2008-07-26 23:55:29362};
363
364class TabAppendedNotificationObserver : public TabStripNotificationObserver {
365 public:
366 TabAppendedNotificationObserver(Browser* parent,
[email protected]1c58a5c2009-05-21 18:47:14367 AutomationProvider* automation,
368 IPC::Message* reply_message)
369 : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
370 automation),
371 parent_(parent),
[email protected]71f65dd2009-02-11 19:14:56372 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29373 }
374
375 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14376 if (automation_->GetIndexForNavigationController(controller, parent_) ==
377 TabStripModel::kNoTab) {
378 // This tab notification doesn't belong to the parent_.
initial.commit09911bf2008-07-26 23:55:29379 return;
380 }
381
[email protected]2e028a082009-08-19 20:32:58382 automation_->AddNavigationStatusListener(controller, reply_message_, 1);
initial.commit09911bf2008-07-26 23:55:29383 }
[email protected]71f65dd2009-02-11 19:14:56384
385 protected:
[email protected]1c58a5c2009-05-21 18:47:14386 Browser* parent_;
[email protected]71f65dd2009-02-11 19:14:56387 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29388};
389
390class TabClosedNotificationObserver : public TabStripNotificationObserver {
391 public:
[email protected]1c58a5c2009-05-21 18:47:14392 TabClosedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56393 bool wait_until_closed,
394 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:14395 : TabStripNotificationObserver(wait_until_closed ?
396 NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
397 automation),
398 reply_message_(reply_message),
399 for_browser_command_(false) {
initial.commit09911bf2008-07-26 23:55:29400 }
401
402 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14403 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42404 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
405 true);
[email protected]1c58a5c2009-05-21 18:47:14406 } else {
[email protected]d79ffea2009-05-07 20:51:42407 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
[email protected]1c58a5c2009-05-21 18:47:14408 }
[email protected]71f65dd2009-02-11 19:14:56409 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29410 }
[email protected]71f65dd2009-02-11 19:14:56411
[email protected]d79ffea2009-05-07 20:51:42412 void set_for_browser_command(bool for_browser_command) {
413 for_browser_command_ = for_browser_command;
414 }
[email protected]1c58a5c2009-05-21 18:47:14415
[email protected]71f65dd2009-02-11 19:14:56416 protected:
417 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42418 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29419};
420
[email protected]14c0a032009-04-13 18:15:14421class BrowserOpenedNotificationObserver : public NotificationObserver {
422 public:
423 BrowserOpenedNotificationObserver(AutomationProvider* automation,
424 IPC::Message* reply_message)
425 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42426 reply_message_(reply_message),
427 for_browser_command_(false) {
[email protected]14c0a032009-04-13 18:15:14428 registrar_.Add(this, NotificationType::BROWSER_OPENED,
429 NotificationService::AllSources());
430 }
431
432 ~BrowserOpenedNotificationObserver() {
433 }
434
435 virtual void Observe(NotificationType type,
436 const NotificationSource& source,
437 const NotificationDetails& details) {
438 if (type == NotificationType::BROWSER_OPENED) {
[email protected]1c58a5c2009-05-21 18:47:14439 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42440 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
441 true);
[email protected]1c58a5c2009-05-21 18:47:14442 }
[email protected]14c0a032009-04-13 18:15:14443 automation_->Send(reply_message_);
444 delete this;
445 } else {
446 NOTREACHED();
447 }
448 }
449
[email protected]d79ffea2009-05-07 20:51:42450 void set_for_browser_command(bool for_browser_command) {
451 for_browser_command_ = for_browser_command;
452 }
[email protected]1c58a5c2009-05-21 18:47:14453
[email protected]14c0a032009-04-13 18:15:14454 private:
[email protected]1c58a5c2009-05-21 18:47:14455 NotificationRegistrar registrar_;
[email protected]14c0a032009-04-13 18:15:14456 AutomationProvider* automation_;
457 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42458 bool for_browser_command_;
[email protected]14c0a032009-04-13 18:15:14459};
460
initial.commit09911bf2008-07-26 23:55:29461class BrowserClosedNotificationObserver : public NotificationObserver {
462 public:
463 BrowserClosedNotificationObserver(Browser* browser,
464 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56465 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29466 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42467 reply_message_(reply_message),
468 for_browser_command_(false) {
[email protected]c300deb32009-05-08 21:26:07469 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
470 Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29471 }
472
473 virtual void Observe(NotificationType type,
474 const NotificationSource& source,
475 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56476 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29477 Details<bool> close_app(details);
[email protected]71f65dd2009-02-11 19:14:56478 DCHECK(reply_message_ != NULL);
[email protected]1c58a5c2009-05-21 18:47:14479 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42480 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
481 true);
[email protected]1c58a5c2009-05-21 18:47:14482 } else {
[email protected]d79ffea2009-05-07 20:51:42483 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
484 *(close_app.ptr()));
[email protected]1c58a5c2009-05-21 18:47:14485 }
[email protected]71f65dd2009-02-11 19:14:56486 automation_->Send(reply_message_);
487 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29488 delete this;
489 }
490
[email protected]d79ffea2009-05-07 20:51:42491 void set_for_browser_command(bool for_browser_command) {
492 for_browser_command_ = for_browser_command;
493 }
[email protected]1c58a5c2009-05-21 18:47:14494
initial.commit09911bf2008-07-26 23:55:29495 private:
[email protected]c300deb32009-05-08 21:26:07496 NotificationRegistrar registrar_;
[email protected]1c58a5c2009-05-21 18:47:14497 AutomationProvider* automation_;
498 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42499 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29500};
501
[email protected]2949e90d2009-08-21 15:32:52502class BrowserCountChangeNotificationObserver : public NotificationObserver {
503 public:
504 BrowserCountChangeNotificationObserver(int target_count,
505 AutomationProvider* automation,
506 IPC::Message* reply_message)
507 : target_count_(target_count),
508 automation_(automation),
509 reply_message_(reply_message) {
510 registrar_.Add(this, NotificationType::BROWSER_OPENED,
511 NotificationService::AllSources());
512 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
513 NotificationService::AllSources());
514 }
515
516 virtual void Observe(NotificationType type,
517 const NotificationSource& source,
518 const NotificationDetails& details) {
519 DCHECK(type == NotificationType::BROWSER_OPENED ||
520 type == NotificationType::BROWSER_CLOSED);
521 int current_count = static_cast<int>(BrowserList::size());
522 if (type == NotificationType::BROWSER_CLOSED) {
523 // At the time of the notification the browser being closed is not removed
524 // from the list. The real count is one less than the reported count.
525 DCHECK_LT(0, current_count);
526 current_count--;
527 }
528 if (current_count == target_count_) {
529 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
530 reply_message_, true);
531 automation_->Send(reply_message_);
532 reply_message_ = NULL;
533 delete this;
534 }
535 }
536
537 private:
538 int target_count_;
539 NotificationRegistrar registrar_;
540 AutomationProvider* automation_;
541 IPC::Message* reply_message_;
542};
543
544class AppModalDialogShownObserver : public NotificationObserver {
545 public:
546 AppModalDialogShownObserver(AutomationProvider* automation,
547 IPC::Message* reply_message)
548 : automation_(automation),
549 reply_message_(reply_message) {
550 registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN,
551 NotificationService::AllSources());
552 }
553
554 ~AppModalDialogShownObserver() {
555 }
556
557 virtual void Observe(NotificationType type,
558 const NotificationSource& source,
559 const NotificationDetails& details) {
560 DCHECK(type == NotificationType::APP_MODAL_DIALOG_SHOWN);
561 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
562 reply_message_, true);
563 automation_->Send(reply_message_);
564 reply_message_ = NULL;
565 delete this;
566 }
567
568 private:
569 NotificationRegistrar registrar_;
570 AutomationProvider* automation_;
571 IPC::Message* reply_message_;
572};
573
[email protected]4e41709d2009-04-08 00:04:27574namespace {
575
576// Define mapping from command to notification
577struct CommandNotification {
578 int command;
579 NotificationType::Type notification_type;
580};
581
582const struct CommandNotification command_notifications[] = {
[email protected]14c0a032009-04-13 18:15:14583 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
[email protected]f8fc5882009-05-06 04:23:43584 {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
[email protected]d79ffea2009-05-07 20:51:42585 // Returns as soon as the restored tab is created. To further wait until
586 // the content page is loaded, use WaitForTabToBeRestored.
[email protected]f8fc5882009-05-06 04:23:43587 {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
[email protected]4e41709d2009-04-08 00:04:27588};
589
590} // namespace
591
[email protected]56e71b7c2009-03-27 03:05:56592class ExecuteBrowserCommandObserver : public NotificationObserver {
593 public:
[email protected]56e71b7c2009-03-27 03:05:56594 ~ExecuteBrowserCommandObserver() {
595 }
596
[email protected]d79ffea2009-05-07 20:51:42597 static bool CreateAndRegisterObserver(AutomationProvider* automation,
598 Browser* browser,
599 int command,
600 IPC::Message* reply_message) {
601 bool result = true;
602 switch (command) {
603 case IDC_NEW_WINDOW:
604 case IDC_NEW_INCOGNITO_WINDOW: {
605 BrowserOpenedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14606 new BrowserOpenedNotificationObserver(automation, reply_message);
[email protected]d79ffea2009-05-07 20:51:42607 observer->set_for_browser_command(true);
608 break;
609 }
610 case IDC_CLOSE_WINDOW: {
611 BrowserClosedNotificationObserver* observer =
612 new BrowserClosedNotificationObserver(browser, automation,
[email protected]d79ffea2009-05-07 20:51:42613 reply_message);
614 observer->set_for_browser_command(true);
615 break;
616 }
617 case IDC_CLOSE_TAB: {
618 TabClosedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14619 new TabClosedNotificationObserver(automation, true, reply_message);
[email protected]d79ffea2009-05-07 20:51:42620 observer->set_for_browser_command(true);
621 break;
622 }
[email protected]27e1c9e02009-05-13 18:41:39623 case IDC_BACK:
624 case IDC_FORWARD:
625 case IDC_RELOAD: {
[email protected]457f5cf2009-08-18 16:37:52626 automation->AddNavigationStatusListener(
[email protected]27e1c9e02009-05-13 18:41:39627 &browser->GetSelectedTabContents()->controller(),
[email protected]2e028a082009-08-19 20:32:58628 reply_message, 1);
[email protected]27e1c9e02009-05-13 18:41:39629 break;
630 }
[email protected]d79ffea2009-05-07 20:51:42631 default: {
632 ExecuteBrowserCommandObserver* observer =
633 new ExecuteBrowserCommandObserver(automation, reply_message);
634 if (!observer->Register(command)) {
635 delete observer;
636 result = false;
637 }
638 break;
639 }
640 }
641 return result;
[email protected]4e41709d2009-04-08 00:04:27642 }
643
[email protected]56e71b7c2009-03-27 03:05:56644 virtual void Observe(NotificationType type,
645 const NotificationSource& source,
646 const NotificationDetails& details) {
647 if (type == notification_type_) {
[email protected]49a14a82009-03-31 04:16:44648 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
649 true);
[email protected]56e71b7c2009-03-27 03:05:56650 automation_->Send(reply_message_);
651 delete this;
652 } else {
653 NOTREACHED();
654 }
655 }
656
657 private:
[email protected]d79ffea2009-05-07 20:51:42658 ExecuteBrowserCommandObserver(AutomationProvider* automation,
659 IPC::Message* reply_message)
660 : automation_(automation),
661 reply_message_(reply_message) {
662 }
663
664 bool Register(int command) {
665 if (!GetNotificationType(command, &notification_type_))
666 return false;
[email protected]1c58a5c2009-05-21 18:47:14667 registrar_.Add(this, notification_type_, NotificationService::AllSources());
[email protected]d79ffea2009-05-07 20:51:42668 return true;
669 }
670
[email protected]4e41709d2009-04-08 00:04:27671 bool GetNotificationType(int command, NotificationType::Type* type) {
672 if (!type)
673 return false;
674 bool found = false;
675 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
676 if (command_notifications[i].command == command) {
677 *type = command_notifications[i].notification_type;
678 found = true;
679 break;
680 }
681 }
682 return found;
683 }
684
[email protected]1c58a5c2009-05-21 18:47:14685 NotificationRegistrar registrar_;
[email protected]56e71b7c2009-03-27 03:05:56686 AutomationProvider* automation_;
687 NotificationType::Type notification_type_;
688 IPC::Message* reply_message_;
[email protected]56e71b7c2009-03-27 03:05:56689};
690
initial.commit09911bf2008-07-26 23:55:29691class FindInPageNotificationObserver : public NotificationObserver {
692 public:
693 FindInPageNotificationObserver(AutomationProvider* automation,
694 TabContents* parent_tab,
[email protected]71f65dd2009-02-11 19:14:56695 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29696 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56697 active_match_ordinal_(-1),
698 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14699 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
700 Source<TabContents>(parent_tab));
initial.commit09911bf2008-07-26 23:55:29701 }
702
703 ~FindInPageNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29704 }
705
[email protected]1c58a5c2009-05-21 18:47:14706 virtual void Observe(NotificationType type,
707 const NotificationSource& source,
708 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56709 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29710 Details<FindNotificationDetails> find_details(details);
711 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49712 // We get multiple responses and one of those will contain the ordinal.
713 // This message comes to us before the final update is sent.
714 if (find_details->active_match_ordinal() > -1)
715 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29716 if (find_details->final_update()) {
[email protected]d97a5642009-07-16 19:33:26717 if (reply_message_ != NULL) {
718 AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
719 active_match_ordinal_, find_details->number_of_matches());
720 automation_->Send(reply_message_);
721 reply_message_ = NULL;
722 } else {
723 DLOG(WARNING) << "Multiple final Find messages observed.";
724 }
initial.commit09911bf2008-07-26 23:55:29725 } else {
726 DLOG(INFO) << "Ignoring, since we only care about the final message";
727 }
728 }
729 } else {
730 NOTREACHED();
731 }
732 }
733
734 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
735 // we wait for notification to find out what the results are. As the user is
736 // typing, new search requests can be issued and the Request ID helps us make
737 // sense of whether this is the current request or an old one. The unit tests,
738 // however, which uses this constant issues only one search at a time, so we
739 // don't need a rolling id to identify each search. But, we still need to
740 // specify one, so we just use a fixed one - its value does not matter.
741 static const int kFindInPageRequestId;
[email protected]1c58a5c2009-05-21 18:47:14742
initial.commit09911bf2008-07-26 23:55:29743 private:
[email protected]1c58a5c2009-05-21 18:47:14744 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29745 AutomationProvider* automation_;
[email protected]aedd85a2008-12-04 19:32:49746 // We will at some point (before final update) be notified of the ordinal and
747 // we need to preserve it so we can send it later.
748 int active_match_ordinal_;
[email protected]71f65dd2009-02-11 19:14:56749 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29750};
751
752const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
753
754class DomOperationNotificationObserver : public NotificationObserver {
755 public:
756 explicit DomOperationNotificationObserver(AutomationProvider* automation)
757 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14758 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
759 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29760 }
761
762 ~DomOperationNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29763 }
764
[email protected]1c58a5c2009-05-21 18:47:14765 virtual void Observe(NotificationType type,
766 const NotificationSource& source,
767 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56768 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29769 Details<DomOperationNotificationDetails> dom_op_details(details);
[email protected]71f65dd2009-02-11 19:14:56770
771 IPC::Message* reply_message = automation_->reply_message_release();
772 DCHECK(reply_message != NULL);
773
[email protected]1c58a5c2009-05-21 18:47:14774 AutomationMsg_DomOperation::WriteReplyParams(reply_message,
775 dom_op_details->json());
[email protected]71f65dd2009-02-11 19:14:56776 automation_->Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29777 }
778 }
[email protected]1c58a5c2009-05-21 18:47:14779
initial.commit09911bf2008-07-26 23:55:29780 private:
[email protected]1c58a5c2009-05-21 18:47:14781 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29782 AutomationProvider* automation_;
783};
784
[email protected]de246f52009-02-25 18:25:45785#if defined(OS_WIN)
786// TODO(port): Enable when printing is ported.
initial.commit09911bf2008-07-26 23:55:29787class DocumentPrintedNotificationObserver : public NotificationObserver {
788 public:
789 DocumentPrintedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56790 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29791 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56792 success_(false),
793 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14794 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
795 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29796 }
797
798 ~DocumentPrintedNotificationObserver() {
[email protected]71f65dd2009-02-11 19:14:56799 DCHECK(reply_message_ != NULL);
800 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
801 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29802 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29803 }
804
805 virtual void Observe(NotificationType type, const NotificationSource& source,
806 const NotificationDetails& details) {
807 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56808 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29809 switch (Details<JobEventDetails>(details)->type()) {
810 case JobEventDetails::JOB_DONE: {
811 // Succeeded.
812 success_ = true;
813 delete this;
814 break;
815 }
816 case JobEventDetails::USER_INIT_CANCELED:
817 case JobEventDetails::FAILED: {
818 // Failed.
819 delete this;
820 break;
821 }
822 case JobEventDetails::NEW_DOC:
823 case JobEventDetails::USER_INIT_DONE:
824 case JobEventDetails::DEFAULT_INIT_DONE:
825 case JobEventDetails::NEW_PAGE:
826 case JobEventDetails::PAGE_DONE:
827 case JobEventDetails::DOC_DONE:
828 case JobEventDetails::ALL_PAGES_REQUESTED: {
829 // Don't care.
830 break;
831 }
832 default: {
833 NOTREACHED();
834 break;
835 }
836 }
837 }
838
839 private:
[email protected]1c58a5c2009-05-21 18:47:14840 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29841 scoped_refptr<AutomationProvider> automation_;
initial.commit09911bf2008-07-26 23:55:29842 bool success_;
[email protected]71f65dd2009-02-11 19:14:56843 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29844};
[email protected]de246f52009-02-25 18:25:45845#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29846
[email protected]cbab76d2008-10-13 22:42:47847class AutomationInterstitialPage : public InterstitialPage {
848 public:
[email protected]57c6a652009-05-04 07:58:34849 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47850 const GURL& url,
851 const std::string& contents)
852 : InterstitialPage(tab, true, url),
853 contents_(contents) {
854 }
855
856 virtual std::string GetHTMLContents() { return contents_; }
857
858 private:
859 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29860
[email protected]cbab76d2008-10-13 22:42:47861 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
862};
863
[email protected]c2cb8542009-08-20 21:16:51864#if !defined(OS_MACOSX)
865class ClickTask : public Task {
866 public:
867 ClickTask(gfx::Point point, int flags) : point_(point), flags_(flags) {}
868 virtual ~ClickTask() {}
869
870 virtual void Run() {
871 ui_controls::MouseButton button = ui_controls::LEFT;
872 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
873 views::Event::EF_LEFT_BUTTON_DOWN) {
874 button = ui_controls::LEFT;
875 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
876 views::Event::EF_RIGHT_BUTTON_DOWN) {
877 button = ui_controls::RIGHT;
878 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
879 views::Event::EF_MIDDLE_BUTTON_DOWN) {
880 button = ui_controls::MIDDLE;
881 } else {
882 NOTREACHED();
883 }
884
885 ui_controls::SendMouseClick(point_, button);
886 }
887
888 private:
889 gfx::Point point_;
890 int flags_;
891
892 DISALLOW_COPY_AND_ASSIGN(ClickTask);
893};
894#endif
895
initial.commit09911bf2008-07-26 23:55:29896AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57897 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56898 profile_(profile),
899 reply_message_(NULL) {
initial.commit09911bf2008-07-26 23:55:29900 browser_tracker_.reset(new AutomationBrowserTracker(this));
initial.commit09911bf2008-07-26 23:55:29901 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20902 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29903 autocomplete_edit_tracker_.reset(
904 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29905 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
906 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
initial.commit09911bf2008-07-26 23:55:29907}
908
909AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50910 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
911 port_containers_.end());
912 port_containers_.clear();
913
[email protected]0da050b92008-08-19 19:29:47914 // Make sure that any outstanding NotificationObservers also get destroyed.
915 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31916 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47917 while ((observer = it.GetNext()) != NULL)
918 delete observer;
initial.commit09911bf2008-07-26 23:55:29919}
920
[email protected]9a3a293b2009-06-04 22:28:16921void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06922 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57923 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06924 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
925 automation_resource_message_filter_,
926 g_browser_process->io_thread()->message_loop(),
927 true, g_browser_process->shutdown_event()));
[email protected]79e966832009-04-21 14:23:05928 scoped_ptr<FileVersionInfo> file_version_info(
929 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
[email protected]cf620752009-04-24 17:05:40930 std::string version_string;
931 if (file_version_info != NULL) {
932 version_string = WideToASCII(file_version_info->file_version());
933 }
[email protected]c6cb1992009-04-13 16:45:29934
935 // Send a hello message with our current automation protocol version.
936 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29937}
938
939void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
940 if (expected_tabs == 0) {
941 Send(new AutomationMsg_InitialLoadsComplete(0));
942 } else {
943 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
944 }
945}
946
initial.commit09911bf2008-07-26 23:55:29947NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58948 NavigationController* tab, IPC::Message* reply_message,
949 int number_of_navigations) {
initial.commit09911bf2008-07-26 23:55:29950 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58951 new NavigationNotificationObserver(tab, this, reply_message,
952 number_of_navigations);
initial.commit09911bf2008-07-26 23:55:29953
[email protected]71f65dd2009-02-11 19:14:56954 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29955 return observer;
956}
957
958void AutomationProvider::RemoveNavigationStatusListener(
959 NotificationObserver* obs) {
960 notification_observer_list_.RemoveObserver(obs);
961}
962
963NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14964 Browser* parent,
965 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56966 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14967 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29968 notification_observer_list_.AddObserver(observer);
969
970 return observer;
971}
972
973void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
974 notification_observer_list_.RemoveObserver(obs);
975}
976
977void AutomationProvider::AddLoginHandler(NavigationController* tab,
978 LoginHandler* handler) {
979 login_handler_map_[tab] = handler;
980}
981
982void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
983 DCHECK(login_handler_map_[tab]);
984 login_handler_map_.erase(tab);
985}
986
[email protected]f44265b2009-05-19 18:52:50987void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
988 int port_id = port->port_id();
989 DCHECK_NE(-1, port_id);
990 DCHECK(port_containers_.find(port_id) == port_containers_.end());
991
992 port_containers_[port_id] = port;
993}
994
995void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
996 int port_id = port->port_id();
997 DCHECK_NE(-1, port_id);
998
999 PortContainerMap::iterator it = port_containers_.find(port_id);
1000 DCHECK(it != port_containers_.end());
1001
1002 if (it != port_containers_.end()) {
1003 delete it->second;
1004 port_containers_.erase(it);
1005 }
1006}
1007
1008ExtensionPortContainer* AutomationProvider::GetPortContainer(
1009 int port_id) const {
1010 PortContainerMap::const_iterator it = port_containers_.find(port_id);
1011 if (it == port_containers_.end())
1012 return NULL;
1013
1014 return it->second;
1015}
1016
initial.commit09911bf2008-07-26 23:55:291017int AutomationProvider::GetIndexForNavigationController(
1018 const NavigationController* controller, const Browser* parent) const {
1019 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:121020 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:291021}
1022
1023void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
1024 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:141025 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:561026 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
1027 CloseBrowserAsync)
1028 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
1029 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
1030 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
1031 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
1032 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
1033 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]1c58a5c2009-05-21 18:47:141034 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:581035 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1036 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
1037 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:561038 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
1039 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
1040 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
1041 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
1042 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:141043 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:561044 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
1045 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
1046 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:141047 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:291048 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
1049 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:561050 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:361051 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:561052 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:291053 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:561054 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:291055 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
1056 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:561057 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:141058 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]de246f52009-02-25 18:25:451059#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561060 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWND, GetWindowHWND)
[email protected]de246f52009-02-25 18:25:451061#endif // defined(OS_WIN)
[email protected]49a14a82009-03-31 04:16:441062 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:331063 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:441064 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:331065 ExecuteBrowserCommand)
[email protected]1c58a5c2009-05-21 18:47:141066 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8f04ff92009-07-08 02:37:151067 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:141068 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]9a08bcf2009-08-12 19:56:281069#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]d1a5941e2009-08-13 23:34:241070 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]1c58a5c2009-05-21 18:47:141071 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]9a08bcf2009-08-12 19:56:281072#endif
1073#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561074 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
1075 WindowSimulateDrag)
[email protected]d7fa7552009-03-20 21:06:371076#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561077 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
1078 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:371079#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561080 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:451081#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561082 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
1083 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:031084 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:561085 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:141086 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
initial.commit09911bf2008-07-26 23:55:291087 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:141088 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:561089 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
1090 ExecuteJavascript)
1091 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:291092 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:141093 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
1094 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:561095 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
1096 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:141097 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:171098 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:141099 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:141100 OpenNewBrowserWindow)
1101 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:561102 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:141103 GetAutocompleteEditForBrowser)
1104 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:451105#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291106 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:171107#endif
[email protected]71f65dd2009-02-11 19:14:561108 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:291109 NavigateInExternalTab)
[email protected]4150ef02009-08-19 23:14:261110 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
1111 NavigateExternalTabAtIndex)
[email protected]71f65dd2009-02-11 19:14:561112 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141113 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:561114 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141115 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:171116#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291117 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
1118 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:171119#endif
[email protected]71f65dd2009-02-11 19:14:561120 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
1121 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:141122 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:171123#if defined(OS_WIN)
[email protected]87eab222009-03-13 00:47:451124 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:391125 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
1126 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:171127#endif
[email protected]1c58a5c2009-05-21 18:47:141128 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
1129 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]71f65dd2009-02-11 19:14:561130 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
1131 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:291132 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
1133 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
1134 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:561135 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:411136 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:561137 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
1138 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:291139 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561140 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:291141 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561142 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:291143 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:561144 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:291145 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:561146 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:451147 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:451148 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
1149 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:141150 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:561151 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:571152 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:561153 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:571154 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:561155 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
1156 GetBookmarkBarVisibility)
[email protected]1c58a5c2009-05-21 18:47:141157 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCount, GetSSLInfoBarCount)
[email protected]71f65dd2009-02-11 19:14:561158 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickSSLInfoBarLink,
1159 ClickSSLInfoBarLink)
1160 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:421161 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:561162 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
1163 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:141164 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:561165 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:441166 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:561167 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:201168 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:141169 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:561170 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161171 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561172 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161173 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561174 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:161175 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:141176 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:201177 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
1178 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:141179 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]b83e4602009-05-15 22:58:331180 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
1181 SetEnableExtensionAutomation)
[email protected]59560e0b2009-06-04 03:30:221182 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:131183 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:191184 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
1185 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
1186 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
1187 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
1188 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
1189 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:521190 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1191 AutomationMsg_WaitForBrowserWindowCountToBecome,
1192 WaitForBrowserWindowCountToBecome)
1193 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1194 AutomationMsg_WaitForAppModalDialogToBeShown,
1195 WaitForAppModalDialogToBeShown)
initial.commit09911bf2008-07-26 23:55:291196 IPC_END_MESSAGE_MAP()
1197}
1198
[email protected]71f65dd2009-02-11 19:14:561199void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
1200 *status = -1;
initial.commit09911bf2008-07-26 23:55:291201 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
1202 Browser* browser = browser_tracker_->GetResource(handle);
1203 if (at_index >= 0 && at_index < browser->tab_count()) {
1204 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:561205 *status = 0;
initial.commit09911bf2008-07-26 23:55:291206 }
1207 }
initial.commit09911bf2008-07-26 23:55:291208}
1209
[email protected]71f65dd2009-02-11 19:14:561210void AutomationProvider::AppendTab(int handle, const GURL& url,
1211 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291212 int append_tab_response = -1; // -1 is the error code
1213 NotificationObserver* observer = NULL;
1214
1215 if (browser_tracker_->ContainsHandle(handle)) {
1216 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:141217 observer = AddTabStripObserver(browser, reply_message);
[email protected]22735af62009-04-07 21:09:581218 TabContents* tab_contents = browser->AddTabWithURL(url, GURL(),
1219 PageTransition::TYPED,
[email protected]5a4940be2009-05-06 06:44:391220 true, -1, false, NULL);
initial.commit09911bf2008-07-26 23:55:291221 if (tab_contents) {
1222 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:571223 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:291224 }
1225 }
1226
1227 if (append_tab_response < 0) {
1228 // The append tab failed. Remove the TabStripObserver
1229 if (observer) {
1230 RemoveTabStripObserver(observer);
1231 delete observer;
1232 }
1233
[email protected]71f65dd2009-02-11 19:14:561234 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
1235 append_tab_response);
1236 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291237 }
1238}
1239
[email protected]71f65dd2009-02-11 19:14:561240void AutomationProvider::NavigateToURL(int handle, const GURL& url,
1241 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:581242 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
1243}
1244
1245void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
1246 int handle, const GURL& url, int number_of_navigations,
1247 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291248 if (tab_tracker_->ContainsHandle(handle)) {
1249 NavigationController* tab = tab_tracker_->GetResource(handle);
1250
1251 // Simulate what a user would do. Activate the tab and then navigate.
1252 // We could allow navigating in a background tab in future.
1253 Browser* browser = FindAndActivateTab(tab);
1254
1255 if (browser) {
[email protected]2e028a082009-08-19 20:32:581256 AddNavigationStatusListener(tab, reply_message, number_of_navigations);
[email protected]71f65dd2009-02-11 19:14:561257
initial.commit09911bf2008-07-26 23:55:291258 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:501259 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:291260 return;
1261 }
1262 }
[email protected]71f65dd2009-02-11 19:14:561263
1264 AutomationMsg_NavigateToURL::WriteReplyParams(
1265 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1266 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291267}
[email protected]2949e90d2009-08-21 15:32:521268
[email protected]71f65dd2009-02-11 19:14:561269void AutomationProvider::NavigationAsync(int handle, const GURL& url,
1270 bool* status) {
1271 *status = false;
initial.commit09911bf2008-07-26 23:55:291272
1273 if (tab_tracker_->ContainsHandle(handle)) {
1274 NavigationController* tab = tab_tracker_->GetResource(handle);
1275
1276 // Simulate what a user would do. Activate the tab and then navigate.
1277 // We could allow navigating in a background tab in future.
1278 Browser* browser = FindAndActivateTab(tab);
1279
1280 if (browser) {
1281 // Don't add any listener unless a callback mechanism is desired.
1282 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:501283 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:561284 *status = true;
initial.commit09911bf2008-07-26 23:55:291285 }
1286 }
initial.commit09911bf2008-07-26 23:55:291287}
1288
[email protected]71f65dd2009-02-11 19:14:561289void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291290 if (tab_tracker_->ContainsHandle(handle)) {
1291 NavigationController* tab = tab_tracker_->GetResource(handle);
1292 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141293 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]2e028a082009-08-19 20:32:581294 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]485fba42009-03-24 23:27:291295 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291296 return;
1297 }
1298 }
[email protected]71f65dd2009-02-11 19:14:561299
1300 AutomationMsg_GoBack::WriteReplyParams(
1301 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1302 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291303}
1304
[email protected]71f65dd2009-02-11 19:14:561305void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291306 if (tab_tracker_->ContainsHandle(handle)) {
1307 NavigationController* tab = tab_tracker_->GetResource(handle);
1308 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141309 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]2e028a082009-08-19 20:32:581310 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]485fba42009-03-24 23:27:291311 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291312 return;
1313 }
1314 }
[email protected]71f65dd2009-02-11 19:14:561315
1316 AutomationMsg_GoForward::WriteReplyParams(
1317 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1318 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291319}
1320
[email protected]71f65dd2009-02-11 19:14:561321void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291322 if (tab_tracker_->ContainsHandle(handle)) {
1323 NavigationController* tab = tab_tracker_->GetResource(handle);
1324 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141325 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]2e028a082009-08-19 20:32:581326 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291327 browser->Reload();
1328 return;
1329 }
1330 }
[email protected]71f65dd2009-02-11 19:14:561331
1332 AutomationMsg_Reload::WriteReplyParams(
1333 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1334 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291335}
1336
[email protected]71f65dd2009-02-11 19:14:561337void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:291338 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:561339 const std::wstring& password,
1340 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291341 if (tab_tracker_->ContainsHandle(tab_handle)) {
1342 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1343 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1344
1345 if (iter != login_handler_map_.end()) {
1346 // If auth is needed again after this, assume login has failed. This is
1347 // not strictly correct, because a navigation can require both proxy and
1348 // server auth, but it should be OK for now.
1349 LoginHandler* handler = iter->second;
[email protected]2e028a082009-08-19 20:32:581350 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291351 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:521352 return;
initial.commit09911bf2008-07-26 23:55:291353 }
1354 }
[email protected]de246f52009-02-25 18:25:451355
[email protected]457f5cf2009-08-18 16:37:521356 AutomationMsg_SetAuth::WriteReplyParams(
1357 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
1358 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291359}
1360
[email protected]71f65dd2009-02-11 19:14:561361void AutomationProvider::CancelAuth(int tab_handle,
1362 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291363 if (tab_tracker_->ContainsHandle(tab_handle)) {
1364 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1365 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1366
1367 if (iter != login_handler_map_.end()) {
1368 // If auth is needed again after this, something is screwy.
1369 LoginHandler* handler = iter->second;
[email protected]2e028a082009-08-19 20:32:581370 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291371 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:521372 return;
initial.commit09911bf2008-07-26 23:55:291373 }
1374 }
[email protected]de246f52009-02-25 18:25:451375
[email protected]457f5cf2009-08-18 16:37:521376 AutomationMsg_CancelAuth::WriteReplyParams(
1377 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
1378 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291379}
1380
[email protected]71f65dd2009-02-11 19:14:561381void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
1382 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:291383
1384 if (tab_tracker_->ContainsHandle(tab_handle)) {
1385 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1386 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1387
1388 if (iter != login_handler_map_.end()) {
1389 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:561390 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:291391 }
1392 }
initial.commit09911bf2008-07-26 23:55:291393}
1394
[email protected]71f65dd2009-02-11 19:14:561395void AutomationProvider::GetRedirectsFrom(int tab_handle,
1396 const GURL& source_url,
1397 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291398 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1399 if (tab_tracker_->ContainsHandle(tab_handle)) {
1400 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1401 HistoryService* history_service =
1402 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1403
1404 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1405 "has no history service";
1406 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:561407 DCHECK(reply_message_ == NULL);
1408 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291409 // Schedule a history query for redirects. The response will be sent
1410 // asynchronously from the callback the history system uses to notify us
1411 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:291412 redirect_query_ = history_service->QueryRedirectsFrom(
1413 source_url, &consumer_,
1414 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1415 return; // Response will be sent when query completes.
1416 }
1417 }
1418
1419 // Send failure response.
[email protected]deb57402009-02-06 01:35:301420 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:561421 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
1422 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291423}
1424
[email protected]71f65dd2009-02-11 19:14:561425void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
1426 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291427 if (browser_tracker_->ContainsHandle(handle)) {
1428 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561429 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:291430 }
initial.commit09911bf2008-07-26 23:55:291431}
1432
[email protected]202e7a72009-06-15 03:48:361433void AutomationProvider::GetBrowserLocale(string16* locale) {
1434 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:061435 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:361436}
1437
[email protected]71f65dd2009-02-11 19:14:561438void AutomationProvider::GetBrowserWindowCount(int* window_count) {
1439 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:291440}
1441
[email protected]24497032009-05-01 17:00:291442void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
1443 *window_count = static_cast<int>(
1444 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
1445}
1446
[email protected]71f65dd2009-02-11 19:14:561447void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1448 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:071449 AppModalDialog* dialog_delegate =
1450 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501451 *showing_dialog = (dialog_delegate != NULL);
1452 if (*showing_dialog)
1453 *dialog_button = dialog_delegate->GetDialogButtons();
1454 else
[email protected]478ff2ed2009-04-21 23:49:181455 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:201456}
1457
[email protected]71f65dd2009-02-11 19:14:561458void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
1459 *success = false;
[email protected]fad84eab2008-12-05 00:37:201460
[email protected]1f460072009-05-28 17:02:071461 AppModalDialog* dialog_delegate =
1462 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501463 if (dialog_delegate &&
1464 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:181465 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
1466 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:281467 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:561468 *success = true;
[email protected]fad84eab2008-12-05 00:37:201469 }
[email protected]478ff2ed2009-04-21 23:49:181470 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
1471 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:561472 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:281473 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:561474 *success = true;
[email protected]fad84eab2008-12-05 00:37:201475 }
1476 }
[email protected]c274acc2008-11-11 20:13:441477}
1478
[email protected]71f65dd2009-02-11 19:14:561479void AutomationProvider::GetBrowserWindow(int index, int* handle) {
1480 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291481 if (index >= 0) {
1482 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:291483 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:291484 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:561485 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:291486 }
1487 }
initial.commit09911bf2008-07-26 23:55:291488}
1489
[email protected]24497032009-05-01 17:00:291490void AutomationProvider::FindNormalBrowserWindow(int* handle) {
1491 *handle = 0;
1492 Browser* browser = BrowserList::FindBrowserWithType(profile_,
1493 Browser::TYPE_NORMAL);
1494 if (browser)
1495 *handle = browser_tracker_->Add(browser);
1496}
1497
[email protected]71f65dd2009-02-11 19:14:561498void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
1499 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291500 Browser* browser = BrowserList::GetLastActive();
1501 if (browser)
[email protected]71f65dd2009-02-11 19:14:561502 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:291503}
1504
[email protected]de246f52009-02-25 18:25:451505#if defined(OS_WIN)
1506// TODO(port): Remove windowsisms.
initial.commit09911bf2008-07-26 23:55:291507BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1508 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1509 return FALSE;
1510 }
1511 return TRUE;
1512}
1513
[email protected]71f65dd2009-02-11 19:14:561514void AutomationProvider::GetActiveWindow(int* handle) {
initial.commit09911bf2008-07-26 23:55:291515 HWND window = GetForegroundWindow();
1516
1517 // Let's make sure this window belongs to our process.
1518 if (EnumThreadWindows(::GetCurrentThreadId(),
1519 EnumThreadWndProc,
1520 reinterpret_cast<LPARAM>(window))) {
1521 // We enumerated all the windows and did not find the foreground window,
1522 // it is not our window, ignore it.
[email protected]71f65dd2009-02-11 19:14:561523 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291524 return;
1525 }
1526
[email protected]71f65dd2009-02-11 19:14:561527 *handle = window_tracker_->Add(window);
initial.commit09911bf2008-07-26 23:55:291528}
1529
[email protected]71f65dd2009-02-11 19:14:561530void AutomationProvider::GetWindowHWND(int handle, HWND* win32_handle) {
1531 *win32_handle = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291532}
[email protected]de246f52009-02-25 18:25:451533#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291534
[email protected]9a08bcf2009-08-12 19:56:281535#if defined(OS_LINUX)
1536// TODO(estade): use this implementation for all platforms?
1537void AutomationProvider::GetActiveWindow(int* handle) {
1538 gfx::NativeWindow window =
1539 BrowserList::GetLastActive()->window()->GetNativeHandle();
1540 *handle = window_tracker_->Add(window);
1541}
1542#endif
1543
[email protected]4f6381ee2009-04-16 02:46:331544void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
1545 bool* success) {
[email protected]71f65dd2009-02-11 19:14:561546 *success = false;
[email protected]4ae62752008-08-04 23:28:471547 if (browser_tracker_->ContainsHandle(handle)) {
1548 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141549 if (browser->command_updater()->SupportsCommand(command) &&
1550 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471551 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:561552 *success = true;
[email protected]4ae62752008-08-04 23:28:471553 }
1554 }
[email protected]4ae62752008-08-04 23:28:471555}
1556
[email protected]4f6381ee2009-04-16 02:46:331557void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:561558 int handle, int command, IPC::Message* reply_message) {
1559 if (browser_tracker_->ContainsHandle(handle)) {
1560 Browser* browser = browser_tracker_->GetResource(handle);
1561 if (browser->command_updater()->SupportsCommand(command) &&
1562 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]d79ffea2009-05-07 20:51:421563 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
1564 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:271565 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:421566 return;
1567 }
[email protected]56e71b7c2009-03-27 03:05:561568 }
1569 }
[email protected]49a14a82009-03-31 04:16:441570 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:561571 Send(reply_message);
1572}
1573
[email protected]71f65dd2009-02-11 19:14:561574void AutomationProvider::WindowGetViewBounds(int handle, int view_id,
1575 bool screen_coordinates,
1576 bool* success,
1577 gfx::Rect* bounds) {
1578 *success = false;
initial.commit09911bf2008-07-26 23:55:291579
[email protected]b410bc32009-08-14 01:11:141580 if (window_tracker_->ContainsHandle(handle)) {
[email protected]15dd4442009-08-13 23:50:291581#if defined(OS_WIN)
[email protected]b410bc32009-08-14 01:11:141582 gfx::NativeWindow window = window_tracker_->GetResource(handle);
[email protected]d1a5941e2009-08-13 23:34:241583 views::RootView* root_view = views::WidgetWin::FindRootView(window);
initial.commit09911bf2008-07-26 23:55:291584 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381585 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291586 if (view) {
[email protected]71f65dd2009-02-11 19:14:561587 *success = true;
[email protected]96b667d2008-10-14 20:58:441588 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291589 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381590 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291591 else
[email protected]c2dacc92008-10-16 23:51:381592 views::View::ConvertPointToView(view, root_view, &point);
[email protected]71f65dd2009-02-11 19:14:561593 *bounds = view->GetLocalBounds(false);
1594 bounds->set_origin(point);
initial.commit09911bf2008-07-26 23:55:291595 }
1596 }
[email protected]c2cb8542009-08-20 21:16:511597#elif defined(OS_LINUX)
1598 gfx::NativeWindow window = window_tracker_->GetResource(handle);
1599 GtkWidget* widget = ViewIDUtil::GetWidget(GTK_WIDGET(window),
1600 static_cast<ViewID>(view_id));
1601 if (!widget)
1602 return;
1603 *success = true;
1604 *bounds = gfx::Rect(0, 0,
1605 widget->allocation.width, widget->allocation.height);
1606 gint x, y;
1607 if (screen_coordinates) {
1608 gdk_window_get_origin(widget->window, &x, &y);
1609 if (GTK_WIDGET_NO_WINDOW(widget)) {
1610 x += widget->allocation.x;
1611 y += widget->allocation.y;
1612 }
1613 } else {
1614 gtk_widget_translate_coordinates(widget, GTK_WIDGET(window),
1615 0, 0, &x, &y);
1616 }
1617 bounds->set_origin(gfx::Point(x, y));
[email protected]de246f52009-02-25 18:25:451618#else
[email protected]d1a5941e2009-08-13 23:34:241619 NOTIMPLEMENTED();
[email protected]de246f52009-02-25 18:25:451620#endif
[email protected]d1a5941e2009-08-13 23:34:241621 }
initial.commit09911bf2008-07-26 23:55:291622}
1623
[email protected]1299c6e2009-07-25 00:27:181624#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291625// This task enqueues a mouse event on the event loop, so that the view
1626// that it's being sent to can do the requisite post-processing.
1627class MouseEventTask : public Task {
1628 public:
[email protected]c2dacc92008-10-16 23:51:381629 MouseEventTask(views::View* view,
1630 views::Event::EventType type,
[email protected]0e80dfe2009-08-07 01:22:581631 const gfx::Point& point,
initial.commit09911bf2008-07-26 23:55:291632 int flags)
1633 : view_(view), type_(type), point_(point), flags_(flags) {}
1634 virtual ~MouseEventTask() {}
1635
1636 virtual void Run() {
[email protected]0e80dfe2009-08-07 01:22:581637 views::MouseEvent event(type_, point_.x(), point_.y(), flags_);
initial.commit09911bf2008-07-26 23:55:291638 // We need to set the cursor position before we process the event because
1639 // some code (tab dragging, for instance) queries the actual cursor location
1640 // rather than the location of the mouse event. Note that the reason why
1641 // the drag code moved away from using mouse event locations was because
1642 // our conversion to screen location doesn't work well with multiple
1643 // monitors, so this only works reliably in a single monitor setup.
[email protected]0e80dfe2009-08-07 01:22:581644 gfx::Point screen_location(point_.x(), point_.y());
initial.commit09911bf2008-07-26 23:55:291645 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]f5446092009-07-30 21:10:011646 MoveMouse(screen_location.ToPOINT());
initial.commit09911bf2008-07-26 23:55:291647 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381648 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291649 view_->OnMousePressed(event);
1650 break;
1651
[email protected]c2dacc92008-10-16 23:51:381652 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291653 view_->OnMouseDragged(event);
1654 break;
1655
[email protected]c2dacc92008-10-16 23:51:381656 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291657 view_->OnMouseReleased(event, false);
1658 break;
1659
1660 default:
1661 NOTREACHED();
1662 }
1663 }
1664
1665 private:
[email protected]c2dacc92008-10-16 23:51:381666 views::View* view_;
1667 views::Event::EventType type_;
[email protected]0e80dfe2009-08-07 01:22:581668 gfx::Point point_;
initial.commit09911bf2008-07-26 23:55:291669 int flags_;
1670
[email protected]5a52f162008-08-27 04:15:311671 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291672};
1673
[email protected]c2dacc92008-10-16 23:51:381674void AutomationProvider::ScheduleMouseEvent(views::View* view,
1675 views::Event::EventType type,
[email protected]0e80dfe2009-08-07 01:22:581676 const gfx::Point& point,
initial.commit09911bf2008-07-26 23:55:291677 int flags) {
1678 MessageLoop::current()->PostTask(FROM_HERE,
1679 new MouseEventTask(view, type, point, flags));
1680}
[email protected]0e80dfe2009-08-07 01:22:581681
[email protected]1299c6e2009-07-25 00:27:181682#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291683
1684// This task just adds another task to the event queue. This is useful if
1685// you want to ensure that any tasks added to the event queue after this one
1686// have already been processed by the time |task| is run.
1687class InvokeTaskLaterTask : public Task {
1688 public:
1689 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1690 virtual ~InvokeTaskLaterTask() {}
1691
1692 virtual void Run() {
1693 MessageLoop::current()->PostTask(FROM_HERE, task_);
1694 }
1695
1696 private:
1697 Task* task_;
1698
[email protected]5a52f162008-08-27 04:15:311699 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291700};
1701
[email protected]de246f52009-02-25 18:25:451702#if defined(OS_WIN)
1703// TODO(port): Replace POINT and other windowsisms.
1704
initial.commit09911bf2008-07-26 23:55:291705// This task sends a WindowDragResponse message with the appropriate
1706// routing ID to the automation proxy. This is implemented as a task so that
1707// we know that the mouse events (and any tasks that they spawn on the message
1708// loop) have been processed by the time this is sent.
1709class WindowDragResponseTask : public Task {
1710 public:
[email protected]1c58a5c2009-05-21 18:47:141711 WindowDragResponseTask(AutomationProvider* provider,
[email protected]71f65dd2009-02-11 19:14:561712 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:141713 : provider_(provider), reply_message_(reply_message) {}
initial.commit09911bf2008-07-26 23:55:291714 virtual ~WindowDragResponseTask() {}
1715
1716 virtual void Run() {
[email protected]71f65dd2009-02-11 19:14:561717 DCHECK(reply_message_ != NULL);
1718 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
1719 provider_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291720 }
1721
1722 private:
1723 AutomationProvider* provider_;
[email protected]71f65dd2009-02-11 19:14:561724 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:291725
[email protected]5a52f162008-08-27 04:15:311726 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291727};
[email protected]d1a5941e2009-08-13 23:34:241728#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291729
[email protected]d1a5941e2009-08-13 23:34:241730#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:291731void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1732 int handle,
[email protected]d1a5941e2009-08-13 23:34:241733 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:291734 int flags) {
initial.commit09911bf2008-07-26 23:55:291735
[email protected]b410bc32009-08-14 01:11:141736 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:511737 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
1738 new ClickTask(click, flags));
initial.commit09911bf2008-07-26 23:55:291739 }
1740}
[email protected]d1a5941e2009-08-13 23:34:241741#endif
initial.commit09911bf2008-07-26 23:55:291742
[email protected]d1a5941e2009-08-13 23:34:241743#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561744void AutomationProvider::WindowSimulateDrag(int handle,
[email protected]fe92e4e2008-11-18 21:31:321745 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441746 int flags,
[email protected]71f65dd2009-02-11 19:14:561747 bool press_escape_en_route,
1748 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291749 bool succeeded = false;
[email protected]e1f113e2009-08-14 23:15:231750 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1751 gfx::NativeWindow window =
1752 browser_tracker_->GetResource(handle)->window()->GetNativeHandle();
[email protected]fe92e4e2008-11-18 21:31:321753 succeeded = true;
1754
1755 UINT down_message = 0;
1756 UINT up_message = 0;
1757 WPARAM wparam_flags = 0;
1758 if (flags & views::Event::EF_SHIFT_DOWN)
1759 wparam_flags |= MK_SHIFT;
1760 if (flags & views::Event::EF_CONTROL_DOWN)
1761 wparam_flags |= MK_CONTROL;
1762 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1763 wparam_flags |= MK_LBUTTON;
1764 down_message = WM_LBUTTONDOWN;
1765 up_message = WM_LBUTTONUP;
1766 }
1767 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1768 wparam_flags |= MK_MBUTTON;
1769 down_message = WM_MBUTTONDOWN;
1770 up_message = WM_MBUTTONUP;
1771 }
1772 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1773 wparam_flags |= MK_RBUTTON;
1774 down_message = WM_LBUTTONDOWN;
1775 up_message = WM_LBUTTONUP;
1776 }
1777
initial.commit09911bf2008-07-26 23:55:291778 Browser* browser = browser_tracker_->GetResource(handle);
1779 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551780 HWND top_level_hwnd =
1781 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321782 POINT temp = drag_path[0];
1783 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
[email protected]f5446092009-07-30 21:10:011784 MoveMouse(temp);
[email protected]fe92e4e2008-11-18 21:31:321785 SendMessage(top_level_hwnd, down_message, wparam_flags,
1786 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1787 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1788 temp = drag_path[i];
1789 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
[email protected]f5446092009-07-30 21:10:011790 MoveMouse(temp);
[email protected]fe92e4e2008-11-18 21:31:321791 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1792 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341793 }
[email protected]fe92e4e2008-11-18 21:31:321794 POINT end = drag_path[drag_path.size() - 1];
1795 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
[email protected]f5446092009-07-30 21:10:011796 MoveMouse(end);
[email protected]fe92e4e2008-11-18 21:31:321797
1798 if (press_escape_en_route) {
1799 // Press Escape.
[email protected]d1a5941e2009-08-13 23:34:241800 ui_controls::SendKeyPress(window, VK_ESCAPE,
[email protected]fe92e4e2008-11-18 21:31:321801 ((flags & views::Event::EF_CONTROL_DOWN)
1802 == views::Event::EF_CONTROL_DOWN),
1803 ((flags & views::Event::EF_SHIFT_DOWN) ==
1804 views::Event::EF_SHIFT_DOWN),
1805 ((flags & views::Event::EF_ALT_DOWN) ==
1806 views::Event::EF_ALT_DOWN));
1807 }
1808 SendMessage(top_level_hwnd, up_message, wparam_flags,
1809 MAKELPARAM(end.x, end.y));
1810
[email protected]1c58a5c2009-05-21 18:47:141811 MessageLoop::current()->PostTask(FROM_HERE, new InvokeTaskLaterTask(
1812 new WindowDragResponseTask(this, reply_message)));
initial.commit09911bf2008-07-26 23:55:291813 } else {
[email protected]71f65dd2009-02-11 19:14:561814 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, true);
1815 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291816 }
1817}
[email protected]9a08bcf2009-08-12 19:56:281818#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291819
[email protected]9a08bcf2009-08-12 19:56:281820#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:291821void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1822 int handle,
1823 wchar_t key,
1824 int flags) {
[email protected]b410bc32009-08-14 01:11:141825 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291826 return;
1827
[email protected]b410bc32009-08-14 01:11:141828 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291829 // The key event is sent to whatever window is active.
[email protected]d1a5941e2009-08-13 23:34:241830 ui_controls::SendKeyPress(window, key,
[email protected]c2dacc92008-10-16 23:51:381831 ((flags & views::Event::EF_CONTROL_DOWN) ==
1832 views::Event::EF_CONTROL_DOWN),
1833 ((flags & views::Event::EF_SHIFT_DOWN) ==
1834 views::Event::EF_SHIFT_DOWN),
1835 ((flags & views::Event::EF_ALT_DOWN) ==
1836 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291837}
[email protected]9a08bcf2009-08-12 19:56:281838#endif
initial.commit09911bf2008-07-26 23:55:291839
[email protected]9a08bcf2009-08-12 19:56:281840#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561841void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
1842 *view_id = -1;
initial.commit09911bf2008-07-26 23:55:291843 if (window_tracker_->ContainsHandle(handle)) {
1844 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381845 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:001846 views::FocusManager::GetFocusManagerForNativeView(hwnd);
initial.commit09911bf2008-07-26 23:55:291847 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381848 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291849 if (focused_view)
[email protected]71f65dd2009-02-11 19:14:561850 *view_id = focused_view->GetID();
initial.commit09911bf2008-07-26 23:55:291851 }
initial.commit09911bf2008-07-26 23:55:291852}
1853
[email protected]8f04ff92009-07-08 02:37:151854void AutomationProvider::SetWindowBounds(int handle, const gfx::Rect& bounds,
1855 bool* success) {
1856 *success = false;
1857 if (window_tracker_->ContainsHandle(handle)) {
1858 HWND hwnd = window_tracker_->GetResource(handle);
1859 if (::MoveWindow(hwnd, bounds.x(), bounds.y(), bounds.width(),
1860 bounds.height(), true)) {
1861 *success = true;
1862 }
1863 }
1864}
1865
[email protected]71f65dd2009-02-11 19:14:561866void AutomationProvider::SetWindowVisible(int handle, bool visible,
1867 bool* result) {
initial.commit09911bf2008-07-26 23:55:291868 if (window_tracker_->ContainsHandle(handle)) {
1869 HWND hwnd = window_tracker_->GetResource(handle);
1870 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
[email protected]71f65dd2009-02-11 19:14:561871 *result = true;
initial.commit09911bf2008-07-26 23:55:291872 } else {
[email protected]71f65dd2009-02-11 19:14:561873 *result = false;
initial.commit09911bf2008-07-26 23:55:291874 }
1875}
[email protected]d2cc6ed2009-04-24 00:26:171876#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291877
[email protected]71f65dd2009-02-11 19:14:561878void AutomationProvider::IsWindowActive(int handle, bool* success,
1879 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291880 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171881 *is_active =
1882 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561883 *success = true;
initial.commit09911bf2008-07-26 23:55:291884 } else {
[email protected]71f65dd2009-02-11 19:14:561885 *success = false;
1886 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291887 }
1888}
1889
[email protected]d2cc6ed2009-04-24 00:26:171890// TODO(port): port this.
1891#if defined(OS_WIN)
[email protected]659d0e82009-02-13 22:43:281892void AutomationProvider::ActivateWindow(int handle) {
initial.commit09911bf2008-07-26 23:55:291893 if (window_tracker_->ContainsHandle(handle)) {
1894 ::SetActiveWindow(window_tracker_->GetResource(handle));
1895 }
1896}
[email protected]d2cc6ed2009-04-24 00:26:171897#endif
initial.commit09911bf2008-07-26 23:55:291898
[email protected]71f65dd2009-02-11 19:14:561899void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1900 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291901
1902 if (browser_tracker_->ContainsHandle(handle)) {
1903 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561904 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291905 }
initial.commit09911bf2008-07-26 23:55:291906}
1907
[email protected]71f65dd2009-02-11 19:14:561908void AutomationProvider::GetTab(int win_handle, int tab_index,
1909 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561910 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291911 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1912 Browser* browser = browser_tracker_->GetResource(win_handle);
1913 if (tab_index < browser->tab_count()) {
1914 TabContents* tab_contents =
1915 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571916 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291917 }
1918 }
initial.commit09911bf2008-07-26 23:55:291919}
1920
[email protected]71f65dd2009-02-11 19:14:561921void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1922 std::wstring* title) {
1923 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291924 if (tab_tracker_->ContainsHandle(handle)) {
1925 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361926 NavigationEntry* entry = tab->GetActiveEntry();
1927 if (entry != NULL) {
1928 *title = UTF16ToWideHack(entry->title());
1929 } else {
1930 *title = std::wstring();
1931 }
[email protected]71f65dd2009-02-11 19:14:561932 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291933 }
initial.commit09911bf2008-07-26 23:55:291934}
1935
[email protected]77bc6732009-04-20 22:01:031936void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1937 *tabstrip_index = -1; // -1 is the error code
1938
1939 if (tab_tracker_->ContainsHandle(handle)) {
1940 NavigationController* tab = tab_tracker_->GetResource(handle);
1941 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121942 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031943 }
1944}
1945
initial.commit09911bf2008-07-26 23:55:291946void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1947 if (window_tracker_->ContainsHandle(handle)) {
1948 window_tracker_->Remove(window_tracker_->GetResource(handle));
1949 }
1950}
1951
1952void AutomationProvider::OnChannelError() {
1953 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571954 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291955}
1956
1957// TODO(brettw) change this to accept GURLs when history supports it
1958void AutomationProvider::OnRedirectQueryComplete(
1959 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371960 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291961 bool success,
[email protected]379c2b12009-07-01 21:50:331962 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291963 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561964 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291965
[email protected]deb57402009-02-06 01:35:301966 std::vector<GURL> redirects_gurl;
initial.commit09911bf2008-07-26 23:55:291967 if (success) {
[email protected]71f65dd2009-02-11 19:14:561968 reply_message_->WriteBool(true);
initial.commit09911bf2008-07-26 23:55:291969 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301970 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291971 } else {
[email protected]71f65dd2009-02-11 19:14:561972 reply_message_->WriteInt(-1); // Negative count indicates failure.
initial.commit09911bf2008-07-26 23:55:291973 }
1974
[email protected]4f3dc372009-02-24 00:10:291975 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301976
[email protected]71f65dd2009-02-11 19:14:561977 Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291978 redirect_query_ = NULL;
[email protected]71f65dd2009-02-11 19:14:561979 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291980}
1981
1982bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571983 DCHECK(channel_.get());
1984 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291985}
1986
1987Browser* AutomationProvider::FindAndActivateTab(
1988 NavigationController* controller) {
1989 int tab_index;
1990 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1991 if (browser)
1992 browser->SelectTabContentsAt(tab_index, true);
1993
1994 return browser;
1995}
1996
[email protected]71f65dd2009-02-11 19:14:561997void AutomationProvider::GetCookies(const GURL& url, int handle,
1998 int* value_size,
1999 std::string* value) {
2000 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:292001 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
2002 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562003 *value =
initial.commit09911bf2008-07-26 23:55:292004 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:562005 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:292006 }
initial.commit09911bf2008-07-26 23:55:292007}
2008
[email protected]71f65dd2009-02-11 19:14:562009void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:292010 const std::string value,
[email protected]71f65dd2009-02-11 19:14:562011 int handle,
2012 int* response_value) {
2013 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:292014
2015 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
2016 NavigationController* tab = tab_tracker_->GetResource(handle);
2017 URLRequestContext* context = tab->profile()->GetRequestContext();
2018 if (context->cookie_store()->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:562019 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:292020 }
initial.commit09911bf2008-07-26 23:55:292021}
2022
[email protected]71f65dd2009-02-11 19:14:562023void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
2024 *success = false;
initial.commit09911bf2008-07-26 23:55:292025 if (tab_tracker_->ContainsHandle(handle)) {
2026 NavigationController* tab = tab_tracker_->GetResource(handle);
2027 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:542028 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:562029 *success = true;
initial.commit09911bf2008-07-26 23:55:292030 }
initial.commit09911bf2008-07-26 23:55:292031}
2032
[email protected]de246f52009-02-25 18:25:452033#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:562034void AutomationProvider::GetTabHWND(int handle, HWND* tab_hwnd) {
2035 *tab_hwnd = NULL;
initial.commit09911bf2008-07-26 23:55:292036
2037 if (tab_tracker_->ContainsHandle(handle)) {
2038 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112039 *tab_hwnd = tab->tab_contents()->GetNativeView();
initial.commit09911bf2008-07-26 23:55:292040 }
initial.commit09911bf2008-07-26 23:55:292041}
[email protected]de246f52009-02-25 18:25:452042#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292043
[email protected]71f65dd2009-02-11 19:14:562044void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
2045 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:292046
2047 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:562048 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:342049 TabContents* tab_contents =
2050 tab_tracker_->GetResource(handle)->tab_contents();
2051 if (tab_contents->process())
2052 *process_id = tab_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:292053 }
initial.commit09911bf2008-07-26 23:55:292054}
2055
2056void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:332057 NOTREACHED() << "This function has been deprecated. "
2058 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:292059}
2060
[email protected]71f65dd2009-02-11 19:14:562061void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:292062 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:562063 const std::wstring& script,
2064 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292065 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:342066 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2067 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:572068 // Set the routing id of this message with the controller.
2069 // This routing id needs to be remembered for the reverse
2070 // communication while sending back the response of
2071 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:332072 std::wstring set_automation_id;
2073 SStringPrintf(&set_automation_id,
2074 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:562075 reply_message->routing_id());
2076
2077 DCHECK(reply_message_ == NULL);
2078 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:292079
[email protected]57c6a652009-05-04 07:58:342080 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:332081 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:342082 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:062083 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:572084 succeeded = true;
initial.commit09911bf2008-07-26 23:55:292085 }
2086
2087 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:562088 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
2089 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292090 }
2091}
2092
[email protected]71f65dd2009-02-11 19:14:562093void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
2094 *visible = false;
[email protected]20e93d12008-08-28 16:31:572095
[email protected]59560e0b2009-06-04 03:30:222096 if (browser_tracker_->ContainsHandle(handle)) {
2097 Browser* browser = browser_tracker_->GetResource(handle);
2098 if (browser) {
2099 *visible = browser->window()->IsDownloadShelfVisible();
2100 }
2101 }
initial.commit09911bf2008-07-26 23:55:292102}
2103
[email protected]59560e0b2009-06-04 03:30:222104void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
2105 if (browser_tracker_->ContainsHandle(handle)) {
2106 Browser* browser = browser_tracker_->GetResource(handle);
2107 if (browser) {
2108 if (visible)
2109 browser->window()->GetDownloadShelf()->Show();
2110 else
2111 browser->window()->GetDownloadShelf()->Close();
2112 }
2113 }
2114}
2115
2116
[email protected]71f65dd2009-02-11 19:14:562117void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
2118 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:292119 if (tab_tracker_->ContainsHandle(handle)) {
2120 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112121 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:292122 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562123 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:292124 }
2125 }
initial.commit09911bf2008-07-26 23:55:292126}
2127
initial.commit09911bf2008-07-26 23:55:292128void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:562129 int handle, const std::wstring& find_request,
2130 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:312131 NOTREACHED() << "This function has been deprecated."
2132 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:562133 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:312134 return;
2135}
2136
[email protected]4f999132009-03-31 18:08:402137void AutomationProvider::HandleFindRequest(
2138 int handle,
2139 const AutomationMsg_Find_Params& params,
2140 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292141 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:562142 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
2143 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292144 return;
2145 }
2146
2147 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112148 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:292149
2150 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:142151 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:292152
[email protected]57c6a652009-05-04 07:58:342153 tab_contents->set_current_find_request_id(
2154 FindInPageNotificationObserver::kFindInPageRequestId);
2155 tab_contents->render_view_host()->StartFinding(
2156 FindInPageNotificationObserver::kFindInPageRequestId,
2157 params.search_string, params.forward, params.match_case,
2158 params.find_next);
initial.commit09911bf2008-07-26 23:55:292159}
2160
[email protected]5f8af2a2008-08-06 22:49:452161void AutomationProvider::HandleOpenFindInPageRequest(
2162 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:292163 if (browser_tracker_->ContainsHandle(handle)) {
2164 Browser* browser = browser_tracker_->GetResource(handle);
2165 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:452166 }
2167}
2168
[email protected]71f65dd2009-02-11 19:14:562169void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]9e0534b2008-10-21 15:03:012170 gfx::Point position;
[email protected]71f65dd2009-02-11 19:14:562171 *visible = false;
[email protected]4f3dc372009-02-24 00:10:292172 if (browser_tracker_->ContainsHandle(handle)) {
2173 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582174 FindBarTesting* find_bar =
2175 browser->find_bar()->find_bar()->GetFindBarTesting();
2176 find_bar->GetFindBarWindowInfo(&position, visible);
[email protected]4f3dc372009-02-24 00:10:292177 }
[email protected]20e93d12008-08-28 16:31:572178}
2179
[email protected]71f65dd2009-02-11 19:14:562180void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
2181 int* y) {
[email protected]9e0534b2008-10-21 15:03:012182 gfx::Point position(0, 0);
2183 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:292184 if (browser_tracker_->ContainsHandle(handle)) {
2185 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582186 FindBarTesting* find_bar =
2187 browser->find_bar()->find_bar()->GetFindBarTesting();
2188 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:292189 }
[email protected]20e93d12008-08-28 16:31:572190
[email protected]71f65dd2009-02-11 19:14:562191 *x = position.x();
2192 *y = position.y();
[email protected]20e93d12008-08-28 16:31:572193}
2194
[email protected]71f65dd2009-02-11 19:14:562195void AutomationProvider::GetBookmarkBarVisibility(int handle, bool* visible,
2196 bool* animating) {
2197 *visible = false;
2198 *animating = false;
[email protected]c2cbeb92008-09-05 21:36:572199
[email protected]de246f52009-02-25 18:25:452200#if defined(OS_WIN)
[email protected]c2cbeb92008-09-05 21:36:572201 if (browser_tracker_->ContainsHandle(handle)) {
2202 Browser* browser = browser_tracker_->GetResource(handle);
2203 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:522204 BrowserWindowTesting* testing =
2205 browser->window()->GetBrowserWindowTesting();
2206 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:572207 if (bookmark_bar) {
[email protected]71f65dd2009-02-11 19:14:562208 *animating = bookmark_bar->IsAnimating();
2209 *visible = browser->window()->IsBookmarkBarVisible();
[email protected]c2cbeb92008-09-05 21:36:572210 }
2211 }
2212 }
[email protected]de246f52009-02-25 18:25:452213#else
2214 // TODO(port): Enable when bookmarks ui is ported.
2215 NOTIMPLEMENTED();
2216#endif
[email protected]c2cbeb92008-09-05 21:36:572217}
2218
initial.commit09911bf2008-07-26 23:55:292219void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562220 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342221 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2222 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562223 DCHECK(reply_message_ == NULL);
2224 reply_message_ = reply_message;
2225
[email protected]d9f9b792009-06-24 13:17:122226 DevToolsManager::GetInstance()->InspectElement(
2227 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292228 } else {
[email protected]71f65dd2009-02-11 19:14:562229 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2230 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292231 }
2232}
2233
2234void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092235 if (reply_message_) {
2236 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2237 num_resources);
2238 Send(reply_message_);
2239 reply_message_ = NULL;
2240 }
initial.commit09911bf2008-07-26 23:55:292241}
2242
[email protected]a7eee32f2009-05-22 18:08:172243class SetProxyConfigTask : public Task {
2244 public:
2245 explicit SetProxyConfigTask(net::ProxyService* proxy_service,
2246 const std::string& new_proxy_config)
2247 : proxy_service_(proxy_service), proxy_config_(new_proxy_config) {}
2248 virtual void Run() {
2249 // First, deserialize the JSON string. If this fails, log and bail.
2250 JSONStringValueSerializer deserializer(proxy_config_);
2251 std::string error_message;
2252 scoped_ptr<Value> root(deserializer.Deserialize(&error_message));
2253 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2254 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
2255 << error_message;
2256 return;
2257 }
2258
2259 scoped_ptr<DictionaryValue> dict(
2260 static_cast<DictionaryValue*>(root.release()));
2261 // Now put together a proxy configuration from the deserialized string.
2262 net::ProxyConfig pc;
2263 PopulateProxyConfig(*dict.get(), &pc);
2264
2265 DCHECK(proxy_service_);
2266 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2267 new net::ProxyConfigServiceFixed(pc));
2268 proxy_service_->ResetConfigService(proxy_config_service.release());
2269 }
2270
2271 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2272 DCHECK(pc);
2273 bool no_proxy = false;
2274 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2275 // Make no changes to the ProxyConfig.
2276 return;
2277 }
2278 bool auto_config;
2279 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
2280 pc->auto_detect = true;
2281 }
2282 std::string pac_url;
2283 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
2284 pc->pac_url = GURL(pac_url);
2285 }
2286 std::string proxy_bypass_list;
2287 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
2288 pc->ParseNoProxyList(proxy_bypass_list);
2289 }
2290 std::string proxy_server;
2291 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
2292 pc->proxy_rules.ParseFromString(proxy_server);
2293 }
2294 }
2295
2296 private:
2297 net::ProxyService* proxy_service_;
2298 std::string proxy_config_;
2299};
2300
2301
2302void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
2303 URLRequestContext* context = Profile::GetDefaultRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172304 if (!context) {
2305 FilePath user_data_dir;
2306 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2307 ProfileManager* profile_manager = g_browser_process->profile_manager();
2308 DCHECK(profile_manager);
2309 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2310 DCHECK(profile);
2311 context = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:172312 }
2313 DCHECK(context);
2314 // Every URLRequestContext should have a proxy service.
2315 net::ProxyService* proxy_service = context->proxy_service();
2316 DCHECK(proxy_service);
2317
[email protected]81ae0a92009-08-06 02:16:162318 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
2319 new SetProxyConfigTask(proxy_service, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:172320}
2321
[email protected]4f3dc372009-02-24 00:10:292322void AutomationProvider::GetDownloadDirectory(
2323 int handle, std::wstring* download_directory) {
initial.commit09911bf2008-07-26 23:55:292324 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292325 if (tab_tracker_->ContainsHandle(handle)) {
2326 NavigationController* tab = tab_tracker_->GetResource(handle);
2327 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2328 DCHECK(dlm);
[email protected]71f65dd2009-02-11 19:14:562329 *download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:292330 }
initial.commit09911bf2008-07-26 23:55:292331}
2332
[email protected]14c0a032009-04-13 18:15:142333void AutomationProvider::OpenNewBrowserWindow(bool show,
2334 IPC::Message* reply_message) {
2335 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292336 // We may have no current browser windows open so don't rely on
2337 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:052338 Browser* browser = Browser::Create(profile_);
2339 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152340 if (show)
[email protected]15952e462008-11-14 00:29:052341 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292342}
2343
[email protected]71f65dd2009-02-11 19:14:562344void AutomationProvider::GetWindowForBrowser(int browser_handle,
2345 bool* success,
2346 int* handle) {
2347 *success = false;
2348 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292349
2350 if (browser_tracker_->ContainsHandle(browser_handle)) {
2351 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202352 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292353 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202354 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562355 *success = true;
initial.commit09911bf2008-07-26 23:55:292356 }
initial.commit09911bf2008-07-26 23:55:292357}
2358
[email protected]13869dd2009-05-05 00:40:062359#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292360void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562361 int browser_handle,
2362 bool* success,
2363 int* autocomplete_edit_handle) {
2364 *success = false;
2365 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292366
2367 if (browser_tracker_->ContainsHandle(browser_handle)) {
2368 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062369 LocationBar* loc_bar = browser->window()->GetLocationBar();
2370 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292371 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562372 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2373 *success = true;
initial.commit09911bf2008-07-26 23:55:292374 }
initial.commit09911bf2008-07-26 23:55:292375}
[email protected]13869dd2009-05-05 00:40:062376#endif // defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292377
[email protected]13869dd2009-05-05 00:40:062378#if defined(OS_WIN)
2379// TODO(port): Remove windowsisms.
[email protected]71f65dd2009-02-11 19:14:562380void AutomationProvider::GetBrowserForWindow(int window_handle,
2381 bool* success,
2382 int* browser_handle) {
2383 *success = false;
2384 *browser_handle = 0;
initial.commit09911bf2008-07-26 23:55:292385
2386 if (window_tracker_->ContainsHandle(window_handle)) {
2387 HWND window = window_tracker_->GetResource(window_handle);
2388 BrowserList::const_iterator iter = BrowserList::begin();
2389 Browser* browser = NULL;
2390 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:312391 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
2392 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:292393 browser = *iter;
2394 break;
2395 }
2396 }
2397 if (browser) {
2398 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562399 *browser_handle = browser_tracker_->Add(browser);
2400 *success = true;
initial.commit09911bf2008-07-26 23:55:292401 }
2402 }
initial.commit09911bf2008-07-26 23:55:292403}
[email protected]de246f52009-02-25 18:25:452404#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292405
[email protected]71f65dd2009-02-11 19:14:562406void AutomationProvider::ShowInterstitialPage(int tab_handle,
2407 const std::string& html_text,
2408 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292409 if (tab_tracker_->ContainsHandle(tab_handle)) {
2410 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112411 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402412
[email protected]2e028a082009-08-19 20:32:582413 AddNavigationStatusListener(controller, reply_message, 1);
[email protected]965524b2009-04-04 21:32:402414 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342415 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402416 GURL("about:interstitial"),
2417 html_text);
2418 interstitial->Show();
2419 return;
initial.commit09911bf2008-07-26 23:55:292420 }
[email protected]71f65dd2009-02-11 19:14:562421
[email protected]457f5cf2009-08-18 16:37:522422 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2423 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562424 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292425}
2426
[email protected]71f65dd2009-02-11 19:14:562427void AutomationProvider::HideInterstitialPage(int tab_handle,
2428 bool* success) {
2429 *success = false;
[email protected]57c6a652009-05-04 07:58:342430 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2431 if (tab_contents && tab_contents->interstitial_page()) {
2432 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562433 *success = true;
initial.commit09911bf2008-07-26 23:55:292434 }
initial.commit09911bf2008-07-26 23:55:292435}
2436
[email protected]71f65dd2009-02-11 19:14:562437void AutomationProvider::CloseTab(int tab_handle,
2438 bool wait_until_closed,
2439 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292440 if (tab_tracker_->ContainsHandle(tab_handle)) {
2441 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2442 int index;
2443 Browser* browser = Browser::GetBrowserForController(controller, &index);
2444 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142445 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112446 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452447 return;
initial.commit09911bf2008-07-26 23:55:292448 }
[email protected]de246f52009-02-25 18:25:452449
2450 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
initial.commit09911bf2008-07-26 23:55:292451}
2452
[email protected]71f65dd2009-02-11 19:14:562453void AutomationProvider::CloseBrowser(int browser_handle,
2454 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292455 if (browser_tracker_->ContainsHandle(browser_handle)) {
2456 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562457 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562458 reply_message);
[email protected]f3e99e32008-07-30 04:48:392459 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292460 } else {
2461 NOTREACHED();
2462 }
2463}
2464
[email protected]71f65dd2009-02-11 19:14:562465void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2466 if (browser_tracker_->ContainsHandle(browser_handle)) {
2467 Browser* browser = browser_tracker_->GetResource(browser_handle);
2468 browser->window()->Close();
2469 } else {
2470 NOTREACHED();
2471 }
2472}
2473
[email protected]de246f52009-02-25 18:25:452474#if defined(OS_WIN)
2475// TODO(port): Remove windowsisms.
[email protected]95c3c592009-07-14 22:09:032476void AutomationProvider::CreateExternalTab(
2477 const IPC::ExternalTabSettings& settings,
2478 gfx::NativeWindow* tab_container_window, gfx::NativeWindow* tab_window,
2479 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:562480 *tab_handle = 0;
2481 *tab_container_window = NULL;
[email protected]c4e944f2009-06-11 18:22:192482 *tab_window = NULL;
[email protected]2e4633c2009-07-09 16:58:062483 ExternalTabContainer* external_tab_container =
2484 new ExternalTabContainer(this, automation_resource_message_filter_);
[email protected]95c3c592009-07-14 22:09:032485 Profile* profile = settings.is_off_the_record ?
2486 profile_->GetOffTheRecordProfile() : profile_;
2487 external_tab_container->Init(profile, settings.parent, settings.dimensions,
[email protected]5f450e52009-07-28 13:28:112488 settings.style, settings.load_requests_via_automation,
[email protected]a50a4902009-08-14 22:39:012489 settings.handle_top_level_requests, NULL);
2490
2491 if (AddExternalTab(external_tab_container)) {
2492 TabContents* tab_contents = external_tab_container->tab_contents();
2493 *tab_handle = external_tab_container->tab_handle();
[email protected]eac83f02009-05-08 18:44:442494 external_tab_container->set_tab_handle(*tab_handle);
[email protected]9095e982009-05-27 17:28:242495 *tab_container_window = external_tab_container->GetNativeView();
[email protected]c4e944f2009-06-11 18:22:192496 *tab_window = tab_contents->GetNativeView();
[email protected]31fb110522009-01-28 21:50:392497 } else {
2498 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292499 }
initial.commit09911bf2008-07-26 23:55:292500}
[email protected]a50a4902009-08-14 22:39:012501
2502bool AutomationProvider::AddExternalTab(ExternalTabContainer* external_tab) {
2503 DCHECK(external_tab != NULL);
2504
2505 TabContents* tab_contents = external_tab->tab_contents();
2506 if (tab_contents) {
2507 int tab_handle = tab_tracker_->Add(&tab_contents->controller());
2508 external_tab->set_tab_handle(tab_handle);
2509 return true;
2510 }
2511
2512 return false;
2513}
2514
[email protected]d2cc6ed2009-04-24 00:26:172515#endif
initial.commit09911bf2008-07-26 23:55:292516
[email protected]71f65dd2009-02-11 19:14:562517void AutomationProvider::NavigateInExternalTab(
2518 int handle, const GURL& url,
2519 AutomationMsg_NavigationResponseValues* status) {
2520 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292521
2522 if (tab_tracker_->ContainsHandle(handle)) {
2523 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502524 tab->LoadURL(url, GURL(), PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562525 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292526 }
initial.commit09911bf2008-07-26 23:55:292527}
2528
[email protected]4150ef02009-08-19 23:14:262529void AutomationProvider::NavigateExternalTabAtIndex(
2530 int handle, int navigation_index,
2531 AutomationMsg_NavigationResponseValues* status) {
2532 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
2533
2534 if (tab_tracker_->ContainsHandle(handle)) {
2535 NavigationController* tab = tab_tracker_->GetResource(handle);
2536 tab->GoToIndex(navigation_index);
2537 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
2538 }
2539}
2540
[email protected]d2cc6ed2009-04-24 00:26:172541#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292542void AutomationProvider::ProcessUnhandledAccelerator(
2543 const IPC::Message& message, int handle, const MSG& msg) {
[email protected]b9d227492009-02-10 15:20:272544 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2545 if (external_tab) {
2546 external_tab->ProcessUnhandledAccelerator(msg);
2547 }
2548 // This message expects no response.
2549}
[email protected]d2cc6ed2009-04-24 00:26:172550#endif
[email protected]b9d227492009-02-10 15:20:272551
[email protected]71f65dd2009-02-11 19:14:562552void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2553 IPC::Message* reply_message) {
2554 if (tab_tracker_->ContainsHandle(tab_handle)) {
2555 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2556 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142557 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562558 }
2559}
2560
[email protected]b9d227492009-02-10 15:20:272561void AutomationProvider::SetInitialFocus(const IPC::Message& message,
2562 int handle, bool reverse) {
[email protected]d2cc6ed2009-04-24 00:26:172563#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272564 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2565 if (external_tab) {
[email protected]90daadb42009-06-08 21:27:282566 external_tab->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:292567 }
2568 // This message expects no response.
[email protected]d2cc6ed2009-04-24 00:26:172569#elif defined(OS_POSIX)
2570 // TODO(port) enable this function.
2571 NOTIMPLEMENTED();
2572#endif
initial.commit09911bf2008-07-26 23:55:292573}
2574
[email protected]71f65dd2009-02-11 19:14:562575void AutomationProvider::GetSecurityState(int handle, bool* success,
2576 SecurityStyle* security_style,
2577 int* ssl_cert_status,
2578 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292579 if (tab_tracker_->ContainsHandle(handle)) {
2580 NavigationController* tab = tab_tracker_->GetResource(handle);
2581 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562582 *success = true;
2583 *security_style = entry->ssl().security_style();
2584 *ssl_cert_status = entry->ssl().cert_status();
2585 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292586 } else {
[email protected]71f65dd2009-02-11 19:14:562587 *success = false;
2588 *security_style = SECURITY_STYLE_UNKNOWN;
2589 *ssl_cert_status = 0;
2590 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292591 }
2592}
2593
[email protected]71f65dd2009-02-11 19:14:562594void AutomationProvider::GetPageType(int handle, bool* success,
2595 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292596 if (tab_tracker_->ContainsHandle(handle)) {
2597 NavigationController* tab = tab_tracker_->GetResource(handle);
2598 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562599 *page_type = entry->page_type();
2600 *success = true;
initial.commit09911bf2008-07-26 23:55:292601 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342602 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562603 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342604 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562605 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292606 } else {
[email protected]71f65dd2009-02-11 19:14:562607 *success = false;
2608 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292609 }
2610}
2611
[email protected]71f65dd2009-02-11 19:14:562612void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2613 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292614 if (tab_tracker_->ContainsHandle(handle)) {
2615 NavigationController* tab = tab_tracker_->GetResource(handle);
2616 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072617 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402618 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472619 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342620 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292621 if (ssl_blocking_page) {
2622 if (proceed) {
[email protected]2e028a082009-08-19 20:32:582623 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]71f65dd2009-02-11 19:14:562624 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292625 return;
2626 }
2627 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522628 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2629 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562630 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292631 return;
2632 }
2633 }
2634 }
2635 // We failed.
[email protected]457f5cf2009-08-18 16:37:522636 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2637 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562638 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292639}
initial.commit09911bf2008-07-26 23:55:292640
[email protected]71f65dd2009-02-11 19:14:562641void AutomationProvider::BringBrowserToFront(int browser_handle,
2642 bool* success) {
initial.commit09911bf2008-07-26 23:55:292643 if (browser_tracker_->ContainsHandle(browser_handle)) {
2644 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062645 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562646 *success = true;
initial.commit09911bf2008-07-26 23:55:292647 } else {
[email protected]71f65dd2009-02-11 19:14:562648 *success = false;
initial.commit09911bf2008-07-26 23:55:292649 }
2650}
2651
[email protected]71f65dd2009-02-11 19:14:562652void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2653 int message_num,
2654 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292655 if (browser_tracker_->ContainsHandle(browser_handle)) {
2656 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562657 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142658 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292659 } else {
[email protected]71f65dd2009-02-11 19:14:562660 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292661 }
2662}
2663
[email protected]de246f52009-02-25 18:25:452664#if defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472665// TODO(port): Enable this.
[email protected]71f65dd2009-02-11 19:14:562666void AutomationProvider::PrintNow(int tab_handle,
2667 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572668 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342669 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2670 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292671 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572672 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142673 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342674 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572675 return;
initial.commit09911bf2008-07-26 23:55:292676 }
[email protected]71f65dd2009-02-11 19:14:562677 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2678 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292679}
[email protected]d301c952009-07-13 15:02:412680
2681void AutomationProvider::PrintAsync(int tab_handle) {
2682 NavigationController* tab = NULL;
2683 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2684 if (tab_contents) {
2685 if (tab_contents->PrintNow())
2686 return;
2687 }
2688}
[email protected]3753f522009-04-14 23:15:472689#endif
initial.commit09911bf2008-07-26 23:55:292690
[email protected]71f65dd2009-02-11 19:14:562691void AutomationProvider::SavePage(int tab_handle,
initial.commit09911bf2008-07-26 23:55:292692 const std::wstring& file_name,
2693 const std::wstring& dir_path,
[email protected]71f65dd2009-02-11 19:14:562694 int type,
2695 bool* success) {
initial.commit09911bf2008-07-26 23:55:292696 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562697 *success = false;
initial.commit09911bf2008-07-26 23:55:292698 return;
2699 }
2700
2701 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2702 Browser* browser = FindAndActivateTab(nav);
2703 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142704 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562705 *success = false;
initial.commit09911bf2008-07-26 23:55:292706 return;
2707 }
2708
initial.commit09911bf2008-07-26 23:55:292709 SavePackage::SavePackageType save_type =
2710 static_cast<SavePackage::SavePackageType>(type);
2711 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2712 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342713 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292714
[email protected]71f65dd2009-02-11 19:14:562715 *success = true;
initial.commit09911bf2008-07-26 23:55:292716}
2717
[email protected]13869dd2009-05-05 00:40:062718#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]3753f522009-04-14 23:15:472719// TODO(port): Enable these.
[email protected]71f65dd2009-02-11 19:14:562720void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2721 bool* success,
2722 std::wstring* text) {
2723 *success = false;
initial.commit09911bf2008-07-26 23:55:292724 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562725 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522726 GetText();
[email protected]71f65dd2009-02-11 19:14:562727 *success = true;
initial.commit09911bf2008-07-26 23:55:292728 }
initial.commit09911bf2008-07-26 23:55:292729}
2730
[email protected]71f65dd2009-02-11 19:14:562731void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2732 const std::wstring& text,
2733 bool* success) {
2734 *success = false;
initial.commit09911bf2008-07-26 23:55:292735 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522736 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2737 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562738 *success = true;
initial.commit09911bf2008-07-26 23:55:292739 }
initial.commit09911bf2008-07-26 23:55:292740}
2741
2742void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562743 int autocomplete_edit_handle,
2744 bool* success,
2745 std::vector<AutocompleteMatchData>* matches) {
2746 *success = false;
initial.commit09911bf2008-07-26 23:55:292747 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272748 const AutocompleteResult& result = autocomplete_edit_tracker_->
2749 GetResource(autocomplete_edit_handle)->model()->result();
2750 for (AutocompleteResult::const_iterator i = result.begin();
2751 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562752 matches->push_back(AutocompleteMatchData(*i));
2753 *success = true;
initial.commit09911bf2008-07-26 23:55:292754 }
initial.commit09911bf2008-07-26 23:55:292755}
2756
2757void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562758 int autocomplete_edit_handle,
2759 bool* success,
2760 bool* query_in_progress) {
2761 *success = false;
2762 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292763 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562764 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522765 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562766 *success = true;
initial.commit09911bf2008-07-26 23:55:292767 }
initial.commit09911bf2008-07-26 23:55:292768}
2769
[email protected]28790922009-03-09 19:48:372770void AutomationProvider::OnMessageFromExternalHost(int handle,
2771 const std::string& message,
2772 const std::string& origin,
2773 const std::string& target) {
[email protected]f7a68432009-07-29 23:18:192774 RenderViewHost* view_host = GetViewForTab(handle);
2775 if (!view_host) {
2776 return;
[email protected]fa83e762008-08-15 21:41:392777 }
[email protected]f7a68432009-07-29 23:18:192778
2779 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
2780 view_host, message, origin, target)) {
2781 // Message was diverted.
2782 return;
2783 }
2784
2785 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
2786 origin, target, this, view_host, handle)) {
2787 // Message was diverted.
2788 return;
2789 }
2790
2791 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
2792 // Message was diverted.
2793 return;
2794 }
2795
2796 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392797}
[email protected]a9024892009-06-16 23:13:552798
2799bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2800 const std::string& message, const std::string& origin,
2801 const std::string& target) {
2802 if (target !=
2803 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2804 return false;
2805
2806 if (origin != extension_automation_constants::kAutomationOrigin) {
2807 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2808 return false;
2809 }
2810
2811 // The message is a JSON-encoded array with two elements, both strings. The
2812 // first is the name of the event to dispatch. The second is a JSON-encoding
2813 // of the arguments specific to that event.
2814 scoped_ptr<Value> message_value(JSONReader::Read(message, false));
2815 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2816 LOG(WARNING) << "Invalid browser event specified through automation";
2817 return false;
2818 }
2819
2820 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2821
2822 std::string event_name;
2823 if (!args->GetString(0, &event_name)) {
2824 LOG(WARNING) << "No browser event name specified through automation";
2825 return false;
2826 }
2827
2828 std::string json_args;
2829 if (!args->GetString(1, &json_args)) {
2830 LOG(WARNING) << "No browser event args specified through automation";
2831 return false;
2832 }
2833
[email protected]7120f132009-07-20 21:05:372834 if (profile()->GetExtensionMessageService()) {
2835 profile()->GetExtensionMessageService()->
2836 DispatchEventToRenderers(event_name.c_str(), json_args);
2837 }
[email protected]a9024892009-06-16 23:13:552838
2839 return true;
2840}
[email protected]13869dd2009-05-05 00:40:062841#endif // defined(OS_WIN) || defined(OS_LINUX)
[email protected]fa83e762008-08-15 21:41:392842
[email protected]57c6a652009-05-04 07:58:342843TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572844 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572845 if (tab_tracker_->ContainsHandle(handle)) {
2846 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342847 if (tab)
2848 *tab = nav_controller;
2849 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572850 }
[email protected]57c6a652009-05-04 07:58:342851 return NULL;
[email protected]20e93d12008-08-28 16:31:572852}
2853
[email protected]5cc063692009-04-07 23:21:312854#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272855ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
2856 if (tab_tracker_->ContainsHandle(handle)) {
2857 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]965524b2009-04-04 21:32:402858 return ExternalTabContainer::GetContainerForTab(
2859 tab->tab_contents()->GetNativeView());
[email protected]b9d227492009-02-10 15:20:272860 }
2861
2862 return NULL;
2863}
[email protected]de246f52009-02-25 18:25:452864#endif // defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272865
initial.commit09911bf2008-07-26 23:55:292866TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2867 : AutomationProvider(profile) {
2868 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142869 registrar_.Add(this, NotificationType::SESSION_END,
2870 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292871}
2872
2873TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292874 BrowserList::RemoveObserver(this);
2875}
2876
2877void TestingAutomationProvider::OnChannelError() {
2878 BrowserList::CloseAllBrowsers(true);
2879 AutomationProvider::OnChannelError();
2880}
2881
2882void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2883 // For backwards compatibility with the testing automation interface, we
2884 // want the automation provider (and hence the process) to go away when the
2885 // last browser goes away.
2886 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292887 // If you change this, update Observer for NotificationType::SESSION_END
2888 // below.
[email protected]295039bd2008-08-15 04:32:572889 MessageLoop::current()->PostTask(FROM_HERE,
2890 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292891 }
2892}
2893
2894void TestingAutomationProvider::Observe(NotificationType type,
2895 const NotificationSource& source,
2896 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562897 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292898 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2899 // before the task runs resulting in this object not being deleted. This
2900 // Release balance out the Release scheduled by OnBrowserRemoving.
2901 Release();
2902}
[email protected]295039bd2008-08-15 04:32:572903
2904void TestingAutomationProvider::OnRemoveProvider() {
2905 AutomationProviderList::GetInstance()->RemoveProvider(this);
2906}
[email protected]8a3422c92008-09-24 17:42:422907
[email protected]71f65dd2009-02-11 19:14:562908void AutomationProvider::GetSSLInfoBarCount(int handle, int* count) {
2909 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422910 if (tab_tracker_->ContainsHandle(handle)) {
2911 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342912 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112913 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422914 }
[email protected]8a3422c92008-09-24 17:42:422915}
2916
[email protected]71f65dd2009-02-11 19:14:562917void AutomationProvider::ClickSSLInfoBarLink(int handle,
[email protected]8a3422c92008-09-24 17:42:422918 int info_bar_index,
[email protected]71f65dd2009-02-11 19:14:562919 bool wait_for_navigation,
2920 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422921 bool success = false;
2922 if (tab_tracker_->ContainsHandle(handle)) {
2923 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2924 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112925 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422926 if (info_bar_index >= 0 && info_bar_index < count) {
2927 if (wait_for_navigation) {
[email protected]2e028a082009-08-19 20:32:582928 AddNavigationStatusListener(nav_controller, reply_message, 1);
[email protected]8a3422c92008-09-24 17:42:422929 }
[email protected]eb9ba192008-12-02 02:41:342930 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112931 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342932 info_bar_index);
2933 if (delegate->AsConfirmInfoBarDelegate())
2934 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422935 success = true;
2936 }
2937 }
[email protected]4f3dc372009-02-24 00:10:292938 }
[email protected]8a3422c92008-09-24 17:42:422939 if (!wait_for_navigation || !success)
[email protected]457f5cf2009-08-18 16:37:522940 AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(
2941 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422942}
2943
[email protected]71f65dd2009-02-11 19:14:562944void AutomationProvider::GetLastNavigationTime(int handle,
2945 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422946 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562947 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422948}
2949
[email protected]71f65dd2009-02-11 19:14:562950void AutomationProvider::WaitForNavigation(int handle,
2951 int64 last_navigation_time,
2952 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422953 NavigationController* controller = NULL;
2954 if (tab_tracker_->ContainsHandle(handle))
2955 controller = tab_tracker_->GetResource(handle);
2956
2957 Time time = tab_tracker_->GetLastNavigationTime(handle);
2958 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562959 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522960 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
2961 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]4f3dc372009-02-24 00:10:292962 return;
[email protected]8a3422c92008-09-24 17:42:422963 }
2964
[email protected]2e028a082009-08-19 20:32:582965 AddNavigationStatusListener(controller, reply_message, 1);
[email protected]8a3422c92008-09-24 17:42:422966}
2967
[email protected]71f65dd2009-02-11 19:14:562968void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162969 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562970 int value,
2971 bool* success) {
2972 *success = false;
[email protected]8a3422c92008-09-24 17:42:422973 if (browser_tracker_->ContainsHandle(handle)) {
2974 Browser* browser = browser_tracker_->GetResource(handle);
2975 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562976 *success = true;
[email protected]8a3422c92008-09-24 17:42:422977 }
[email protected]8a3422c92008-09-24 17:42:422978}
[email protected]97fa6ce32008-12-19 01:48:162979
[email protected]71f65dd2009-02-11 19:14:562980void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162981 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562982 const std::wstring& value,
2983 bool* success) {
2984 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162985 if (browser_tracker_->ContainsHandle(handle)) {
2986 Browser* browser = browser_tracker_->GetResource(handle);
2987 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562988 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162989 }
[email protected]97fa6ce32008-12-19 01:48:162990}
2991
[email protected]71f65dd2009-02-11 19:14:562992void AutomationProvider::GetBooleanPreference(int handle,
2993 const std::wstring& name,
2994 bool* success,
2995 bool* value) {
2996 *success = false;
2997 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162998 if (browser_tracker_->ContainsHandle(handle)) {
2999 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:563000 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
3001 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163002 }
[email protected]97fa6ce32008-12-19 01:48:163003}
3004
[email protected]71f65dd2009-02-11 19:14:563005void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:163006 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:563007 bool value,
3008 bool* success) {
3009 *success = false;
[email protected]97fa6ce32008-12-19 01:48:163010 if (browser_tracker_->ContainsHandle(handle)) {
3011 Browser* browser = browser_tracker_->GetResource(handle);
3012 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:563013 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163014 }
[email protected]97fa6ce32008-12-19 01:48:163015}
3016
3017// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563018void AutomationProvider::GetPageCurrentEncoding(
3019 int tab_handle, std::wstring* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:163020 if (tab_tracker_->ContainsHandle(tab_handle)) {
3021 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3022 Browser* browser = FindAndActivateTab(nav);
3023 DCHECK(browser);
3024
[email protected]57c6a652009-05-04 07:58:343025 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
3026 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:163027 }
[email protected]97fa6ce32008-12-19 01:48:163028}
3029
3030// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:563031void AutomationProvider::OverrideEncoding(int tab_handle,
3032 const std::wstring& encoding_name,
3033 bool* success) {
3034 *success = false;
[email protected]de246f52009-02-25 18:25:453035#if defined(OS_WIN)
[email protected]97fa6ce32008-12-19 01:48:163036 if (tab_tracker_->ContainsHandle(tab_handle)) {
3037 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
3038 Browser* browser = FindAndActivateTab(nav);
3039 DCHECK(browser);
3040
[email protected]1fc025202009-01-20 23:03:143041 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:113042 TabContents* tab_contents = nav->tab_contents();
[email protected]97fa6ce32008-12-19 01:48:163043 int selected_encoding_id =
3044 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
3045 if (selected_encoding_id) {
3046 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:563047 *success = true;
[email protected]97fa6ce32008-12-19 01:48:163048 }
3049 }
3050 }
[email protected]de246f52009-02-25 18:25:453051#else
3052 // TODO(port): Enable when encoding-related parts of Browser are ported.
3053 NOTIMPLEMENTED();
3054#endif
[email protected]97fa6ce32008-12-19 01:48:163055}
[email protected]5bcdb312009-01-07 21:43:203056
[email protected]4d434a1a2009-02-11 21:06:573057void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:203058 SavePackage::SetShouldPromptUser(should_prompt);
3059}
[email protected]87eab222009-03-13 00:47:453060
[email protected]b83e4602009-05-15 22:58:333061void AutomationProvider::SetEnableExtensionAutomation(bool automation_enabled) {
3062 AutomationExtensionFunction::SetEnabled(automation_enabled);
3063}
3064
[email protected]d2cc6ed2009-04-24 00:26:173065#if defined(OS_WIN)
3066// TODO(port): Reposition_Params is win-specific. We'll need to port it.
[email protected]87eab222009-03-13 00:47:453067void AutomationProvider::OnTabReposition(
3068 int tab_handle, const IPC::Reposition_Params& params) {
3069 if (!tab_tracker_->ContainsHandle(tab_handle))
3070 return;
3071
3072 if (!IsWindow(params.window))
3073 return;
3074
3075 unsigned long process_id = 0;
3076 unsigned long thread_id = 0;
3077
3078 thread_id = GetWindowThreadProcessId(params.window, &process_id);
3079
3080 if (thread_id != GetCurrentThreadId()) {
3081 NOTREACHED();
3082 return;
3083 }
3084
[email protected]a9233d0f2009-04-20 05:39:333085 SetWindowPos(params.window, params.window_insert_after, params.left,
3086 params.top, params.width, params.height, params.flags);
3087
[email protected]a2c5a9892009-04-07 16:13:453088 if (params.set_parent) {
3089 if (IsWindow(params.parent_window)) {
3090 if (!SetParent(params.window, params.parent_window))
3091 DLOG(WARNING) << "SetParent failed. Error 0x%x" << GetLastError();
3092 }
3093 }
[email protected]87eab222009-03-13 00:47:453094}
[email protected]e943d6662009-06-12 03:50:393095
3096void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle,
3097 int command) {
3098 if (tab_tracker_->ContainsHandle(tab_handle)) {
3099 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3100 if (!tab) {
3101 NOTREACHED();
3102 return;
3103 }
3104
3105 TabContents* tab_contents = tab->tab_contents();
3106 if (!tab_contents || !tab_contents->delegate()) {
3107 NOTREACHED();
3108 return;
3109 }
3110
3111 tab_contents->delegate()->ExecuteContextMenuCommand(command);
3112 }
3113}
3114
3115#endif // defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:473116
3117void AutomationProvider::GetWindowTitle(int handle, string16* text) {
3118 gfx::NativeWindow window = window_tracker_->GetResource(handle);
3119 text->assign(platform_util::GetWindowTitle(window));
3120}
[email protected]66ba4932009-06-04 19:22:133121
3122void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3123 *count = -1; // -1 is the error code
3124 if (tab_tracker_->ContainsHandle(handle)) {
3125 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3126 TabContents* tab_contents = nav_controller->tab_contents();
3127 if (tab_contents) {
3128 BlockedPopupContainer* container =
3129 tab_contents->blocked_popup_container();
3130 if (container) {
3131 *count = static_cast<int>(container->GetBlockedPopupCount());
3132 } else {
3133 // If we don't have a container, we don't have any blocked popups to
3134 // contain!
3135 *count = 0;
3136 }
3137 }
3138 }
3139}
[email protected]f7a68432009-07-29 23:18:193140
3141void AutomationProvider::SelectAll(int tab_handle) {
3142 RenderViewHost* view = GetViewForTab(tab_handle);
3143 if (!view) {
3144 NOTREACHED();
3145 return;
3146 }
3147
3148 view->SelectAll();
3149}
3150
3151void AutomationProvider::Cut(int tab_handle) {
3152 RenderViewHost* view = GetViewForTab(tab_handle);
3153 if (!view) {
3154 NOTREACHED();
3155 return;
3156 }
3157
3158 view->Cut();
3159}
3160
3161void AutomationProvider::Copy(int tab_handle) {
3162 RenderViewHost* view = GetViewForTab(tab_handle);
3163 if (!view) {
3164 NOTREACHED();
3165 return;
3166 }
3167
3168 view->Copy();
3169}
3170
3171void AutomationProvider::Paste(int tab_handle) {
3172 RenderViewHost* view = GetViewForTab(tab_handle);
3173 if (!view) {
3174 NOTREACHED();
3175 return;
3176 }
3177
3178 view->Paste();
3179}
3180
3181void AutomationProvider::ReloadAsync(int tab_handle) {
3182 if (tab_tracker_->ContainsHandle(tab_handle)) {
3183 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3184 if (!tab) {
3185 NOTREACHED();
3186 return;
3187 }
3188
3189 tab->Reload(false);
3190 }
3191}
3192
3193void AutomationProvider::StopAsync(int tab_handle) {
3194 RenderViewHost* view = GetViewForTab(tab_handle);
3195 if (!view) {
3196 NOTREACHED();
3197 return;
3198 }
3199
3200 view->Stop();
3201}
3202
[email protected]2949e90d2009-08-21 15:32:523203void AutomationProvider::WaitForBrowserWindowCountToBecome(
3204 int target_count, IPC::Message* reply_message) {
3205 if (static_cast<int>(BrowserList::size()) == target_count) {
3206 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
3207 reply_message, true);
3208 Send(reply_message);
3209 return;
3210 }
3211
3212 // Set up an observer (it will delete itself).
3213 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
3214}
3215
3216void AutomationProvider::WaitForAppModalDialogToBeShown(
3217 IPC::Message* reply_message) {
3218 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
3219 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
3220 reply_message, true);
3221 Send(reply_message);
3222 return;
3223 }
3224
3225 // Set up an observer (it will delete itself).
3226 new AppModalDialogShownObserver(this, reply_message);
3227}
3228
[email protected]f7a68432009-07-29 23:18:193229RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
3230 if (tab_tracker_->ContainsHandle(tab_handle)) {
3231 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3232 if (!tab) {
3233 NOTREACHED();
3234 return NULL;
3235 }
3236
3237 TabContents* tab_contents = tab->tab_contents();
3238 if (!tab_contents) {
3239 NOTREACHED();
3240 return NULL;
3241 }
3242
3243 RenderViewHost* view_host = tab_contents->render_view_host();
3244 return view_host;
3245 }
3246
3247 return NULL;
3248}