blob: a613f7823668abd4d788a998dcf3bd5b96165e2f [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// 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
7#include "base/path_service.h"
[email protected]9e0534b2008-10-21 15:03:018#include "chrome/app/chrome_dll_resource.h"
[email protected]b6ad1cab2009-01-16 22:41:429#include "chrome/browser/app_modal_dialog_queue.h"
initial.commit09911bf2008-07-26 23:55:2910#include "chrome/browser/automation/automation_provider_list.h"
11#include "chrome/browser/automation/ui_controls.h"
12#include "chrome/browser/automation/url_request_failed_dns_job.h"
13#include "chrome/browser/automation/url_request_mock_http_job.h"
14#include "chrome/browser/automation/url_request_slow_download_job.h"
[email protected]f3e99e32008-07-30 04:48:3915#include "chrome/browser/browser_window.h"
[email protected]97fa6ce32008-12-19 01:48:1616#include "chrome/browser/character_encoding.h"
initial.commit09911bf2008-07-26 23:55:2917#include "chrome/browser/dom_operation_notification_details.h"
[email protected]cdaa8652008-09-13 02:48:5918#include "chrome/browser/download/download_manager.h"
[email protected]37936ee2008-09-14 01:09:5019#include "chrome/browser/download/save_package.h"
initial.commit09911bf2008-07-26 23:55:2920#include "chrome/browser/external_tab_container.h"
21#include "chrome/browser/find_notification_details.h"
22#include "chrome/browser/login_prompt.h"
initial.commit09911bf2008-07-26 23:55:2923#include "chrome/browser/printing/print_job.h"
[email protected]6524b5f92009-01-22 17:48:2524#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0325#include "chrome/browser/ssl/ssl_manager.h"
26#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]f3ec7742009-01-15 00:59:1627#include "chrome/browser/tab_contents/navigation_entry.h"
28#include "chrome/browser/tab_contents/web_contents.h"
29#include "chrome/browser/tab_contents/web_contents_view.h"
[email protected]c2cbeb92008-09-05 21:36:5730#include "chrome/browser/views/bookmark_bar_view.h"
[email protected]195442e2008-07-31 22:41:2831#include "chrome/browser/views/location_bar_view.h"
initial.commit09911bf2008-07-26 23:55:2932#include "chrome/common/chrome_paths.h"
[email protected]6a02963e2009-01-06 16:58:0333#include "chrome/common/notification_registrar.h"
[email protected]8a3422c92008-09-24 17:42:4234#include "chrome/common/pref_service.h"
initial.commit09911bf2008-07-26 23:55:2935#include "chrome/test/automation/automation_messages.h"
[email protected]fad84eab2008-12-05 00:37:2036#include "chrome/views/app_modal_dialog_delegate.h"
37#include "chrome/views/window.h"
initial.commit09911bf2008-07-26 23:55:2938#include "net/base/cookie_monster.h"
39#include "net/url_request/url_request_filter.h"
40
[email protected]e1acf6f2008-10-27 20:43:3341using base::Time;
42
initial.commit09911bf2008-07-26 23:55:2943class InitialLoadObserver : public NotificationObserver {
44 public:
45 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
46 : outstanding_tab_count_(tab_count),
47 automation_(automation) {
48 if (outstanding_tab_count_ > 0) {
49 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:5650 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:0351 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:5652 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:0353 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:2954 }
55 }
56
57 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:2958 }
59
60 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:0361 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:2962 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
63 }
64
initial.commit09911bf2008-07-26 23:55:2965 virtual void Observe(NotificationType type,
66 const NotificationSource& source,
67 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:5668 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:2969 if (outstanding_tab_count_ > loading_tabs_.size())
70 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:5671 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:2972 if (outstanding_tab_count_ > finished_tabs_.size()) {
73 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
74 finished_tabs_.insert(source.map_key());
75 if (outstanding_tab_count_ == finished_tabs_.size())
76 ConditionMet();
77 }
78 } else {
79 NOTREACHED();
80 }
81 }
82
83 private:
84 typedef std::set<uintptr_t> TabSet;
85
[email protected]6a02963e2009-01-06 16:58:0386 NotificationRegistrar registrar_;
87
initial.commit09911bf2008-07-26 23:55:2988 AutomationProvider* automation_;
89 size_t outstanding_tab_count_;
90 TabSet loading_tabs_;
91 TabSet finished_tabs_;
92};
93
94// Watches for NewTabUI page loads for performance timing purposes.
95class NewTabUILoadObserver : public NotificationObserver {
96 public:
97 explicit NewTabUILoadObserver(AutomationProvider* automation)
98 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:5699 NotificationService::current()->AddObserver(
100 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
101 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29102 }
103
104 ~NewTabUILoadObserver() {
105 Unregister();
106 }
107
108 void Unregister() {
[email protected]bfd04a62009-02-01 18:16:56109 NotificationService::current()->RemoveObserver(
110 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
111 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29112 }
113
114 virtual void Observe(NotificationType type,
115 const NotificationSource& source,
116 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56117 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29118 Details<int> load_time(details);
119 automation_->Send(
120 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
121 } else {
122 NOTREACHED();
123 }
124 }
125
126 private:
127 AutomationProvider* automation_;
128};
129
130class NavigationControllerRestoredObserver : public NotificationObserver {
131 public:
132 NavigationControllerRestoredObserver(AutomationProvider* automation,
133 NavigationController* controller,
134 int32 routing_id)
135 : automation_(automation),
136 controller_(controller),
137 routing_id_(routing_id) {
138 if (FinishedRestoring()) {
139 registered_ = false;
140 SendDone();
141 } else {
142 registered_ = true;
143 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56144 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29145 NotificationService::AllSources());
146 }
147 }
148
149 ~NavigationControllerRestoredObserver() {
150 if (registered_)
151 Unregister();
152 }
153
154 virtual void Observe(NotificationType type,
155 const NotificationSource& source,
156 const NotificationDetails& details) {
157 if (FinishedRestoring()) {
158 SendDone();
159 Unregister();
160 }
161 }
162
163 private:
164 void Unregister() {
165 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56166 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29167 NotificationService::AllSources());
168 registered_ = false;
169 }
170
171 bool FinishedRestoring() {
172 return (!controller_->needs_reload() && !controller_->GetPendingEntry() &&
[email protected]d5f942ba2008-09-26 19:30:34173 !controller_->active_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29174 }
175
176 void SendDone() {
177 automation_->Send(new AutomationMsg_TabFinishedRestoring(routing_id_));
178 }
179
180 bool registered_;
181 AutomationProvider* automation_;
182 NavigationController* controller_;
183 const int routing_id_;
184
[email protected]5a52f162008-08-27 04:15:31185 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29186};
187
initial.commit09911bf2008-07-26 23:55:29188class NavigationNotificationObserver : public NotificationObserver {
189 public:
190 NavigationNotificationObserver(NavigationController* controller,
191 AutomationProvider* automation,
192 IPC::Message* completed_response,
193 IPC::Message* auth_needed_response)
194 : automation_(automation),
195 completed_response_(completed_response),
196 auth_needed_response_(auth_needed_response),
197 controller_(controller),
198 navigation_started_(false) {
199 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56200 service->AddObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42201 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56202 service->AddObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29203 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56204 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29205 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56206 service->AddObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29207 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56208 service->AddObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29209 Source<NavigationController>(controller_));
210 }
211
212 ~NavigationNotificationObserver() {
213 if (completed_response_) delete completed_response_;
214 if (auth_needed_response_) delete auth_needed_response_;
215 Unregister();
216 }
217
218 void ConditionMet(IPC::Message** response) {
219 if (*response) {
220 automation_->Send(*response);
221 *response = NULL; // *response is deleted by Send.
222 }
[email protected]d5798082008-09-29 21:02:03223 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29224 delete this;
225 }
226
227 void Unregister() {
228 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56229 service->RemoveObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42230 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56231 service->RemoveObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29232 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56233 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29234 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56235 service->RemoveObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29236 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56237 service->RemoveObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29238 Source<NavigationController>(controller_));
239 }
240
241 virtual void Observe(NotificationType type,
242 const NotificationSource& source,
243 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42244 // We listen for 2 events to determine when the navigation started because:
245 // - when this is used by the WaitForNavigation method, we might be invoked
246 // afer the load has started (but not after the entry was committed, as
247 // WaitForNavigation compares times of the last navigation).
248 // - when this is used with a page requiring authentication, we will not get
[email protected]bfd04a62009-02-01 18:16:56249 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so we need the
250 // NotificationType::LOAD_START.
251 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
252 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29253 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56254 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29255 if (navigation_started_) {
256 navigation_started_ = false;
257 ConditionMet(&completed_response_);
258 }
[email protected]bfd04a62009-02-01 18:16:56259 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29260 // The LoginHandler for this tab is no longer valid.
261 automation_->RemoveLoginHandler(controller_);
262
263 // Treat this as if navigation started again, since load start/stop don't
264 // occur while authentication is ongoing.
265 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56266 } else if (type == NotificationType::AUTH_NEEDED) {
initial.commit09911bf2008-07-26 23:55:29267 if (navigation_started_) {
268 // Remember the login handler that wants authentication.
269 LoginHandler* handler =
270 Details<LoginNotificationDetails>(details)->handler();
271 automation_->AddLoginHandler(controller_, handler);
272
273 // Respond that authentication is needed.
274 navigation_started_ = false;
275 ConditionMet(&auth_needed_response_);
276 } else {
277 NOTREACHED();
278 }
279 } else {
280 NOTREACHED();
281 }
282 }
283
284 private:
285 AutomationProvider* automation_;
286 IPC::Message* completed_response_;
287 IPC::Message* auth_needed_response_;
288 NavigationController* controller_;
289 bool navigation_started_;
290};
291
292class TabStripNotificationObserver : public NotificationObserver {
293 public:
294 TabStripNotificationObserver(Browser* parent, NotificationType notification,
295 AutomationProvider* automation, int32 routing_id)
296 : automation_(automation),
297 notification_(notification),
298 parent_(parent),
299 routing_id_(routing_id) {
300 NotificationService::current()->
301 AddObserver(this, notification_, NotificationService::AllSources());
302 }
303
304 virtual ~TabStripNotificationObserver() {
305 Unregister();
306 }
307
308 void Unregister() {
309 NotificationService::current()->
310 RemoveObserver(this, notification_, NotificationService::AllSources());
311 }
312
313 virtual void Observe(NotificationType type,
314 const NotificationSource& source,
315 const NotificationDetails& details) {
316 if (type == notification_) {
317 ObserveTab(Source<NavigationController>(source).ptr());
318
319 // If verified, no need to observe anymore
320 automation_->RemoveTabStripObserver(this);
321 delete this;
322 } else {
323 NOTREACHED();
324 }
325 }
326
327 virtual void ObserveTab(NavigationController* controller) = 0;
328
329 protected:
330 AutomationProvider* automation_;
331 Browser* parent_;
332 NotificationType notification_;
333 int32 routing_id_;
334};
335
336class TabAppendedNotificationObserver : public TabStripNotificationObserver {
337 public:
338 TabAppendedNotificationObserver(Browser* parent,
339 AutomationProvider* automation, int32 routing_id)
[email protected]bfd04a62009-02-01 18:16:56340 : TabStripNotificationObserver(parent, NotificationType::TAB_PARENTED,
341 automation, routing_id) {
initial.commit09911bf2008-07-26 23:55:29342 }
343
344 virtual void ObserveTab(NavigationController* controller) {
345 int tab_index =
346 automation_->GetIndexForNavigationController(controller, parent_);
347 if (tab_index == TabStripModel::kNoTab) {
348 // This tab notification doesn't belong to the parent_
349 return;
350 }
351
352 // Give the same response even if auth is needed, since it doesn't matter.
353 automation_->AddNavigationStatusListener(controller,
354 new AutomationMsg_AppendTabResponse(routing_id_, tab_index),
355 new AutomationMsg_AppendTabResponse(routing_id_, tab_index));
356 }
357};
358
359class TabClosedNotificationObserver : public TabStripNotificationObserver {
360 public:
361 TabClosedNotificationObserver(Browser* parent,
362 AutomationProvider* automation,
363 int32 routing_id,
364 bool wait_until_closed)
365 : TabStripNotificationObserver(parent,
[email protected]bfd04a62009-02-01 18:16:56366 wait_until_closed ? NotificationType::TAB_CLOSED :
367 NotificationType::TAB_CLOSING,
368 automation,
369 routing_id) {
initial.commit09911bf2008-07-26 23:55:29370 }
371
372 virtual void ObserveTab(NavigationController* controller) {
373 automation_->Send(new AutomationMsg_CloseTabResponse(routing_id_, true));
374 }
375};
376
377class BrowserClosedNotificationObserver : public NotificationObserver {
378 public:
379 BrowserClosedNotificationObserver(Browser* browser,
380 AutomationProvider* automation,
381 int32 routing_id)
382 : automation_(automation),
383 routing_id_(routing_id) {
[email protected]bfd04a62009-02-01 18:16:56384 NotificationService::current()->AddObserver(this,
385 NotificationType::BROWSER_CLOSED, Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29386 }
387
388 virtual void Observe(NotificationType type,
389 const NotificationSource& source,
390 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56391 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29392 Details<bool> close_app(details);
393 automation_->Send(
394 new AutomationMsg_CloseBrowserResponse(routing_id_,
395 true,
396 *(close_app.ptr())));
397 delete this;
398 }
399
400 private:
401 AutomationProvider* automation_;
402 int32 routing_id_;
403};
404
405class FindInPageNotificationObserver : public NotificationObserver {
406 public:
407 FindInPageNotificationObserver(AutomationProvider* automation,
408 TabContents* parent_tab,
409 int32 routing_id)
410 : automation_(automation),
411 parent_tab_(parent_tab),
[email protected]aedd85a2008-12-04 19:32:49412 routing_id_(routing_id),
413 active_match_ordinal_(-1) {
[email protected]bfd04a62009-02-01 18:16:56414 NotificationService::current()->AddObserver(
415 this,
416 NotificationType::FIND_RESULT_AVAILABLE,
417 Source<TabContents>(parent_tab_));
initial.commit09911bf2008-07-26 23:55:29418 }
419
420 ~FindInPageNotificationObserver() {
421 Unregister();
422 }
423
424 void Unregister() {
425 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56426 RemoveObserver(this, NotificationType::FIND_RESULT_AVAILABLE,
initial.commit09911bf2008-07-26 23:55:29427 Source<TabContents>(parent_tab_));
428 }
429
430 virtual void Observe(NotificationType type, const NotificationSource& source,
431 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56432 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29433 Details<FindNotificationDetails> find_details(details);
434 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49435 // We get multiple responses and one of those will contain the ordinal.
436 // This message comes to us before the final update is sent.
437 if (find_details->active_match_ordinal() > -1)
438 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29439 if (find_details->final_update()) {
[email protected]aedd85a2008-12-04 19:32:49440 automation_->Send(new AutomationMsg_FindInPageResponse2(routing_id_,
441 active_match_ordinal_,
initial.commit09911bf2008-07-26 23:55:29442 find_details->number_of_matches()));
443 } else {
444 DLOG(INFO) << "Ignoring, since we only care about the final message";
445 }
446 }
447 } else {
448 NOTREACHED();
449 }
450 }
451
452 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
453 // we wait for notification to find out what the results are. As the user is
454 // typing, new search requests can be issued and the Request ID helps us make
455 // sense of whether this is the current request or an old one. The unit tests,
456 // however, which uses this constant issues only one search at a time, so we
457 // don't need a rolling id to identify each search. But, we still need to
458 // specify one, so we just use a fixed one - its value does not matter.
459 static const int kFindInPageRequestId;
460 private:
461 AutomationProvider* automation_;
462 TabContents* parent_tab_;
463 int32 routing_id_;
[email protected]aedd85a2008-12-04 19:32:49464 // We will at some point (before final update) be notified of the ordinal and
465 // we need to preserve it so we can send it later.
466 int active_match_ordinal_;
initial.commit09911bf2008-07-26 23:55:29467};
468
469const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
470
471class DomOperationNotificationObserver : public NotificationObserver {
472 public:
473 explicit DomOperationNotificationObserver(AutomationProvider* automation)
474 : automation_(automation) {
475 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56476 AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29477 NotificationService::AllSources());
478 }
479
480 ~DomOperationNotificationObserver() {
481 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56482 RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29483 NotificationService::AllSources());
484 }
485
486 virtual void Observe(NotificationType type, const NotificationSource& source,
487 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56488 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29489 Details<DomOperationNotificationDetails> dom_op_details(details);
490 automation_->Send(new AutomationMsg_DomOperationResponse(
491 dom_op_details->automation_id(),
492 dom_op_details->json()));
493 }
494 }
495 private:
496 AutomationProvider* automation_;
497};
498
499class DomInspectorNotificationObserver : public NotificationObserver {
500 public:
501 explicit DomInspectorNotificationObserver(AutomationProvider* automation)
502 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:56503 NotificationService::current()->AddObserver(
504 this,
505 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
506 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29507 }
508
509 ~DomInspectorNotificationObserver() {
[email protected]bfd04a62009-02-01 18:16:56510 NotificationService::current()->RemoveObserver(
511 this,
512 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
513 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29514 }
515
516 virtual void Observe(NotificationType type, const NotificationSource& source,
517 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56518 if (NotificationType::DOM_INSPECT_ELEMENT_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29519 Details<int> dom_inspect_details(details);
520 automation_->ReceivedInspectElementResponse(*(dom_inspect_details.ptr()));
521 }
522 }
523
524 private:
525 AutomationProvider* automation_;
526};
527
528class DocumentPrintedNotificationObserver : public NotificationObserver {
529 public:
530 DocumentPrintedNotificationObserver(AutomationProvider* automation,
531 int32 routing_id)
532 : automation_(automation),
533 routing_id_(routing_id),
534 success_(false) {
[email protected]bfd04a62009-02-01 18:16:56535 NotificationService::current()->AddObserver(
536 this,
537 NotificationType::PRINT_JOB_EVENT,
538 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29539 }
540
541 ~DocumentPrintedNotificationObserver() {
542 automation_->Send(
543 new AutomationMsg_PrintNowResponse(routing_id_, success_));
544 automation_->RemoveNavigationStatusListener(this);
[email protected]bfd04a62009-02-01 18:16:56545 NotificationService::current()->RemoveObserver(
546 this,
547 NotificationType::PRINT_JOB_EVENT,
548 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29549 }
550
551 virtual void Observe(NotificationType type, const NotificationSource& source,
552 const NotificationDetails& details) {
553 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56554 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29555 switch (Details<JobEventDetails>(details)->type()) {
556 case JobEventDetails::JOB_DONE: {
557 // Succeeded.
558 success_ = true;
559 delete this;
560 break;
561 }
562 case JobEventDetails::USER_INIT_CANCELED:
563 case JobEventDetails::FAILED: {
564 // Failed.
565 delete this;
566 break;
567 }
568 case JobEventDetails::NEW_DOC:
569 case JobEventDetails::USER_INIT_DONE:
570 case JobEventDetails::DEFAULT_INIT_DONE:
571 case JobEventDetails::NEW_PAGE:
572 case JobEventDetails::PAGE_DONE:
573 case JobEventDetails::DOC_DONE:
574 case JobEventDetails::ALL_PAGES_REQUESTED: {
575 // Don't care.
576 break;
577 }
578 default: {
579 NOTREACHED();
580 break;
581 }
582 }
583 }
584
585 private:
586 scoped_refptr<AutomationProvider> automation_;
587 int32 routing_id_;
588 bool success_;
589};
590
[email protected]cbab76d2008-10-13 22:42:47591class AutomationInterstitialPage : public InterstitialPage {
592 public:
[email protected]a3a1d142008-12-19 00:42:30593 AutomationInterstitialPage(WebContents* tab,
[email protected]cbab76d2008-10-13 22:42:47594 const GURL& url,
595 const std::string& contents)
596 : InterstitialPage(tab, true, url),
597 contents_(contents) {
598 }
599
600 virtual std::string GetHTMLContents() { return contents_; }
601
602 private:
603 std::string contents_;
604
605 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
606};
607
initial.commit09911bf2008-07-26 23:55:29608AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57609 : redirect_query_(0),
initial.commit09911bf2008-07-26 23:55:29610 profile_(profile) {
initial.commit09911bf2008-07-26 23:55:29611 browser_tracker_.reset(new AutomationBrowserTracker(this));
612 window_tracker_.reset(new AutomationWindowTracker(this));
613 tab_tracker_.reset(new AutomationTabTracker(this));
614 autocomplete_edit_tracker_.reset(
615 new AutomationAutocompleteEditTracker(this));
616 cwindow_tracker_.reset(new AutomationConstrainedWindowTracker(this));
617 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
618 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
619 dom_inspector_observer_.reset(new DomInspectorNotificationObserver(this));
620}
621
622AutomationProvider::~AutomationProvider() {
[email protected]0da050b92008-08-19 19:29:47623 // Make sure that any outstanding NotificationObservers also get destroyed.
624 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31625 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47626 while ((observer = it.GetNext()) != NULL)
627 delete observer;
initial.commit09911bf2008-07-26 23:55:29628}
629
630void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) {
[email protected]295039bd2008-08-15 04:32:57631 channel_.reset(
632 new IPC::ChannelProxy(channel_id, IPC::Channel::MODE_CLIENT, this, NULL,
633 g_browser_process->io_thread()->message_loop()));
634 channel_->Send(new AutomationMsg_Hello(0));
initial.commit09911bf2008-07-26 23:55:29635}
636
637void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
638 if (expected_tabs == 0) {
639 Send(new AutomationMsg_InitialLoadsComplete(0));
640 } else {
641 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
642 }
643}
644
645NotificationObserver* AutomationProvider::AddNavigationStatusListener(
646 NavigationController* tab, IPC::Message* completed_response,
647 IPC::Message* auth_needed_response) {
648 NotificationObserver* observer =
649 new NavigationNotificationObserver(tab, this, completed_response,
650 auth_needed_response);
651 notification_observer_list_.AddObserver(observer);
652
653 return observer;
654}
655
656void AutomationProvider::RemoveNavigationStatusListener(
657 NotificationObserver* obs) {
658 notification_observer_list_.RemoveObserver(obs);
659}
660
661NotificationObserver* AutomationProvider::AddTabStripObserver(
662 Browser* parent, int32 routing_id) {
663 NotificationObserver* observer = new
664 TabAppendedNotificationObserver(parent, this, routing_id);
665 notification_observer_list_.AddObserver(observer);
666
667 return observer;
668}
669
670void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
671 notification_observer_list_.RemoveObserver(obs);
672}
673
674void AutomationProvider::AddLoginHandler(NavigationController* tab,
675 LoginHandler* handler) {
676 login_handler_map_[tab] = handler;
677}
678
679void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
680 DCHECK(login_handler_map_[tab]);
681 login_handler_map_.erase(tab);
682}
683
684int AutomationProvider::GetIndexForNavigationController(
685 const NavigationController* controller, const Browser* parent) const {
686 DCHECK(parent);
687 return parent->GetIndexOfController(controller);
688}
689
690void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
691 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
692 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequest, CloseBrowser)
693 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTabRequest, ActivateTab)
694 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndexRequest, GetActiveTabIndex)
695 IPC_MESSAGE_HANDLER(AutomationMsg_AppendTabRequest, AppendTab)
696 IPC_MESSAGE_HANDLER(AutomationMsg_CloseTabRequest, CloseTab)
697 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesRequest, GetCookies)
698 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieRequest, SetCookie)
699 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateToURLRequest, NavigateToURL)
700 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncRequest, NavigationAsync)
701 IPC_MESSAGE_HANDLER(AutomationMsg_GoBackRequest, GoBack)
702 IPC_MESSAGE_HANDLER(AutomationMsg_GoForwardRequest, GoForward)
703 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadRequest, Reload)
704 IPC_MESSAGE_HANDLER(AutomationMsg_SetAuthRequest, SetAuth)
705 IPC_MESSAGE_HANDLER(AutomationMsg_CancelAuthRequest, CancelAuth)
706 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuthRequest, NeedsAuth)
707 IPC_MESSAGE_HANDLER(AutomationMsg_RedirectsFromRequest, GetRedirectsFrom)
708 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCountRequest,
709 GetBrowserWindowCount)
710 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowRequest, GetBrowserWindow)
711 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindowRequest,
712 GetLastActiveBrowserWindow)
713 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindowRequest, GetActiveWindow)
714 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActiveRequest, IsWindowActive)
715 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow);
716 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWNDRequest, GetWindowHWND)
[email protected]4ae62752008-08-04 23:28:47717 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandRequest,
718 ExecuteBrowserCommand)
initial.commit09911bf2008-07-26 23:55:29719 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBoundsRequest,
720 WindowGetViewBounds)
721 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisibleRequest, SetWindowVisible)
722 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClickRequest, WindowSimulateClick)
723 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPressRequest,
724 WindowSimulateKeyPress)
725 IPC_MESSAGE_HANDLER(AutomationMsg_WindowDragRequest, WindowSimulateDrag)
726 IPC_MESSAGE_HANDLER(AutomationMsg_TabCountRequest, GetTabCount)
727 IPC_MESSAGE_HANDLER(AutomationMsg_TabRequest, GetTab)
728 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWNDRequest, GetTabHWND)
729 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessIDRequest, GetTabProcessID)
730 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitleRequest, GetTabTitle)
731 IPC_MESSAGE_HANDLER(AutomationMsg_TabURLRequest, GetTabURL)
732 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibilityRequest,
733 GetShelfVisibility)
734 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
735 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAcceleratorRequest, ApplyAccelerator)
736 IPC_MESSAGE_HANDLER(AutomationMsg_DomOperationRequest, ExecuteJavascript)
737 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCountRequest,
738 GetConstrainedWindowCount)
739 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowRequest,
740 GetConstrainedWindow)
741 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedTitleRequest,
742 GetConstrainedTitle)
743 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPageRequest,
744 HandleFindInPageRequest)
745 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewIDRequest, GetFocusedViewID)
746 IPC_MESSAGE_HANDLER(AutomationMsg_InspectElementRequest,
747 HandleInspectElementRequest)
748 IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet,
749 SetFilteredInet);
750 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectoryRequest,
751 GetDownloadDirectory);
752 IPC_MESSAGE_HANDLER(AutomationMsg_OpenNewBrowserWindow,
753 OpenNewBrowserWindow);
754 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowserRequest,
755 GetWindowForBrowser);
756 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowserRequest,
757 GetAutocompleteEditForBrowser);
758 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindowRequest,
759 GetBrowserForWindow);
760 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
761 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTabRequest,
762 NavigateInExternalTab)
763 IPC_MESSAGE_HANDLER(AutomationMsg_ShowInterstitialPageRequest,
764 ShowInterstitialPage);
765 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPageRequest,
766 HideInterstitialPage);
767 IPC_MESSAGE_HANDLER(AutomationMsg_SetAcceleratorsForTab,
768 SetAcceleratorsForTab)
769 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
770 ProcessUnhandledAccelerator)
771 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForTabToBeRestored,
772 WaitForTabToBeRestored)
773 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState,
774 GetSecurityState)
775 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType,
776 GetPageType)
777 IPC_MESSAGE_HANDLER(AutomationMsg_ActionOnSSLBlockingPage,
778 ActionOnSSLBlockingPage)
779 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
780 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
781 IsPageMenuCommandEnabled)
782 IPC_MESSAGE_HANDLER(AutomationMsg_PrintNowRequest, PrintNow)
783 IPC_MESSAGE_HANDLER(AutomationMsg_SavePageRequest, SavePage)
784 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetTextRequest,
785 GetAutocompleteEditText)
786 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetTextRequest,
787 SetAutocompleteEditText)
788 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgressRequest,
789 AutocompleteEditIsQueryInProgress)
790 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatchesRequest,
791 AutocompleteEditGetMatches)
792 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowBoundsRequest,
793 GetConstrainedWindowBounds)
[email protected]5f8af2a2008-08-06 22:49:45794 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPageRequest,
795 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:45796 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
797 OnMessageFromExternalHost)
[email protected]5a52f162008-08-27 04:15:31798 IPC_MESSAGE_HANDLER(AutomationMsg_FindRequest,
799 HandleFindRequest)
[email protected]20e93d12008-08-28 16:31:57800 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibilityRequest,
801 GetFindWindowVisibility)
802 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocationRequest,
803 HandleFindWindowLocationRequest)
[email protected]c2cbeb92008-09-05 21:36:57804 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibilityRequest,
805 GetBookmarkBarVisitility)
[email protected]8a3422c92008-09-24 17:42:42806 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCountRequest,
807 GetSSLInfoBarCount)
808 IPC_MESSAGE_HANDLER(AutomationMsg_ClickSSLInfoBarLinkRequest,
809 ClickSSLInfoBarLink)
810 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTimeRequest,
811 GetLastNavigationTime)
812 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForNavigationRequest,
813 WaitForNavigation)
814 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreferenceRequest,
815 SetIntPreference)
[email protected]c274acc2008-11-11 20:13:44816 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialogRequest,
817 GetShowingAppModalDialog)
[email protected]fad84eab2008-12-05 00:37:20818 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButtonRequest,
819 ClickAppModalDialogButton)
[email protected]97fa6ce32008-12-19 01:48:16820 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreferenceRequest,
821 SetStringPreference)
822 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreferenceRequest,
823 GetBooleanPreference)
824 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreferenceRequest,
825 SetBooleanPreference)
826 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncodingRequest,
827 GetPageCurrentEncoding)
828 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncodingRequest,
829 OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20830 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
831 SavePackageShouldPromptUser)
initial.commit09911bf2008-07-26 23:55:29832 IPC_END_MESSAGE_MAP()
833}
834
835void AutomationProvider::ActivateTab(const IPC::Message& message,
836 int handle, int at_index) {
837 int status = -1;
838 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
839 Browser* browser = browser_tracker_->GetResource(handle);
840 if (at_index >= 0 && at_index < browser->tab_count()) {
841 browser->SelectTabContentsAt(at_index, true);
842 status = 0;
843 }
844 }
845 Send(new AutomationMsg_ActivateTabResponse(message.routing_id(), status));
846}
847
848void AutomationProvider::AppendTab(const IPC::Message& message,
849 int handle, const GURL& url) {
850 int append_tab_response = -1; // -1 is the error code
851 NotificationObserver* observer = NULL;
852
853 if (browser_tracker_->ContainsHandle(handle)) {
854 Browser* browser = browser_tracker_->GetResource(handle);
855 observer = AddTabStripObserver(browser, message.routing_id());
856 TabContents* tab_contents =
[email protected]c0588052008-10-27 23:01:50857 browser->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, NULL);
initial.commit09911bf2008-07-26 23:55:29858 if (tab_contents) {
859 append_tab_response =
860 GetIndexForNavigationController(tab_contents->controller(), browser);
861 }
862 }
863
864 if (append_tab_response < 0) {
865 // The append tab failed. Remove the TabStripObserver
866 if (observer) {
867 RemoveTabStripObserver(observer);
868 delete observer;
869 }
870
871 // This will be reached only if the tab could not be appended. In case of a
872 // successful tab append, a successful navigation notification triggers the
873 // send.
874 Send(new AutomationMsg_AppendTabResponse(message.routing_id(),
875 append_tab_response));
876 }
877}
878
879void AutomationProvider::NavigateToURL(const IPC::Message& message,
880 int handle, const GURL& url) {
881 int status = AUTOMATION_MSG_NAVIGATION_ERROR;
882
883 if (tab_tracker_->ContainsHandle(handle)) {
884 NavigationController* tab = tab_tracker_->GetResource(handle);
885
886 // Simulate what a user would do. Activate the tab and then navigate.
887 // We could allow navigating in a background tab in future.
888 Browser* browser = FindAndActivateTab(tab);
889
890 if (browser) {
891 AddNavigationStatusListener(tab,
892 new AutomationMsg_NavigateToURLResponse(
893 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
894 new AutomationMsg_NavigateToURLResponse(
895 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
896 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50897 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29898 return;
899 }
900 }
901 Send(new AutomationMsg_NavigateToURLResponse(
902 message.routing_id(), AUTOMATION_MSG_NAVIGATION_ERROR));
903}
904
905void AutomationProvider::NavigationAsync(const IPC::Message& message,
906 int handle, const GURL& url) {
907 bool status = false;
908
909 if (tab_tracker_->ContainsHandle(handle)) {
910 NavigationController* tab = tab_tracker_->GetResource(handle);
911
912 // Simulate what a user would do. Activate the tab and then navigate.
913 // We could allow navigating in a background tab in future.
914 Browser* browser = FindAndActivateTab(tab);
915
916 if (browser) {
917 // Don't add any listener unless a callback mechanism is desired.
918 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:50919 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29920 status = true;
921 }
922 }
923
924 Send(new AutomationMsg_NavigationAsyncResponse(message.routing_id(), status));
925}
926
927void AutomationProvider::GoBack(const IPC::Message& message, int handle) {
928 if (tab_tracker_->ContainsHandle(handle)) {
929 NavigationController* tab = tab_tracker_->GetResource(handle);
930 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14931 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
initial.commit09911bf2008-07-26 23:55:29932 AddNavigationStatusListener(tab,
933 new AutomationMsg_GoBackResponse(
934 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
935 new AutomationMsg_GoBackResponse(
936 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
937 browser->GoBack();
938 return;
939 }
940 }
941 Send(new AutomationMsg_GoBackResponse(message.routing_id(),
942 AUTOMATION_MSG_NAVIGATION_ERROR));
943}
944
945void AutomationProvider::GoForward(const IPC::Message& message, int handle) {
946 if (tab_tracker_->ContainsHandle(handle)) {
947 NavigationController* tab = tab_tracker_->GetResource(handle);
948 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14949 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
initial.commit09911bf2008-07-26 23:55:29950 AddNavigationStatusListener(tab,
951 new AutomationMsg_GoForwardResponse(
952 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
953 new AutomationMsg_GoForwardResponse(
954 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
955 browser->GoForward();
956 return;
957 }
958 }
959 Send(new AutomationMsg_GoForwardResponse(message.routing_id(),
960 AUTOMATION_MSG_NAVIGATION_ERROR));
961}
962
963void AutomationProvider::Reload(const IPC::Message& message, int handle) {
964 if (tab_tracker_->ContainsHandle(handle)) {
965 NavigationController* tab = tab_tracker_->GetResource(handle);
966 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14967 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
initial.commit09911bf2008-07-26 23:55:29968 AddNavigationStatusListener(tab,
969 new AutomationMsg_ReloadResponse(
970 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
971 new AutomationMsg_ReloadResponse(
972 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
973 browser->Reload();
974 return;
975 }
976 }
977 Send(new AutomationMsg_ReloadResponse(message.routing_id(),
978 AUTOMATION_MSG_NAVIGATION_ERROR));
979}
980
981void AutomationProvider::SetAuth(const IPC::Message& message, int tab_handle,
982 const std::wstring& username,
983 const std::wstring& password) {
984 int status = -1;
985
986 if (tab_tracker_->ContainsHandle(tab_handle)) {
987 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
988 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
989
990 if (iter != login_handler_map_.end()) {
991 // If auth is needed again after this, assume login has failed. This is
992 // not strictly correct, because a navigation can require both proxy and
993 // server auth, but it should be OK for now.
994 LoginHandler* handler = iter->second;
995 AddNavigationStatusListener(tab,
996 new AutomationMsg_SetAuthResponse(message.routing_id(), 0),
997 new AutomationMsg_SetAuthResponse(message.routing_id(), -1));
998 handler->SetAuth(username, password);
999 status = 0;
1000 }
1001 }
1002 if (status < 0) {
1003 Send(new AutomationMsg_SetAuthResponse(message.routing_id(), status));
1004 }
1005}
1006
1007void AutomationProvider::CancelAuth(const IPC::Message& message,
1008 int tab_handle) {
1009 int status = -1;
1010
1011 if (tab_tracker_->ContainsHandle(tab_handle)) {
1012 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1013 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1014
1015 if (iter != login_handler_map_.end()) {
1016 // If auth is needed again after this, something is screwy.
1017 LoginHandler* handler = iter->second;
1018 AddNavigationStatusListener(tab,
1019 new AutomationMsg_CancelAuthResponse(message.routing_id(), 0),
1020 new AutomationMsg_CancelAuthResponse(message.routing_id(), -1));
1021 handler->CancelAuth();
1022 status = 0;
1023 }
1024 }
1025 if (status < 0) {
1026 Send(new AutomationMsg_CancelAuthResponse(message.routing_id(), status));
1027 }
1028}
1029
1030void AutomationProvider::NeedsAuth(const IPC::Message& message,
1031 int tab_handle) {
1032 bool needs_auth = false;
1033
1034 if (tab_tracker_->ContainsHandle(tab_handle)) {
1035 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1036 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1037
1038 if (iter != login_handler_map_.end()) {
1039 // The LoginHandler will be in our map IFF the tab needs auth.
1040 needs_auth = true;
1041 }
1042 }
1043
1044 Send(new AutomationMsg_NeedsAuthResponse(message.routing_id(), needs_auth));
1045}
1046
1047void AutomationProvider::GetRedirectsFrom(const IPC::Message& message,
1048 int tab_handle,
1049 const GURL& source_url) {
1050 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1051 if (tab_tracker_->ContainsHandle(tab_handle)) {
1052 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1053 HistoryService* history_service =
1054 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1055
1056 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1057 "has no history service";
1058 if (history_service) {
1059 // Schedule a history query for redirects. The response will be sent
1060 // asynchronously from the callback the history system uses to notify us
1061 // that it's done: OnRedirectQueryComplete.
1062 redirect_query_routing_id_ = message.routing_id();
1063 redirect_query_ = history_service->QueryRedirectsFrom(
1064 source_url, &consumer_,
1065 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1066 return; // Response will be sent when query completes.
1067 }
1068 }
1069
1070 // Send failure response.
1071 IPC::Message* msg = new IPC::Message(
1072 message.routing_id(), AutomationMsg_RedirectsFromResponse::ID,
1073 IPC::Message::PRIORITY_NORMAL);
1074 msg->WriteInt(-1); // Negative string count indicates an error.
1075 Send(msg);
1076}
1077
1078void AutomationProvider::GetActiveTabIndex(const IPC::Message& message,
1079 int handle) {
1080 int active_tab_index = -1; // -1 is the error code
1081 if (browser_tracker_->ContainsHandle(handle)) {
1082 Browser* browser = browser_tracker_->GetResource(handle);
1083 active_tab_index = browser->selected_index();
1084 }
1085 Send(new AutomationMsg_ActiveTabIndexResponse(message.routing_id(),
1086 active_tab_index));
1087}
1088
1089void AutomationProvider::GetBrowserWindowCount(const IPC::Message& message) {
1090 Send(new AutomationMsg_BrowserWindowCountResponse(
1091 message.routing_id(), static_cast<int>(BrowserList::size())));
1092}
1093
[email protected]c274acc2008-11-11 20:13:441094void AutomationProvider::GetShowingAppModalDialog(const IPC::Message& message) {
[email protected]fad84eab2008-12-05 00:37:201095 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421096 AppModalDialogQueue::active_dialog();
[email protected]c274acc2008-11-11 20:13:441097 Send(new AutomationMsg_ShowingAppModalDialogResponse(
[email protected]fad84eab2008-12-05 00:37:201098 message.routing_id(), dialog_delegate != NULL,
1099 dialog_delegate ? dialog_delegate->GetDialogButtons() :
1100 views::DialogDelegate::DIALOGBUTTON_NONE));
1101}
1102
1103void AutomationProvider::ClickAppModalDialogButton(const IPC::Message& message,
1104 int button) {
1105 bool success = false;
1106
1107 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421108 AppModalDialogQueue::active_dialog();
[email protected]fad84eab2008-12-05 00:37:201109 if (dialog_delegate &&
1110 (dialog_delegate->GetDialogButtons() & button) == button) {
1111 views::DialogClientView* client_view =
1112 dialog_delegate->window()->client_view()->AsDialogClientView();
1113 if ((button & views::DialogDelegate::DIALOGBUTTON_OK) ==
1114 views::DialogDelegate::DIALOGBUTTON_OK) {
1115 client_view->AcceptWindow();
1116 success = true;
1117 }
1118 if ((button & views::DialogDelegate::DIALOGBUTTON_CANCEL) ==
1119 views::DialogDelegate::DIALOGBUTTON_CANCEL) {
1120 DCHECK(!success) << "invalid param, OK and CANCEL specified";
1121 client_view->CancelWindow();
1122 success = true;
1123 }
1124 }
1125 Send(new AutomationMsg_ClickAppModalDialogButtonResponse(
1126 message.routing_id(), success));
[email protected]c274acc2008-11-11 20:13:441127}
1128
initial.commit09911bf2008-07-26 23:55:291129void AutomationProvider::GetBrowserWindow(const IPC::Message& message,
1130 int index) {
1131 int handle = 0;
1132 if (index >= 0) {
1133 BrowserList::const_iterator iter = BrowserList::begin();
1134
1135 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
1136 if (iter != BrowserList::end()) {
1137 handle = browser_tracker_->Add(*iter);
1138 }
1139 }
1140
1141 Send(new AutomationMsg_BrowserWindowResponse(message.routing_id(), handle));
1142}
1143
1144void AutomationProvider::GetLastActiveBrowserWindow(
1145 const IPC::Message& message) {
1146 int handle = 0;
1147 Browser* browser = BrowserList::GetLastActive();
1148 if (browser)
1149 handle = browser_tracker_->Add(browser);
1150 Send(new AutomationMsg_LastActiveBrowserWindowResponse(message.routing_id(),
1151 handle));
1152}
1153
1154BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1155 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1156 return FALSE;
1157 }
1158 return TRUE;
1159}
1160
1161void AutomationProvider::GetActiveWindow(const IPC::Message& message) {
1162 HWND window = GetForegroundWindow();
1163
1164 // Let's make sure this window belongs to our process.
1165 if (EnumThreadWindows(::GetCurrentThreadId(),
1166 EnumThreadWndProc,
1167 reinterpret_cast<LPARAM>(window))) {
1168 // We enumerated all the windows and did not find the foreground window,
1169 // it is not our window, ignore it.
1170 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), 0));
1171 return;
1172 }
1173
1174 int handle = window_tracker_->Add(window);
1175 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), handle));
1176}
1177
1178void AutomationProvider::GetWindowHWND(const IPC::Message& message,
1179 int handle) {
1180 HWND win32_handle = window_tracker_->GetResource(handle);
1181 Send(new AutomationMsg_WindowHWNDResponse(message.routing_id(),
1182 win32_handle));
1183}
1184
[email protected]4ae62752008-08-04 23:28:471185void AutomationProvider::ExecuteBrowserCommand(const IPC::Message& message,
1186 int handle,
1187 int command) {
[email protected]4ae62752008-08-04 23:28:471188 bool success = false;
1189 if (browser_tracker_->ContainsHandle(handle)) {
1190 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141191 if (browser->command_updater()->SupportsCommand(command) &&
1192 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471193 browser->ExecuteCommand(command);
1194 success = true;
1195 }
1196 }
1197 Send(new AutomationMsg_WindowExecuteCommandResponse(message.routing_id(),
1198 success));
1199}
1200
initial.commit09911bf2008-07-26 23:55:291201void AutomationProvider::WindowGetViewBounds(const IPC::Message& message,
1202 int handle,
1203 int view_id,
1204 bool screen_coordinates) {
1205 bool succeeded = false;
[email protected]80f8b9f2008-10-16 18:17:471206 gfx::Rect bounds;
initial.commit09911bf2008-07-26 23:55:291207
1208 void* iter = NULL;
1209 if (window_tracker_->ContainsHandle(handle)) {
1210 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201211 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291212 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381213 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291214 if (view) {
1215 succeeded = true;
[email protected]96b667d2008-10-14 20:58:441216 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291217 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381218 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291219 else
[email protected]c2dacc92008-10-16 23:51:381220 views::View::ConvertPointToView(view, root_view, &point);
[email protected]80f8b9f2008-10-16 18:17:471221 bounds = view->GetLocalBounds(false);
1222 bounds.set_origin(point);
initial.commit09911bf2008-07-26 23:55:291223 }
1224 }
1225 }
1226
[email protected]80f8b9f2008-10-16 18:17:471227 Send(new AutomationMsg_WindowViewBoundsResponse(message.routing_id(),
1228 succeeded, bounds));
initial.commit09911bf2008-07-26 23:55:291229}
1230
1231// This task enqueues a mouse event on the event loop, so that the view
1232// that it's being sent to can do the requisite post-processing.
1233class MouseEventTask : public Task {
1234 public:
[email protected]c2dacc92008-10-16 23:51:381235 MouseEventTask(views::View* view,
1236 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291237 POINT point,
1238 int flags)
1239 : view_(view), type_(type), point_(point), flags_(flags) {}
1240 virtual ~MouseEventTask() {}
1241
1242 virtual void Run() {
[email protected]c2dacc92008-10-16 23:51:381243 views::MouseEvent event(type_, point_.x, point_.y, flags_);
initial.commit09911bf2008-07-26 23:55:291244 // We need to set the cursor position before we process the event because
1245 // some code (tab dragging, for instance) queries the actual cursor location
1246 // rather than the location of the mouse event. Note that the reason why
1247 // the drag code moved away from using mouse event locations was because
1248 // our conversion to screen location doesn't work well with multiple
1249 // monitors, so this only works reliably in a single monitor setup.
[email protected]96b667d2008-10-14 20:58:441250 gfx::Point screen_location(point_.x, point_.y);
initial.commit09911bf2008-07-26 23:55:291251 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]96b667d2008-10-14 20:58:441252 ::SetCursorPos(screen_location.x(), screen_location.y());
initial.commit09911bf2008-07-26 23:55:291253 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381254 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291255 view_->OnMousePressed(event);
1256 break;
1257
[email protected]c2dacc92008-10-16 23:51:381258 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291259 view_->OnMouseDragged(event);
1260 break;
1261
[email protected]c2dacc92008-10-16 23:51:381262 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291263 view_->OnMouseReleased(event, false);
1264 break;
1265
1266 default:
1267 NOTREACHED();
1268 }
1269 }
1270
1271 private:
[email protected]c2dacc92008-10-16 23:51:381272 views::View* view_;
1273 views::Event::EventType type_;
initial.commit09911bf2008-07-26 23:55:291274 POINT point_;
1275 int flags_;
1276
[email protected]5a52f162008-08-27 04:15:311277 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291278};
1279
[email protected]c2dacc92008-10-16 23:51:381280void AutomationProvider::ScheduleMouseEvent(views::View* view,
1281 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291282 POINT point,
1283 int flags) {
1284 MessageLoop::current()->PostTask(FROM_HERE,
1285 new MouseEventTask(view, type, point, flags));
1286}
1287
1288// This task just adds another task to the event queue. This is useful if
1289// you want to ensure that any tasks added to the event queue after this one
1290// have already been processed by the time |task| is run.
1291class InvokeTaskLaterTask : public Task {
1292 public:
1293 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1294 virtual ~InvokeTaskLaterTask() {}
1295
1296 virtual void Run() {
1297 MessageLoop::current()->PostTask(FROM_HERE, task_);
1298 }
1299
1300 private:
1301 Task* task_;
1302
[email protected]5a52f162008-08-27 04:15:311303 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291304};
1305
1306// This task sends a WindowDragResponse message with the appropriate
1307// routing ID to the automation proxy. This is implemented as a task so that
1308// we know that the mouse events (and any tasks that they spawn on the message
1309// loop) have been processed by the time this is sent.
1310class WindowDragResponseTask : public Task {
1311 public:
1312 WindowDragResponseTask(AutomationProvider* provider, int routing_id)
1313 : provider_(provider), routing_id_(routing_id) {}
1314 virtual ~WindowDragResponseTask() {}
1315
1316 virtual void Run() {
1317 provider_->Send(new AutomationMsg_WindowDragResponse(routing_id_, true));
1318 }
1319
1320 private:
1321 AutomationProvider* provider_;
1322 int routing_id_;
1323
[email protected]5a52f162008-08-27 04:15:311324 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291325};
1326
1327void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1328 int handle,
1329 POINT click,
1330 int flags) {
1331 HWND hwnd = 0;
1332
1333 if (window_tracker_->ContainsHandle(handle)) {
1334 hwnd = window_tracker_->GetResource(handle);
1335
initial.commit09911bf2008-07-26 23:55:291336 ui_controls::SendMouseMove(click.x, click.y);
1337
1338 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381339 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1340 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291341 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381342 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1343 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291344 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381345 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1346 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291347 button = ui_controls::MIDDLE;
1348 } else {
1349 NOTREACHED();
1350 }
1351 ui_controls::SendMouseClick(button);
1352 }
1353}
1354
1355void AutomationProvider::WindowSimulateDrag(const IPC::Message& message,
1356 int handle,
[email protected]fe92e4e2008-11-18 21:31:321357 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441358 int flags,
1359 bool press_escape_en_route) {
initial.commit09911bf2008-07-26 23:55:291360 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321361 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1362 succeeded = true;
1363
1364 UINT down_message = 0;
1365 UINT up_message = 0;
1366 WPARAM wparam_flags = 0;
1367 if (flags & views::Event::EF_SHIFT_DOWN)
1368 wparam_flags |= MK_SHIFT;
1369 if (flags & views::Event::EF_CONTROL_DOWN)
1370 wparam_flags |= MK_CONTROL;
1371 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1372 wparam_flags |= MK_LBUTTON;
1373 down_message = WM_LBUTTONDOWN;
1374 up_message = WM_LBUTTONUP;
1375 }
1376 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1377 wparam_flags |= MK_MBUTTON;
1378 down_message = WM_MBUTTONDOWN;
1379 up_message = WM_MBUTTONUP;
1380 }
1381 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1382 wparam_flags |= MK_RBUTTON;
1383 down_message = WM_LBUTTONDOWN;
1384 up_message = WM_LBUTTONUP;
1385 }
1386
initial.commit09911bf2008-07-26 23:55:291387 Browser* browser = browser_tracker_->GetResource(handle);
1388 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551389 HWND top_level_hwnd =
1390 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321391 POINT temp = drag_path[0];
1392 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1393 SetCursorPos(temp.x, temp.y);
1394 SendMessage(top_level_hwnd, down_message, wparam_flags,
1395 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1396 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1397 temp = drag_path[i];
1398 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1399 SetCursorPos(temp.x, temp.y);
1400 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1401 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341402 }
[email protected]fe92e4e2008-11-18 21:31:321403 POINT end = drag_path[drag_path.size() - 1];
1404 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
1405 SetCursorPos(end.x, end.y);
1406
1407 if (press_escape_en_route) {
1408 // Press Escape.
1409 ui_controls::SendKeyPress(VK_ESCAPE,
1410 ((flags & views::Event::EF_CONTROL_DOWN)
1411 == views::Event::EF_CONTROL_DOWN),
1412 ((flags & views::Event::EF_SHIFT_DOWN) ==
1413 views::Event::EF_SHIFT_DOWN),
1414 ((flags & views::Event::EF_ALT_DOWN) ==
1415 views::Event::EF_ALT_DOWN));
1416 }
1417 SendMessage(top_level_hwnd, up_message, wparam_flags,
1418 MAKELPARAM(end.x, end.y));
1419
initial.commit09911bf2008-07-26 23:55:291420 MessageLoop::current()->PostTask(FROM_HERE,
1421 new InvokeTaskLaterTask(
1422 new WindowDragResponseTask(this, message.routing_id())));
1423 } else {
1424 Send(new AutomationMsg_WindowDragResponse(message.routing_id(), true));
1425 }
1426}
1427
1428void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1429 int handle,
1430 wchar_t key,
1431 int flags) {
1432 if (!window_tracker_->ContainsHandle(handle))
1433 return;
1434
1435 // The key event is sent to whatever window is active.
1436 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381437 ((flags & views::Event::EF_CONTROL_DOWN) ==
1438 views::Event::EF_CONTROL_DOWN),
1439 ((flags & views::Event::EF_SHIFT_DOWN) ==
1440 views::Event::EF_SHIFT_DOWN),
1441 ((flags & views::Event::EF_ALT_DOWN) ==
1442 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291443}
1444
1445void AutomationProvider::GetFocusedViewID(const IPC::Message& message,
1446 int handle) {
1447 int view_id = -1;
1448 if (window_tracker_->ContainsHandle(handle)) {
1449 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381450 views::FocusManager* focus_manager =
1451 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:291452 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381453 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291454 if (focused_view)
1455 view_id = focused_view->GetID();
1456 }
1457 Send(new AutomationMsg_GetFocusedViewIDResponse(message.routing_id(),
1458 view_id));
1459}
1460
1461void AutomationProvider::SetWindowVisible(const IPC::Message& message,
1462 int handle, bool visible) {
1463 if (window_tracker_->ContainsHandle(handle)) {
1464 HWND hwnd = window_tracker_->GetResource(handle);
1465 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
1466 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1467 true));
1468 } else {
1469 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1470 false));
1471 }
1472}
1473
1474void AutomationProvider::IsWindowActive(const IPC::Message& message,
1475 int handle) {
1476 if (window_tracker_->ContainsHandle(handle)) {
1477 HWND hwnd = window_tracker_->GetResource(handle);
1478 bool is_active = ::GetForegroundWindow() == hwnd;
1479 Send(new AutomationMsg_IsWindowActiveResponse(
1480 message.routing_id(), true, is_active));
1481 } else {
1482 Send(new AutomationMsg_IsWindowActiveResponse(message.routing_id(),
1483 false, false));
1484 }
1485}
1486
1487void AutomationProvider::ActivateWindow(const IPC::Message& message,
1488 int handle) {
1489 if (window_tracker_->ContainsHandle(handle)) {
1490 ::SetActiveWindow(window_tracker_->GetResource(handle));
1491 }
1492}
1493
1494void AutomationProvider::GetTabCount(const IPC::Message& message, int handle) {
1495 int tab_count = -1; // -1 is the error code
1496
1497 if (browser_tracker_->ContainsHandle(handle)) {
1498 Browser* browser = browser_tracker_->GetResource(handle);
1499 tab_count = browser->tab_count();
1500 }
1501
1502 Send(new AutomationMsg_TabCountResponse(message.routing_id(), tab_count));
1503}
1504
1505void AutomationProvider::GetTab(const IPC::Message& message,
1506 int win_handle, int tab_index) {
1507 void* iter = NULL;
1508 int tab_handle = 0;
1509 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1510 Browser* browser = browser_tracker_->GetResource(win_handle);
1511 if (tab_index < browser->tab_count()) {
1512 TabContents* tab_contents =
1513 browser->GetTabContentsAt(tab_index);
1514 tab_handle = tab_tracker_->Add(tab_contents->controller());
1515 }
1516 }
1517
1518 Send(new AutomationMsg_TabResponse(message.routing_id(), tab_handle));
1519}
1520
1521void AutomationProvider::GetTabTitle(const IPC::Message& message, int handle) {
1522 int title_string_size = -1; // -1 is the error code
1523 std::wstring title;
1524 if (tab_tracker_->ContainsHandle(handle)) {
1525 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]1e5645ff2008-08-27 18:09:071526 title = tab->GetActiveEntry()->title();
initial.commit09911bf2008-07-26 23:55:291527 title_string_size = static_cast<int>(title.size());
1528 }
1529
1530 Send(new AutomationMsg_TabTitleResponse(message.routing_id(),
1531 title_string_size, title));
1532}
1533
1534void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1535 if (window_tracker_->ContainsHandle(handle)) {
1536 window_tracker_->Remove(window_tracker_->GetResource(handle));
1537 }
1538}
1539
1540void AutomationProvider::OnChannelError() {
1541 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571542 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291543}
1544
1545// TODO(brettw) change this to accept GURLs when history supports it
1546void AutomationProvider::OnRedirectQueryComplete(
1547 HistoryService::Handle request_handle,
1548 GURL from_url,
1549 bool success,
1550 HistoryService::RedirectList* redirects) {
1551 DCHECK(request_handle == redirect_query_);
1552
1553 // Respond to the pending request for the redirect list.
1554 IPC::Message* msg = new IPC::Message(redirect_query_routing_id_,
1555 AutomationMsg_RedirectsFromResponse::ID,
1556 IPC::Message::PRIORITY_NORMAL);
1557 if (success) {
1558 msg->WriteInt(static_cast<int>(redirects->size()));
1559 for (size_t i = 0; i < redirects->size(); i++)
1560 IPC::ParamTraits<GURL>::Write(msg, redirects->at(i));
1561 } else {
1562 msg->WriteInt(-1); // Negative count indicates failure.
1563 }
1564
1565 Send(msg);
1566 redirect_query_ = NULL;
1567}
1568
1569bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571570 DCHECK(channel_.get());
1571 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291572}
1573
1574Browser* AutomationProvider::FindAndActivateTab(
1575 NavigationController* controller) {
1576 int tab_index;
1577 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1578 if (browser)
1579 browser->SelectTabContentsAt(tab_index, true);
1580
1581 return browser;
1582}
1583
1584void AutomationProvider::GetCookies(const IPC::Message& message,
1585 const GURL& url, int handle) {
1586 std::string value;
1587
1588 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1589 NavigationController* tab = tab_tracker_->GetResource(handle);
1590 value =
1591 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
1592 }
1593
1594 Send(new AutomationMsg_GetCookiesResponse(message.routing_id(),
1595 static_cast<int>(value.size()), value));
1596}
1597
1598void AutomationProvider::SetCookie(const IPC::Message& message,
1599 const GURL& url,
1600 const std::string value,
1601 int handle) {
1602 int response_value = -1;
1603
1604 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1605 NavigationController* tab = tab_tracker_->GetResource(handle);
1606 URLRequestContext* context = tab->profile()->GetRequestContext();
1607 if (context->cookie_store()->SetCookie(url, value))
1608 response_value = 1;
1609 }
1610
1611 Send(new AutomationMsg_SetCookieResponse(message.routing_id(),
1612 response_value));
1613}
1614
1615void AutomationProvider::GetTabURL(const IPC::Message& message, int handle) {
1616 bool success = false;
1617 GURL url;
1618 if (tab_tracker_->ContainsHandle(handle)) {
1619 NavigationController* tab = tab_tracker_->GetResource(handle);
1620 // Return what the user would see in the location bar.
[email protected]1e5645ff2008-08-27 18:09:071621 url = tab->GetActiveEntry()->display_url();
initial.commit09911bf2008-07-26 23:55:291622 success = true;
1623 }
1624
1625 Send(new AutomationMsg_TabURLResponse(message.routing_id(), success, url));
1626}
1627
1628void AutomationProvider::GetTabHWND(const IPC::Message& message, int handle) {
1629 HWND tab_hwnd = NULL;
1630
1631 if (tab_tracker_->ContainsHandle(handle)) {
1632 NavigationController* tab = tab_tracker_->GetResource(handle);
1633 tab_hwnd = tab->active_contents()->GetContainerHWND();
1634 }
1635
1636 Send(new AutomationMsg_TabHWNDResponse(message.routing_id(), tab_hwnd));
1637}
1638
1639void AutomationProvider::GetTabProcessID(
1640 const IPC::Message& message, int handle) {
1641 int process_id = -1;
1642
1643 if (tab_tracker_->ContainsHandle(handle)) {
1644 process_id = 0;
1645 NavigationController* tab = tab_tracker_->GetResource(handle);
1646 if (tab->active_contents()->AsWebContents()) {
1647 WebContents* web_contents = tab->active_contents()->AsWebContents();
[email protected]2f15de42008-11-11 22:35:191648 if (web_contents->process())
1649 process_id = web_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291650 }
1651 }
1652
1653 Send(new AutomationMsg_TabProcessIDResponse(message.routing_id(),
1654 process_id));
1655}
1656
1657void AutomationProvider::ApplyAccelerator(int handle, int id) {
1658 if (browser_tracker_->ContainsHandle(handle)) {
1659 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141660 browser->ExecuteCommand(id);
initial.commit09911bf2008-07-26 23:55:291661 }
1662}
1663
1664void AutomationProvider::ExecuteJavascript(const IPC::Message& message,
1665 int handle,
1666 const std::wstring& frame_xpath,
1667 const std::wstring& script) {
1668 bool succeeded = false;
[email protected]20e93d12008-08-28 16:31:571669 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1670 if (web_contents) {
1671 // Set the routing id of this message with the controller.
1672 // This routing id needs to be remembered for the reverse
1673 // communication while sending back the response of
1674 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331675 std::wstring set_automation_id;
1676 SStringPrintf(&set_automation_id,
1677 L"window.domAutomationController.setAutomationId(%d);",
[email protected]20e93d12008-08-28 16:31:571678 message.routing_id());
initial.commit09911bf2008-07-26 23:55:291679
[email protected]1f5af4442008-09-25 22:11:061680 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331681 frame_xpath, set_automation_id);
[email protected]1f5af4442008-09-25 22:11:061682 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1683 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571684 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291685 }
1686
1687 if (!succeeded) {
1688 Send(new AutomationMsg_DomOperationResponse(message.routing_id(), ""));
1689 }
1690}
1691
1692void AutomationProvider::GetShelfVisibility(const IPC::Message& message,
1693 int handle) {
1694 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571695
1696 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1697 if (web_contents)
1698 visible = web_contents->IsDownloadShelfVisible();
initial.commit09911bf2008-07-26 23:55:291699
1700 Send(new AutomationMsg_ShelfVisibilityResponse(message.routing_id(),
1701 visible));
1702}
1703
1704void AutomationProvider::GetConstrainedWindowCount(const IPC::Message& message,
1705 int handle) {
1706 int count = -1; // -1 is the error code
1707 if (tab_tracker_->ContainsHandle(handle)) {
1708 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1709 TabContents* tab_contents = nav_controller->active_contents();
1710 if (tab_contents) {
1711 count = static_cast<int>(tab_contents->child_windows_.size());
1712 }
1713 }
1714
1715 Send(new AutomationMsg_ConstrainedWindowCountResponse(message.routing_id(),
1716 count));
1717}
1718
1719void AutomationProvider::GetConstrainedWindow(const IPC::Message& message,
1720 int handle, int index) {
1721 int cwindow_handle = 0;
1722 if (tab_tracker_->ContainsHandle(handle) && index >= 0) {
1723 NavigationController* nav_controller =
1724 tab_tracker_->GetResource(handle);
1725 TabContents* tab = nav_controller->active_contents();
[email protected]d5f942ba2008-09-26 19:30:341726 if (tab && index < static_cast<int>(tab->child_windows_.size())) {
1727 ConstrainedWindow* window = tab->child_windows_[index];
initial.commit09911bf2008-07-26 23:55:291728 cwindow_handle = cwindow_tracker_->Add(window);
1729 }
1730 }
1731
1732 Send(new AutomationMsg_ConstrainedWindowResponse(message.routing_id(),
1733 cwindow_handle));
1734}
1735
1736void AutomationProvider::GetConstrainedTitle(const IPC::Message& message,
1737 int handle) {
1738 int title_string_size = -1; // -1 is the error code
1739 std::wstring title;
1740 if (cwindow_tracker_->ContainsHandle(handle)) {
1741 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1742 title = window->GetWindowTitle();
1743 title_string_size = static_cast<int>(title.size());
1744 }
1745
1746 Send(new AutomationMsg_ConstrainedTitleResponse(message.routing_id(),
1747 title_string_size, title));
1748}
1749
1750void AutomationProvider::GetConstrainedWindowBounds(const IPC::Message& message,
1751 int handle) {
1752 bool exists = false;
1753 gfx::Rect rect(0, 0, 0, 0);
1754 if (cwindow_tracker_->ContainsHandle(handle)) {
1755 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1756 if (window) {
1757 exists = true;
1758 rect = window->GetCurrentBounds();
1759 }
1760 }
1761
1762 Send(new AutomationMsg_ConstrainedWindowBoundsResponse(message.routing_id(),
1763 exists, rect));
1764}
1765
1766void AutomationProvider::HandleFindInPageRequest(
1767 const IPC::Message& message, int handle, const std::wstring& find_request,
1768 int forward, int match_case) {
[email protected]5a52f162008-08-27 04:15:311769 NOTREACHED() << "This function has been deprecated."
1770 << "Please use HandleFindRequest instead.";
[email protected]aedd85a2008-12-04 19:32:491771 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
[email protected]5a52f162008-08-27 04:15:311772 return;
1773}
1774
1775void AutomationProvider::HandleFindRequest(const IPC::Message& message,
1776 int handle, const FindInPageRequest& request) {
initial.commit09911bf2008-07-26 23:55:291777 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]aedd85a2008-12-04 19:32:491778 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
initial.commit09911bf2008-07-26 23:55:291779 return;
1780 }
1781
1782 NavigationController* nav = tab_tracker_->GetResource(handle);
1783 TabContents* tab_contents = nav->active_contents();
1784
1785 find_in_page_observer_.reset(new
1786 FindInPageNotificationObserver(this, tab_contents, message.routing_id()));
1787
[email protected]edc28612008-08-14 20:23:361788 // The find in page dialog must be up for us to get the notification that the
[email protected]9e0534b2008-10-21 15:03:011789 // find was complete.
1790 WebContents* web_contents = tab_contents->AsWebContents();
1791 if (web_contents) {
[email protected]edc28612008-08-14 20:23:361792 NavigationController* tab = tab_tracker_->GetResource(handle);
1793 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011794 web_contents->view()->FindInPage(*browser, true, request.forward);
[email protected]edc28612008-08-14 20:23:361795
[email protected]9e0534b2008-10-21 15:03:011796 web_contents->render_view_host()->StartFinding(
1797 FindInPageNotificationObserver::kFindInPageRequestId,
1798 request.search_string, request.forward, request.match_case,
1799 request.find_next);
1800 }
initial.commit09911bf2008-07-26 23:55:291801}
1802
[email protected]5f8af2a2008-08-06 22:49:451803void AutomationProvider::HandleOpenFindInPageRequest(
1804 const IPC::Message& message, int handle) {
[email protected]20e93d12008-08-28 16:31:571805 NavigationController* tab = NULL;
1806 WebContents* web_contents = GetWebContentsForHandle(handle, &tab);
1807 if (web_contents) {
[email protected]5f8af2a2008-08-06 22:49:451808 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011809 web_contents->view()->FindInPage(*browser, false, false);
[email protected]5f8af2a2008-08-06 22:49:451810 }
1811}
1812
[email protected]20e93d12008-08-28 16:31:571813void AutomationProvider::GetFindWindowVisibility(const IPC::Message& message,
1814 int handle) {
[email protected]9e0534b2008-10-21 15:03:011815 gfx::Point position;
[email protected]20e93d12008-08-28 16:31:571816 bool visible = false;
1817 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1818 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091819 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571820
1821 Send(new AutomationMsg_FindWindowVisibilityResponse(message.routing_id(),
1822 visible));
1823}
1824
1825void AutomationProvider::HandleFindWindowLocationRequest(
1826 const IPC::Message& message, int handle) {
[email protected]9e0534b2008-10-21 15:03:011827 gfx::Point position(0, 0);
1828 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571829 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1830 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091831 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571832
1833 Send(new AutomationMsg_FindWindowLocationResponse(message.routing_id(),
[email protected]9e0534b2008-10-21 15:03:011834 position.x(),
1835 position.y()));
[email protected]20e93d12008-08-28 16:31:571836}
1837
[email protected]c2cbeb92008-09-05 21:36:571838void AutomationProvider::GetBookmarkBarVisitility(const IPC::Message& message,
1839 int handle) {
1840 bool visible = false;
1841 bool animating = false;
1842
1843 void* iter = NULL;
1844 if (browser_tracker_->ContainsHandle(handle)) {
1845 Browser* browser = browser_tracker_->GetResource(handle);
1846 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:521847 BrowserWindowTesting* testing =
1848 browser->window()->GetBrowserWindowTesting();
1849 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:571850 if (bookmark_bar) {
1851 animating = bookmark_bar->IsAnimating();
1852 visible = browser->window()->IsBookmarkBarVisible();
1853 }
1854 }
1855 }
1856
1857 Send(new AutomationMsg_BookmarkBarVisibilityResponse(message.routing_id(),
1858 visible, animating));
1859}
1860
initial.commit09911bf2008-07-26 23:55:291861void AutomationProvider::HandleInspectElementRequest(
1862 const IPC::Message& message, int handle, int x, int y) {
[email protected]20e93d12008-08-28 16:31:571863 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1864 if (web_contents) {
[email protected]1f5af4442008-09-25 22:11:061865 web_contents->render_view_host()->InspectElementAt(x, y);
initial.commit09911bf2008-07-26 23:55:291866 inspect_element_routing_id_ = message.routing_id();
1867 } else {
1868 Send(new AutomationMsg_InspectElementResponse(message.routing_id(), -1));
1869 }
1870}
1871
1872void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
1873 Send(new AutomationMsg_InspectElementResponse(inspect_element_routing_id_,
1874 num_resources));
1875}
1876
1877// Helper class for making changes to the URLRequest ProtocolFactory on the
1878// IO thread.
1879class SetFilteredInetTask : public Task {
1880 public:
1881 explicit SetFilteredInetTask(bool enabled) : enabled_(enabled) { }
1882 virtual void Run() {
1883 if (enabled_) {
1884 URLRequestFilter::GetInstance()->ClearHandlers();
1885
1886 URLRequestFailedDnsJob::AddUITestUrls();
1887 URLRequestSlowDownloadJob::AddUITestUrls();
1888
1889 std::wstring root_http;
1890 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
1891 URLRequestMockHTTPJob::AddUITestUrls(root_http);
1892 } else {
1893 // Revert to the default handlers.
1894 URLRequestFilter::GetInstance()->ClearHandlers();
1895 }
1896 }
1897 private:
1898 bool enabled_;
1899};
1900
1901void AutomationProvider::SetFilteredInet(const IPC::Message& message,
1902 bool enabled) {
1903 // Since this involves changing the URLRequest ProtocolFactory, we want to
1904 // run on the main thread.
1905 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
1906 new SetFilteredInetTask(enabled));
1907}
1908
1909void AutomationProvider::GetDownloadDirectory(const IPC::Message& message,
1910 int handle) {
1911 DLOG(INFO) << "Handling download directory request";
1912 std::wstring download_directory;
1913 if (tab_tracker_->ContainsHandle(handle)) {
1914 NavigationController* tab = tab_tracker_->GetResource(handle);
1915 DownloadManager* dlm = tab->profile()->GetDownloadManager();
1916 DCHECK(dlm);
[email protected]7ae7c2cb2009-01-06 23:31:411917 download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:291918 }
1919
1920 Send(new AutomationMsg_DownloadDirectoryResponse(message.routing_id(),
1921 download_directory));
1922}
1923
1924void AutomationProvider::OpenNewBrowserWindow(int show_command) {
1925 // We may have no current browser windows open so don't rely on
1926 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:051927 Browser* browser = Browser::Create(profile_);
1928 browser->AddBlankTab(true);
1929 if (show_command != SW_HIDE)
1930 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:291931}
1932
1933void AutomationProvider::GetWindowForBrowser(const IPC::Message& message,
1934 int browser_handle) {
1935 bool success = false;
1936 int window_handle = 0;
1937
1938 if (browser_tracker_->ContainsHandle(browser_handle)) {
1939 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]2d46c842008-11-14 19:24:311940 HWND hwnd = reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
initial.commit09911bf2008-07-26 23:55:291941 // Add() returns the existing handle for the resource if any.
1942 window_handle = window_tracker_->Add(hwnd);
1943 success = true;
1944 }
1945 Send(new AutomationMsg_WindowForBrowserResponse(message.routing_id(),
1946 success, window_handle));
1947}
1948
1949void AutomationProvider::GetAutocompleteEditForBrowser(
1950 const IPC::Message& message,
1951 int browser_handle) {
1952 bool success = false;
1953 int autocomplete_edit_handle = 0;
1954
1955 if (browser_tracker_->ContainsHandle(browser_handle)) {
1956 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]7745b822009-01-27 20:15:351957 BrowserWindowTesting* testing_interface =
1958 browser->window()->GetBrowserWindowTesting();
1959 LocationBarView* loc_bar_view = testing_interface->GetLocationBarView();
[email protected]81c21222008-09-10 19:35:521960 AutocompleteEditView* edit_view = loc_bar_view->location_entry();
initial.commit09911bf2008-07-26 23:55:291961 // Add() returns the existing handle for the resource if any.
[email protected]81c21222008-09-10 19:35:521962 autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
initial.commit09911bf2008-07-26 23:55:291963 success = true;
1964 }
1965 Send(new AutomationMsg_AutocompleteEditForBrowserResponse(
1966 message.routing_id(), success, autocomplete_edit_handle));
1967}
1968
1969void AutomationProvider::GetBrowserForWindow(const IPC::Message& message,
1970 int window_handle) {
1971 bool success = false;
1972 int browser_handle = 0;
1973
1974 if (window_tracker_->ContainsHandle(window_handle)) {
1975 HWND window = window_tracker_->GetResource(window_handle);
1976 BrowserList::const_iterator iter = BrowserList::begin();
1977 Browser* browser = NULL;
1978 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:311979 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
1980 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:291981 browser = *iter;
1982 break;
1983 }
1984 }
1985 if (browser) {
1986 // Add() returns the existing handle for the resource if any.
1987 browser_handle = browser_tracker_->Add(browser);
1988 success = true;
1989 }
1990 }
1991 Send(new AutomationMsg_BrowserForWindowResponse(message.routing_id(),
1992 success, browser_handle));
1993}
1994
1995void AutomationProvider::ShowInterstitialPage(const IPC::Message& message,
1996 int tab_handle,
1997 const std::string& html_text) {
1998 if (tab_tracker_->ContainsHandle(tab_handle)) {
1999 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2000 TabContents* tab_contents = controller->active_contents();
2001 if (tab_contents->type() == TAB_CONTENTS_WEB) {
2002 AddNavigationStatusListener(controller,
2003 new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
2004 true),
2005 NULL);
2006 WebContents* web_contents = tab_contents->AsWebContents();
[email protected]cbab76d2008-10-13 22:42:472007 AutomationInterstitialPage* interstitial =
2008 new AutomationInterstitialPage(web_contents,
2009 GURL("about:interstitial"),
2010 html_text);
[email protected]a3a1d142008-12-19 00:42:302011 interstitial->Show();
initial.commit09911bf2008-07-26 23:55:292012 return;
2013 }
2014 }
2015 Send(new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
2016 false));
2017}
2018
2019void AutomationProvider::HideInterstitialPage(const IPC::Message& message,
2020 int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572021 WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
[email protected]a3a1d142008-12-19 00:42:302022 if (web_contents && web_contents->interstitial_page()) {
2023 web_contents->interstitial_page()->DontProceed();
[email protected]20e93d12008-08-28 16:31:572024 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2025 true));
2026 return;
initial.commit09911bf2008-07-26 23:55:292027 }
2028 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2029 false));
2030}
2031
2032void AutomationProvider::CloseTab(const IPC::Message& message,
2033 int tab_handle,
2034 bool wait_until_closed) {
2035 if (tab_tracker_->ContainsHandle(tab_handle)) {
2036 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2037 int index;
2038 Browser* browser = Browser::GetBrowserForController(controller, &index);
2039 DCHECK(browser);
2040 TabClosedNotificationObserver* observer =
2041 new TabClosedNotificationObserver(browser, this, message.routing_id(),
2042 wait_until_closed);
2043 browser->CloseContents(controller->active_contents());
2044 } else {
2045 Send(new AutomationMsg_CloseTabResponse(message.routing_id(), false));
2046 }
2047}
2048
2049void AutomationProvider::CloseBrowser(const IPC::Message& message,
2050 int browser_handle) {
2051 if (browser_tracker_->ContainsHandle(browser_handle)) {
2052 Browser* browser = browser_tracker_->GetResource(browser_handle);
2053 new BrowserClosedNotificationObserver(browser, this, message.routing_id());
[email protected]f3e99e32008-07-30 04:48:392054 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292055 } else {
2056 NOTREACHED();
2057 }
2058}
2059
[email protected]31fb110522009-01-28 21:50:392060void AutomationProvider::CreateExternalTab(const IPC::Message& message,
2061 HWND parent,
2062 const gfx::Rect& dimensions,
2063 unsigned int style) {
initial.commit09911bf2008-07-26 23:55:292064 int tab_handle = 0;
2065 HWND tab_container_window = NULL;
2066 ExternalTabContainer *external_tab_container =
2067 new ExternalTabContainer(this);
[email protected]31fb110522009-01-28 21:50:392068 external_tab_container->Init(profile_, parent, dimensions, style);
initial.commit09911bf2008-07-26 23:55:292069 TabContents* tab_contents = external_tab_container->tab_contents();
2070 if (tab_contents) {
2071 tab_handle = tab_tracker_->Add(tab_contents->controller());
2072 tab_container_window = *external_tab_container;
[email protected]31fb110522009-01-28 21:50:392073 } else {
2074 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292075 }
[email protected]31fb110522009-01-28 21:50:392076
initial.commit09911bf2008-07-26 23:55:292077 Send(new AutomationMsg_CreateExternalTabResponse(message.routing_id(),
2078 tab_container_window,
2079 tab_handle));
2080}
2081
2082void AutomationProvider::NavigateInExternalTab(const IPC::Message& message,
2083 int handle, const GURL& url) {
2084 bool status = false;
2085
2086 if (tab_tracker_->ContainsHandle(handle)) {
2087 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502088 tab->LoadURL(url, GURL(), PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:292089 status = true;
2090 }
2091
2092 Send(new AutomationMsg_NavigateInExternalTabResponse(message.routing_id(),
2093 status));
2094}
2095
2096void AutomationProvider::SetAcceleratorsForTab(const IPC::Message& message,
2097 int handle,
2098 HACCEL accel_table,
2099 int accel_entry_count) {
2100 bool status = false;
2101 if (tab_tracker_->ContainsHandle(handle)) {
2102 NavigationController* tab = tab_tracker_->GetResource(handle);
2103 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2104 ExternalTabContainer* external_tab_container =
2105 ExternalTabContainer::GetContainerForTab(
2106 tab_contents->GetContainerHWND());
2107 // This call is only valid on an externally hosted tab
2108 if (external_tab_container) {
2109 external_tab_container->SetAccelerators(accel_table,
2110 accel_entry_count);
2111 status = true;
2112 }
2113 }
2114 Send(new AutomationMsg_SetAcceleratorsForTabResponse(message.routing_id(),
2115 status));
2116}
2117
2118void AutomationProvider::ProcessUnhandledAccelerator(
2119 const IPC::Message& message, int handle, const MSG& msg) {
2120 if (tab_tracker_->ContainsHandle(handle)) {
2121 NavigationController* tab = tab_tracker_->GetResource(handle);
2122 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2123 ExternalTabContainer* external_tab_container =
2124 ExternalTabContainer::GetContainerForTab(
2125 tab_contents->GetContainerHWND());
2126 // This call is only valid on an externally hosted tab
2127 if (external_tab_container) {
2128 external_tab_container->ProcessUnhandledAccelerator(msg);
2129 }
2130 }
2131 // This message expects no response.
2132}
2133
2134void AutomationProvider::WaitForTabToBeRestored(
2135 const IPC::Message& message,
2136 int tab_handle) {
2137 if (tab_tracker_->ContainsHandle(tab_handle)) {
2138 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2139 restore_tracker_.reset(
2140 new NavigationControllerRestoredObserver(this, tab,
2141 message.routing_id()));
2142 }
2143}
2144
2145void AutomationProvider::GetSecurityState(const IPC::Message& message,
2146 int handle) {
2147 if (tab_tracker_->ContainsHandle(handle)) {
2148 NavigationController* tab = tab_tracker_->GetResource(handle);
2149 NavigationEntry* entry = tab->GetActiveEntry();
2150 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), true,
[email protected]eb34392b2008-08-19 15:42:202151 entry->ssl().security_style(), entry->ssl().cert_status(),
2152 entry->ssl().content_status()));
initial.commit09911bf2008-07-26 23:55:292153 } else {
2154 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), false,
2155 SECURITY_STYLE_UNKNOWN,
2156 0, 0));
2157 }
2158}
2159
2160void AutomationProvider::GetPageType(const IPC::Message& message, int handle) {
2161 if (tab_tracker_->ContainsHandle(handle)) {
2162 NavigationController* tab = tab_tracker_->GetResource(handle);
2163 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072164 NavigationEntry::PageType page_type = entry->page_type();
initial.commit09911bf2008-07-26 23:55:292165 // In order to return the proper result when an interstitial is shown and
2166 // no navigation entry were created for it we need to ask the WebContents.
2167 if (page_type == NavigationEntry::NORMAL_PAGE &&
2168 tab->active_contents()->AsWebContents() &&
[email protected]b6e09ac2008-08-12 16:11:092169 tab->active_contents()->AsWebContents()->showing_interstitial_page())
initial.commit09911bf2008-07-26 23:55:292170 page_type = NavigationEntry::INTERSTITIAL_PAGE;
2171
2172 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), true,
2173 page_type));
2174 } else {
2175 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), false,
2176 NavigationEntry::NORMAL_PAGE));
2177 }
2178}
2179
2180void AutomationProvider::ActionOnSSLBlockingPage(const IPC::Message& message,
2181 int handle, bool proceed) {
2182 if (tab_tracker_->ContainsHandle(handle)) {
2183 NavigationController* tab = tab_tracker_->GetResource(handle);
2184 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072185 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
initial.commit09911bf2008-07-26 23:55:292186 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
[email protected]cbab76d2008-10-13 22:42:472187 InterstitialPage* ssl_blocking_page =
[email protected]a3a1d142008-12-19 00:42:302188 InterstitialPage::GetInterstitialPage(tab_contents->AsWebContents());
initial.commit09911bf2008-07-26 23:55:292189 if (ssl_blocking_page) {
2190 if (proceed) {
2191 AddNavigationStatusListener(tab,
2192 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2193 message.routing_id(), true),
2194 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2195 message.routing_id(), true));
2196 ssl_blocking_page->Proceed();
2197 return;
2198 }
2199 ssl_blocking_page->DontProceed();
2200 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(
2201 message.routing_id(), true));
2202 return;
2203 }
2204 }
2205 }
2206 // We failed.
2207 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(message.routing_id(),
2208 false));
2209}
2210
2211void AutomationProvider::BringBrowserToFront(const IPC::Message& message,
2212 int browser_handle) {
2213 if (browser_tracker_->ContainsHandle(browser_handle)) {
2214 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062215 browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:292216 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2217 true));
2218 } else {
2219 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2220 false));
2221 }
2222}
2223
2224void AutomationProvider::IsPageMenuCommandEnabled(const IPC::Message& message,
2225 int browser_handle,
2226 int message_num) {
2227 if (browser_tracker_->ContainsHandle(browser_handle)) {
2228 Browser* browser = browser_tracker_->GetResource(browser_handle);
2229 bool menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142230 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292231 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2232 message.routing_id(), menu_item_enabled));
2233 } else {
2234 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2235 message.routing_id(), false));
2236 }
2237}
2238
2239void AutomationProvider::PrintNow(const IPC::Message& message, int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572240 NavigationController* tab = NULL;
2241 WebContents* web_contents = GetWebContentsForHandle(tab_handle, &tab);
2242 if (web_contents) {
initial.commit09911bf2008-07-26 23:55:292243 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572244 notification_observer_list_.AddObserver(
2245 new DocumentPrintedNotificationObserver(this, message.routing_id()));
2246 if (web_contents->PrintNow())
2247 return;
initial.commit09911bf2008-07-26 23:55:292248 }
2249 Send(new AutomationMsg_PrintNowResponse(message.routing_id(), false));
2250}
2251
2252void AutomationProvider::SavePage(const IPC::Message& message,
2253 int tab_handle,
2254 const std::wstring& file_name,
2255 const std::wstring& dir_path,
2256 int type) {
2257 if (!tab_tracker_->ContainsHandle(tab_handle)) {
2258 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2259 return;
2260 }
2261
2262 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2263 Browser* browser = FindAndActivateTab(nav);
2264 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142265 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
initial.commit09911bf2008-07-26 23:55:292266 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2267 return;
2268 }
2269
2270 TabContents* tab_contents = nav->active_contents();
2271 if (tab_contents->type() != TAB_CONTENTS_WEB) {
2272 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2273 return;
2274 }
2275
2276 SavePackage::SavePackageType save_type =
2277 static_cast<SavePackage::SavePackageType>(type);
2278 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2279 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
2280 tab_contents->AsWebContents()->SavePage(file_name, dir_path, save_type);
2281
2282 Send(new AutomationMsg_SavePageResponse(
2283 message.routing_id(), true));
2284}
2285
2286void AutomationProvider::GetAutocompleteEditText(const IPC::Message& message,
2287 int autocomplete_edit_handle) {
2288 bool success = false;
2289 std::wstring text;
2290 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522291 text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2292 GetText();
initial.commit09911bf2008-07-26 23:55:292293 success = true;
2294 }
2295 Send(new AutomationMsg_AutocompleteEditGetTextResponse(message.routing_id(),
2296 success, text));
2297}
2298
2299void AutomationProvider::SetAutocompleteEditText(const IPC::Message& message,
2300 int autocomplete_edit_handle,
2301 const std::wstring& text) {
2302 bool success = false;
2303 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522304 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2305 SetUserText(text);
initial.commit09911bf2008-07-26 23:55:292306 success = true;
2307 }
2308 Send(new AutomationMsg_AutocompleteEditSetTextResponse(
2309 message.routing_id(), success));
2310}
2311
2312void AutomationProvider::AutocompleteEditGetMatches(
2313 const IPC::Message& message,
2314 int autocomplete_edit_handle) {
2315 bool success = false;
2316 std::vector<AutocompleteMatchData> matches;
2317 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272318 const AutocompleteResult& result = autocomplete_edit_tracker_->
2319 GetResource(autocomplete_edit_handle)->model()->result();
2320 for (AutocompleteResult::const_iterator i = result.begin();
2321 i != result.end(); ++i)
initial.commit09911bf2008-07-26 23:55:292322 matches.push_back(AutocompleteMatchData(*i));
2323 success = true;
2324 }
2325 Send(new AutomationMsg_AutocompleteEditGetMatchesResponse(
2326 message.routing_id(), success, matches));
2327}
2328
2329void AutomationProvider::AutocompleteEditIsQueryInProgress(
2330 const IPC::Message& message,
2331 int autocomplete_edit_handle) {
2332 bool success = false;
2333 bool query_in_progress = false;
2334 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522335 query_in_progress = autocomplete_edit_tracker_->
2336 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
initial.commit09911bf2008-07-26 23:55:292337 success = true;
2338 }
2339 Send(new AutomationMsg_AutocompleteEditIsQueryInProgressResponse(
2340 message.routing_id(), success, query_in_progress));
2341}
2342
[email protected]18cb2572008-08-21 20:34:452343void AutomationProvider::OnMessageFromExternalHost(
2344 int handle, const std::string& target, const std::string& message) {
[email protected]fa83e762008-08-15 21:41:392345 if (tab_tracker_->ContainsHandle(handle)) {
2346 NavigationController* tab = tab_tracker_->GetResource(handle);
2347 if (!tab) {
2348 NOTREACHED();
2349 return;
2350 }
2351 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2352 if (!tab_contents) {
2353 NOTREACHED();
2354 return;
2355 }
2356
2357 WebContents* web_contents = tab_contents->AsWebContents();
2358 if (!web_contents) {
2359 NOTREACHED();
2360 return;
2361 }
2362
2363 RenderViewHost* view_host = web_contents->render_view_host();
2364 if (!view_host) {
2365 return;
2366 }
2367
[email protected]18cb2572008-08-21 20:34:452368 view_host->ForwardMessageFromExternalHost(target, message);
[email protected]fa83e762008-08-15 21:41:392369 }
2370}
2371
[email protected]20e93d12008-08-28 16:31:572372WebContents* AutomationProvider::GetWebContentsForHandle(
2373 int handle, NavigationController** tab) {
2374 WebContents* web_contents = NULL;
2375 if (tab_tracker_->ContainsHandle(handle)) {
2376 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2377 TabContents* tab_contents = nav_controller->active_contents();
2378 if (tab_contents && tab_contents->type() == TAB_CONTENTS_WEB) {
2379 web_contents = tab_contents->AsWebContents();
2380 if (tab)
2381 *tab = nav_controller;
2382 }
2383 }
2384 return web_contents;
2385}
2386
initial.commit09911bf2008-07-26 23:55:292387TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2388 : AutomationProvider(profile) {
2389 BrowserList::AddObserver(this);
[email protected]bfd04a62009-02-01 18:16:562390 NotificationService::current()->AddObserver(
2391 this,
2392 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292393 NotificationService::AllSources());
2394}
2395
2396TestingAutomationProvider::~TestingAutomationProvider() {
[email protected]bfd04a62009-02-01 18:16:562397 NotificationService::current()->RemoveObserver(
2398 this,
2399 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292400 NotificationService::AllSources());
2401 BrowserList::RemoveObserver(this);
2402}
2403
2404void TestingAutomationProvider::OnChannelError() {
2405 BrowserList::CloseAllBrowsers(true);
2406 AutomationProvider::OnChannelError();
2407}
2408
2409void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2410 // For backwards compatibility with the testing automation interface, we
2411 // want the automation provider (and hence the process) to go away when the
2412 // last browser goes away.
2413 if (BrowserList::size() == 1) {
[email protected]bfd04a62009-02-01 18:16:562414 // If you change this, update Observer for NotificationType::SESSION_END below.
[email protected]295039bd2008-08-15 04:32:572415 MessageLoop::current()->PostTask(FROM_HERE,
2416 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292417 }
2418}
2419
2420void TestingAutomationProvider::Observe(NotificationType type,
2421 const NotificationSource& source,
2422 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562423 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292424 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2425 // before the task runs resulting in this object not being deleted. This
2426 // Release balance out the Release scheduled by OnBrowserRemoving.
2427 Release();
2428}
[email protected]295039bd2008-08-15 04:32:572429
2430void TestingAutomationProvider::OnRemoveProvider() {
2431 AutomationProviderList::GetInstance()->RemoveProvider(this);
2432}
[email protected]8a3422c92008-09-24 17:42:422433
2434void AutomationProvider::GetSSLInfoBarCount(const IPC::Message& message,
2435 int handle) {
2436 int count = -1; // -1 means error.
2437 if (tab_tracker_->ContainsHandle(handle)) {
2438 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342439 if (nav_controller)
2440 count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422441 }
2442 Send(new AutomationMsg_GetSSLInfoBarCountResponse(message.routing_id(),
2443 count));
2444}
2445
2446void AutomationProvider::ClickSSLInfoBarLink(const IPC::Message& message,
2447 int handle,
2448 int info_bar_index,
2449 bool wait_for_navigation) {
2450 bool success = false;
2451 if (tab_tracker_->ContainsHandle(handle)) {
2452 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2453 if (nav_controller) {
[email protected]eb9ba192008-12-02 02:41:342454 int count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422455 if (info_bar_index >= 0 && info_bar_index < count) {
2456 if (wait_for_navigation) {
2457 AddNavigationStatusListener(nav_controller,
2458 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2459 message.routing_id(), true),
2460 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2461 message.routing_id(), true));
2462 }
[email protected]eb9ba192008-12-02 02:41:342463 InfoBarDelegate* delegate =
2464 nav_controller->active_contents()->GetInfoBarDelegateAt(
2465 info_bar_index);
2466 if (delegate->AsConfirmInfoBarDelegate())
2467 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422468 success = true;
2469 }
2470 }
2471 }
2472 if (!wait_for_navigation || !success)
2473 Send(new AutomationMsg_ClickSSLInfoBarLinkResponse(message.routing_id(),
2474 success));
2475}
2476
2477void AutomationProvider::GetLastNavigationTime(const IPC::Message& message,
2478 int handle) {
2479 Time time = tab_tracker_->GetLastNavigationTime(handle);
2480 Send(new AutomationMsg_GetLastNavigationTimeResponse(message.routing_id(),
2481 time.ToInternalValue()));
2482}
2483
2484void AutomationProvider::WaitForNavigation(const IPC::Message& message,
2485 int handle,
2486 int64 last_navigation_time) {
2487 NavigationController* controller = NULL;
2488 if (tab_tracker_->ContainsHandle(handle))
2489 controller = tab_tracker_->GetResource(handle);
2490
2491 Time time = tab_tracker_->GetLastNavigationTime(handle);
2492 if (time.ToInternalValue() > last_navigation_time || !controller) {
2493 Send(new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2494 controller != NULL));
2495 return;
2496 }
2497
2498 AddNavigationStatusListener(controller,
2499 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2500 true),
2501 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2502 true));
2503}
2504
2505void AutomationProvider::SetIntPreference(const IPC::Message& message,
2506 int handle,
[email protected]97fa6ce32008-12-19 01:48:162507 const std::wstring& name,
[email protected]8a3422c92008-09-24 17:42:422508 int value) {
2509 bool success = false;
2510 if (browser_tracker_->ContainsHandle(handle)) {
2511 Browser* browser = browser_tracker_->GetResource(handle);
2512 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
2513 success = true;
2514 }
2515 Send(new AutomationMsg_SetIntPreferenceResponse(message.routing_id(),
2516 success));
2517}
[email protected]97fa6ce32008-12-19 01:48:162518
2519void AutomationProvider::SetStringPreference(const IPC::Message& message,
2520 int handle,
2521 const std::wstring& name,
2522 const std::wstring& value) {
2523 bool success = false;
2524 if (browser_tracker_->ContainsHandle(handle)) {
2525 Browser* browser = browser_tracker_->GetResource(handle);
2526 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
2527 success = true;
2528 }
2529 Send(new AutomationMsg_SetStringPreferenceResponse(message.routing_id(),
2530 success));
2531}
2532
2533void AutomationProvider::GetBooleanPreference(const IPC::Message& message,
2534 int handle,
2535 const std::wstring& name) {
2536 bool success = false;
2537 bool value = false;
2538 if (browser_tracker_->ContainsHandle(handle)) {
2539 Browser* browser = browser_tracker_->GetResource(handle);
2540 value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2541 success = true;
2542 }
2543 Send(new AutomationMsg_GetBooleanPreferenceResponse(message.routing_id(),
2544 success, value));
2545}
2546
2547void AutomationProvider::SetBooleanPreference(const IPC::Message& message,
2548 int handle,
2549 const std::wstring& name,
2550 bool value) {
2551 bool success = false;
2552 if (browser_tracker_->ContainsHandle(handle)) {
2553 Browser* browser = browser_tracker_->GetResource(handle);
2554 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
2555 success = true;
2556 }
2557 Send(new AutomationMsg_SetBooleanPreferenceResponse(message.routing_id(),
2558 success));
2559}
2560
2561// Gets the current used encoding name of the page in the specified tab.
2562void AutomationProvider::GetPageCurrentEncoding(const IPC::Message& message,
2563 int tab_handle) {
2564 std::wstring current_encoding;
2565 if (tab_tracker_->ContainsHandle(tab_handle)) {
2566 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2567 Browser* browser = FindAndActivateTab(nav);
2568 DCHECK(browser);
2569
[email protected]1fc025202009-01-20 23:03:142570 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162571 TabContents* tab_contents = nav->active_contents();
2572 DCHECK(tab_contents->type() == TAB_CONTENTS_WEB);
2573 current_encoding = tab_contents->AsWebContents()->encoding();
2574 }
2575 }
2576 Send(new AutomationMsg_GetPageCurrentEncodingResponse(message.routing_id(),
2577 current_encoding));
2578}
2579
2580// Gets the current used encoding name of the page in the specified tab.
2581void AutomationProvider::OverrideEncoding(const IPC::Message& message,
2582 int tab_handle,
2583 const std::wstring& encoding_name) {
2584 bool succeed = false;
2585 if (tab_tracker_->ContainsHandle(tab_handle)) {
2586 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2587 Browser* browser = FindAndActivateTab(nav);
2588 DCHECK(browser);
2589
[email protected]1fc025202009-01-20 23:03:142590 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162591 TabContents* tab_contents = nav->active_contents();
2592 DCHECK(tab_contents->type() == TAB_CONTENTS_WEB);
2593 int selected_encoding_id =
2594 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2595 if (selected_encoding_id) {
2596 browser->OverrideEncoding(selected_encoding_id);
2597 succeed = true;
2598 }
2599 }
2600 }
2601 Send(new AutomationMsg_OverrideEncodingResponse(message.routing_id(),
2602 succeed));
2603}
[email protected]5bcdb312009-01-07 21:43:202604
2605void AutomationProvider::SavePackageShouldPromptUser(
2606 const IPC::Message& message, bool should_prompt) {
2607 SavePackage::SetShouldPromptUser(should_prompt);
2608}