blob: 1845fd71581d7056b7d5461727618f9a081ace9f [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]c6cb1992009-04-13 16:45:297#include "base/file_version_info.h"
[email protected]5fac9622009-02-04 21:49:388#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:299#include "base/path_service.h"
[email protected]4c4d8d22009-03-04 05:29:2710#include "base/string_util.h"
[email protected]5fac9622009-02-04 21:49:3811#include "base/thread.h"
[email protected]4f3dc372009-02-24 00:10:2912#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2813#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0914#include "chrome/browser/app_modal_dialog_queue.h"
initial.commit09911bf2008-07-26 23:55:2915#include "chrome/browser/automation/automation_provider_list.h"
initial.commit09911bf2008-07-26 23:55:2916#include "chrome/browser/automation/url_request_failed_dns_job.h"
17#include "chrome/browser/automation/url_request_mock_http_job.h"
18#include "chrome/browser/automation/url_request_slow_download_job.h"
[email protected]f3e99e32008-07-30 04:48:3919#include "chrome/browser/browser_window.h"
initial.commit09911bf2008-07-26 23:55:2920#include "chrome/browser/dom_operation_notification_details.h"
[email protected]cdaa8652008-09-13 02:48:5921#include "chrome/browser/download/download_manager.h"
[email protected]4801ecc2009-04-05 04:52:5822#include "chrome/browser/find_bar.h"
23#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2924#include "chrome/browser/find_notification_details.h"
[email protected]6524b5f92009-01-22 17:48:2525#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0326#include "chrome/browser/ssl/ssl_manager.h"
27#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]f3ec7742009-01-15 00:59:1628#include "chrome/browser/tab_contents/web_contents.h"
29#include "chrome/browser/tab_contents/web_contents_view.h"
initial.commit09911bf2008-07-26 23:55:2930#include "chrome/common/chrome_paths.h"
[email protected]6a02963e2009-01-06 16:58:0331#include "chrome/common/notification_registrar.h"
[email protected]3753f522009-04-14 23:15:4732#include "chrome/common/platform_util.h"
[email protected]8a3422c92008-09-24 17:42:4233#include "chrome/common/pref_service.h"
[email protected]71f65dd2009-02-11 19:14:5634#include "chrome/test/automation/automation_messages.h"
initial.commit09911bf2008-07-26 23:55:2935#include "net/base/cookie_monster.h"
[email protected]319d9e6f2009-02-18 19:47:2136#include "net/url_request/url_request_context.h"
initial.commit09911bf2008-07-26 23:55:2937#include "net/url_request/url_request_filter.h"
38
[email protected]de246f52009-02-25 18:25:4539#if defined(OS_WIN)
40// TODO(port): Port these headers.
[email protected]de246f52009-02-25 18:25:4541#include "chrome/browser/automation/ui_controls.h"
42#include "chrome/browser/character_encoding.h"
43#include "chrome/browser/download/save_package.h"
44#include "chrome/browser/external_tab_container.h"
45#include "chrome/browser/login_prompt.h"
46#include "chrome/browser/printing/print_job.h"
47#include "chrome/browser/views/bookmark_bar_view.h"
48#include "chrome/browser/views/location_bar_view.h"
[email protected]0bfa713f2009-04-07 20:18:2849#include "chrome/views/window/dialog_delegate.h"
[email protected]0e8588c12009-03-17 01:44:3650#include "chrome/views/window/window.h"
[email protected]de246f52009-02-25 18:25:4551#endif // defined(OS_WIN)
52
[email protected]e1acf6f2008-10-27 20:43:3353using base::Time;
54
initial.commit09911bf2008-07-26 23:55:2955class InitialLoadObserver : public NotificationObserver {
56 public:
57 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
[email protected]66791d22009-02-24 20:11:3358 : automation_(automation),
59 outstanding_tab_count_(tab_count) {
initial.commit09911bf2008-07-26 23:55:2960 if (outstanding_tab_count_ > 0) {
[email protected]bfd04a62009-02-01 18:16:5661 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:0362 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:5663 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:0364 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:2965 }
66 }
67
68 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:2969 }
70
71 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:0372 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:2973 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
74 }
75
initial.commit09911bf2008-07-26 23:55:2976 virtual void Observe(NotificationType type,
77 const NotificationSource& source,
78 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:5679 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:2980 if (outstanding_tab_count_ > loading_tabs_.size())
81 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:5682 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:2983 if (outstanding_tab_count_ > finished_tabs_.size()) {
84 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
85 finished_tabs_.insert(source.map_key());
86 if (outstanding_tab_count_ == finished_tabs_.size())
87 ConditionMet();
88 }
89 } else {
90 NOTREACHED();
91 }
92 }
93
94 private:
95 typedef std::set<uintptr_t> TabSet;
96
[email protected]6a02963e2009-01-06 16:58:0397 NotificationRegistrar registrar_;
98
initial.commit09911bf2008-07-26 23:55:2999 AutomationProvider* automation_;
100 size_t outstanding_tab_count_;
101 TabSet loading_tabs_;
102 TabSet finished_tabs_;
103};
104
105// Watches for NewTabUI page loads for performance timing purposes.
106class NewTabUILoadObserver : public NotificationObserver {
107 public:
108 explicit NewTabUILoadObserver(AutomationProvider* automation)
109 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:56110 NotificationService::current()->AddObserver(
111 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
112 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29113 }
114
115 ~NewTabUILoadObserver() {
116 Unregister();
117 }
118
119 void Unregister() {
[email protected]bfd04a62009-02-01 18:16:56120 NotificationService::current()->RemoveObserver(
121 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
122 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29123 }
124
125 virtual void Observe(NotificationType type,
126 const NotificationSource& source,
127 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56128 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29129 Details<int> load_time(details);
130 automation_->Send(
131 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
132 } else {
133 NOTREACHED();
134 }
135 }
136
137 private:
138 AutomationProvider* automation_;
139};
140
141class NavigationControllerRestoredObserver : public NotificationObserver {
142 public:
143 NavigationControllerRestoredObserver(AutomationProvider* automation,
144 NavigationController* controller,
[email protected]71f65dd2009-02-11 19:14:56145 int32 routing_id,
146 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29147 : automation_(automation),
148 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56149 routing_id_(routing_id),
150 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29151 if (FinishedRestoring()) {
152 registered_ = false;
153 SendDone();
154 } else {
155 registered_ = true;
156 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56157 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29158 NotificationService::AllSources());
159 }
160 }
161
162 ~NavigationControllerRestoredObserver() {
163 if (registered_)
164 Unregister();
165 }
166
167 virtual void Observe(NotificationType type,
168 const NotificationSource& source,
169 const NotificationDetails& details) {
170 if (FinishedRestoring()) {
171 SendDone();
172 Unregister();
173 }
174 }
175
176 private:
177 void Unregister() {
178 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56179 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29180 NotificationService::AllSources());
181 registered_ = false;
182 }
183
184 bool FinishedRestoring() {
[email protected]7f0005a2009-04-15 03:25:11185 return (!controller_->needs_reload() && !controller_->pending_entry() &&
186 !controller_->tab_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29187 }
188
189 void SendDone() {
[email protected]71f65dd2009-02-11 19:14:56190 DCHECK(reply_message_ != NULL);
191 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29192 }
193
194 bool registered_;
195 AutomationProvider* automation_;
196 NavigationController* controller_;
197 const int routing_id_;
[email protected]71f65dd2009-02-11 19:14:56198 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29199
[email protected]5a52f162008-08-27 04:15:31200 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29201};
202
[email protected]71f65dd2009-02-11 19:14:56203template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29204class NavigationNotificationObserver : public NotificationObserver {
205 public:
206 NavigationNotificationObserver(NavigationController* controller,
207 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56208 IPC::Message* reply_message,
209 NavigationCodeType success_code,
210 NavigationCodeType auth_needed_code,
211 NavigationCodeType failed_code)
initial.commit09911bf2008-07-26 23:55:29212 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56213 reply_message_(reply_message),
initial.commit09911bf2008-07-26 23:55:29214 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56215 navigation_started_(false),
216 success_code_(success_code),
217 auth_needed_code_(auth_needed_code),
218 failed_code_(failed_code) {
initial.commit09911bf2008-07-26 23:55:29219 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56220 service->AddObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42221 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56222 service->AddObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29223 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56224 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29225 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56226 service->AddObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29227 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56228 service->AddObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29229 Source<NavigationController>(controller_));
230 }
231
232 ~NavigationNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29233 Unregister();
234 }
235
[email protected]71f65dd2009-02-11 19:14:56236 void ConditionMet(NavigationCodeType navigation_result) {
237 DCHECK(reply_message_ != NULL);
238
239 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
240 navigation_result);
241 automation_->Send(reply_message_);
242 reply_message_ = NULL;
243
[email protected]d5798082008-09-29 21:02:03244 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29245 delete this;
246 }
247
248 void Unregister() {
[email protected]71f65dd2009-02-11 19:14:56249 // 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.
252 if (reply_message_) {
253 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
254 failed_code_);
255 automation_->Send(reply_message_);
256 reply_message_ = NULL;
257 }
258
initial.commit09911bf2008-07-26 23:55:29259 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56260 service->RemoveObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42261 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56262 service->RemoveObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29263 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56264 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29265 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56266 service->RemoveObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29267 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56268 service->RemoveObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29269 Source<NavigationController>(controller_));
270 }
271
272 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]71f65dd2009-02-11 19:14:56288 ConditionMet(success_code_);
initial.commit09911bf2008-07-26 23:55:29289 }
[email protected]bfd04a62009-02-01 18:16:56290 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29291 // The LoginHandler for this tab is no longer valid.
292 automation_->RemoveLoginHandler(controller_);
293
294 // Treat this as if navigation started again, since load start/stop don't
295 // occur while authentication is ongoing.
296 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56297 } else if (type == NotificationType::AUTH_NEEDED) {
[email protected]de246f52009-02-25 18:25:45298#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29299 if (navigation_started_) {
300 // Remember the login handler that wants authentication.
301 LoginHandler* handler =
302 Details<LoginNotificationDetails>(details)->handler();
303 automation_->AddLoginHandler(controller_, handler);
304
305 // Respond that authentication is needed.
306 navigation_started_ = false;
[email protected]71f65dd2009-02-11 19:14:56307 ConditionMet(auth_needed_code_);
initial.commit09911bf2008-07-26 23:55:29308 } else {
309 NOTREACHED();
310 }
[email protected]de246f52009-02-25 18:25:45311#else
312 // TODO(port): Enable when we have LoginNotificationDetails etc.
313 NOTIMPLEMENTED();
314#endif
initial.commit09911bf2008-07-26 23:55:29315 } else {
316 NOTREACHED();
317 }
318 }
319
320 private:
321 AutomationProvider* automation_;
[email protected]71f65dd2009-02-11 19:14:56322 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29323 NavigationController* controller_;
324 bool navigation_started_;
[email protected]71f65dd2009-02-11 19:14:56325 NavigationCodeType success_code_;
326 NavigationCodeType auth_needed_code_;
327 NavigationCodeType failed_code_;
initial.commit09911bf2008-07-26 23:55:29328};
329
330class TabStripNotificationObserver : public NotificationObserver {
331 public:
332 TabStripNotificationObserver(Browser* parent, NotificationType notification,
333 AutomationProvider* automation, int32 routing_id)
334 : automation_(automation),
initial.commit09911bf2008-07-26 23:55:29335 parent_(parent),
[email protected]66791d22009-02-24 20:11:33336 notification_(notification),
initial.commit09911bf2008-07-26 23:55:29337 routing_id_(routing_id) {
338 NotificationService::current()->
339 AddObserver(this, notification_, NotificationService::AllSources());
340 }
341
342 virtual ~TabStripNotificationObserver() {
343 Unregister();
344 }
345
346 void Unregister() {
347 NotificationService::current()->
348 RemoveObserver(this, notification_, NotificationService::AllSources());
349 }
350
351 virtual void Observe(NotificationType type,
352 const NotificationSource& source,
353 const NotificationDetails& details) {
354 if (type == notification_) {
355 ObserveTab(Source<NavigationController>(source).ptr());
356
357 // If verified, no need to observe anymore
358 automation_->RemoveTabStripObserver(this);
359 delete this;
360 } else {
361 NOTREACHED();
362 }
363 }
364
365 virtual void ObserveTab(NavigationController* controller) = 0;
366
367 protected:
368 AutomationProvider* automation_;
369 Browser* parent_;
370 NotificationType notification_;
371 int32 routing_id_;
372};
373
374class TabAppendedNotificationObserver : public TabStripNotificationObserver {
375 public:
376 TabAppendedNotificationObserver(Browser* parent,
[email protected]4f3dc372009-02-24 00:10:29377 AutomationProvider* automation, int32 routing_id,
[email protected]71f65dd2009-02-11 19:14:56378 IPC::Message* reply_message)
[email protected]bfd04a62009-02-01 18:16:56379 : TabStripNotificationObserver(parent, NotificationType::TAB_PARENTED,
[email protected]71f65dd2009-02-11 19:14:56380 automation, routing_id),
381 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29382 }
383
384 virtual void ObserveTab(NavigationController* controller) {
385 int tab_index =
386 automation_->GetIndexForNavigationController(controller, parent_);
387 if (tab_index == TabStripModel::kNoTab) {
388 // This tab notification doesn't belong to the parent_
389 return;
390 }
391
392 // Give the same response even if auth is needed, since it doesn't matter.
[email protected]71f65dd2009-02-11 19:14:56393 automation_->AddNavigationStatusListener<int>(
394 controller, reply_message_, AUTOMATION_MSG_NAVIGATION_SUCCESS,
395 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED, AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:29396 }
[email protected]71f65dd2009-02-11 19:14:56397
398 protected:
399 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29400};
401
402class TabClosedNotificationObserver : public TabStripNotificationObserver {
403 public:
404 TabClosedNotificationObserver(Browser* parent,
405 AutomationProvider* automation,
406 int32 routing_id,
[email protected]71f65dd2009-02-11 19:14:56407 bool wait_until_closed,
408 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29409 : TabStripNotificationObserver(parent,
[email protected]bfd04a62009-02-01 18:16:56410 wait_until_closed ? NotificationType::TAB_CLOSED :
411 NotificationType::TAB_CLOSING,
412 automation,
[email protected]71f65dd2009-02-11 19:14:56413 routing_id),
414 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29415 }
416
417 virtual void ObserveTab(NavigationController* controller) {
[email protected]71f65dd2009-02-11 19:14:56418 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
419 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29420 }
[email protected]71f65dd2009-02-11 19:14:56421
422 protected:
423 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29424};
425
[email protected]14c0a032009-04-13 18:15:14426class BrowserOpenedNotificationObserver : public NotificationObserver {
427 public:
428 BrowserOpenedNotificationObserver(AutomationProvider* automation,
429 IPC::Message* reply_message)
430 : automation_(automation),
431 reply_message_(reply_message) {
432 registrar_.Add(this, NotificationType::BROWSER_OPENED,
433 NotificationService::AllSources());
434 }
435
436 ~BrowserOpenedNotificationObserver() {
437 }
438
439 virtual void Observe(NotificationType type,
440 const NotificationSource& source,
441 const NotificationDetails& details) {
442 if (type == NotificationType::BROWSER_OPENED) {
443 automation_->Send(reply_message_);
444 delete this;
445 } else {
446 NOTREACHED();
447 }
448 }
449
450 private:
451 AutomationProvider* automation_;
452 IPC::Message* reply_message_;
453 NotificationRegistrar registrar_;
454};
455
initial.commit09911bf2008-07-26 23:55:29456class BrowserClosedNotificationObserver : public NotificationObserver {
457 public:
458 BrowserClosedNotificationObserver(Browser* browser,
459 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56460 int32 routing_id,
461 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29462 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56463 routing_id_(routing_id),
464 reply_message_(reply_message) {
[email protected]bfd04a62009-02-01 18:16:56465 NotificationService::current()->AddObserver(this,
466 NotificationType::BROWSER_CLOSED, Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29467 }
468
469 virtual void Observe(NotificationType type,
470 const NotificationSource& source,
471 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56472 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29473 Details<bool> close_app(details);
[email protected]71f65dd2009-02-11 19:14:56474 DCHECK(reply_message_ != NULL);
475 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
476 *(close_app.ptr()));
477 automation_->Send(reply_message_);
478 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29479 delete this;
480 }
481
482 private:
483 AutomationProvider* automation_;
484 int32 routing_id_;
[email protected]71f65dd2009-02-11 19:14:56485 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29486};
487
[email protected]4e41709d2009-04-08 00:04:27488namespace {
489
490// Define mapping from command to notification
491struct CommandNotification {
492 int command;
493 NotificationType::Type notification_type;
494};
495
496const struct CommandNotification command_notifications[] = {
[email protected]14c0a032009-04-13 18:15:14497 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
[email protected]4e41709d2009-04-08 00:04:27498 {IDC_NEW_TAB, NotificationType::TAB_PARENTED}
499};
500
501} // namespace
502
[email protected]56e71b7c2009-03-27 03:05:56503class ExecuteBrowserCommandObserver : public NotificationObserver {
504 public:
[email protected]4e41709d2009-04-08 00:04:27505 ExecuteBrowserCommandObserver(AutomationProvider* automation,
506 IPC::Message* reply_message)
[email protected]56e71b7c2009-03-27 03:05:56507 : automation_(automation),
[email protected]56e71b7c2009-03-27 03:05:56508 reply_message_(reply_message) {
[email protected]56e71b7c2009-03-27 03:05:56509 }
510
511 ~ExecuteBrowserCommandObserver() {
512 }
513
[email protected]4e41709d2009-04-08 00:04:27514 bool Register(int command) {
515 if (!GetNotificationType(command, &notification_type_))
516 return false;
517 registrar_.Add(this, notification_type_,
518 NotificationService::AllSources());
519 return true;
520 }
521
[email protected]56e71b7c2009-03-27 03:05:56522 virtual void Observe(NotificationType type,
523 const NotificationSource& source,
524 const NotificationDetails& details) {
525 if (type == notification_type_) {
[email protected]49a14a82009-03-31 04:16:44526 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
527 true);
[email protected]56e71b7c2009-03-27 03:05:56528 automation_->Send(reply_message_);
529 delete this;
530 } else {
531 NOTREACHED();
532 }
533 }
534
535 private:
[email protected]4e41709d2009-04-08 00:04:27536 bool GetNotificationType(int command, NotificationType::Type* type) {
537 if (!type)
538 return false;
539 bool found = false;
540 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
541 if (command_notifications[i].command == command) {
542 *type = command_notifications[i].notification_type;
543 found = true;
544 break;
545 }
546 }
547 return found;
548 }
549
[email protected]56e71b7c2009-03-27 03:05:56550 AutomationProvider* automation_;
551 NotificationType::Type notification_type_;
552 IPC::Message* reply_message_;
553 NotificationRegistrar registrar_;
554};
555
initial.commit09911bf2008-07-26 23:55:29556class FindInPageNotificationObserver : public NotificationObserver {
557 public:
558 FindInPageNotificationObserver(AutomationProvider* automation,
559 TabContents* parent_tab,
[email protected]71f65dd2009-02-11 19:14:56560 int32 routing_id,
561 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29562 : automation_(automation),
563 parent_tab_(parent_tab),
[email protected]aedd85a2008-12-04 19:32:49564 routing_id_(routing_id),
[email protected]71f65dd2009-02-11 19:14:56565 active_match_ordinal_(-1),
566 reply_message_(reply_message) {
[email protected]bfd04a62009-02-01 18:16:56567 NotificationService::current()->AddObserver(
568 this,
569 NotificationType::FIND_RESULT_AVAILABLE,
570 Source<TabContents>(parent_tab_));
initial.commit09911bf2008-07-26 23:55:29571 }
572
573 ~FindInPageNotificationObserver() {
574 Unregister();
575 }
576
577 void Unregister() {
[email protected]71f65dd2009-02-11 19:14:56578 DCHECK(reply_message_ == NULL);
initial.commit09911bf2008-07-26 23:55:29579 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56580 RemoveObserver(this, NotificationType::FIND_RESULT_AVAILABLE,
initial.commit09911bf2008-07-26 23:55:29581 Source<TabContents>(parent_tab_));
582 }
583
584 virtual void Observe(NotificationType type, const NotificationSource& source,
585 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56586 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29587 Details<FindNotificationDetails> find_details(details);
588 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49589 // We get multiple responses and one of those will contain the ordinal.
590 // This message comes to us before the final update is sent.
591 if (find_details->active_match_ordinal() > -1)
592 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29593 if (find_details->final_update()) {
[email protected]71f65dd2009-02-11 19:14:56594 DCHECK(reply_message_ != NULL);
595
596 AutomationMsg_FindInPage::WriteReplyParams(
597 reply_message_, active_match_ordinal_,
598 find_details->number_of_matches());
599
600 automation_->Send(reply_message_);
601 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29602 } else {
603 DLOG(INFO) << "Ignoring, since we only care about the final message";
604 }
605 }
606 } else {
607 NOTREACHED();
608 }
609 }
610
611 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
612 // we wait for notification to find out what the results are. As the user is
613 // typing, new search requests can be issued and the Request ID helps us make
614 // sense of whether this is the current request or an old one. The unit tests,
615 // however, which uses this constant issues only one search at a time, so we
616 // don't need a rolling id to identify each search. But, we still need to
617 // specify one, so we just use a fixed one - its value does not matter.
618 static const int kFindInPageRequestId;
619 private:
620 AutomationProvider* automation_;
621 TabContents* parent_tab_;
622 int32 routing_id_;
[email protected]aedd85a2008-12-04 19:32:49623 // We will at some point (before final update) be notified of the ordinal and
624 // we need to preserve it so we can send it later.
625 int active_match_ordinal_;
[email protected]71f65dd2009-02-11 19:14:56626 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29627};
628
629const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
630
631class DomOperationNotificationObserver : public NotificationObserver {
632 public:
633 explicit DomOperationNotificationObserver(AutomationProvider* automation)
634 : automation_(automation) {
635 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56636 AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29637 NotificationService::AllSources());
638 }
639
640 ~DomOperationNotificationObserver() {
641 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56642 RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29643 NotificationService::AllSources());
644 }
645
646 virtual void Observe(NotificationType type, const NotificationSource& source,
647 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56648 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29649 Details<DomOperationNotificationDetails> dom_op_details(details);
[email protected]71f65dd2009-02-11 19:14:56650
651 IPC::Message* reply_message = automation_->reply_message_release();
652 DCHECK(reply_message != NULL);
653
654 AutomationMsg_DomOperation::WriteReplyParams(
655 reply_message, dom_op_details->json());
656 automation_->Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29657 }
658 }
659 private:
660 AutomationProvider* automation_;
661};
662
663class DomInspectorNotificationObserver : public NotificationObserver {
664 public:
665 explicit DomInspectorNotificationObserver(AutomationProvider* automation)
666 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:56667 NotificationService::current()->AddObserver(
668 this,
669 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
670 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29671 }
672
673 ~DomInspectorNotificationObserver() {
[email protected]bfd04a62009-02-01 18:16:56674 NotificationService::current()->RemoveObserver(
675 this,
676 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
677 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29678 }
679
680 virtual void Observe(NotificationType type, const NotificationSource& source,
681 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56682 if (NotificationType::DOM_INSPECT_ELEMENT_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29683 Details<int> dom_inspect_details(details);
684 automation_->ReceivedInspectElementResponse(*(dom_inspect_details.ptr()));
685 }
686 }
687
688 private:
689 AutomationProvider* automation_;
690};
691
[email protected]de246f52009-02-25 18:25:45692#if defined(OS_WIN)
693// TODO(port): Enable when printing is ported.
initial.commit09911bf2008-07-26 23:55:29694class DocumentPrintedNotificationObserver : public NotificationObserver {
695 public:
696 DocumentPrintedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56697 int32 routing_id,
698 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29699 : automation_(automation),
700 routing_id_(routing_id),
[email protected]71f65dd2009-02-11 19:14:56701 success_(false),
702 reply_message_(reply_message) {
[email protected]bfd04a62009-02-01 18:16:56703 NotificationService::current()->AddObserver(
704 this,
705 NotificationType::PRINT_JOB_EVENT,
706 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29707 }
708
709 ~DocumentPrintedNotificationObserver() {
[email protected]71f65dd2009-02-11 19:14:56710 DCHECK(reply_message_ != NULL);
711 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
712 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29713 automation_->RemoveNavigationStatusListener(this);
[email protected]bfd04a62009-02-01 18:16:56714 NotificationService::current()->RemoveObserver(
715 this,
716 NotificationType::PRINT_JOB_EVENT,
717 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29718 }
719
720 virtual void Observe(NotificationType type, const NotificationSource& source,
721 const NotificationDetails& details) {
722 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56723 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29724 switch (Details<JobEventDetails>(details)->type()) {
725 case JobEventDetails::JOB_DONE: {
726 // Succeeded.
727 success_ = true;
728 delete this;
729 break;
730 }
731 case JobEventDetails::USER_INIT_CANCELED:
732 case JobEventDetails::FAILED: {
733 // Failed.
734 delete this;
735 break;
736 }
737 case JobEventDetails::NEW_DOC:
738 case JobEventDetails::USER_INIT_DONE:
739 case JobEventDetails::DEFAULT_INIT_DONE:
740 case JobEventDetails::NEW_PAGE:
741 case JobEventDetails::PAGE_DONE:
742 case JobEventDetails::DOC_DONE:
743 case JobEventDetails::ALL_PAGES_REQUESTED: {
744 // Don't care.
745 break;
746 }
747 default: {
748 NOTREACHED();
749 break;
750 }
751 }
752 }
753
754 private:
755 scoped_refptr<AutomationProvider> automation_;
756 int32 routing_id_;
757 bool success_;
[email protected]71f65dd2009-02-11 19:14:56758 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29759};
[email protected]de246f52009-02-25 18:25:45760#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29761
[email protected]cbab76d2008-10-13 22:42:47762class AutomationInterstitialPage : public InterstitialPage {
763 public:
[email protected]a3a1d142008-12-19 00:42:30764 AutomationInterstitialPage(WebContents* tab,
[email protected]cbab76d2008-10-13 22:42:47765 const GURL& url,
766 const std::string& contents)
767 : InterstitialPage(tab, true, url),
768 contents_(contents) {
769 }
770
771 virtual std::string GetHTMLContents() { return contents_; }
772
773 private:
774 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29775
[email protected]cbab76d2008-10-13 22:42:47776 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
777};
778
initial.commit09911bf2008-07-26 23:55:29779AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57780 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56781 profile_(profile),
782 reply_message_(NULL) {
initial.commit09911bf2008-07-26 23:55:29783 browser_tracker_.reset(new AutomationBrowserTracker(this));
initial.commit09911bf2008-07-26 23:55:29784 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20785 window_tracker_.reset(new AutomationWindowTracker(this));
[email protected]de246f52009-02-25 18:25:45786#if defined(OS_WIN)
787 // TODO(port): Enable as the trackers get ported.
initial.commit09911bf2008-07-26 23:55:29788 autocomplete_edit_tracker_.reset(
789 new AutomationAutocompleteEditTracker(this));
790 cwindow_tracker_.reset(new AutomationConstrainedWindowTracker(this));
791 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
[email protected]de246f52009-02-25 18:25:45792#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29793 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
794 dom_inspector_observer_.reset(new DomInspectorNotificationObserver(this));
795}
796
797AutomationProvider::~AutomationProvider() {
[email protected]0da050b92008-08-19 19:29:47798 // Make sure that any outstanding NotificationObservers also get destroyed.
799 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31800 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47801 while ((observer = it.GetNext()) != NULL)
802 delete observer;
initial.commit09911bf2008-07-26 23:55:29803}
804
805void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) {
[email protected]295039bd2008-08-15 04:32:57806 channel_.reset(
[email protected]71f65dd2009-02-11 19:14:56807 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this, NULL,
808 g_browser_process->io_thread()->message_loop(),
809 true, g_browser_process->shutdown_event()));
[email protected]c6cb1992009-04-13 16:45:29810 FileVersionInfo* file_version_info =
811 FileVersionInfo::CreateFileVersionInfoForCurrentModule();
812 std::string version_string(WideToASCII(file_version_info->file_version()));
813
814 // Send a hello message with our current automation protocol version.
815 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29816}
817
818void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
819 if (expected_tabs == 0) {
820 Send(new AutomationMsg_InitialLoadsComplete(0));
821 } else {
822 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
823 }
824}
825
[email protected]71f65dd2009-02-11 19:14:56826template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29827NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]71f65dd2009-02-11 19:14:56828 NavigationController* tab, IPC::Message* reply_message,
829 NavigationCodeType success_code,
830 NavigationCodeType auth_needed_code,
831 NavigationCodeType failed_code) {
initial.commit09911bf2008-07-26 23:55:29832 NotificationObserver* observer =
[email protected]71f65dd2009-02-11 19:14:56833 new NavigationNotificationObserver<NavigationCodeType>(
834 tab, this, reply_message, success_code, auth_needed_code,
835 failed_code);
initial.commit09911bf2008-07-26 23:55:29836
[email protected]71f65dd2009-02-11 19:14:56837 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29838 return observer;
839}
840
841void AutomationProvider::RemoveNavigationStatusListener(
842 NotificationObserver* obs) {
843 notification_observer_list_.RemoveObserver(obs);
844}
845
846NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]71f65dd2009-02-11 19:14:56847 Browser* parent, int32 routing_id, IPC::Message* reply_message) {
848 NotificationObserver* observer =
849 new TabAppendedNotificationObserver(parent, this, routing_id,
850 reply_message);
initial.commit09911bf2008-07-26 23:55:29851 notification_observer_list_.AddObserver(observer);
852
853 return observer;
854}
855
856void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
857 notification_observer_list_.RemoveObserver(obs);
858}
859
860void AutomationProvider::AddLoginHandler(NavigationController* tab,
861 LoginHandler* handler) {
862 login_handler_map_[tab] = handler;
863}
864
865void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
866 DCHECK(login_handler_map_[tab]);
867 login_handler_map_.erase(tab);
868}
869
870int AutomationProvider::GetIndexForNavigationController(
871 const NavigationController* controller, const Browser* parent) const {
872 DCHECK(parent);
873 return parent->GetIndexOfController(controller);
874}
875
876void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
877 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]71f65dd2009-02-11 19:14:56878 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser,
879 CloseBrowser)
880 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
881 CloseBrowserAsync)
882 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
883 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
884 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
885 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
886 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
887 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
888 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL,
889 NavigateToURL)
890 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
891 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
892 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
893 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
894 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
895 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth,
896 CancelAuth)
897 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
898 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
899 GetRedirectsFrom)
900 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount,
initial.commit09911bf2008-07-26 23:55:29901 GetBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56902 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
903 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29904 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56905 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
906 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
initial.commit09911bf2008-07-26 23:55:29907 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow);
[email protected]de246f52009-02-25 18:25:45908#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56909 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWND, GetWindowHWND)
[email protected]de246f52009-02-25 18:25:45910#endif // defined(OS_WIN)
[email protected]49a14a82009-03-31 04:16:44911 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33912 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44913 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33914 ExecuteBrowserCommand)
[email protected]71f65dd2009-02-11 19:14:56915 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds,
initial.commit09911bf2008-07-26 23:55:29916 WindowGetViewBounds)
[email protected]71f65dd2009-02-11 19:14:56917 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible,
918 SetWindowVisible)
[email protected]de246f52009-02-25 18:25:45919#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56920 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
921 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress,
initial.commit09911bf2008-07-26 23:55:29922 WindowSimulateKeyPress)
[email protected]71f65dd2009-02-11 19:14:56923 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
924 WindowSimulateDrag)
[email protected]d7fa7552009-03-20 21:06:37925#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56926 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
927 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37928#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56929 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45930#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56931 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
932 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
933 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
934 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility,
initial.commit09911bf2008-07-26 23:55:29935 GetShelfVisibility)
936 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]71f65dd2009-02-11 19:14:56937 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator,
938 ApplyAccelerator)
939 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
940 ExecuteJavascript)
941 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29942 GetConstrainedWindowCount)
[email protected]71f65dd2009-02-11 19:14:56943 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindow,
initial.commit09911bf2008-07-26 23:55:29944 GetConstrainedWindow)
[email protected]71f65dd2009-02-11 19:14:56945 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedTitle,
initial.commit09911bf2008-07-26 23:55:29946 GetConstrainedTitle)
[email protected]71f65dd2009-02-11 19:14:56947 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage,
initial.commit09911bf2008-07-26 23:55:29948 HandleFindInPageRequest)
[email protected]71f65dd2009-02-11 19:14:56949 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID,
950 GetFocusedViewID)
951 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
952 HandleInspectElementRequest)
initial.commit09911bf2008-07-26 23:55:29953 IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet,
954 SetFilteredInet);
[email protected]71f65dd2009-02-11 19:14:56955 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory,
initial.commit09911bf2008-07-26 23:55:29956 GetDownloadDirectory);
[email protected]14c0a032009-04-13 18:15:14957 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
958 OpenNewBrowserWindow);
[email protected]71f65dd2009-02-11 19:14:56959 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser,
initial.commit09911bf2008-07-26 23:55:29960 GetWindowForBrowser);
[email protected]71f65dd2009-02-11 19:14:56961 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
initial.commit09911bf2008-07-26 23:55:29962 GetAutocompleteEditForBrowser);
[email protected]71f65dd2009-02-11 19:14:56963 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow,
initial.commit09911bf2008-07-26 23:55:29964 GetBrowserForWindow);
[email protected]de246f52009-02-25 18:25:45965#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29966 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]71f65dd2009-02-11 19:14:56967 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:29968 NavigateInExternalTab)
[email protected]71f65dd2009-02-11 19:14:56969 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
970 ShowInterstitialPage);
971 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
initial.commit09911bf2008-07-26 23:55:29972 HideInterstitialPage);
973 IPC_MESSAGE_HANDLER(AutomationMsg_SetAcceleratorsForTab,
974 SetAcceleratorsForTab)
975 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
976 ProcessUnhandledAccelerator)
[email protected]71f65dd2009-02-11 19:14:56977 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
978 WaitForTabToBeRestored)
[email protected]b9d227492009-02-10 15:20:27979 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus,
980 SetInitialFocus)
[email protected]87eab222009-03-13 00:47:45981 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]de246f52009-02-25 18:25:45982#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29983 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState,
984 GetSecurityState)
985 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType,
986 GetPageType)
[email protected]71f65dd2009-02-11 19:14:56987 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
988 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:29989 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
990 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
991 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:56992 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
993 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
994 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:29995 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56996 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:29997 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:56998 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:29999 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:561000 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:291001 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:561002 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowBounds,
initial.commit09911bf2008-07-26 23:55:291003 GetConstrainedWindowBounds)
[email protected]71f65dd2009-02-11 19:14:561004 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:451005 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:451006 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
1007 OnMessageFromExternalHost)
[email protected]71f65dd2009-02-11 19:14:561008 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find,
1009 HandleFindRequest)
1010 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:571011 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:561012 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:571013 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:561014 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
1015 GetBookmarkBarVisibility)
1016 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCount,
[email protected]8a3422c92008-09-24 17:42:421017 GetSSLInfoBarCount)
[email protected]71f65dd2009-02-11 19:14:561018 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickSSLInfoBarLink,
1019 ClickSSLInfoBarLink)
1020 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:421021 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:561022 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
1023 WaitForNavigation)
1024 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference,
[email protected]8a3422c92008-09-24 17:42:421025 SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:561026 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:441027 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:561028 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:201029 ClickAppModalDialogButton)
[email protected]71f65dd2009-02-11 19:14:561030 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference,
[email protected]97fa6ce32008-12-19 01:48:161031 SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:561032 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161033 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561034 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161035 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561036 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:161037 GetPageCurrentEncoding)
[email protected]71f65dd2009-02-11 19:14:561038 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding,
[email protected]97fa6ce32008-12-19 01:48:161039 OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:201040 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
1041 SavePackageShouldPromptUser)
[email protected]3753f522009-04-14 23:15:471042 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle,
1043 GetWindowTitle)
initial.commit09911bf2008-07-26 23:55:291044 IPC_END_MESSAGE_MAP()
1045}
1046
[email protected]71f65dd2009-02-11 19:14:561047void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
1048 *status = -1;
initial.commit09911bf2008-07-26 23:55:291049 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
1050 Browser* browser = browser_tracker_->GetResource(handle);
1051 if (at_index >= 0 && at_index < browser->tab_count()) {
1052 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:561053 *status = 0;
initial.commit09911bf2008-07-26 23:55:291054 }
1055 }
initial.commit09911bf2008-07-26 23:55:291056}
1057
[email protected]71f65dd2009-02-11 19:14:561058void AutomationProvider::AppendTab(int handle, const GURL& url,
1059 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291060 int append_tab_response = -1; // -1 is the error code
1061 NotificationObserver* observer = NULL;
1062
1063 if (browser_tracker_->ContainsHandle(handle)) {
1064 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561065 observer = AddTabStripObserver(browser, reply_message->routing_id(),
1066 reply_message);
[email protected]22735af62009-04-07 21:09:581067 TabContents* tab_contents = browser->AddTabWithURL(url, GURL(),
1068 PageTransition::TYPED,
1069 true, -1, NULL);
initial.commit09911bf2008-07-26 23:55:291070 if (tab_contents) {
1071 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:571072 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:291073 }
1074 }
1075
1076 if (append_tab_response < 0) {
1077 // The append tab failed. Remove the TabStripObserver
1078 if (observer) {
1079 RemoveTabStripObserver(observer);
1080 delete observer;
1081 }
1082
[email protected]71f65dd2009-02-11 19:14:561083 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
1084 append_tab_response);
1085 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291086 }
1087}
1088
[email protected]71f65dd2009-02-11 19:14:561089void AutomationProvider::NavigateToURL(int handle, const GURL& url,
1090 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291091 if (tab_tracker_->ContainsHandle(handle)) {
1092 NavigationController* tab = tab_tracker_->GetResource(handle);
1093
1094 // Simulate what a user would do. Activate the tab and then navigate.
1095 // We could allow navigating in a background tab in future.
1096 Browser* browser = FindAndActivateTab(tab);
1097
1098 if (browser) {
[email protected]71f65dd2009-02-11 19:14:561099 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1100 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1101 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1102 AUTOMATION_MSG_NAVIGATION_ERROR);
1103
initial.commit09911bf2008-07-26 23:55:291104 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:501105 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:291106 return;
1107 }
1108 }
[email protected]71f65dd2009-02-11 19:14:561109
1110 AutomationMsg_NavigateToURL::WriteReplyParams(
1111 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1112 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291113}
1114
[email protected]71f65dd2009-02-11 19:14:561115void AutomationProvider::NavigationAsync(int handle, const GURL& url,
1116 bool* status) {
1117 *status = false;
initial.commit09911bf2008-07-26 23:55:291118
1119 if (tab_tracker_->ContainsHandle(handle)) {
1120 NavigationController* tab = tab_tracker_->GetResource(handle);
1121
1122 // Simulate what a user would do. Activate the tab and then navigate.
1123 // We could allow navigating in a background tab in future.
1124 Browser* browser = FindAndActivateTab(tab);
1125
1126 if (browser) {
1127 // Don't add any listener unless a callback mechanism is desired.
1128 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:501129 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:561130 *status = true;
initial.commit09911bf2008-07-26 23:55:291131 }
1132 }
initial.commit09911bf2008-07-26 23:55:291133}
1134
[email protected]71f65dd2009-02-11 19:14:561135void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291136 if (tab_tracker_->ContainsHandle(handle)) {
1137 NavigationController* tab = tab_tracker_->GetResource(handle);
1138 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141139 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]71f65dd2009-02-11 19:14:561140 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1141 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1142 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1143 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291144 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291145 return;
1146 }
1147 }
[email protected]71f65dd2009-02-11 19:14:561148
1149 AutomationMsg_GoBack::WriteReplyParams(
1150 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1151 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291152}
1153
[email protected]71f65dd2009-02-11 19:14:561154void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291155 if (tab_tracker_->ContainsHandle(handle)) {
1156 NavigationController* tab = tab_tracker_->GetResource(handle);
1157 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141158 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]71f65dd2009-02-11 19:14:561159 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1160 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1161 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1162 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291163 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291164 return;
1165 }
1166 }
[email protected]71f65dd2009-02-11 19:14:561167
1168 AutomationMsg_GoForward::WriteReplyParams(
1169 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1170 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291171}
1172
[email protected]71f65dd2009-02-11 19:14:561173void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291174 if (tab_tracker_->ContainsHandle(handle)) {
1175 NavigationController* tab = tab_tracker_->GetResource(handle);
1176 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141177 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]71f65dd2009-02-11 19:14:561178 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1179 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1180 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1181 AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:291182 browser->Reload();
1183 return;
1184 }
1185 }
[email protected]71f65dd2009-02-11 19:14:561186
1187 AutomationMsg_Reload::WriteReplyParams(
1188 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1189 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291190}
1191
[email protected]71f65dd2009-02-11 19:14:561192void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:291193 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:561194 const std::wstring& password,
1195 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291196 int status = -1;
1197
1198 if (tab_tracker_->ContainsHandle(tab_handle)) {
1199 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1200 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1201
1202 if (iter != login_handler_map_.end()) {
1203 // If auth is needed again after this, assume login has failed. This is
1204 // not strictly correct, because a navigation can require both proxy and
1205 // server auth, but it should be OK for now.
1206 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561207 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291208 handler->SetAuth(username, password);
1209 status = 0;
1210 }
1211 }
[email protected]de246f52009-02-25 18:25:451212
initial.commit09911bf2008-07-26 23:55:291213 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561214 AutomationMsg_SetAuth::WriteReplyParams(reply_message, status);
1215 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291216 }
1217}
1218
[email protected]71f65dd2009-02-11 19:14:561219void AutomationProvider::CancelAuth(int tab_handle,
1220 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291221 int status = -1;
1222
1223 if (tab_tracker_->ContainsHandle(tab_handle)) {
1224 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1225 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1226
1227 if (iter != login_handler_map_.end()) {
1228 // If auth is needed again after this, something is screwy.
1229 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561230 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291231 handler->CancelAuth();
1232 status = 0;
1233 }
1234 }
[email protected]de246f52009-02-25 18:25:451235
initial.commit09911bf2008-07-26 23:55:291236 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561237 AutomationMsg_CancelAuth::WriteReplyParams(reply_message, status);
1238 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291239 }
1240}
1241
[email protected]71f65dd2009-02-11 19:14:561242void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
1243 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:291244
1245 if (tab_tracker_->ContainsHandle(tab_handle)) {
1246 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1247 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1248
1249 if (iter != login_handler_map_.end()) {
1250 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:561251 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:291252 }
1253 }
initial.commit09911bf2008-07-26 23:55:291254}
1255
[email protected]71f65dd2009-02-11 19:14:561256void AutomationProvider::GetRedirectsFrom(int tab_handle,
1257 const GURL& source_url,
1258 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291259 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1260 if (tab_tracker_->ContainsHandle(tab_handle)) {
1261 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1262 HistoryService* history_service =
1263 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1264
1265 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1266 "has no history service";
1267 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:561268 DCHECK(reply_message_ == NULL);
1269 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291270 // Schedule a history query for redirects. The response will be sent
1271 // asynchronously from the callback the history system uses to notify us
1272 // that it's done: OnRedirectQueryComplete.
[email protected]71f65dd2009-02-11 19:14:561273 redirect_query_routing_id_ = reply_message->routing_id();
initial.commit09911bf2008-07-26 23:55:291274 redirect_query_ = history_service->QueryRedirectsFrom(
1275 source_url, &consumer_,
1276 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1277 return; // Response will be sent when query completes.
1278 }
1279 }
1280
1281 // Send failure response.
[email protected]deb57402009-02-06 01:35:301282 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:561283 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
1284 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291285}
1286
[email protected]71f65dd2009-02-11 19:14:561287void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
1288 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291289 if (browser_tracker_->ContainsHandle(handle)) {
1290 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561291 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:291292 }
initial.commit09911bf2008-07-26 23:55:291293}
1294
[email protected]71f65dd2009-02-11 19:14:561295void AutomationProvider::GetBrowserWindowCount(int* window_count) {
1296 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:291297}
1298
[email protected]de246f52009-02-25 18:25:451299#if defined(OS_WIN)
[email protected]464146e2009-04-09 18:17:091300// TODO(port): Move the views::DialogDelegate::DialogButton enum out into a
1301// common place then remove the OS_WIN guard.
[email protected]71f65dd2009-02-11 19:14:561302void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1303 int* dialog_button) {
[email protected]0bfa713f2009-04-07 20:18:281304 AppModalDialog* dialog_delegate = AppModalDialogQueue::active_dialog();
[email protected]b3a70332009-02-25 02:40:501305 *showing_dialog = (dialog_delegate != NULL);
1306 if (*showing_dialog)
1307 *dialog_button = dialog_delegate->GetDialogButtons();
1308 else
1309 *dialog_button = views::DialogDelegate::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:201310}
1311
[email protected]71f65dd2009-02-11 19:14:561312void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
1313 *success = false;
[email protected]fad84eab2008-12-05 00:37:201314
[email protected]0bfa713f2009-04-07 20:18:281315 AppModalDialog* dialog_delegate = AppModalDialogQueue::active_dialog();
[email protected]b3a70332009-02-25 02:40:501316 if (dialog_delegate &&
1317 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]fad84eab2008-12-05 00:37:201318 if ((button & views::DialogDelegate::DIALOGBUTTON_OK) ==
1319 views::DialogDelegate::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:281320 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:561321 *success = true;
[email protected]fad84eab2008-12-05 00:37:201322 }
1323 if ((button & views::DialogDelegate::DIALOGBUTTON_CANCEL) ==
1324 views::DialogDelegate::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:561325 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:281326 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:561327 *success = true;
[email protected]fad84eab2008-12-05 00:37:201328 }
1329 }
[email protected]c274acc2008-11-11 20:13:441330}
[email protected]de246f52009-02-25 18:25:451331#endif
[email protected]c274acc2008-11-11 20:13:441332
[email protected]71f65dd2009-02-11 19:14:561333void AutomationProvider::GetBrowserWindow(int index, int* handle) {
1334 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291335 if (index >= 0) {
1336 BrowserList::const_iterator iter = BrowserList::begin();
1337
1338 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
1339 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:561340 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:291341 }
1342 }
initial.commit09911bf2008-07-26 23:55:291343}
1344
[email protected]71f65dd2009-02-11 19:14:561345void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
1346 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291347 Browser* browser = BrowserList::GetLastActive();
1348 if (browser)
[email protected]71f65dd2009-02-11 19:14:561349 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:291350}
1351
[email protected]de246f52009-02-25 18:25:451352#if defined(OS_WIN)
1353// TODO(port): Remove windowsisms.
initial.commit09911bf2008-07-26 23:55:291354BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1355 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1356 return FALSE;
1357 }
1358 return TRUE;
1359}
1360
[email protected]71f65dd2009-02-11 19:14:561361void AutomationProvider::GetActiveWindow(int* handle) {
initial.commit09911bf2008-07-26 23:55:291362 HWND window = GetForegroundWindow();
1363
1364 // Let's make sure this window belongs to our process.
1365 if (EnumThreadWindows(::GetCurrentThreadId(),
1366 EnumThreadWndProc,
1367 reinterpret_cast<LPARAM>(window))) {
1368 // We enumerated all the windows and did not find the foreground window,
1369 // it is not our window, ignore it.
[email protected]71f65dd2009-02-11 19:14:561370 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291371 return;
1372 }
1373
[email protected]71f65dd2009-02-11 19:14:561374 *handle = window_tracker_->Add(window);
initial.commit09911bf2008-07-26 23:55:291375}
1376
[email protected]71f65dd2009-02-11 19:14:561377void AutomationProvider::GetWindowHWND(int handle, HWND* win32_handle) {
1378 *win32_handle = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291379}
[email protected]de246f52009-02-25 18:25:451380#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291381
[email protected]4f6381ee2009-04-16 02:46:331382void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
1383 bool* success) {
[email protected]71f65dd2009-02-11 19:14:561384 *success = false;
[email protected]4ae62752008-08-04 23:28:471385 if (browser_tracker_->ContainsHandle(handle)) {
1386 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141387 if (browser->command_updater()->SupportsCommand(command) &&
1388 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471389 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:561390 *success = true;
[email protected]4ae62752008-08-04 23:28:471391 }
1392 }
[email protected]4ae62752008-08-04 23:28:471393}
1394
[email protected]4f6381ee2009-04-16 02:46:331395void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:561396 int handle, int command, IPC::Message* reply_message) {
1397 if (browser_tracker_->ContainsHandle(handle)) {
1398 Browser* browser = browser_tracker_->GetResource(handle);
1399 if (browser->command_updater()->SupportsCommand(command) &&
1400 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4e41709d2009-04-08 00:04:271401 ExecuteBrowserCommandObserver* observer =
1402 new ExecuteBrowserCommandObserver(this, reply_message);
1403 if (observer->Register(command))
1404 browser->ExecuteCommand(command);
1405 else
1406 delete observer;
[email protected]56e71b7c2009-03-27 03:05:561407 return;
1408 }
1409 }
[email protected]49a14a82009-03-31 04:16:441410 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:561411 Send(reply_message);
1412}
1413
[email protected]71f65dd2009-02-11 19:14:561414void AutomationProvider::WindowGetViewBounds(int handle, int view_id,
1415 bool screen_coordinates,
1416 bool* success,
1417 gfx::Rect* bounds) {
1418 *success = false;
initial.commit09911bf2008-07-26 23:55:291419
[email protected]de246f52009-02-25 18:25:451420#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291421 void* iter = NULL;
1422 if (window_tracker_->ContainsHandle(handle)) {
1423 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201424 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291425 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381426 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291427 if (view) {
[email protected]71f65dd2009-02-11 19:14:561428 *success = true;
[email protected]96b667d2008-10-14 20:58:441429 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291430 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381431 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291432 else
[email protected]c2dacc92008-10-16 23:51:381433 views::View::ConvertPointToView(view, root_view, &point);
[email protected]71f65dd2009-02-11 19:14:561434 *bounds = view->GetLocalBounds(false);
1435 bounds->set_origin(point);
initial.commit09911bf2008-07-26 23:55:291436 }
1437 }
1438 }
[email protected]de246f52009-02-25 18:25:451439#else
1440 // TODO(port): Enable when window_tracker is ported.
1441 NOTIMPLEMENTED();
1442#endif
initial.commit09911bf2008-07-26 23:55:291443}
1444
[email protected]de246f52009-02-25 18:25:451445#if defined(OS_WIN)
1446// TODO(port): Use portable replacement for POINT.
1447
initial.commit09911bf2008-07-26 23:55:291448// This task enqueues a mouse event on the event loop, so that the view
1449// that it's being sent to can do the requisite post-processing.
1450class MouseEventTask : public Task {
1451 public:
[email protected]c2dacc92008-10-16 23:51:381452 MouseEventTask(views::View* view,
1453 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291454 POINT point,
1455 int flags)
1456 : view_(view), type_(type), point_(point), flags_(flags) {}
1457 virtual ~MouseEventTask() {}
1458
1459 virtual void Run() {
[email protected]c2dacc92008-10-16 23:51:381460 views::MouseEvent event(type_, point_.x, point_.y, flags_);
initial.commit09911bf2008-07-26 23:55:291461 // We need to set the cursor position before we process the event because
1462 // some code (tab dragging, for instance) queries the actual cursor location
1463 // rather than the location of the mouse event. Note that the reason why
1464 // the drag code moved away from using mouse event locations was because
1465 // our conversion to screen location doesn't work well with multiple
1466 // monitors, so this only works reliably in a single monitor setup.
[email protected]96b667d2008-10-14 20:58:441467 gfx::Point screen_location(point_.x, point_.y);
initial.commit09911bf2008-07-26 23:55:291468 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]96b667d2008-10-14 20:58:441469 ::SetCursorPos(screen_location.x(), screen_location.y());
initial.commit09911bf2008-07-26 23:55:291470 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381471 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291472 view_->OnMousePressed(event);
1473 break;
1474
[email protected]c2dacc92008-10-16 23:51:381475 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291476 view_->OnMouseDragged(event);
1477 break;
1478
[email protected]c2dacc92008-10-16 23:51:381479 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291480 view_->OnMouseReleased(event, false);
1481 break;
1482
1483 default:
1484 NOTREACHED();
1485 }
1486 }
1487
1488 private:
[email protected]c2dacc92008-10-16 23:51:381489 views::View* view_;
1490 views::Event::EventType type_;
initial.commit09911bf2008-07-26 23:55:291491 POINT point_;
1492 int flags_;
1493
[email protected]5a52f162008-08-27 04:15:311494 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291495};
1496
[email protected]c2dacc92008-10-16 23:51:381497void AutomationProvider::ScheduleMouseEvent(views::View* view,
1498 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291499 POINT point,
1500 int flags) {
1501 MessageLoop::current()->PostTask(FROM_HERE,
1502 new MouseEventTask(view, type, point, flags));
1503}
[email protected]de246f52009-02-25 18:25:451504#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291505
1506// This task just adds another task to the event queue. This is useful if
1507// you want to ensure that any tasks added to the event queue after this one
1508// have already been processed by the time |task| is run.
1509class InvokeTaskLaterTask : public Task {
1510 public:
1511 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1512 virtual ~InvokeTaskLaterTask() {}
1513
1514 virtual void Run() {
1515 MessageLoop::current()->PostTask(FROM_HERE, task_);
1516 }
1517
1518 private:
1519 Task* task_;
1520
[email protected]5a52f162008-08-27 04:15:311521 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291522};
1523
[email protected]de246f52009-02-25 18:25:451524#if defined(OS_WIN)
1525// TODO(port): Replace POINT and other windowsisms.
1526
initial.commit09911bf2008-07-26 23:55:291527// This task sends a WindowDragResponse message with the appropriate
1528// routing ID to the automation proxy. This is implemented as a task so that
1529// we know that the mouse events (and any tasks that they spawn on the message
1530// loop) have been processed by the time this is sent.
1531class WindowDragResponseTask : public Task {
1532 public:
[email protected]71f65dd2009-02-11 19:14:561533 WindowDragResponseTask(AutomationProvider* provider, int routing_id,
1534 IPC::Message* reply_message)
1535 : provider_(provider), routing_id_(routing_id),
1536 reply_message_(reply_message) {}
initial.commit09911bf2008-07-26 23:55:291537 virtual ~WindowDragResponseTask() {}
1538
1539 virtual void Run() {
[email protected]71f65dd2009-02-11 19:14:561540 DCHECK(reply_message_ != NULL);
1541 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
1542 provider_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291543 }
1544
1545 private:
1546 AutomationProvider* provider_;
1547 int routing_id_;
[email protected]71f65dd2009-02-11 19:14:561548 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:291549
[email protected]5a52f162008-08-27 04:15:311550 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291551};
1552
1553void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1554 int handle,
1555 POINT click,
1556 int flags) {
1557 HWND hwnd = 0;
1558
1559 if (window_tracker_->ContainsHandle(handle)) {
1560 hwnd = window_tracker_->GetResource(handle);
1561
initial.commit09911bf2008-07-26 23:55:291562 ui_controls::SendMouseMove(click.x, click.y);
1563
1564 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381565 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1566 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291567 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381568 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1569 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291570 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381571 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1572 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291573 button = ui_controls::MIDDLE;
1574 } else {
1575 NOTREACHED();
1576 }
1577 ui_controls::SendMouseClick(button);
1578 }
1579}
1580
[email protected]71f65dd2009-02-11 19:14:561581void AutomationProvider::WindowSimulateDrag(int handle,
[email protected]fe92e4e2008-11-18 21:31:321582 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441583 int flags,
[email protected]71f65dd2009-02-11 19:14:561584 bool press_escape_en_route,
1585 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291586 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321587 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1588 succeeded = true;
1589
1590 UINT down_message = 0;
1591 UINT up_message = 0;
1592 WPARAM wparam_flags = 0;
1593 if (flags & views::Event::EF_SHIFT_DOWN)
1594 wparam_flags |= MK_SHIFT;
1595 if (flags & views::Event::EF_CONTROL_DOWN)
1596 wparam_flags |= MK_CONTROL;
1597 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1598 wparam_flags |= MK_LBUTTON;
1599 down_message = WM_LBUTTONDOWN;
1600 up_message = WM_LBUTTONUP;
1601 }
1602 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1603 wparam_flags |= MK_MBUTTON;
1604 down_message = WM_MBUTTONDOWN;
1605 up_message = WM_MBUTTONUP;
1606 }
1607 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1608 wparam_flags |= MK_RBUTTON;
1609 down_message = WM_LBUTTONDOWN;
1610 up_message = WM_LBUTTONUP;
1611 }
1612
initial.commit09911bf2008-07-26 23:55:291613 Browser* browser = browser_tracker_->GetResource(handle);
1614 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551615 HWND top_level_hwnd =
1616 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321617 POINT temp = drag_path[0];
1618 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1619 SetCursorPos(temp.x, temp.y);
1620 SendMessage(top_level_hwnd, down_message, wparam_flags,
1621 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1622 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1623 temp = drag_path[i];
1624 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1625 SetCursorPos(temp.x, temp.y);
1626 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1627 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341628 }
[email protected]fe92e4e2008-11-18 21:31:321629 POINT end = drag_path[drag_path.size() - 1];
1630 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
1631 SetCursorPos(end.x, end.y);
1632
1633 if (press_escape_en_route) {
1634 // Press Escape.
1635 ui_controls::SendKeyPress(VK_ESCAPE,
1636 ((flags & views::Event::EF_CONTROL_DOWN)
1637 == views::Event::EF_CONTROL_DOWN),
1638 ((flags & views::Event::EF_SHIFT_DOWN) ==
1639 views::Event::EF_SHIFT_DOWN),
1640 ((flags & views::Event::EF_ALT_DOWN) ==
1641 views::Event::EF_ALT_DOWN));
1642 }
1643 SendMessage(top_level_hwnd, up_message, wparam_flags,
1644 MAKELPARAM(end.x, end.y));
1645
initial.commit09911bf2008-07-26 23:55:291646 MessageLoop::current()->PostTask(FROM_HERE,
1647 new InvokeTaskLaterTask(
[email protected]71f65dd2009-02-11 19:14:561648 new WindowDragResponseTask(this, reply_message->routing_id(),
1649 reply_message)));
initial.commit09911bf2008-07-26 23:55:291650 } else {
[email protected]71f65dd2009-02-11 19:14:561651 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, true);
1652 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291653 }
1654}
1655
1656void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1657 int handle,
1658 wchar_t key,
1659 int flags) {
1660 if (!window_tracker_->ContainsHandle(handle))
1661 return;
1662
1663 // The key event is sent to whatever window is active.
1664 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381665 ((flags & views::Event::EF_CONTROL_DOWN) ==
1666 views::Event::EF_CONTROL_DOWN),
1667 ((flags & views::Event::EF_SHIFT_DOWN) ==
1668 views::Event::EF_SHIFT_DOWN),
1669 ((flags & views::Event::EF_ALT_DOWN) ==
1670 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291671}
1672
[email protected]71f65dd2009-02-11 19:14:561673void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
1674 *view_id = -1;
initial.commit09911bf2008-07-26 23:55:291675 if (window_tracker_->ContainsHandle(handle)) {
1676 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381677 views::FocusManager* focus_manager =
1678 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:291679 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381680 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291681 if (focused_view)
[email protected]71f65dd2009-02-11 19:14:561682 *view_id = focused_view->GetID();
initial.commit09911bf2008-07-26 23:55:291683 }
initial.commit09911bf2008-07-26 23:55:291684}
1685
[email protected]71f65dd2009-02-11 19:14:561686void AutomationProvider::SetWindowVisible(int handle, bool visible,
1687 bool* result) {
initial.commit09911bf2008-07-26 23:55:291688 if (window_tracker_->ContainsHandle(handle)) {
1689 HWND hwnd = window_tracker_->GetResource(handle);
1690 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
[email protected]71f65dd2009-02-11 19:14:561691 *result = true;
initial.commit09911bf2008-07-26 23:55:291692 } else {
[email protected]71f65dd2009-02-11 19:14:561693 *result = false;
initial.commit09911bf2008-07-26 23:55:291694 }
1695}
1696
[email protected]71f65dd2009-02-11 19:14:561697void AutomationProvider::IsWindowActive(int handle, bool* success,
1698 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291699 if (window_tracker_->ContainsHandle(handle)) {
1700 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561701 *is_active = ::GetForegroundWindow() == hwnd;
1702 *success = true;
initial.commit09911bf2008-07-26 23:55:291703 } else {
[email protected]71f65dd2009-02-11 19:14:561704 *success = false;
1705 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291706 }
1707}
1708
[email protected]659d0e82009-02-13 22:43:281709void AutomationProvider::ActivateWindow(int handle) {
initial.commit09911bf2008-07-26 23:55:291710 if (window_tracker_->ContainsHandle(handle)) {
1711 ::SetActiveWindow(window_tracker_->GetResource(handle));
1712 }
1713}
[email protected]de246f52009-02-25 18:25:451714#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291715
[email protected]71f65dd2009-02-11 19:14:561716void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1717 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291718
1719 if (browser_tracker_->ContainsHandle(handle)) {
1720 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561721 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291722 }
initial.commit09911bf2008-07-26 23:55:291723}
1724
[email protected]71f65dd2009-02-11 19:14:561725void AutomationProvider::GetTab(int win_handle, int tab_index,
1726 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561727 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291728 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1729 Browser* browser = browser_tracker_->GetResource(win_handle);
1730 if (tab_index < browser->tab_count()) {
1731 TabContents* tab_contents =
1732 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571733 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291734 }
1735 }
initial.commit09911bf2008-07-26 23:55:291736}
1737
[email protected]71f65dd2009-02-11 19:14:561738void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1739 std::wstring* title) {
1740 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291741 if (tab_tracker_->ContainsHandle(handle)) {
1742 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]4c4d8d22009-03-04 05:29:271743 *title = UTF16ToWideHack(tab->GetActiveEntry()->title());
[email protected]71f65dd2009-02-11 19:14:561744 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291745 }
initial.commit09911bf2008-07-26 23:55:291746}
1747
1748void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1749 if (window_tracker_->ContainsHandle(handle)) {
1750 window_tracker_->Remove(window_tracker_->GetResource(handle));
1751 }
1752}
1753
1754void AutomationProvider::OnChannelError() {
1755 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571756 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291757}
1758
1759// TODO(brettw) change this to accept GURLs when history supports it
1760void AutomationProvider::OnRedirectQueryComplete(
1761 HistoryService::Handle request_handle,
1762 GURL from_url,
1763 bool success,
1764 HistoryService::RedirectList* redirects) {
1765 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561766 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291767
[email protected]deb57402009-02-06 01:35:301768 std::vector<GURL> redirects_gurl;
initial.commit09911bf2008-07-26 23:55:291769 if (success) {
[email protected]71f65dd2009-02-11 19:14:561770 reply_message_->WriteBool(true);
initial.commit09911bf2008-07-26 23:55:291771 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301772 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291773 } else {
[email protected]71f65dd2009-02-11 19:14:561774 reply_message_->WriteInt(-1); // Negative count indicates failure.
initial.commit09911bf2008-07-26 23:55:291775 }
1776
[email protected]4f3dc372009-02-24 00:10:291777 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301778
[email protected]71f65dd2009-02-11 19:14:561779 Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291780 redirect_query_ = NULL;
[email protected]71f65dd2009-02-11 19:14:561781 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291782}
1783
1784bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571785 DCHECK(channel_.get());
1786 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291787}
1788
1789Browser* AutomationProvider::FindAndActivateTab(
1790 NavigationController* controller) {
1791 int tab_index;
1792 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1793 if (browser)
1794 browser->SelectTabContentsAt(tab_index, true);
1795
1796 return browser;
1797}
1798
[email protected]71f65dd2009-02-11 19:14:561799void AutomationProvider::GetCookies(const GURL& url, int handle,
1800 int* value_size,
1801 std::string* value) {
1802 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291803 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1804 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561805 *value =
initial.commit09911bf2008-07-26 23:55:291806 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561807 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291808 }
initial.commit09911bf2008-07-26 23:55:291809}
1810
[email protected]71f65dd2009-02-11 19:14:561811void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291812 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561813 int handle,
1814 int* response_value) {
1815 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291816
1817 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1818 NavigationController* tab = tab_tracker_->GetResource(handle);
1819 URLRequestContext* context = tab->profile()->GetRequestContext();
1820 if (context->cookie_store()->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561821 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291822 }
initial.commit09911bf2008-07-26 23:55:291823}
1824
[email protected]71f65dd2009-02-11 19:14:561825void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1826 *success = false;
initial.commit09911bf2008-07-26 23:55:291827 if (tab_tracker_->ContainsHandle(handle)) {
1828 NavigationController* tab = tab_tracker_->GetResource(handle);
1829 // Return what the user would see in the location bar.
[email protected]71f65dd2009-02-11 19:14:561830 *url = tab->GetActiveEntry()->display_url();
1831 *success = true;
initial.commit09911bf2008-07-26 23:55:291832 }
initial.commit09911bf2008-07-26 23:55:291833}
1834
[email protected]de246f52009-02-25 18:25:451835#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561836void AutomationProvider::GetTabHWND(int handle, HWND* tab_hwnd) {
1837 *tab_hwnd = NULL;
initial.commit09911bf2008-07-26 23:55:291838
1839 if (tab_tracker_->ContainsHandle(handle)) {
1840 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111841 *tab_hwnd = tab->tab_contents()->GetNativeView();
initial.commit09911bf2008-07-26 23:55:291842 }
initial.commit09911bf2008-07-26 23:55:291843}
[email protected]de246f52009-02-25 18:25:451844#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291845
[email protected]71f65dd2009-02-11 19:14:561846void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1847 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291848
1849 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561850 *process_id = 0;
initial.commit09911bf2008-07-26 23:55:291851 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111852 if (tab->tab_contents()->AsWebContents()) {
1853 WebContents* web_contents = tab->tab_contents()->AsWebContents();
[email protected]2f15de42008-11-11 22:35:191854 if (web_contents->process())
[email protected]71f65dd2009-02-11 19:14:561855 *process_id = web_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291856 }
1857 }
initial.commit09911bf2008-07-26 23:55:291858}
1859
1860void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331861 NOTREACHED() << "This function has been deprecated. "
1862 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291863}
1864
[email protected]71f65dd2009-02-11 19:14:561865void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291866 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561867 const std::wstring& script,
1868 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291869 bool succeeded = false;
[email protected]20e93d12008-08-28 16:31:571870 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1871 if (web_contents) {
1872 // Set the routing id of this message with the controller.
1873 // This routing id needs to be remembered for the reverse
1874 // communication while sending back the response of
1875 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331876 std::wstring set_automation_id;
1877 SStringPrintf(&set_automation_id,
1878 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561879 reply_message->routing_id());
1880
1881 DCHECK(reply_message_ == NULL);
1882 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291883
[email protected]1f5af4442008-09-25 22:11:061884 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331885 frame_xpath, set_automation_id);
[email protected]1f5af4442008-09-25 22:11:061886 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1887 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571888 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291889 }
1890
1891 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561892 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1893 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291894 }
1895}
1896
[email protected]71f65dd2009-02-11 19:14:561897void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1898 *visible = false;
[email protected]20e93d12008-08-28 16:31:571899
1900 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1901 if (web_contents)
[email protected]71f65dd2009-02-11 19:14:561902 *visible = web_contents->IsDownloadShelfVisible();
initial.commit09911bf2008-07-26 23:55:291903}
1904
[email protected]71f65dd2009-02-11 19:14:561905void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1906 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291907 if (tab_tracker_->ContainsHandle(handle)) {
1908 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111909 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291910 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561911 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291912 }
1913 }
initial.commit09911bf2008-07-26 23:55:291914}
1915
[email protected]71f65dd2009-02-11 19:14:561916void AutomationProvider::GetConstrainedWindow(int handle, int index,
1917 int* cwindow_handle) {
1918 *cwindow_handle = 0;
initial.commit09911bf2008-07-26 23:55:291919 if (tab_tracker_->ContainsHandle(handle) && index >= 0) {
1920 NavigationController* nav_controller =
1921 tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111922 TabContents* tab = nav_controller->tab_contents();
[email protected]d5f942ba2008-09-26 19:30:341923 if (tab && index < static_cast<int>(tab->child_windows_.size())) {
[email protected]de246f52009-02-25 18:25:451924#if defined(OS_WIN)
[email protected]d5f942ba2008-09-26 19:30:341925 ConstrainedWindow* window = tab->child_windows_[index];
[email protected]71f65dd2009-02-11 19:14:561926 *cwindow_handle = cwindow_tracker_->Add(window);
[email protected]de246f52009-02-25 18:25:451927#else
1928 // TODO(port): Enable when cwindow_tracker is ported.
1929 NOTIMPLEMENTED();
1930#endif
initial.commit09911bf2008-07-26 23:55:291931 }
1932 }
initial.commit09911bf2008-07-26 23:55:291933}
1934
[email protected]71f65dd2009-02-11 19:14:561935void AutomationProvider::GetConstrainedTitle(int handle,
1936 int* title_string_size,
1937 std::wstring* title) {
1938 *title_string_size = -1; // -1 is the error code
[email protected]de246f52009-02-25 18:25:451939#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291940 if (cwindow_tracker_->ContainsHandle(handle)) {
1941 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561942 *title = window->GetWindowTitle();
1943 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291944 }
[email protected]de246f52009-02-25 18:25:451945#else
1946 // TODO(port): Enable when cwindow_tracker is ported.
1947 NOTIMPLEMENTED();
1948#endif
initial.commit09911bf2008-07-26 23:55:291949}
1950
[email protected]71f65dd2009-02-11 19:14:561951void AutomationProvider::GetConstrainedWindowBounds(int handle, bool* exists,
1952 gfx::Rect* rect) {
1953 *rect = gfx::Rect(0, 0, 0, 0);
[email protected]de246f52009-02-25 18:25:451954#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291955 if (cwindow_tracker_->ContainsHandle(handle)) {
1956 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1957 if (window) {
[email protected]71f65dd2009-02-11 19:14:561958 *exists = true;
1959 *rect = window->GetCurrentBounds();
initial.commit09911bf2008-07-26 23:55:291960 }
1961 }
[email protected]de246f52009-02-25 18:25:451962#else
1963 // TODO(port): Enable when cwindow_tracker is ported.
1964 NOTIMPLEMENTED();
1965#endif
initial.commit09911bf2008-07-26 23:55:291966}
1967
1968void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561969 int handle, const std::wstring& find_request,
1970 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311971 NOTREACHED() << "This function has been deprecated."
1972 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561973 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311974 return;
1975}
1976
[email protected]4f999132009-03-31 18:08:401977void AutomationProvider::HandleFindRequest(
1978 int handle,
1979 const AutomationMsg_Find_Params& params,
1980 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291981 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561982 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1983 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291984 return;
1985 }
1986
1987 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111988 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291989
1990 find_in_page_observer_.reset(new
[email protected]71f65dd2009-02-11 19:14:561991 FindInPageNotificationObserver(this, tab_contents,
1992 reply_message->routing_id(),
1993 reply_message));
initial.commit09911bf2008-07-26 23:55:291994
[email protected]9e0534b2008-10-21 15:03:011995 WebContents* web_contents = tab_contents->AsWebContents();
1996 if (web_contents) {
[email protected]4f3dc372009-02-24 00:10:291997 web_contents->set_current_find_request_id(
1998 FindInPageNotificationObserver::kFindInPageRequestId);
[email protected]9e0534b2008-10-21 15:03:011999 web_contents->render_view_host()->StartFinding(
2000 FindInPageNotificationObserver::kFindInPageRequestId,
[email protected]4f999132009-03-31 18:08:402001 params.search_string, params.forward, params.match_case,
2002 params.find_next);
[email protected]9e0534b2008-10-21 15:03:012003 }
initial.commit09911bf2008-07-26 23:55:292004}
2005
[email protected]5f8af2a2008-08-06 22:49:452006void AutomationProvider::HandleOpenFindInPageRequest(
2007 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:292008 if (browser_tracker_->ContainsHandle(handle)) {
[email protected]de246f52009-02-25 18:25:452009#if defined(OS_WIN)
[email protected]4f3dc372009-02-24 00:10:292010 Browser* browser = browser_tracker_->GetResource(handle);
2011 browser->FindInPage(false, false);
[email protected]de246f52009-02-25 18:25:452012#else
2013 // TODO(port): Enable when Browser::FindInPage is ported.
2014 NOTIMPLEMENTED();
2015#endif
[email protected]5f8af2a2008-08-06 22:49:452016 }
2017}
2018
[email protected]71f65dd2009-02-11 19:14:562019void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]9e0534b2008-10-21 15:03:012020 gfx::Point position;
[email protected]71f65dd2009-02-11 19:14:562021 *visible = false;
[email protected]4f3dc372009-02-24 00:10:292022 if (browser_tracker_->ContainsHandle(handle)) {
2023 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582024 FindBarTesting* find_bar =
2025 browser->find_bar()->find_bar()->GetFindBarTesting();
2026 find_bar->GetFindBarWindowInfo(&position, visible);
[email protected]4f3dc372009-02-24 00:10:292027 }
[email protected]20e93d12008-08-28 16:31:572028}
2029
[email protected]71f65dd2009-02-11 19:14:562030void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
2031 int* y) {
[email protected]9e0534b2008-10-21 15:03:012032 gfx::Point position(0, 0);
2033 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:292034 if (browser_tracker_->ContainsHandle(handle)) {
2035 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582036 FindBarTesting* find_bar =
2037 browser->find_bar()->find_bar()->GetFindBarTesting();
2038 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:292039 }
[email protected]20e93d12008-08-28 16:31:572040
[email protected]71f65dd2009-02-11 19:14:562041 *x = position.x();
2042 *y = position.y();
[email protected]20e93d12008-08-28 16:31:572043}
2044
[email protected]71f65dd2009-02-11 19:14:562045void AutomationProvider::GetBookmarkBarVisibility(int handle, bool* visible,
2046 bool* animating) {
2047 *visible = false;
2048 *animating = false;
[email protected]c2cbeb92008-09-05 21:36:572049
[email protected]de246f52009-02-25 18:25:452050#if defined(OS_WIN)
[email protected]c2cbeb92008-09-05 21:36:572051 if (browser_tracker_->ContainsHandle(handle)) {
2052 Browser* browser = browser_tracker_->GetResource(handle);
2053 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:522054 BrowserWindowTesting* testing =
2055 browser->window()->GetBrowserWindowTesting();
2056 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:572057 if (bookmark_bar) {
[email protected]71f65dd2009-02-11 19:14:562058 *animating = bookmark_bar->IsAnimating();
2059 *visible = browser->window()->IsBookmarkBarVisible();
[email protected]c2cbeb92008-09-05 21:36:572060 }
2061 }
2062 }
[email protected]de246f52009-02-25 18:25:452063#else
2064 // TODO(port): Enable when bookmarks ui is ported.
2065 NOTIMPLEMENTED();
2066#endif
[email protected]c2cbeb92008-09-05 21:36:572067}
2068
initial.commit09911bf2008-07-26 23:55:292069void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562070 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572071 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
2072 if (web_contents) {
[email protected]71f65dd2009-02-11 19:14:562073 DCHECK(reply_message_ == NULL);
2074 reply_message_ = reply_message;
2075
[email protected]1f5af4442008-09-25 22:11:062076 web_contents->render_view_host()->InspectElementAt(x, y);
[email protected]71f65dd2009-02-11 19:14:562077 inspect_element_routing_id_ = reply_message->routing_id();
initial.commit09911bf2008-07-26 23:55:292078 } else {
[email protected]71f65dd2009-02-11 19:14:562079 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2080 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292081 }
2082}
2083
2084void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092085 if (reply_message_) {
2086 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2087 num_resources);
2088 Send(reply_message_);
2089 reply_message_ = NULL;
2090 }
initial.commit09911bf2008-07-26 23:55:292091}
2092
2093// Helper class for making changes to the URLRequest ProtocolFactory on the
2094// IO thread.
2095class SetFilteredInetTask : public Task {
2096 public:
2097 explicit SetFilteredInetTask(bool enabled) : enabled_(enabled) { }
2098 virtual void Run() {
2099 if (enabled_) {
2100 URLRequestFilter::GetInstance()->ClearHandlers();
2101
2102 URLRequestFailedDnsJob::AddUITestUrls();
2103 URLRequestSlowDownloadJob::AddUITestUrls();
2104
2105 std::wstring root_http;
2106 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
2107 URLRequestMockHTTPJob::AddUITestUrls(root_http);
2108 } else {
2109 // Revert to the default handlers.
2110 URLRequestFilter::GetInstance()->ClearHandlers();
2111 }
2112 }
2113 private:
2114 bool enabled_;
2115};
2116
2117void AutomationProvider::SetFilteredInet(const IPC::Message& message,
2118 bool enabled) {
2119 // Since this involves changing the URLRequest ProtocolFactory, we want to
2120 // run on the main thread.
2121 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
2122 new SetFilteredInetTask(enabled));
2123}
2124
[email protected]4f3dc372009-02-24 00:10:292125void AutomationProvider::GetDownloadDirectory(
2126 int handle, std::wstring* download_directory) {
initial.commit09911bf2008-07-26 23:55:292127 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292128 if (tab_tracker_->ContainsHandle(handle)) {
2129 NavigationController* tab = tab_tracker_->GetResource(handle);
2130 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2131 DCHECK(dlm);
[email protected]71f65dd2009-02-11 19:14:562132 *download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:292133 }
initial.commit09911bf2008-07-26 23:55:292134}
2135
[email protected]14c0a032009-04-13 18:15:142136void AutomationProvider::OpenNewBrowserWindow(bool show,
2137 IPC::Message* reply_message) {
2138 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292139 // We may have no current browser windows open so don't rely on
2140 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:052141 Browser* browser = Browser::Create(profile_);
2142 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152143 if (show)
[email protected]15952e462008-11-14 00:29:052144 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292145}
2146
[email protected]71f65dd2009-02-11 19:14:562147void AutomationProvider::GetWindowForBrowser(int browser_handle,
2148 bool* success,
2149 int* handle) {
2150 *success = false;
2151 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292152
2153 if (browser_tracker_->ContainsHandle(browser_handle)) {
2154 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202155 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292156 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202157 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562158 *success = true;
initial.commit09911bf2008-07-26 23:55:292159 }
initial.commit09911bf2008-07-26 23:55:292160}
2161
[email protected]0e9f4ee2009-04-08 01:44:202162#if defined(OS_WIN)
2163// TODO(port): Remove windowsisms.
initial.commit09911bf2008-07-26 23:55:292164void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562165 int browser_handle,
2166 bool* success,
2167 int* autocomplete_edit_handle) {
2168 *success = false;
2169 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292170
2171 if (browser_tracker_->ContainsHandle(browser_handle)) {
2172 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]7745b822009-01-27 20:15:352173 BrowserWindowTesting* testing_interface =
2174 browser->window()->GetBrowserWindowTesting();
2175 LocationBarView* loc_bar_view = testing_interface->GetLocationBarView();
[email protected]81c21222008-09-10 19:35:522176 AutocompleteEditView* edit_view = loc_bar_view->location_entry();
initial.commit09911bf2008-07-26 23:55:292177 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562178 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2179 *success = true;
initial.commit09911bf2008-07-26 23:55:292180 }
initial.commit09911bf2008-07-26 23:55:292181}
2182
[email protected]71f65dd2009-02-11 19:14:562183void AutomationProvider::GetBrowserForWindow(int window_handle,
2184 bool* success,
2185 int* browser_handle) {
2186 *success = false;
2187 *browser_handle = 0;
initial.commit09911bf2008-07-26 23:55:292188
2189 if (window_tracker_->ContainsHandle(window_handle)) {
2190 HWND window = window_tracker_->GetResource(window_handle);
2191 BrowserList::const_iterator iter = BrowserList::begin();
2192 Browser* browser = NULL;
2193 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:312194 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
2195 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:292196 browser = *iter;
2197 break;
2198 }
2199 }
2200 if (browser) {
2201 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562202 *browser_handle = browser_tracker_->Add(browser);
2203 *success = true;
initial.commit09911bf2008-07-26 23:55:292204 }
2205 }
initial.commit09911bf2008-07-26 23:55:292206}
[email protected]de246f52009-02-25 18:25:452207#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292208
[email protected]71f65dd2009-02-11 19:14:562209void AutomationProvider::ShowInterstitialPage(int tab_handle,
2210 const std::string& html_text,
2211 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292212 if (tab_tracker_->ContainsHandle(tab_handle)) {
2213 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112214 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402215
2216 AddNavigationStatusListener<bool>(controller, reply_message, true,
2217 false, false);
2218 WebContents* web_contents = tab_contents->AsWebContents();
2219 AutomationInterstitialPage* interstitial =
2220 new AutomationInterstitialPage(web_contents,
2221 GURL("about:interstitial"),
2222 html_text);
2223 interstitial->Show();
2224 return;
initial.commit09911bf2008-07-26 23:55:292225 }
[email protected]71f65dd2009-02-11 19:14:562226
2227 AutomationMsg_ShowInterstitialPage::WriteReplyParams(reply_message, false);
2228 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292229}
2230
[email protected]71f65dd2009-02-11 19:14:562231void AutomationProvider::HideInterstitialPage(int tab_handle,
2232 bool* success) {
2233 *success = false;
[email protected]20e93d12008-08-28 16:31:572234 WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
[email protected]a3a1d142008-12-19 00:42:302235 if (web_contents && web_contents->interstitial_page()) {
2236 web_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562237 *success = true;
initial.commit09911bf2008-07-26 23:55:292238 }
initial.commit09911bf2008-07-26 23:55:292239}
2240
[email protected]71f65dd2009-02-11 19:14:562241void AutomationProvider::CloseTab(int tab_handle,
2242 bool wait_until_closed,
2243 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292244 if (tab_tracker_->ContainsHandle(tab_handle)) {
2245 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2246 int index;
2247 Browser* browser = Browser::GetBrowserForController(controller, &index);
2248 DCHECK(browser);
[email protected]de246f52009-02-25 18:25:452249 new TabClosedNotificationObserver(browser, this,
2250 reply_message->routing_id(),
2251 wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112252 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452253 return;
initial.commit09911bf2008-07-26 23:55:292254 }
[email protected]de246f52009-02-25 18:25:452255
2256 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
initial.commit09911bf2008-07-26 23:55:292257}
2258
[email protected]71f65dd2009-02-11 19:14:562259void AutomationProvider::CloseBrowser(int browser_handle,
2260 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292261 if (browser_tracker_->ContainsHandle(browser_handle)) {
2262 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562263 new BrowserClosedNotificationObserver(browser, this,
2264 reply_message->routing_id(),
2265 reply_message);
[email protected]f3e99e32008-07-30 04:48:392266 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292267 } else {
2268 NOTREACHED();
2269 }
2270}
2271
[email protected]71f65dd2009-02-11 19:14:562272void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2273 if (browser_tracker_->ContainsHandle(browser_handle)) {
2274 Browser* browser = browser_tracker_->GetResource(browser_handle);
2275 browser->window()->Close();
2276 } else {
2277 NOTREACHED();
2278 }
2279}
2280
[email protected]de246f52009-02-25 18:25:452281#if defined(OS_WIN)
2282// TODO(port): Remove windowsisms.
[email protected]71f65dd2009-02-11 19:14:562283void AutomationProvider::CreateExternalTab(HWND parent,
[email protected]31fb110522009-01-28 21:50:392284 const gfx::Rect& dimensions,
[email protected]71f65dd2009-02-11 19:14:562285 unsigned int style,
2286 HWND* tab_container_window,
2287 int* tab_handle) {
2288 *tab_handle = 0;
2289 *tab_container_window = NULL;
initial.commit09911bf2008-07-26 23:55:292290 ExternalTabContainer *external_tab_container =
2291 new ExternalTabContainer(this);
[email protected]31fb110522009-01-28 21:50:392292 external_tab_container->Init(profile_, parent, dimensions, style);
initial.commit09911bf2008-07-26 23:55:292293 TabContents* tab_contents = external_tab_container->tab_contents();
2294 if (tab_contents) {
[email protected]ce3fa3c2009-04-20 19:55:572295 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
[email protected]71f65dd2009-02-11 19:14:562296 *tab_container_window = *external_tab_container;
[email protected]31fb110522009-01-28 21:50:392297 } else {
2298 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292299 }
initial.commit09911bf2008-07-26 23:55:292300}
2301
[email protected]71f65dd2009-02-11 19:14:562302void AutomationProvider::NavigateInExternalTab(
2303 int handle, const GURL& url,
2304 AutomationMsg_NavigationResponseValues* status) {
2305 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292306
2307 if (tab_tracker_->ContainsHandle(handle)) {
2308 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502309 tab->LoadURL(url, GURL(), PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562310 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292311 }
initial.commit09911bf2008-07-26 23:55:292312}
2313
[email protected]71f65dd2009-02-11 19:14:562314void AutomationProvider::SetAcceleratorsForTab(int handle,
initial.commit09911bf2008-07-26 23:55:292315 HACCEL accel_table,
[email protected]71f65dd2009-02-11 19:14:562316 int accel_entry_count,
2317 bool* status) {
2318 *status = false;
2319
[email protected]b9d227492009-02-10 15:20:272320 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2321 if (external_tab) {
2322 external_tab->SetAccelerators(accel_table, accel_entry_count);
[email protected]71f65dd2009-02-11 19:14:562323 *status = true;
initial.commit09911bf2008-07-26 23:55:292324 }
initial.commit09911bf2008-07-26 23:55:292325}
2326
2327void AutomationProvider::ProcessUnhandledAccelerator(
2328 const IPC::Message& message, int handle, const MSG& msg) {
[email protected]b9d227492009-02-10 15:20:272329 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2330 if (external_tab) {
2331 external_tab->ProcessUnhandledAccelerator(msg);
2332 }
2333 // This message expects no response.
2334}
2335
[email protected]71f65dd2009-02-11 19:14:562336void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2337 IPC::Message* reply_message) {
2338 if (tab_tracker_->ContainsHandle(tab_handle)) {
2339 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2340 restore_tracker_.reset(
2341 new NavigationControllerRestoredObserver(this, tab,
2342 reply_message->routing_id(),
2343 reply_message));
2344 }
2345}
2346
[email protected]b9d227492009-02-10 15:20:272347void AutomationProvider::SetInitialFocus(const IPC::Message& message,
2348 int handle, bool reverse) {
2349 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2350 if (external_tab) {
2351 external_tab->SetInitialFocus(reverse);
initial.commit09911bf2008-07-26 23:55:292352 }
2353 // This message expects no response.
2354}
2355
[email protected]71f65dd2009-02-11 19:14:562356void AutomationProvider::GetSecurityState(int handle, bool* success,
2357 SecurityStyle* security_style,
2358 int* ssl_cert_status,
2359 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292360 if (tab_tracker_->ContainsHandle(handle)) {
2361 NavigationController* tab = tab_tracker_->GetResource(handle);
2362 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562363 *success = true;
2364 *security_style = entry->ssl().security_style();
2365 *ssl_cert_status = entry->ssl().cert_status();
2366 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292367 } else {
[email protected]71f65dd2009-02-11 19:14:562368 *success = false;
2369 *security_style = SECURITY_STYLE_UNKNOWN;
2370 *ssl_cert_status = 0;
2371 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292372 }
2373}
2374
[email protected]71f65dd2009-02-11 19:14:562375void AutomationProvider::GetPageType(int handle, bool* success,
2376 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292377 if (tab_tracker_->ContainsHandle(handle)) {
2378 NavigationController* tab = tab_tracker_->GetResource(handle);
2379 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562380 *page_type = entry->page_type();
2381 *success = true;
initial.commit09911bf2008-07-26 23:55:292382 // In order to return the proper result when an interstitial is shown and
2383 // no navigation entry were created for it we need to ask the WebContents.
[email protected]71f65dd2009-02-11 19:14:562384 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]7f0005a2009-04-15 03:25:112385 tab->tab_contents()->AsWebContents() &&
2386 tab->tab_contents()->AsWebContents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562387 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292388 } else {
[email protected]71f65dd2009-02-11 19:14:562389 *success = false;
2390 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292391 }
2392}
2393
[email protected]71f65dd2009-02-11 19:14:562394void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2395 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292396 if (tab_tracker_->ContainsHandle(handle)) {
2397 NavigationController* tab = tab_tracker_->GetResource(handle);
2398 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072399 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402400 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472401 InterstitialPage* ssl_blocking_page =
[email protected]a3a1d142008-12-19 00:42:302402 InterstitialPage::GetInterstitialPage(tab_contents->AsWebContents());
initial.commit09911bf2008-07-26 23:55:292403 if (ssl_blocking_page) {
2404 if (proceed) {
[email protected]71f65dd2009-02-11 19:14:562405 AddNavigationStatusListener<bool>(tab, reply_message, true, true,
2406 false);
2407 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292408 return;
2409 }
2410 ssl_blocking_page->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562411 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2412 true);
2413 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292414 return;
2415 }
2416 }
2417 }
2418 // We failed.
[email protected]71f65dd2009-02-11 19:14:562419 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2420 false);
2421 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292422}
[email protected]de246f52009-02-25 18:25:452423#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292424
[email protected]71f65dd2009-02-11 19:14:562425void AutomationProvider::BringBrowserToFront(int browser_handle,
2426 bool* success) {
initial.commit09911bf2008-07-26 23:55:292427 if (browser_tracker_->ContainsHandle(browser_handle)) {
2428 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062429 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562430 *success = true;
initial.commit09911bf2008-07-26 23:55:292431 } else {
[email protected]71f65dd2009-02-11 19:14:562432 *success = false;
initial.commit09911bf2008-07-26 23:55:292433 }
2434}
2435
[email protected]71f65dd2009-02-11 19:14:562436void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2437 int message_num,
2438 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292439 if (browser_tracker_->ContainsHandle(browser_handle)) {
2440 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562441 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142442 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292443 } else {
[email protected]71f65dd2009-02-11 19:14:562444 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292445 }
2446}
2447
[email protected]de246f52009-02-25 18:25:452448#if defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472449// TODO(port): Enable this.
[email protected]71f65dd2009-02-11 19:14:562450void AutomationProvider::PrintNow(int tab_handle,
2451 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572452 NavigationController* tab = NULL;
2453 WebContents* web_contents = GetWebContentsForHandle(tab_handle, &tab);
2454 if (web_contents) {
initial.commit09911bf2008-07-26 23:55:292455 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572456 notification_observer_list_.AddObserver(
[email protected]71f65dd2009-02-11 19:14:562457 new DocumentPrintedNotificationObserver(this,
2458 reply_message->routing_id(),
2459 reply_message));
[email protected]20e93d12008-08-28 16:31:572460 if (web_contents->PrintNow())
2461 return;
initial.commit09911bf2008-07-26 23:55:292462 }
[email protected]71f65dd2009-02-11 19:14:562463 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2464 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292465}
[email protected]3753f522009-04-14 23:15:472466#endif
initial.commit09911bf2008-07-26 23:55:292467
[email protected]71f65dd2009-02-11 19:14:562468void AutomationProvider::SavePage(int tab_handle,
initial.commit09911bf2008-07-26 23:55:292469 const std::wstring& file_name,
2470 const std::wstring& dir_path,
[email protected]71f65dd2009-02-11 19:14:562471 int type,
2472 bool* success) {
initial.commit09911bf2008-07-26 23:55:292473 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562474 *success = false;
initial.commit09911bf2008-07-26 23:55:292475 return;
2476 }
2477
2478 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2479 Browser* browser = FindAndActivateTab(nav);
2480 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142481 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562482 *success = false;
initial.commit09911bf2008-07-26 23:55:292483 return;
2484 }
2485
initial.commit09911bf2008-07-26 23:55:292486 SavePackage::SavePackageType save_type =
2487 static_cast<SavePackage::SavePackageType>(type);
2488 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2489 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]965524b2009-04-04 21:32:402490 nav->tab_contents()->AsWebContents()->SavePage(
2491 file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292492
[email protected]71f65dd2009-02-11 19:14:562493 *success = true;
initial.commit09911bf2008-07-26 23:55:292494}
2495
[email protected]3753f522009-04-14 23:15:472496#if defined(OS_WIN)
2497// TODO(port): Enable these.
[email protected]71f65dd2009-02-11 19:14:562498void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2499 bool* success,
2500 std::wstring* text) {
2501 *success = false;
initial.commit09911bf2008-07-26 23:55:292502 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562503 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522504 GetText();
[email protected]71f65dd2009-02-11 19:14:562505 *success = true;
initial.commit09911bf2008-07-26 23:55:292506 }
initial.commit09911bf2008-07-26 23:55:292507}
2508
[email protected]71f65dd2009-02-11 19:14:562509void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2510 const std::wstring& text,
2511 bool* success) {
2512 *success = false;
initial.commit09911bf2008-07-26 23:55:292513 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522514 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2515 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562516 *success = true;
initial.commit09911bf2008-07-26 23:55:292517 }
initial.commit09911bf2008-07-26 23:55:292518}
2519
2520void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562521 int autocomplete_edit_handle,
2522 bool* success,
2523 std::vector<AutocompleteMatchData>* matches) {
2524 *success = false;
initial.commit09911bf2008-07-26 23:55:292525 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272526 const AutocompleteResult& result = autocomplete_edit_tracker_->
2527 GetResource(autocomplete_edit_handle)->model()->result();
2528 for (AutocompleteResult::const_iterator i = result.begin();
2529 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562530 matches->push_back(AutocompleteMatchData(*i));
2531 *success = true;
initial.commit09911bf2008-07-26 23:55:292532 }
initial.commit09911bf2008-07-26 23:55:292533}
2534
2535void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562536 int autocomplete_edit_handle,
2537 bool* success,
2538 bool* query_in_progress) {
2539 *success = false;
2540 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292541 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562542 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522543 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562544 *success = true;
initial.commit09911bf2008-07-26 23:55:292545 }
initial.commit09911bf2008-07-26 23:55:292546}
2547
[email protected]28790922009-03-09 19:48:372548void AutomationProvider::OnMessageFromExternalHost(int handle,
2549 const std::string& message,
2550 const std::string& origin,
2551 const std::string& target) {
[email protected]fa83e762008-08-15 21:41:392552 if (tab_tracker_->ContainsHandle(handle)) {
2553 NavigationController* tab = tab_tracker_->GetResource(handle);
2554 if (!tab) {
2555 NOTREACHED();
2556 return;
2557 }
[email protected]965524b2009-04-04 21:32:402558 TabContents* tab_contents = tab->tab_contents();
[email protected]fa83e762008-08-15 21:41:392559 if (!tab_contents) {
2560 NOTREACHED();
2561 return;
2562 }
2563
2564 WebContents* web_contents = tab_contents->AsWebContents();
2565 if (!web_contents) {
2566 NOTREACHED();
2567 return;
2568 }
2569
2570 RenderViewHost* view_host = web_contents->render_view_host();
2571 if (!view_host) {
2572 return;
2573 }
2574
[email protected]28790922009-03-09 19:48:372575 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392576 }
2577}
[email protected]5cc063692009-04-07 23:21:312578#endif // defined(OS_WIN)
[email protected]fa83e762008-08-15 21:41:392579
[email protected]20e93d12008-08-28 16:31:572580WebContents* AutomationProvider::GetWebContentsForHandle(
2581 int handle, NavigationController** tab) {
2582 WebContents* web_contents = NULL;
2583 if (tab_tracker_->ContainsHandle(handle)) {
2584 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112585 TabContents* tab_contents = nav_controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402586 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:572587 web_contents = tab_contents->AsWebContents();
2588 if (tab)
2589 *tab = nav_controller;
2590 }
2591 }
2592 return web_contents;
2593}
2594
[email protected]5cc063692009-04-07 23:21:312595#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272596ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
2597 if (tab_tracker_->ContainsHandle(handle)) {
2598 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]965524b2009-04-04 21:32:402599 return ExternalTabContainer::GetContainerForTab(
2600 tab->tab_contents()->GetNativeView());
[email protected]b9d227492009-02-10 15:20:272601 }
2602
2603 return NULL;
2604}
[email protected]de246f52009-02-25 18:25:452605#endif // defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272606
initial.commit09911bf2008-07-26 23:55:292607TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2608 : AutomationProvider(profile) {
2609 BrowserList::AddObserver(this);
[email protected]bfd04a62009-02-01 18:16:562610 NotificationService::current()->AddObserver(
2611 this,
2612 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292613 NotificationService::AllSources());
2614}
2615
2616TestingAutomationProvider::~TestingAutomationProvider() {
[email protected]bfd04a62009-02-01 18:16:562617 NotificationService::current()->RemoveObserver(
2618 this,
2619 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292620 NotificationService::AllSources());
2621 BrowserList::RemoveObserver(this);
2622}
2623
2624void TestingAutomationProvider::OnChannelError() {
2625 BrowserList::CloseAllBrowsers(true);
2626 AutomationProvider::OnChannelError();
2627}
2628
2629void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2630 // For backwards compatibility with the testing automation interface, we
2631 // want the automation provider (and hence the process) to go away when the
2632 // last browser goes away.
2633 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292634 // If you change this, update Observer for NotificationType::SESSION_END
2635 // below.
[email protected]295039bd2008-08-15 04:32:572636 MessageLoop::current()->PostTask(FROM_HERE,
2637 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292638 }
2639}
2640
2641void TestingAutomationProvider::Observe(NotificationType type,
2642 const NotificationSource& source,
2643 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562644 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292645 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2646 // before the task runs resulting in this object not being deleted. This
2647 // Release balance out the Release scheduled by OnBrowserRemoving.
2648 Release();
2649}
[email protected]295039bd2008-08-15 04:32:572650
2651void TestingAutomationProvider::OnRemoveProvider() {
2652 AutomationProviderList::GetInstance()->RemoveProvider(this);
2653}
[email protected]8a3422c92008-09-24 17:42:422654
[email protected]71f65dd2009-02-11 19:14:562655void AutomationProvider::GetSSLInfoBarCount(int handle, int* count) {
2656 *count = -1; // -1 means error.
[email protected]de246f52009-02-25 18:25:452657#if defined(OS_WIN)
[email protected]8a3422c92008-09-24 17:42:422658 if (tab_tracker_->ContainsHandle(handle)) {
2659 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342660 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112661 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422662 }
[email protected]de246f52009-02-25 18:25:452663#else
2664 // TODO(port): Enable when TabContents infobar related stuff is ported.
2665 NOTIMPLEMENTED();
2666#endif
[email protected]8a3422c92008-09-24 17:42:422667}
2668
[email protected]71f65dd2009-02-11 19:14:562669void AutomationProvider::ClickSSLInfoBarLink(int handle,
[email protected]8a3422c92008-09-24 17:42:422670 int info_bar_index,
[email protected]71f65dd2009-02-11 19:14:562671 bool wait_for_navigation,
2672 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422673 bool success = false;
[email protected]de246f52009-02-25 18:25:452674#if defined(OS_WIN)
[email protected]8a3422c92008-09-24 17:42:422675 if (tab_tracker_->ContainsHandle(handle)) {
2676 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2677 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112678 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422679 if (info_bar_index >= 0 && info_bar_index < count) {
2680 if (wait_for_navigation) {
[email protected]71f65dd2009-02-11 19:14:562681 AddNavigationStatusListener<bool>(nav_controller, reply_message,
2682 true, true, false);
[email protected]8a3422c92008-09-24 17:42:422683 }
[email protected]eb9ba192008-12-02 02:41:342684 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112685 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342686 info_bar_index);
2687 if (delegate->AsConfirmInfoBarDelegate())
2688 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422689 success = true;
2690 }
2691 }
[email protected]4f3dc372009-02-24 00:10:292692 }
[email protected]de246f52009-02-25 18:25:452693#else
2694 // TODO(port): Enable when TabContents infobar related stuff is ported.
2695 NOTIMPLEMENTED();
2696#endif
[email protected]8a3422c92008-09-24 17:42:422697 if (!wait_for_navigation || !success)
[email protected]71f65dd2009-02-11 19:14:562698 AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(reply_message,
2699 success);
[email protected]8a3422c92008-09-24 17:42:422700}
2701
[email protected]71f65dd2009-02-11 19:14:562702void AutomationProvider::GetLastNavigationTime(int handle,
2703 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422704 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562705 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422706}
2707
[email protected]71f65dd2009-02-11 19:14:562708void AutomationProvider::WaitForNavigation(int handle,
2709 int64 last_navigation_time,
2710 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422711 NavigationController* controller = NULL;
2712 if (tab_tracker_->ContainsHandle(handle))
2713 controller = tab_tracker_->GetResource(handle);
2714
2715 Time time = tab_tracker_->GetLastNavigationTime(handle);
2716 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562717 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
2718 controller != NULL);
[email protected]4f3dc372009-02-24 00:10:292719 return;
[email protected]8a3422c92008-09-24 17:42:422720 }
2721
[email protected]71f65dd2009-02-11 19:14:562722 AddNavigationStatusListener<bool>(controller, reply_message, true, true,
2723 false);
[email protected]8a3422c92008-09-24 17:42:422724}
2725
[email protected]71f65dd2009-02-11 19:14:562726void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162727 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562728 int value,
2729 bool* success) {
2730 *success = false;
[email protected]8a3422c92008-09-24 17:42:422731 if (browser_tracker_->ContainsHandle(handle)) {
2732 Browser* browser = browser_tracker_->GetResource(handle);
2733 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562734 *success = true;
[email protected]8a3422c92008-09-24 17:42:422735 }
[email protected]8a3422c92008-09-24 17:42:422736}
[email protected]97fa6ce32008-12-19 01:48:162737
[email protected]71f65dd2009-02-11 19:14:562738void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162739 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562740 const std::wstring& value,
2741 bool* success) {
2742 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162743 if (browser_tracker_->ContainsHandle(handle)) {
2744 Browser* browser = browser_tracker_->GetResource(handle);
2745 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562746 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162747 }
[email protected]97fa6ce32008-12-19 01:48:162748}
2749
[email protected]71f65dd2009-02-11 19:14:562750void AutomationProvider::GetBooleanPreference(int handle,
2751 const std::wstring& name,
2752 bool* success,
2753 bool* value) {
2754 *success = false;
2755 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162756 if (browser_tracker_->ContainsHandle(handle)) {
2757 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562758 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2759 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162760 }
[email protected]97fa6ce32008-12-19 01:48:162761}
2762
[email protected]71f65dd2009-02-11 19:14:562763void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162764 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562765 bool value,
2766 bool* success) {
2767 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162768 if (browser_tracker_->ContainsHandle(handle)) {
2769 Browser* browser = browser_tracker_->GetResource(handle);
2770 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562771 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162772 }
[email protected]97fa6ce32008-12-19 01:48:162773}
2774
2775// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562776void AutomationProvider::GetPageCurrentEncoding(
2777 int tab_handle, std::wstring* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162778 if (tab_tracker_->ContainsHandle(tab_handle)) {
2779 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2780 Browser* browser = FindAndActivateTab(nav);
2781 DCHECK(browser);
2782
[email protected]1fc025202009-01-20 23:03:142783 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:112784 TabContents* tab_contents = nav->tab_contents();
[email protected]71f65dd2009-02-11 19:14:562785 *current_encoding = tab_contents->AsWebContents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162786 }
2787 }
[email protected]97fa6ce32008-12-19 01:48:162788}
2789
2790// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562791void AutomationProvider::OverrideEncoding(int tab_handle,
2792 const std::wstring& encoding_name,
2793 bool* success) {
2794 *success = false;
[email protected]de246f52009-02-25 18:25:452795#if defined(OS_WIN)
[email protected]97fa6ce32008-12-19 01:48:162796 if (tab_tracker_->ContainsHandle(tab_handle)) {
2797 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2798 Browser* browser = FindAndActivateTab(nav);
2799 DCHECK(browser);
2800
[email protected]1fc025202009-01-20 23:03:142801 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:112802 TabContents* tab_contents = nav->tab_contents();
[email protected]97fa6ce32008-12-19 01:48:162803 int selected_encoding_id =
2804 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2805 if (selected_encoding_id) {
2806 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562807 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162808 }
2809 }
2810 }
[email protected]de246f52009-02-25 18:25:452811#else
2812 // TODO(port): Enable when encoding-related parts of Browser are ported.
2813 NOTIMPLEMENTED();
2814#endif
[email protected]97fa6ce32008-12-19 01:48:162815}
[email protected]5bcdb312009-01-07 21:43:202816
[email protected]4d434a1a2009-02-11 21:06:572817void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:202818 SavePackage::SetShouldPromptUser(should_prompt);
2819}
[email protected]87eab222009-03-13 00:47:452820
2821#ifdef OS_WIN
2822void AutomationProvider::OnTabReposition(
2823 int tab_handle, const IPC::Reposition_Params& params) {
2824 if (!tab_tracker_->ContainsHandle(tab_handle))
2825 return;
2826
2827 if (!IsWindow(params.window))
2828 return;
2829
2830 unsigned long process_id = 0;
2831 unsigned long thread_id = 0;
2832
2833 thread_id = GetWindowThreadProcessId(params.window, &process_id);
2834
2835 if (thread_id != GetCurrentThreadId()) {
2836 NOTREACHED();
2837 return;
2838 }
2839
[email protected]a9233d0f2009-04-20 05:39:332840 SetWindowPos(params.window, params.window_insert_after, params.left,
2841 params.top, params.width, params.height, params.flags);
2842
[email protected]a2c5a9892009-04-07 16:13:452843 if (params.set_parent) {
2844 if (IsWindow(params.parent_window)) {
2845 if (!SetParent(params.window, params.parent_window))
2846 DLOG(WARNING) << "SetParent failed. Error 0x%x" << GetLastError();
2847 }
2848 }
[email protected]87eab222009-03-13 00:47:452849}
[email protected]a2c5a9892009-04-07 16:13:452850
[email protected]87eab222009-03-13 00:47:452851#endif // defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472852
2853void AutomationProvider::GetWindowTitle(int handle, string16* text) {
2854 gfx::NativeWindow window = window_tracker_->GetResource(handle);
2855 text->assign(platform_util::GetWindowTitle(window));
2856}