blob: 5ec7ffdd300507ed3421ec295f5d451164f72830 [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]fa83e762008-08-15 21:41:3924#include "chrome/browser/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]6a02963e2009-01-06 16:58:0350 registrar_.Add(this, NOTIFY_LOAD_START,
51 NotificationService::AllSources());
52 registrar_.Add(this, NOTIFY_LOAD_STOP,
53 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) {
68 if (type == NOTIFY_LOAD_START) {
69 if (outstanding_tab_count_ > loading_tabs_.size())
70 loading_tabs_.insert(source.map_key());
71 } else if (type == NOTIFY_LOAD_STOP) {
72 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) {
99 NotificationService::current()->
100 AddObserver(this, NOTIFY_INITIAL_NEW_TAB_UI_LOAD,
101 NotificationService::AllSources());
102 }
103
104 ~NewTabUILoadObserver() {
105 Unregister();
106 }
107
108 void Unregister() {
109 NotificationService::current()->
110 RemoveObserver(this, NOTIFY_INITIAL_NEW_TAB_UI_LOAD,
111 NotificationService::AllSources());
112 }
113
114 virtual void Observe(NotificationType type,
115 const NotificationSource& source,
116 const NotificationDetails& details) {
117 if (type == NOTIFY_INITIAL_NEW_TAB_UI_LOAD) {
118 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();
144 service->AddObserver(this, NOTIFY_LOAD_STOP,
145 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();
166 service->RemoveObserver(this, NOTIFY_LOAD_STOP,
167 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]8a3422c92008-09-24 17:42:42200 service->AddObserver(this, NOTIFY_NAV_ENTRY_COMMITTED,
201 Source<NavigationController>(controller_));
initial.commit09911bf2008-07-26 23:55:29202 service->AddObserver(this, NOTIFY_LOAD_START,
203 Source<NavigationController>(controller_));
204 service->AddObserver(this, NOTIFY_LOAD_STOP,
205 Source<NavigationController>(controller_));
206 service->AddObserver(this, NOTIFY_AUTH_NEEDED,
207 Source<NavigationController>(controller_));
208 service->AddObserver(this, NOTIFY_AUTH_SUPPLIED,
209 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]8a3422c92008-09-24 17:42:42229 service->RemoveObserver(this, NOTIFY_NAV_ENTRY_COMMITTED,
230 Source<NavigationController>(controller_));
initial.commit09911bf2008-07-26 23:55:29231 service->RemoveObserver(this, NOTIFY_LOAD_START,
232 Source<NavigationController>(controller_));
233 service->RemoveObserver(this, NOTIFY_LOAD_STOP,
234 Source<NavigationController>(controller_));
235 service->RemoveObserver(this, NOTIFY_AUTH_NEEDED,
236 Source<NavigationController>(controller_));
237 service->RemoveObserver(this, NOTIFY_AUTH_SUPPLIED,
238 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
249 // a NOTIFY_NAV_ENTRY_COMMITTED until after we authenticate, so we need the
250 // NOTIFY_LOAD_START.
251 if (type == NOTIFY_NAV_ENTRY_COMMITTED || type == NOTIFY_LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29252 navigation_started_ = true;
253 } else if (type == NOTIFY_LOAD_STOP) {
254 if (navigation_started_) {
255 navigation_started_ = false;
256 ConditionMet(&completed_response_);
257 }
258 } else if (type == NOTIFY_AUTH_SUPPLIED) {
259 // The LoginHandler for this tab is no longer valid.
260 automation_->RemoveLoginHandler(controller_);
261
262 // Treat this as if navigation started again, since load start/stop don't
263 // occur while authentication is ongoing.
264 navigation_started_ = true;
265 } else if (type == NOTIFY_AUTH_NEEDED) {
266 if (navigation_started_) {
267 // Remember the login handler that wants authentication.
268 LoginHandler* handler =
269 Details<LoginNotificationDetails>(details)->handler();
270 automation_->AddLoginHandler(controller_, handler);
271
272 // Respond that authentication is needed.
273 navigation_started_ = false;
274 ConditionMet(&auth_needed_response_);
275 } else {
276 NOTREACHED();
277 }
278 } else {
279 NOTREACHED();
280 }
281 }
282
283 private:
284 AutomationProvider* automation_;
285 IPC::Message* completed_response_;
286 IPC::Message* auth_needed_response_;
287 NavigationController* controller_;
288 bool navigation_started_;
289};
290
291class TabStripNotificationObserver : public NotificationObserver {
292 public:
293 TabStripNotificationObserver(Browser* parent, NotificationType notification,
294 AutomationProvider* automation, int32 routing_id)
295 : automation_(automation),
296 notification_(notification),
297 parent_(parent),
298 routing_id_(routing_id) {
299 NotificationService::current()->
300 AddObserver(this, notification_, NotificationService::AllSources());
301 }
302
303 virtual ~TabStripNotificationObserver() {
304 Unregister();
305 }
306
307 void Unregister() {
308 NotificationService::current()->
309 RemoveObserver(this, notification_, NotificationService::AllSources());
310 }
311
312 virtual void Observe(NotificationType type,
313 const NotificationSource& source,
314 const NotificationDetails& details) {
315 if (type == notification_) {
316 ObserveTab(Source<NavigationController>(source).ptr());
317
318 // If verified, no need to observe anymore
319 automation_->RemoveTabStripObserver(this);
320 delete this;
321 } else {
322 NOTREACHED();
323 }
324 }
325
326 virtual void ObserveTab(NavigationController* controller) = 0;
327
328 protected:
329 AutomationProvider* automation_;
330 Browser* parent_;
331 NotificationType notification_;
332 int32 routing_id_;
333};
334
335class TabAppendedNotificationObserver : public TabStripNotificationObserver {
336 public:
337 TabAppendedNotificationObserver(Browser* parent,
338 AutomationProvider* automation, int32 routing_id)
[email protected]534e54b2008-08-13 15:40:09339 : TabStripNotificationObserver(parent, NOTIFY_TAB_PARENTED, automation,
initial.commit09911bf2008-07-26 23:55:29340 routing_id) {
341 }
342
343 virtual void ObserveTab(NavigationController* controller) {
344 int tab_index =
345 automation_->GetIndexForNavigationController(controller, parent_);
346 if (tab_index == TabStripModel::kNoTab) {
347 // This tab notification doesn't belong to the parent_
348 return;
349 }
350
351 // Give the same response even if auth is needed, since it doesn't matter.
352 automation_->AddNavigationStatusListener(controller,
353 new AutomationMsg_AppendTabResponse(routing_id_, tab_index),
354 new AutomationMsg_AppendTabResponse(routing_id_, tab_index));
355 }
356};
357
358class TabClosedNotificationObserver : public TabStripNotificationObserver {
359 public:
360 TabClosedNotificationObserver(Browser* parent,
361 AutomationProvider* automation,
362 int32 routing_id,
363 bool wait_until_closed)
364 : TabStripNotificationObserver(parent,
365 wait_until_closed ? NOTIFY_TAB_CLOSED :
366 NOTIFY_TAB_CLOSING,
367 automation,
368 routing_id) {
369 }
370
371 virtual void ObserveTab(NavigationController* controller) {
372 automation_->Send(new AutomationMsg_CloseTabResponse(routing_id_, true));
373 }
374};
375
376class BrowserClosedNotificationObserver : public NotificationObserver {
377 public:
378 BrowserClosedNotificationObserver(Browser* browser,
379 AutomationProvider* automation,
380 int32 routing_id)
381 : automation_(automation),
382 routing_id_(routing_id) {
383 NotificationService::current()->
384 AddObserver(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(browser));
385 }
386
387 virtual void Observe(NotificationType type,
388 const NotificationSource& source,
389 const NotificationDetails& details) {
390 DCHECK(type == NOTIFY_BROWSER_CLOSED);
391 Details<bool> close_app(details);
392 automation_->Send(
393 new AutomationMsg_CloseBrowserResponse(routing_id_,
394 true,
395 *(close_app.ptr())));
396 delete this;
397 }
398
399 private:
400 AutomationProvider* automation_;
401 int32 routing_id_;
402};
403
404class FindInPageNotificationObserver : public NotificationObserver {
405 public:
406 FindInPageNotificationObserver(AutomationProvider* automation,
407 TabContents* parent_tab,
408 int32 routing_id)
409 : automation_(automation),
410 parent_tab_(parent_tab),
[email protected]aedd85a2008-12-04 19:32:49411 routing_id_(routing_id),
412 active_match_ordinal_(-1) {
initial.commit09911bf2008-07-26 23:55:29413 NotificationService::current()->
414 AddObserver(this, NOTIFY_FIND_RESULT_AVAILABLE,
415 Source<TabContents>(parent_tab_));
416 }
417
418 ~FindInPageNotificationObserver() {
419 Unregister();
420 }
421
422 void Unregister() {
423 NotificationService::current()->
424 RemoveObserver(this, NOTIFY_FIND_RESULT_AVAILABLE,
425 Source<TabContents>(parent_tab_));
426 }
427
428 virtual void Observe(NotificationType type, const NotificationSource& source,
429 const NotificationDetails& details) {
430 if (type == NOTIFY_FIND_RESULT_AVAILABLE) {
431 Details<FindNotificationDetails> find_details(details);
432 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49433 // We get multiple responses and one of those will contain the ordinal.
434 // This message comes to us before the final update is sent.
435 if (find_details->active_match_ordinal() > -1)
436 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29437 if (find_details->final_update()) {
[email protected]aedd85a2008-12-04 19:32:49438 automation_->Send(new AutomationMsg_FindInPageResponse2(routing_id_,
439 active_match_ordinal_,
initial.commit09911bf2008-07-26 23:55:29440 find_details->number_of_matches()));
441 } else {
442 DLOG(INFO) << "Ignoring, since we only care about the final message";
443 }
444 }
445 } else {
446 NOTREACHED();
447 }
448 }
449
450 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
451 // we wait for notification to find out what the results are. As the user is
452 // typing, new search requests can be issued and the Request ID helps us make
453 // sense of whether this is the current request or an old one. The unit tests,
454 // however, which uses this constant issues only one search at a time, so we
455 // don't need a rolling id to identify each search. But, we still need to
456 // specify one, so we just use a fixed one - its value does not matter.
457 static const int kFindInPageRequestId;
458 private:
459 AutomationProvider* automation_;
460 TabContents* parent_tab_;
461 int32 routing_id_;
[email protected]aedd85a2008-12-04 19:32:49462 // We will at some point (before final update) be notified of the ordinal and
463 // we need to preserve it so we can send it later.
464 int active_match_ordinal_;
initial.commit09911bf2008-07-26 23:55:29465};
466
467const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
468
469class DomOperationNotificationObserver : public NotificationObserver {
470 public:
471 explicit DomOperationNotificationObserver(AutomationProvider* automation)
472 : automation_(automation) {
473 NotificationService::current()->
474 AddObserver(this, NOTIFY_DOM_OPERATION_RESPONSE,
475 NotificationService::AllSources());
476 }
477
478 ~DomOperationNotificationObserver() {
479 NotificationService::current()->
480 RemoveObserver(this, NOTIFY_DOM_OPERATION_RESPONSE,
481 NotificationService::AllSources());
482 }
483
484 virtual void Observe(NotificationType type, const NotificationSource& source,
485 const NotificationDetails& details) {
486 if (NOTIFY_DOM_OPERATION_RESPONSE == type) {
487 Details<DomOperationNotificationDetails> dom_op_details(details);
488 automation_->Send(new AutomationMsg_DomOperationResponse(
489 dom_op_details->automation_id(),
490 dom_op_details->json()));
491 }
492 }
493 private:
494 AutomationProvider* automation_;
495};
496
497class DomInspectorNotificationObserver : public NotificationObserver {
498 public:
499 explicit DomInspectorNotificationObserver(AutomationProvider* automation)
500 : automation_(automation) {
501 NotificationService::current()->
502 AddObserver(this, NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE,
503 NotificationService::AllSources());
504 }
505
506 ~DomInspectorNotificationObserver() {
507 NotificationService::current()->
508 RemoveObserver(this, NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE,
509 NotificationService::AllSources());
510 }
511
512 virtual void Observe(NotificationType type, const NotificationSource& source,
513 const NotificationDetails& details) {
514 if (NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE == type) {
515 Details<int> dom_inspect_details(details);
516 automation_->ReceivedInspectElementResponse(*(dom_inspect_details.ptr()));
517 }
518 }
519
520 private:
521 AutomationProvider* automation_;
522};
523
524class DocumentPrintedNotificationObserver : public NotificationObserver {
525 public:
526 DocumentPrintedNotificationObserver(AutomationProvider* automation,
527 int32 routing_id)
528 : automation_(automation),
529 routing_id_(routing_id),
530 success_(false) {
531 NotificationService::current()->
532 AddObserver(this, NOTIFY_PRINT_JOB_EVENT,
533 NotificationService::AllSources());
534 }
535
536 ~DocumentPrintedNotificationObserver() {
537 automation_->Send(
538 new AutomationMsg_PrintNowResponse(routing_id_, success_));
539 automation_->RemoveNavigationStatusListener(this);
540 NotificationService::current()->
541 RemoveObserver(this, NOTIFY_PRINT_JOB_EVENT,
542 NotificationService::AllSources());
543 }
544
545 virtual void Observe(NotificationType type, const NotificationSource& source,
546 const NotificationDetails& details) {
547 using namespace printing;
548 DCHECK(type == NOTIFY_PRINT_JOB_EVENT);
549 switch (Details<JobEventDetails>(details)->type()) {
550 case JobEventDetails::JOB_DONE: {
551 // Succeeded.
552 success_ = true;
553 delete this;
554 break;
555 }
556 case JobEventDetails::USER_INIT_CANCELED:
557 case JobEventDetails::FAILED: {
558 // Failed.
559 delete this;
560 break;
561 }
562 case JobEventDetails::NEW_DOC:
563 case JobEventDetails::USER_INIT_DONE:
564 case JobEventDetails::DEFAULT_INIT_DONE:
565 case JobEventDetails::NEW_PAGE:
566 case JobEventDetails::PAGE_DONE:
567 case JobEventDetails::DOC_DONE:
568 case JobEventDetails::ALL_PAGES_REQUESTED: {
569 // Don't care.
570 break;
571 }
572 default: {
573 NOTREACHED();
574 break;
575 }
576 }
577 }
578
579 private:
580 scoped_refptr<AutomationProvider> automation_;
581 int32 routing_id_;
582 bool success_;
583};
584
[email protected]cbab76d2008-10-13 22:42:47585class AutomationInterstitialPage : public InterstitialPage {
586 public:
[email protected]a3a1d142008-12-19 00:42:30587 AutomationInterstitialPage(WebContents* tab,
[email protected]cbab76d2008-10-13 22:42:47588 const GURL& url,
589 const std::string& contents)
590 : InterstitialPage(tab, true, url),
591 contents_(contents) {
592 }
593
594 virtual std::string GetHTMLContents() { return contents_; }
595
596 private:
597 std::string contents_;
598
599 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
600};
601
initial.commit09911bf2008-07-26 23:55:29602AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57603 : redirect_query_(0),
initial.commit09911bf2008-07-26 23:55:29604 profile_(profile) {
initial.commit09911bf2008-07-26 23:55:29605 browser_tracker_.reset(new AutomationBrowserTracker(this));
606 window_tracker_.reset(new AutomationWindowTracker(this));
607 tab_tracker_.reset(new AutomationTabTracker(this));
608 autocomplete_edit_tracker_.reset(
609 new AutomationAutocompleteEditTracker(this));
610 cwindow_tracker_.reset(new AutomationConstrainedWindowTracker(this));
611 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
612 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
613 dom_inspector_observer_.reset(new DomInspectorNotificationObserver(this));
614}
615
616AutomationProvider::~AutomationProvider() {
[email protected]0da050b92008-08-19 19:29:47617 // Make sure that any outstanding NotificationObservers also get destroyed.
618 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31619 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47620 while ((observer = it.GetNext()) != NULL)
621 delete observer;
initial.commit09911bf2008-07-26 23:55:29622}
623
624void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) {
[email protected]295039bd2008-08-15 04:32:57625 channel_.reset(
626 new IPC::ChannelProxy(channel_id, IPC::Channel::MODE_CLIENT, this, NULL,
627 g_browser_process->io_thread()->message_loop()));
628 channel_->Send(new AutomationMsg_Hello(0));
initial.commit09911bf2008-07-26 23:55:29629}
630
631void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
632 if (expected_tabs == 0) {
633 Send(new AutomationMsg_InitialLoadsComplete(0));
634 } else {
635 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
636 }
637}
638
639NotificationObserver* AutomationProvider::AddNavigationStatusListener(
640 NavigationController* tab, IPC::Message* completed_response,
641 IPC::Message* auth_needed_response) {
642 NotificationObserver* observer =
643 new NavigationNotificationObserver(tab, this, completed_response,
644 auth_needed_response);
645 notification_observer_list_.AddObserver(observer);
646
647 return observer;
648}
649
650void AutomationProvider::RemoveNavigationStatusListener(
651 NotificationObserver* obs) {
652 notification_observer_list_.RemoveObserver(obs);
653}
654
655NotificationObserver* AutomationProvider::AddTabStripObserver(
656 Browser* parent, int32 routing_id) {
657 NotificationObserver* observer = new
658 TabAppendedNotificationObserver(parent, this, routing_id);
659 notification_observer_list_.AddObserver(observer);
660
661 return observer;
662}
663
664void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
665 notification_observer_list_.RemoveObserver(obs);
666}
667
668void AutomationProvider::AddLoginHandler(NavigationController* tab,
669 LoginHandler* handler) {
670 login_handler_map_[tab] = handler;
671}
672
673void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
674 DCHECK(login_handler_map_[tab]);
675 login_handler_map_.erase(tab);
676}
677
678int AutomationProvider::GetIndexForNavigationController(
679 const NavigationController* controller, const Browser* parent) const {
680 DCHECK(parent);
681 return parent->GetIndexOfController(controller);
682}
683
684void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
685 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
686 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequest, CloseBrowser)
687 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTabRequest, ActivateTab)
688 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndexRequest, GetActiveTabIndex)
689 IPC_MESSAGE_HANDLER(AutomationMsg_AppendTabRequest, AppendTab)
690 IPC_MESSAGE_HANDLER(AutomationMsg_CloseTabRequest, CloseTab)
691 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesRequest, GetCookies)
692 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieRequest, SetCookie)
693 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateToURLRequest, NavigateToURL)
694 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncRequest, NavigationAsync)
695 IPC_MESSAGE_HANDLER(AutomationMsg_GoBackRequest, GoBack)
696 IPC_MESSAGE_HANDLER(AutomationMsg_GoForwardRequest, GoForward)
697 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadRequest, Reload)
698 IPC_MESSAGE_HANDLER(AutomationMsg_SetAuthRequest, SetAuth)
699 IPC_MESSAGE_HANDLER(AutomationMsg_CancelAuthRequest, CancelAuth)
700 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuthRequest, NeedsAuth)
701 IPC_MESSAGE_HANDLER(AutomationMsg_RedirectsFromRequest, GetRedirectsFrom)
702 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCountRequest,
703 GetBrowserWindowCount)
704 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowRequest, GetBrowserWindow)
705 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindowRequest,
706 GetLastActiveBrowserWindow)
707 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindowRequest, GetActiveWindow)
708 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActiveRequest, IsWindowActive)
709 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow);
710 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWNDRequest, GetWindowHWND)
[email protected]4ae62752008-08-04 23:28:47711 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandRequest,
712 ExecuteBrowserCommand)
initial.commit09911bf2008-07-26 23:55:29713 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBoundsRequest,
714 WindowGetViewBounds)
715 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisibleRequest, SetWindowVisible)
716 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClickRequest, WindowSimulateClick)
717 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPressRequest,
718 WindowSimulateKeyPress)
719 IPC_MESSAGE_HANDLER(AutomationMsg_WindowDragRequest, WindowSimulateDrag)
720 IPC_MESSAGE_HANDLER(AutomationMsg_TabCountRequest, GetTabCount)
721 IPC_MESSAGE_HANDLER(AutomationMsg_TabRequest, GetTab)
722 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWNDRequest, GetTabHWND)
723 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessIDRequest, GetTabProcessID)
724 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitleRequest, GetTabTitle)
725 IPC_MESSAGE_HANDLER(AutomationMsg_TabURLRequest, GetTabURL)
726 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibilityRequest,
727 GetShelfVisibility)
728 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
729 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAcceleratorRequest, ApplyAccelerator)
730 IPC_MESSAGE_HANDLER(AutomationMsg_DomOperationRequest, ExecuteJavascript)
731 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCountRequest,
732 GetConstrainedWindowCount)
733 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowRequest,
734 GetConstrainedWindow)
735 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedTitleRequest,
736 GetConstrainedTitle)
737 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPageRequest,
738 HandleFindInPageRequest)
739 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewIDRequest, GetFocusedViewID)
740 IPC_MESSAGE_HANDLER(AutomationMsg_InspectElementRequest,
741 HandleInspectElementRequest)
742 IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet,
743 SetFilteredInet);
744 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectoryRequest,
745 GetDownloadDirectory);
746 IPC_MESSAGE_HANDLER(AutomationMsg_OpenNewBrowserWindow,
747 OpenNewBrowserWindow);
748 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowserRequest,
749 GetWindowForBrowser);
750 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowserRequest,
751 GetAutocompleteEditForBrowser);
752 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindowRequest,
753 GetBrowserForWindow);
754 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
755 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTabRequest,
756 NavigateInExternalTab)
757 IPC_MESSAGE_HANDLER(AutomationMsg_ShowInterstitialPageRequest,
758 ShowInterstitialPage);
759 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPageRequest,
760 HideInterstitialPage);
761 IPC_MESSAGE_HANDLER(AutomationMsg_SetAcceleratorsForTab,
762 SetAcceleratorsForTab)
763 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
764 ProcessUnhandledAccelerator)
765 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForTabToBeRestored,
766 WaitForTabToBeRestored)
767 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState,
768 GetSecurityState)
769 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType,
770 GetPageType)
771 IPC_MESSAGE_HANDLER(AutomationMsg_ActionOnSSLBlockingPage,
772 ActionOnSSLBlockingPage)
773 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
774 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
775 IsPageMenuCommandEnabled)
776 IPC_MESSAGE_HANDLER(AutomationMsg_PrintNowRequest, PrintNow)
777 IPC_MESSAGE_HANDLER(AutomationMsg_SavePageRequest, SavePage)
778 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetTextRequest,
779 GetAutocompleteEditText)
780 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetTextRequest,
781 SetAutocompleteEditText)
782 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgressRequest,
783 AutocompleteEditIsQueryInProgress)
784 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatchesRequest,
785 AutocompleteEditGetMatches)
786 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowBoundsRequest,
787 GetConstrainedWindowBounds)
[email protected]5f8af2a2008-08-06 22:49:45788 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPageRequest,
789 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:45790 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
791 OnMessageFromExternalHost)
[email protected]5a52f162008-08-27 04:15:31792 IPC_MESSAGE_HANDLER(AutomationMsg_FindRequest,
793 HandleFindRequest)
[email protected]20e93d12008-08-28 16:31:57794 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibilityRequest,
795 GetFindWindowVisibility)
796 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocationRequest,
797 HandleFindWindowLocationRequest)
[email protected]c2cbeb92008-09-05 21:36:57798 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibilityRequest,
799 GetBookmarkBarVisitility)
[email protected]8a3422c92008-09-24 17:42:42800 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCountRequest,
801 GetSSLInfoBarCount)
802 IPC_MESSAGE_HANDLER(AutomationMsg_ClickSSLInfoBarLinkRequest,
803 ClickSSLInfoBarLink)
804 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTimeRequest,
805 GetLastNavigationTime)
806 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForNavigationRequest,
807 WaitForNavigation)
808 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreferenceRequest,
809 SetIntPreference)
[email protected]c274acc2008-11-11 20:13:44810 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialogRequest,
811 GetShowingAppModalDialog)
[email protected]fad84eab2008-12-05 00:37:20812 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButtonRequest,
813 ClickAppModalDialogButton)
[email protected]97fa6ce32008-12-19 01:48:16814 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreferenceRequest,
815 SetStringPreference)
816 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreferenceRequest,
817 GetBooleanPreference)
818 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreferenceRequest,
819 SetBooleanPreference)
820 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncodingRequest,
821 GetPageCurrentEncoding)
822 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncodingRequest,
823 OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20824 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
825 SavePackageShouldPromptUser)
initial.commit09911bf2008-07-26 23:55:29826 IPC_END_MESSAGE_MAP()
827}
828
829void AutomationProvider::ActivateTab(const IPC::Message& message,
830 int handle, int at_index) {
831 int status = -1;
832 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
833 Browser* browser = browser_tracker_->GetResource(handle);
834 if (at_index >= 0 && at_index < browser->tab_count()) {
835 browser->SelectTabContentsAt(at_index, true);
836 status = 0;
837 }
838 }
839 Send(new AutomationMsg_ActivateTabResponse(message.routing_id(), status));
840}
841
842void AutomationProvider::AppendTab(const IPC::Message& message,
843 int handle, const GURL& url) {
844 int append_tab_response = -1; // -1 is the error code
845 NotificationObserver* observer = NULL;
846
847 if (browser_tracker_->ContainsHandle(handle)) {
848 Browser* browser = browser_tracker_->GetResource(handle);
849 observer = AddTabStripObserver(browser, message.routing_id());
850 TabContents* tab_contents =
[email protected]c0588052008-10-27 23:01:50851 browser->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, NULL);
initial.commit09911bf2008-07-26 23:55:29852 if (tab_contents) {
853 append_tab_response =
854 GetIndexForNavigationController(tab_contents->controller(), browser);
855 }
856 }
857
858 if (append_tab_response < 0) {
859 // The append tab failed. Remove the TabStripObserver
860 if (observer) {
861 RemoveTabStripObserver(observer);
862 delete observer;
863 }
864
865 // This will be reached only if the tab could not be appended. In case of a
866 // successful tab append, a successful navigation notification triggers the
867 // send.
868 Send(new AutomationMsg_AppendTabResponse(message.routing_id(),
869 append_tab_response));
870 }
871}
872
873void AutomationProvider::NavigateToURL(const IPC::Message& message,
874 int handle, const GURL& url) {
875 int status = AUTOMATION_MSG_NAVIGATION_ERROR;
876
877 if (tab_tracker_->ContainsHandle(handle)) {
878 NavigationController* tab = tab_tracker_->GetResource(handle);
879
880 // Simulate what a user would do. Activate the tab and then navigate.
881 // We could allow navigating in a background tab in future.
882 Browser* browser = FindAndActivateTab(tab);
883
884 if (browser) {
885 AddNavigationStatusListener(tab,
886 new AutomationMsg_NavigateToURLResponse(
887 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
888 new AutomationMsg_NavigateToURLResponse(
889 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
890 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50891 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29892 return;
893 }
894 }
895 Send(new AutomationMsg_NavigateToURLResponse(
896 message.routing_id(), AUTOMATION_MSG_NAVIGATION_ERROR));
897}
898
899void AutomationProvider::NavigationAsync(const IPC::Message& message,
900 int handle, const GURL& url) {
901 bool status = false;
902
903 if (tab_tracker_->ContainsHandle(handle)) {
904 NavigationController* tab = tab_tracker_->GetResource(handle);
905
906 // Simulate what a user would do. Activate the tab and then navigate.
907 // We could allow navigating in a background tab in future.
908 Browser* browser = FindAndActivateTab(tab);
909
910 if (browser) {
911 // Don't add any listener unless a callback mechanism is desired.
912 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:50913 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29914 status = true;
915 }
916 }
917
918 Send(new AutomationMsg_NavigationAsyncResponse(message.routing_id(), status));
919}
920
921void AutomationProvider::GoBack(const IPC::Message& message, int handle) {
922 if (tab_tracker_->ContainsHandle(handle)) {
923 NavigationController* tab = tab_tracker_->GetResource(handle);
924 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14925 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
initial.commit09911bf2008-07-26 23:55:29926 AddNavigationStatusListener(tab,
927 new AutomationMsg_GoBackResponse(
928 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
929 new AutomationMsg_GoBackResponse(
930 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
931 browser->GoBack();
932 return;
933 }
934 }
935 Send(new AutomationMsg_GoBackResponse(message.routing_id(),
936 AUTOMATION_MSG_NAVIGATION_ERROR));
937}
938
939void AutomationProvider::GoForward(const IPC::Message& message, int handle) {
940 if (tab_tracker_->ContainsHandle(handle)) {
941 NavigationController* tab = tab_tracker_->GetResource(handle);
942 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14943 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
initial.commit09911bf2008-07-26 23:55:29944 AddNavigationStatusListener(tab,
945 new AutomationMsg_GoForwardResponse(
946 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
947 new AutomationMsg_GoForwardResponse(
948 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
949 browser->GoForward();
950 return;
951 }
952 }
953 Send(new AutomationMsg_GoForwardResponse(message.routing_id(),
954 AUTOMATION_MSG_NAVIGATION_ERROR));
955}
956
957void AutomationProvider::Reload(const IPC::Message& message, int handle) {
958 if (tab_tracker_->ContainsHandle(handle)) {
959 NavigationController* tab = tab_tracker_->GetResource(handle);
960 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14961 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
initial.commit09911bf2008-07-26 23:55:29962 AddNavigationStatusListener(tab,
963 new AutomationMsg_ReloadResponse(
964 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
965 new AutomationMsg_ReloadResponse(
966 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
967 browser->Reload();
968 return;
969 }
970 }
971 Send(new AutomationMsg_ReloadResponse(message.routing_id(),
972 AUTOMATION_MSG_NAVIGATION_ERROR));
973}
974
975void AutomationProvider::SetAuth(const IPC::Message& message, int tab_handle,
976 const std::wstring& username,
977 const std::wstring& password) {
978 int status = -1;
979
980 if (tab_tracker_->ContainsHandle(tab_handle)) {
981 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
982 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
983
984 if (iter != login_handler_map_.end()) {
985 // If auth is needed again after this, assume login has failed. This is
986 // not strictly correct, because a navigation can require both proxy and
987 // server auth, but it should be OK for now.
988 LoginHandler* handler = iter->second;
989 AddNavigationStatusListener(tab,
990 new AutomationMsg_SetAuthResponse(message.routing_id(), 0),
991 new AutomationMsg_SetAuthResponse(message.routing_id(), -1));
992 handler->SetAuth(username, password);
993 status = 0;
994 }
995 }
996 if (status < 0) {
997 Send(new AutomationMsg_SetAuthResponse(message.routing_id(), status));
998 }
999}
1000
1001void AutomationProvider::CancelAuth(const IPC::Message& message,
1002 int tab_handle) {
1003 int status = -1;
1004
1005 if (tab_tracker_->ContainsHandle(tab_handle)) {
1006 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1007 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1008
1009 if (iter != login_handler_map_.end()) {
1010 // If auth is needed again after this, something is screwy.
1011 LoginHandler* handler = iter->second;
1012 AddNavigationStatusListener(tab,
1013 new AutomationMsg_CancelAuthResponse(message.routing_id(), 0),
1014 new AutomationMsg_CancelAuthResponse(message.routing_id(), -1));
1015 handler->CancelAuth();
1016 status = 0;
1017 }
1018 }
1019 if (status < 0) {
1020 Send(new AutomationMsg_CancelAuthResponse(message.routing_id(), status));
1021 }
1022}
1023
1024void AutomationProvider::NeedsAuth(const IPC::Message& message,
1025 int tab_handle) {
1026 bool needs_auth = false;
1027
1028 if (tab_tracker_->ContainsHandle(tab_handle)) {
1029 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1030 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1031
1032 if (iter != login_handler_map_.end()) {
1033 // The LoginHandler will be in our map IFF the tab needs auth.
1034 needs_auth = true;
1035 }
1036 }
1037
1038 Send(new AutomationMsg_NeedsAuthResponse(message.routing_id(), needs_auth));
1039}
1040
1041void AutomationProvider::GetRedirectsFrom(const IPC::Message& message,
1042 int tab_handle,
1043 const GURL& source_url) {
1044 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1045 if (tab_tracker_->ContainsHandle(tab_handle)) {
1046 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1047 HistoryService* history_service =
1048 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1049
1050 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1051 "has no history service";
1052 if (history_service) {
1053 // Schedule a history query for redirects. The response will be sent
1054 // asynchronously from the callback the history system uses to notify us
1055 // that it's done: OnRedirectQueryComplete.
1056 redirect_query_routing_id_ = message.routing_id();
1057 redirect_query_ = history_service->QueryRedirectsFrom(
1058 source_url, &consumer_,
1059 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1060 return; // Response will be sent when query completes.
1061 }
1062 }
1063
1064 // Send failure response.
1065 IPC::Message* msg = new IPC::Message(
1066 message.routing_id(), AutomationMsg_RedirectsFromResponse::ID,
1067 IPC::Message::PRIORITY_NORMAL);
1068 msg->WriteInt(-1); // Negative string count indicates an error.
1069 Send(msg);
1070}
1071
1072void AutomationProvider::GetActiveTabIndex(const IPC::Message& message,
1073 int handle) {
1074 int active_tab_index = -1; // -1 is the error code
1075 if (browser_tracker_->ContainsHandle(handle)) {
1076 Browser* browser = browser_tracker_->GetResource(handle);
1077 active_tab_index = browser->selected_index();
1078 }
1079 Send(new AutomationMsg_ActiveTabIndexResponse(message.routing_id(),
1080 active_tab_index));
1081}
1082
1083void AutomationProvider::GetBrowserWindowCount(const IPC::Message& message) {
1084 Send(new AutomationMsg_BrowserWindowCountResponse(
1085 message.routing_id(), static_cast<int>(BrowserList::size())));
1086}
1087
[email protected]c274acc2008-11-11 20:13:441088void AutomationProvider::GetShowingAppModalDialog(const IPC::Message& message) {
[email protected]fad84eab2008-12-05 00:37:201089 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421090 AppModalDialogQueue::active_dialog();
[email protected]c274acc2008-11-11 20:13:441091 Send(new AutomationMsg_ShowingAppModalDialogResponse(
[email protected]fad84eab2008-12-05 00:37:201092 message.routing_id(), dialog_delegate != NULL,
1093 dialog_delegate ? dialog_delegate->GetDialogButtons() :
1094 views::DialogDelegate::DIALOGBUTTON_NONE));
1095}
1096
1097void AutomationProvider::ClickAppModalDialogButton(const IPC::Message& message,
1098 int button) {
1099 bool success = false;
1100
1101 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421102 AppModalDialogQueue::active_dialog();
[email protected]fad84eab2008-12-05 00:37:201103 if (dialog_delegate &&
1104 (dialog_delegate->GetDialogButtons() & button) == button) {
1105 views::DialogClientView* client_view =
1106 dialog_delegate->window()->client_view()->AsDialogClientView();
1107 if ((button & views::DialogDelegate::DIALOGBUTTON_OK) ==
1108 views::DialogDelegate::DIALOGBUTTON_OK) {
1109 client_view->AcceptWindow();
1110 success = true;
1111 }
1112 if ((button & views::DialogDelegate::DIALOGBUTTON_CANCEL) ==
1113 views::DialogDelegate::DIALOGBUTTON_CANCEL) {
1114 DCHECK(!success) << "invalid param, OK and CANCEL specified";
1115 client_view->CancelWindow();
1116 success = true;
1117 }
1118 }
1119 Send(new AutomationMsg_ClickAppModalDialogButtonResponse(
1120 message.routing_id(), success));
[email protected]c274acc2008-11-11 20:13:441121}
1122
initial.commit09911bf2008-07-26 23:55:291123void AutomationProvider::GetBrowserWindow(const IPC::Message& message,
1124 int index) {
1125 int handle = 0;
1126 if (index >= 0) {
1127 BrowserList::const_iterator iter = BrowserList::begin();
1128
1129 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
1130 if (iter != BrowserList::end()) {
1131 handle = browser_tracker_->Add(*iter);
1132 }
1133 }
1134
1135 Send(new AutomationMsg_BrowserWindowResponse(message.routing_id(), handle));
1136}
1137
1138void AutomationProvider::GetLastActiveBrowserWindow(
1139 const IPC::Message& message) {
1140 int handle = 0;
1141 Browser* browser = BrowserList::GetLastActive();
1142 if (browser)
1143 handle = browser_tracker_->Add(browser);
1144 Send(new AutomationMsg_LastActiveBrowserWindowResponse(message.routing_id(),
1145 handle));
1146}
1147
1148BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1149 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1150 return FALSE;
1151 }
1152 return TRUE;
1153}
1154
1155void AutomationProvider::GetActiveWindow(const IPC::Message& message) {
1156 HWND window = GetForegroundWindow();
1157
1158 // Let's make sure this window belongs to our process.
1159 if (EnumThreadWindows(::GetCurrentThreadId(),
1160 EnumThreadWndProc,
1161 reinterpret_cast<LPARAM>(window))) {
1162 // We enumerated all the windows and did not find the foreground window,
1163 // it is not our window, ignore it.
1164 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), 0));
1165 return;
1166 }
1167
1168 int handle = window_tracker_->Add(window);
1169 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), handle));
1170}
1171
1172void AutomationProvider::GetWindowHWND(const IPC::Message& message,
1173 int handle) {
1174 HWND win32_handle = window_tracker_->GetResource(handle);
1175 Send(new AutomationMsg_WindowHWNDResponse(message.routing_id(),
1176 win32_handle));
1177}
1178
[email protected]4ae62752008-08-04 23:28:471179void AutomationProvider::ExecuteBrowserCommand(const IPC::Message& message,
1180 int handle,
1181 int command) {
[email protected]4ae62752008-08-04 23:28:471182 bool success = false;
1183 if (browser_tracker_->ContainsHandle(handle)) {
1184 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141185 if (browser->command_updater()->SupportsCommand(command) &&
1186 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471187 browser->ExecuteCommand(command);
1188 success = true;
1189 }
1190 }
1191 Send(new AutomationMsg_WindowExecuteCommandResponse(message.routing_id(),
1192 success));
1193}
1194
initial.commit09911bf2008-07-26 23:55:291195void AutomationProvider::WindowGetViewBounds(const IPC::Message& message,
1196 int handle,
1197 int view_id,
1198 bool screen_coordinates) {
1199 bool succeeded = false;
[email protected]80f8b9f2008-10-16 18:17:471200 gfx::Rect bounds;
initial.commit09911bf2008-07-26 23:55:291201
1202 void* iter = NULL;
1203 if (window_tracker_->ContainsHandle(handle)) {
1204 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201205 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291206 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381207 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291208 if (view) {
1209 succeeded = true;
[email protected]96b667d2008-10-14 20:58:441210 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291211 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381212 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291213 else
[email protected]c2dacc92008-10-16 23:51:381214 views::View::ConvertPointToView(view, root_view, &point);
[email protected]80f8b9f2008-10-16 18:17:471215 bounds = view->GetLocalBounds(false);
1216 bounds.set_origin(point);
initial.commit09911bf2008-07-26 23:55:291217 }
1218 }
1219 }
1220
[email protected]80f8b9f2008-10-16 18:17:471221 Send(new AutomationMsg_WindowViewBoundsResponse(message.routing_id(),
1222 succeeded, bounds));
initial.commit09911bf2008-07-26 23:55:291223}
1224
1225// This task enqueues a mouse event on the event loop, so that the view
1226// that it's being sent to can do the requisite post-processing.
1227class MouseEventTask : public Task {
1228 public:
[email protected]c2dacc92008-10-16 23:51:381229 MouseEventTask(views::View* view,
1230 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291231 POINT point,
1232 int flags)
1233 : view_(view), type_(type), point_(point), flags_(flags) {}
1234 virtual ~MouseEventTask() {}
1235
1236 virtual void Run() {
[email protected]c2dacc92008-10-16 23:51:381237 views::MouseEvent event(type_, point_.x, point_.y, flags_);
initial.commit09911bf2008-07-26 23:55:291238 // We need to set the cursor position before we process the event because
1239 // some code (tab dragging, for instance) queries the actual cursor location
1240 // rather than the location of the mouse event. Note that the reason why
1241 // the drag code moved away from using mouse event locations was because
1242 // our conversion to screen location doesn't work well with multiple
1243 // monitors, so this only works reliably in a single monitor setup.
[email protected]96b667d2008-10-14 20:58:441244 gfx::Point screen_location(point_.x, point_.y);
initial.commit09911bf2008-07-26 23:55:291245 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]96b667d2008-10-14 20:58:441246 ::SetCursorPos(screen_location.x(), screen_location.y());
initial.commit09911bf2008-07-26 23:55:291247 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381248 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291249 view_->OnMousePressed(event);
1250 break;
1251
[email protected]c2dacc92008-10-16 23:51:381252 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291253 view_->OnMouseDragged(event);
1254 break;
1255
[email protected]c2dacc92008-10-16 23:51:381256 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291257 view_->OnMouseReleased(event, false);
1258 break;
1259
1260 default:
1261 NOTREACHED();
1262 }
1263 }
1264
1265 private:
[email protected]c2dacc92008-10-16 23:51:381266 views::View* view_;
1267 views::Event::EventType type_;
initial.commit09911bf2008-07-26 23:55:291268 POINT point_;
1269 int flags_;
1270
[email protected]5a52f162008-08-27 04:15:311271 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291272};
1273
[email protected]c2dacc92008-10-16 23:51:381274void AutomationProvider::ScheduleMouseEvent(views::View* view,
1275 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291276 POINT point,
1277 int flags) {
1278 MessageLoop::current()->PostTask(FROM_HERE,
1279 new MouseEventTask(view, type, point, flags));
1280}
1281
1282// This task just adds another task to the event queue. This is useful if
1283// you want to ensure that any tasks added to the event queue after this one
1284// have already been processed by the time |task| is run.
1285class InvokeTaskLaterTask : public Task {
1286 public:
1287 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1288 virtual ~InvokeTaskLaterTask() {}
1289
1290 virtual void Run() {
1291 MessageLoop::current()->PostTask(FROM_HERE, task_);
1292 }
1293
1294 private:
1295 Task* task_;
1296
[email protected]5a52f162008-08-27 04:15:311297 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291298};
1299
1300// This task sends a WindowDragResponse message with the appropriate
1301// routing ID to the automation proxy. This is implemented as a task so that
1302// we know that the mouse events (and any tasks that they spawn on the message
1303// loop) have been processed by the time this is sent.
1304class WindowDragResponseTask : public Task {
1305 public:
1306 WindowDragResponseTask(AutomationProvider* provider, int routing_id)
1307 : provider_(provider), routing_id_(routing_id) {}
1308 virtual ~WindowDragResponseTask() {}
1309
1310 virtual void Run() {
1311 provider_->Send(new AutomationMsg_WindowDragResponse(routing_id_, true));
1312 }
1313
1314 private:
1315 AutomationProvider* provider_;
1316 int routing_id_;
1317
[email protected]5a52f162008-08-27 04:15:311318 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291319};
1320
1321void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1322 int handle,
1323 POINT click,
1324 int flags) {
1325 HWND hwnd = 0;
1326
1327 if (window_tracker_->ContainsHandle(handle)) {
1328 hwnd = window_tracker_->GetResource(handle);
1329
initial.commit09911bf2008-07-26 23:55:291330 ui_controls::SendMouseMove(click.x, click.y);
1331
1332 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381333 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1334 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291335 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381336 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1337 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291338 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381339 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1340 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291341 button = ui_controls::MIDDLE;
1342 } else {
1343 NOTREACHED();
1344 }
1345 ui_controls::SendMouseClick(button);
1346 }
1347}
1348
1349void AutomationProvider::WindowSimulateDrag(const IPC::Message& message,
1350 int handle,
[email protected]fe92e4e2008-11-18 21:31:321351 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441352 int flags,
1353 bool press_escape_en_route) {
initial.commit09911bf2008-07-26 23:55:291354 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321355 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1356 succeeded = true;
1357
1358 UINT down_message = 0;
1359 UINT up_message = 0;
1360 WPARAM wparam_flags = 0;
1361 if (flags & views::Event::EF_SHIFT_DOWN)
1362 wparam_flags |= MK_SHIFT;
1363 if (flags & views::Event::EF_CONTROL_DOWN)
1364 wparam_flags |= MK_CONTROL;
1365 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1366 wparam_flags |= MK_LBUTTON;
1367 down_message = WM_LBUTTONDOWN;
1368 up_message = WM_LBUTTONUP;
1369 }
1370 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1371 wparam_flags |= MK_MBUTTON;
1372 down_message = WM_MBUTTONDOWN;
1373 up_message = WM_MBUTTONUP;
1374 }
1375 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1376 wparam_flags |= MK_RBUTTON;
1377 down_message = WM_LBUTTONDOWN;
1378 up_message = WM_LBUTTONUP;
1379 }
1380
initial.commit09911bf2008-07-26 23:55:291381 Browser* browser = browser_tracker_->GetResource(handle);
1382 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551383 HWND top_level_hwnd =
1384 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321385 POINT temp = drag_path[0];
1386 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1387 SetCursorPos(temp.x, temp.y);
1388 SendMessage(top_level_hwnd, down_message, wparam_flags,
1389 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1390 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1391 temp = drag_path[i];
1392 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1393 SetCursorPos(temp.x, temp.y);
1394 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1395 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341396 }
[email protected]fe92e4e2008-11-18 21:31:321397 POINT end = drag_path[drag_path.size() - 1];
1398 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
1399 SetCursorPos(end.x, end.y);
1400
1401 if (press_escape_en_route) {
1402 // Press Escape.
1403 ui_controls::SendKeyPress(VK_ESCAPE,
1404 ((flags & views::Event::EF_CONTROL_DOWN)
1405 == views::Event::EF_CONTROL_DOWN),
1406 ((flags & views::Event::EF_SHIFT_DOWN) ==
1407 views::Event::EF_SHIFT_DOWN),
1408 ((flags & views::Event::EF_ALT_DOWN) ==
1409 views::Event::EF_ALT_DOWN));
1410 }
1411 SendMessage(top_level_hwnd, up_message, wparam_flags,
1412 MAKELPARAM(end.x, end.y));
1413
initial.commit09911bf2008-07-26 23:55:291414 MessageLoop::current()->PostTask(FROM_HERE,
1415 new InvokeTaskLaterTask(
1416 new WindowDragResponseTask(this, message.routing_id())));
1417 } else {
1418 Send(new AutomationMsg_WindowDragResponse(message.routing_id(), true));
1419 }
1420}
1421
1422void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1423 int handle,
1424 wchar_t key,
1425 int flags) {
1426 if (!window_tracker_->ContainsHandle(handle))
1427 return;
1428
1429 // The key event is sent to whatever window is active.
1430 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381431 ((flags & views::Event::EF_CONTROL_DOWN) ==
1432 views::Event::EF_CONTROL_DOWN),
1433 ((flags & views::Event::EF_SHIFT_DOWN) ==
1434 views::Event::EF_SHIFT_DOWN),
1435 ((flags & views::Event::EF_ALT_DOWN) ==
1436 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291437}
1438
1439void AutomationProvider::GetFocusedViewID(const IPC::Message& message,
1440 int handle) {
1441 int view_id = -1;
1442 if (window_tracker_->ContainsHandle(handle)) {
1443 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381444 views::FocusManager* focus_manager =
1445 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:291446 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381447 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291448 if (focused_view)
1449 view_id = focused_view->GetID();
1450 }
1451 Send(new AutomationMsg_GetFocusedViewIDResponse(message.routing_id(),
1452 view_id));
1453}
1454
1455void AutomationProvider::SetWindowVisible(const IPC::Message& message,
1456 int handle, bool visible) {
1457 if (window_tracker_->ContainsHandle(handle)) {
1458 HWND hwnd = window_tracker_->GetResource(handle);
1459 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
1460 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1461 true));
1462 } else {
1463 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1464 false));
1465 }
1466}
1467
1468void AutomationProvider::IsWindowActive(const IPC::Message& message,
1469 int handle) {
1470 if (window_tracker_->ContainsHandle(handle)) {
1471 HWND hwnd = window_tracker_->GetResource(handle);
1472 bool is_active = ::GetForegroundWindow() == hwnd;
1473 Send(new AutomationMsg_IsWindowActiveResponse(
1474 message.routing_id(), true, is_active));
1475 } else {
1476 Send(new AutomationMsg_IsWindowActiveResponse(message.routing_id(),
1477 false, false));
1478 }
1479}
1480
1481void AutomationProvider::ActivateWindow(const IPC::Message& message,
1482 int handle) {
1483 if (window_tracker_->ContainsHandle(handle)) {
1484 ::SetActiveWindow(window_tracker_->GetResource(handle));
1485 }
1486}
1487
1488void AutomationProvider::GetTabCount(const IPC::Message& message, int handle) {
1489 int tab_count = -1; // -1 is the error code
1490
1491 if (browser_tracker_->ContainsHandle(handle)) {
1492 Browser* browser = browser_tracker_->GetResource(handle);
1493 tab_count = browser->tab_count();
1494 }
1495
1496 Send(new AutomationMsg_TabCountResponse(message.routing_id(), tab_count));
1497}
1498
1499void AutomationProvider::GetTab(const IPC::Message& message,
1500 int win_handle, int tab_index) {
1501 void* iter = NULL;
1502 int tab_handle = 0;
1503 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1504 Browser* browser = browser_tracker_->GetResource(win_handle);
1505 if (tab_index < browser->tab_count()) {
1506 TabContents* tab_contents =
1507 browser->GetTabContentsAt(tab_index);
1508 tab_handle = tab_tracker_->Add(tab_contents->controller());
1509 }
1510 }
1511
1512 Send(new AutomationMsg_TabResponse(message.routing_id(), tab_handle));
1513}
1514
1515void AutomationProvider::GetTabTitle(const IPC::Message& message, int handle) {
1516 int title_string_size = -1; // -1 is the error code
1517 std::wstring title;
1518 if (tab_tracker_->ContainsHandle(handle)) {
1519 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]1e5645ff2008-08-27 18:09:071520 title = tab->GetActiveEntry()->title();
initial.commit09911bf2008-07-26 23:55:291521 title_string_size = static_cast<int>(title.size());
1522 }
1523
1524 Send(new AutomationMsg_TabTitleResponse(message.routing_id(),
1525 title_string_size, title));
1526}
1527
1528void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1529 if (window_tracker_->ContainsHandle(handle)) {
1530 window_tracker_->Remove(window_tracker_->GetResource(handle));
1531 }
1532}
1533
1534void AutomationProvider::OnChannelError() {
1535 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571536 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291537}
1538
1539// TODO(brettw) change this to accept GURLs when history supports it
1540void AutomationProvider::OnRedirectQueryComplete(
1541 HistoryService::Handle request_handle,
1542 GURL from_url,
1543 bool success,
1544 HistoryService::RedirectList* redirects) {
1545 DCHECK(request_handle == redirect_query_);
1546
1547 // Respond to the pending request for the redirect list.
1548 IPC::Message* msg = new IPC::Message(redirect_query_routing_id_,
1549 AutomationMsg_RedirectsFromResponse::ID,
1550 IPC::Message::PRIORITY_NORMAL);
1551 if (success) {
1552 msg->WriteInt(static_cast<int>(redirects->size()));
1553 for (size_t i = 0; i < redirects->size(); i++)
1554 IPC::ParamTraits<GURL>::Write(msg, redirects->at(i));
1555 } else {
1556 msg->WriteInt(-1); // Negative count indicates failure.
1557 }
1558
1559 Send(msg);
1560 redirect_query_ = NULL;
1561}
1562
1563bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571564 DCHECK(channel_.get());
1565 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291566}
1567
1568Browser* AutomationProvider::FindAndActivateTab(
1569 NavigationController* controller) {
1570 int tab_index;
1571 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1572 if (browser)
1573 browser->SelectTabContentsAt(tab_index, true);
1574
1575 return browser;
1576}
1577
1578void AutomationProvider::GetCookies(const IPC::Message& message,
1579 const GURL& url, int handle) {
1580 std::string value;
1581
1582 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1583 NavigationController* tab = tab_tracker_->GetResource(handle);
1584 value =
1585 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
1586 }
1587
1588 Send(new AutomationMsg_GetCookiesResponse(message.routing_id(),
1589 static_cast<int>(value.size()), value));
1590}
1591
1592void AutomationProvider::SetCookie(const IPC::Message& message,
1593 const GURL& url,
1594 const std::string value,
1595 int handle) {
1596 int response_value = -1;
1597
1598 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1599 NavigationController* tab = tab_tracker_->GetResource(handle);
1600 URLRequestContext* context = tab->profile()->GetRequestContext();
1601 if (context->cookie_store()->SetCookie(url, value))
1602 response_value = 1;
1603 }
1604
1605 Send(new AutomationMsg_SetCookieResponse(message.routing_id(),
1606 response_value));
1607}
1608
1609void AutomationProvider::GetTabURL(const IPC::Message& message, int handle) {
1610 bool success = false;
1611 GURL url;
1612 if (tab_tracker_->ContainsHandle(handle)) {
1613 NavigationController* tab = tab_tracker_->GetResource(handle);
1614 // Return what the user would see in the location bar.
[email protected]1e5645ff2008-08-27 18:09:071615 url = tab->GetActiveEntry()->display_url();
initial.commit09911bf2008-07-26 23:55:291616 success = true;
1617 }
1618
1619 Send(new AutomationMsg_TabURLResponse(message.routing_id(), success, url));
1620}
1621
1622void AutomationProvider::GetTabHWND(const IPC::Message& message, int handle) {
1623 HWND tab_hwnd = NULL;
1624
1625 if (tab_tracker_->ContainsHandle(handle)) {
1626 NavigationController* tab = tab_tracker_->GetResource(handle);
1627 tab_hwnd = tab->active_contents()->GetContainerHWND();
1628 }
1629
1630 Send(new AutomationMsg_TabHWNDResponse(message.routing_id(), tab_hwnd));
1631}
1632
1633void AutomationProvider::GetTabProcessID(
1634 const IPC::Message& message, int handle) {
1635 int process_id = -1;
1636
1637 if (tab_tracker_->ContainsHandle(handle)) {
1638 process_id = 0;
1639 NavigationController* tab = tab_tracker_->GetResource(handle);
1640 if (tab->active_contents()->AsWebContents()) {
1641 WebContents* web_contents = tab->active_contents()->AsWebContents();
[email protected]2f15de42008-11-11 22:35:191642 if (web_contents->process())
1643 process_id = web_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291644 }
1645 }
1646
1647 Send(new AutomationMsg_TabProcessIDResponse(message.routing_id(),
1648 process_id));
1649}
1650
1651void AutomationProvider::ApplyAccelerator(int handle, int id) {
1652 if (browser_tracker_->ContainsHandle(handle)) {
1653 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141654 browser->ExecuteCommand(id);
initial.commit09911bf2008-07-26 23:55:291655 }
1656}
1657
1658void AutomationProvider::ExecuteJavascript(const IPC::Message& message,
1659 int handle,
1660 const std::wstring& frame_xpath,
1661 const std::wstring& script) {
1662 bool succeeded = false;
[email protected]20e93d12008-08-28 16:31:571663 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1664 if (web_contents) {
1665 // Set the routing id of this message with the controller.
1666 // This routing id needs to be remembered for the reverse
1667 // communication while sending back the response of
1668 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331669 std::wstring set_automation_id;
1670 SStringPrintf(&set_automation_id,
1671 L"window.domAutomationController.setAutomationId(%d);",
[email protected]20e93d12008-08-28 16:31:571672 message.routing_id());
initial.commit09911bf2008-07-26 23:55:291673
[email protected]1f5af4442008-09-25 22:11:061674 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331675 frame_xpath, set_automation_id);
[email protected]1f5af4442008-09-25 22:11:061676 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1677 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571678 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291679 }
1680
1681 if (!succeeded) {
1682 Send(new AutomationMsg_DomOperationResponse(message.routing_id(), ""));
1683 }
1684}
1685
1686void AutomationProvider::GetShelfVisibility(const IPC::Message& message,
1687 int handle) {
1688 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571689
1690 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1691 if (web_contents)
1692 visible = web_contents->IsDownloadShelfVisible();
initial.commit09911bf2008-07-26 23:55:291693
1694 Send(new AutomationMsg_ShelfVisibilityResponse(message.routing_id(),
1695 visible));
1696}
1697
1698void AutomationProvider::GetConstrainedWindowCount(const IPC::Message& message,
1699 int handle) {
1700 int count = -1; // -1 is the error code
1701 if (tab_tracker_->ContainsHandle(handle)) {
1702 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1703 TabContents* tab_contents = nav_controller->active_contents();
1704 if (tab_contents) {
1705 count = static_cast<int>(tab_contents->child_windows_.size());
1706 }
1707 }
1708
1709 Send(new AutomationMsg_ConstrainedWindowCountResponse(message.routing_id(),
1710 count));
1711}
1712
1713void AutomationProvider::GetConstrainedWindow(const IPC::Message& message,
1714 int handle, int index) {
1715 int cwindow_handle = 0;
1716 if (tab_tracker_->ContainsHandle(handle) && index >= 0) {
1717 NavigationController* nav_controller =
1718 tab_tracker_->GetResource(handle);
1719 TabContents* tab = nav_controller->active_contents();
[email protected]d5f942ba2008-09-26 19:30:341720 if (tab && index < static_cast<int>(tab->child_windows_.size())) {
1721 ConstrainedWindow* window = tab->child_windows_[index];
initial.commit09911bf2008-07-26 23:55:291722 cwindow_handle = cwindow_tracker_->Add(window);
1723 }
1724 }
1725
1726 Send(new AutomationMsg_ConstrainedWindowResponse(message.routing_id(),
1727 cwindow_handle));
1728}
1729
1730void AutomationProvider::GetConstrainedTitle(const IPC::Message& message,
1731 int handle) {
1732 int title_string_size = -1; // -1 is the error code
1733 std::wstring title;
1734 if (cwindow_tracker_->ContainsHandle(handle)) {
1735 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1736 title = window->GetWindowTitle();
1737 title_string_size = static_cast<int>(title.size());
1738 }
1739
1740 Send(new AutomationMsg_ConstrainedTitleResponse(message.routing_id(),
1741 title_string_size, title));
1742}
1743
1744void AutomationProvider::GetConstrainedWindowBounds(const IPC::Message& message,
1745 int handle) {
1746 bool exists = false;
1747 gfx::Rect rect(0, 0, 0, 0);
1748 if (cwindow_tracker_->ContainsHandle(handle)) {
1749 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1750 if (window) {
1751 exists = true;
1752 rect = window->GetCurrentBounds();
1753 }
1754 }
1755
1756 Send(new AutomationMsg_ConstrainedWindowBoundsResponse(message.routing_id(),
1757 exists, rect));
1758}
1759
1760void AutomationProvider::HandleFindInPageRequest(
1761 const IPC::Message& message, int handle, const std::wstring& find_request,
1762 int forward, int match_case) {
[email protected]5a52f162008-08-27 04:15:311763 NOTREACHED() << "This function has been deprecated."
1764 << "Please use HandleFindRequest instead.";
[email protected]aedd85a2008-12-04 19:32:491765 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
[email protected]5a52f162008-08-27 04:15:311766 return;
1767}
1768
1769void AutomationProvider::HandleFindRequest(const IPC::Message& message,
1770 int handle, const FindInPageRequest& request) {
initial.commit09911bf2008-07-26 23:55:291771 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]aedd85a2008-12-04 19:32:491772 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
initial.commit09911bf2008-07-26 23:55:291773 return;
1774 }
1775
1776 NavigationController* nav = tab_tracker_->GetResource(handle);
1777 TabContents* tab_contents = nav->active_contents();
1778
1779 find_in_page_observer_.reset(new
1780 FindInPageNotificationObserver(this, tab_contents, message.routing_id()));
1781
[email protected]edc28612008-08-14 20:23:361782 // The find in page dialog must be up for us to get the notification that the
[email protected]9e0534b2008-10-21 15:03:011783 // find was complete.
1784 WebContents* web_contents = tab_contents->AsWebContents();
1785 if (web_contents) {
[email protected]edc28612008-08-14 20:23:361786 NavigationController* tab = tab_tracker_->GetResource(handle);
1787 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011788 web_contents->view()->FindInPage(*browser, true, request.forward);
[email protected]edc28612008-08-14 20:23:361789
[email protected]9e0534b2008-10-21 15:03:011790 web_contents->render_view_host()->StartFinding(
1791 FindInPageNotificationObserver::kFindInPageRequestId,
1792 request.search_string, request.forward, request.match_case,
1793 request.find_next);
1794 }
initial.commit09911bf2008-07-26 23:55:291795}
1796
[email protected]5f8af2a2008-08-06 22:49:451797void AutomationProvider::HandleOpenFindInPageRequest(
1798 const IPC::Message& message, int handle) {
[email protected]20e93d12008-08-28 16:31:571799 NavigationController* tab = NULL;
1800 WebContents* web_contents = GetWebContentsForHandle(handle, &tab);
1801 if (web_contents) {
[email protected]5f8af2a2008-08-06 22:49:451802 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011803 web_contents->view()->FindInPage(*browser, false, false);
[email protected]5f8af2a2008-08-06 22:49:451804 }
1805}
1806
[email protected]20e93d12008-08-28 16:31:571807void AutomationProvider::GetFindWindowVisibility(const IPC::Message& message,
1808 int handle) {
[email protected]9e0534b2008-10-21 15:03:011809 gfx::Point position;
[email protected]20e93d12008-08-28 16:31:571810 bool visible = false;
1811 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1812 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091813 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571814
1815 Send(new AutomationMsg_FindWindowVisibilityResponse(message.routing_id(),
1816 visible));
1817}
1818
1819void AutomationProvider::HandleFindWindowLocationRequest(
1820 const IPC::Message& message, int handle) {
[email protected]9e0534b2008-10-21 15:03:011821 gfx::Point position(0, 0);
1822 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571823 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1824 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091825 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571826
1827 Send(new AutomationMsg_FindWindowLocationResponse(message.routing_id(),
[email protected]9e0534b2008-10-21 15:03:011828 position.x(),
1829 position.y()));
[email protected]20e93d12008-08-28 16:31:571830}
1831
[email protected]c2cbeb92008-09-05 21:36:571832void AutomationProvider::GetBookmarkBarVisitility(const IPC::Message& message,
1833 int handle) {
1834 bool visible = false;
1835 bool animating = false;
1836
1837 void* iter = NULL;
1838 if (browser_tracker_->ContainsHandle(handle)) {
1839 Browser* browser = browser_tracker_->GetResource(handle);
1840 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:521841 BrowserWindowTesting* testing =
1842 browser->window()->GetBrowserWindowTesting();
1843 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:571844 if (bookmark_bar) {
1845 animating = bookmark_bar->IsAnimating();
1846 visible = browser->window()->IsBookmarkBarVisible();
1847 }
1848 }
1849 }
1850
1851 Send(new AutomationMsg_BookmarkBarVisibilityResponse(message.routing_id(),
1852 visible, animating));
1853}
1854
initial.commit09911bf2008-07-26 23:55:291855void AutomationProvider::HandleInspectElementRequest(
1856 const IPC::Message& message, int handle, int x, int y) {
[email protected]20e93d12008-08-28 16:31:571857 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1858 if (web_contents) {
[email protected]1f5af4442008-09-25 22:11:061859 web_contents->render_view_host()->InspectElementAt(x, y);
initial.commit09911bf2008-07-26 23:55:291860 inspect_element_routing_id_ = message.routing_id();
1861 } else {
1862 Send(new AutomationMsg_InspectElementResponse(message.routing_id(), -1));
1863 }
1864}
1865
1866void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
1867 Send(new AutomationMsg_InspectElementResponse(inspect_element_routing_id_,
1868 num_resources));
1869}
1870
1871// Helper class for making changes to the URLRequest ProtocolFactory on the
1872// IO thread.
1873class SetFilteredInetTask : public Task {
1874 public:
1875 explicit SetFilteredInetTask(bool enabled) : enabled_(enabled) { }
1876 virtual void Run() {
1877 if (enabled_) {
1878 URLRequestFilter::GetInstance()->ClearHandlers();
1879
1880 URLRequestFailedDnsJob::AddUITestUrls();
1881 URLRequestSlowDownloadJob::AddUITestUrls();
1882
1883 std::wstring root_http;
1884 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
1885 URLRequestMockHTTPJob::AddUITestUrls(root_http);
1886 } else {
1887 // Revert to the default handlers.
1888 URLRequestFilter::GetInstance()->ClearHandlers();
1889 }
1890 }
1891 private:
1892 bool enabled_;
1893};
1894
1895void AutomationProvider::SetFilteredInet(const IPC::Message& message,
1896 bool enabled) {
1897 // Since this involves changing the URLRequest ProtocolFactory, we want to
1898 // run on the main thread.
1899 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
1900 new SetFilteredInetTask(enabled));
1901}
1902
1903void AutomationProvider::GetDownloadDirectory(const IPC::Message& message,
1904 int handle) {
1905 DLOG(INFO) << "Handling download directory request";
1906 std::wstring download_directory;
1907 if (tab_tracker_->ContainsHandle(handle)) {
1908 NavigationController* tab = tab_tracker_->GetResource(handle);
1909 DownloadManager* dlm = tab->profile()->GetDownloadManager();
1910 DCHECK(dlm);
[email protected]7ae7c2cb2009-01-06 23:31:411911 download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:291912 }
1913
1914 Send(new AutomationMsg_DownloadDirectoryResponse(message.routing_id(),
1915 download_directory));
1916}
1917
1918void AutomationProvider::OpenNewBrowserWindow(int show_command) {
1919 // We may have no current browser windows open so don't rely on
1920 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:051921 Browser* browser = Browser::Create(profile_);
1922 browser->AddBlankTab(true);
1923 if (show_command != SW_HIDE)
1924 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:291925}
1926
1927void AutomationProvider::GetWindowForBrowser(const IPC::Message& message,
1928 int browser_handle) {
1929 bool success = false;
1930 int window_handle = 0;
1931
1932 if (browser_tracker_->ContainsHandle(browser_handle)) {
1933 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]2d46c842008-11-14 19:24:311934 HWND hwnd = reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
initial.commit09911bf2008-07-26 23:55:291935 // Add() returns the existing handle for the resource if any.
1936 window_handle = window_tracker_->Add(hwnd);
1937 success = true;
1938 }
1939 Send(new AutomationMsg_WindowForBrowserResponse(message.routing_id(),
1940 success, window_handle));
1941}
1942
1943void AutomationProvider::GetAutocompleteEditForBrowser(
1944 const IPC::Message& message,
1945 int browser_handle) {
1946 bool success = false;
1947 int autocomplete_edit_handle = 0;
1948
1949 if (browser_tracker_->ContainsHandle(browser_handle)) {
1950 Browser* browser = browser_tracker_->GetResource(browser_handle);
1951 LocationBarView* loc_bar_view = browser->GetLocationBarView();
[email protected]81c21222008-09-10 19:35:521952 AutocompleteEditView* edit_view = loc_bar_view->location_entry();
initial.commit09911bf2008-07-26 23:55:291953 // Add() returns the existing handle for the resource if any.
[email protected]81c21222008-09-10 19:35:521954 autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
initial.commit09911bf2008-07-26 23:55:291955 success = true;
1956 }
1957 Send(new AutomationMsg_AutocompleteEditForBrowserResponse(
1958 message.routing_id(), success, autocomplete_edit_handle));
1959}
1960
1961void AutomationProvider::GetBrowserForWindow(const IPC::Message& message,
1962 int window_handle) {
1963 bool success = false;
1964 int browser_handle = 0;
1965
1966 if (window_tracker_->ContainsHandle(window_handle)) {
1967 HWND window = window_tracker_->GetResource(window_handle);
1968 BrowserList::const_iterator iter = BrowserList::begin();
1969 Browser* browser = NULL;
1970 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:311971 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
1972 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:291973 browser = *iter;
1974 break;
1975 }
1976 }
1977 if (browser) {
1978 // Add() returns the existing handle for the resource if any.
1979 browser_handle = browser_tracker_->Add(browser);
1980 success = true;
1981 }
1982 }
1983 Send(new AutomationMsg_BrowserForWindowResponse(message.routing_id(),
1984 success, browser_handle));
1985}
1986
1987void AutomationProvider::ShowInterstitialPage(const IPC::Message& message,
1988 int tab_handle,
1989 const std::string& html_text) {
1990 if (tab_tracker_->ContainsHandle(tab_handle)) {
1991 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
1992 TabContents* tab_contents = controller->active_contents();
1993 if (tab_contents->type() == TAB_CONTENTS_WEB) {
1994 AddNavigationStatusListener(controller,
1995 new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
1996 true),
1997 NULL);
1998 WebContents* web_contents = tab_contents->AsWebContents();
[email protected]cbab76d2008-10-13 22:42:471999 AutomationInterstitialPage* interstitial =
2000 new AutomationInterstitialPage(web_contents,
2001 GURL("about:interstitial"),
2002 html_text);
[email protected]a3a1d142008-12-19 00:42:302003 interstitial->Show();
initial.commit09911bf2008-07-26 23:55:292004 return;
2005 }
2006 }
2007 Send(new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
2008 false));
2009}
2010
2011void AutomationProvider::HideInterstitialPage(const IPC::Message& message,
2012 int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572013 WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
[email protected]a3a1d142008-12-19 00:42:302014 if (web_contents && web_contents->interstitial_page()) {
2015 web_contents->interstitial_page()->DontProceed();
[email protected]20e93d12008-08-28 16:31:572016 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2017 true));
2018 return;
initial.commit09911bf2008-07-26 23:55:292019 }
2020 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2021 false));
2022}
2023
2024void AutomationProvider::CloseTab(const IPC::Message& message,
2025 int tab_handle,
2026 bool wait_until_closed) {
2027 if (tab_tracker_->ContainsHandle(tab_handle)) {
2028 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2029 int index;
2030 Browser* browser = Browser::GetBrowserForController(controller, &index);
2031 DCHECK(browser);
2032 TabClosedNotificationObserver* observer =
2033 new TabClosedNotificationObserver(browser, this, message.routing_id(),
2034 wait_until_closed);
2035 browser->CloseContents(controller->active_contents());
2036 } else {
2037 Send(new AutomationMsg_CloseTabResponse(message.routing_id(), false));
2038 }
2039}
2040
2041void AutomationProvider::CloseBrowser(const IPC::Message& message,
2042 int browser_handle) {
2043 if (browser_tracker_->ContainsHandle(browser_handle)) {
2044 Browser* browser = browser_tracker_->GetResource(browser_handle);
2045 new BrowserClosedNotificationObserver(browser, this, message.routing_id());
[email protected]f3e99e32008-07-30 04:48:392046 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292047 } else {
2048 NOTREACHED();
2049 }
2050}
2051
2052void AutomationProvider::CreateExternalTab(const IPC::Message& message) {
2053 int tab_handle = 0;
2054 HWND tab_container_window = NULL;
2055 ExternalTabContainer *external_tab_container =
2056 new ExternalTabContainer(this);
2057 external_tab_container->Init(profile_);
2058 TabContents* tab_contents = external_tab_container->tab_contents();
2059 if (tab_contents) {
2060 tab_handle = tab_tracker_->Add(tab_contents->controller());
2061 tab_container_window = *external_tab_container;
2062 }
2063 Send(new AutomationMsg_CreateExternalTabResponse(message.routing_id(),
2064 tab_container_window,
2065 tab_handle));
2066}
2067
2068void AutomationProvider::NavigateInExternalTab(const IPC::Message& message,
2069 int handle, const GURL& url) {
2070 bool status = false;
2071
2072 if (tab_tracker_->ContainsHandle(handle)) {
2073 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502074 tab->LoadURL(url, GURL(), PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:292075 status = true;
2076 }
2077
2078 Send(new AutomationMsg_NavigateInExternalTabResponse(message.routing_id(),
2079 status));
2080}
2081
2082void AutomationProvider::SetAcceleratorsForTab(const IPC::Message& message,
2083 int handle,
2084 HACCEL accel_table,
2085 int accel_entry_count) {
2086 bool status = false;
2087 if (tab_tracker_->ContainsHandle(handle)) {
2088 NavigationController* tab = tab_tracker_->GetResource(handle);
2089 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2090 ExternalTabContainer* external_tab_container =
2091 ExternalTabContainer::GetContainerForTab(
2092 tab_contents->GetContainerHWND());
2093 // This call is only valid on an externally hosted tab
2094 if (external_tab_container) {
2095 external_tab_container->SetAccelerators(accel_table,
2096 accel_entry_count);
2097 status = true;
2098 }
2099 }
2100 Send(new AutomationMsg_SetAcceleratorsForTabResponse(message.routing_id(),
2101 status));
2102}
2103
2104void AutomationProvider::ProcessUnhandledAccelerator(
2105 const IPC::Message& message, int handle, const MSG& msg) {
2106 if (tab_tracker_->ContainsHandle(handle)) {
2107 NavigationController* tab = tab_tracker_->GetResource(handle);
2108 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2109 ExternalTabContainer* external_tab_container =
2110 ExternalTabContainer::GetContainerForTab(
2111 tab_contents->GetContainerHWND());
2112 // This call is only valid on an externally hosted tab
2113 if (external_tab_container) {
2114 external_tab_container->ProcessUnhandledAccelerator(msg);
2115 }
2116 }
2117 // This message expects no response.
2118}
2119
2120void AutomationProvider::WaitForTabToBeRestored(
2121 const IPC::Message& message,
2122 int tab_handle) {
2123 if (tab_tracker_->ContainsHandle(tab_handle)) {
2124 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2125 restore_tracker_.reset(
2126 new NavigationControllerRestoredObserver(this, tab,
2127 message.routing_id()));
2128 }
2129}
2130
2131void AutomationProvider::GetSecurityState(const IPC::Message& message,
2132 int handle) {
2133 if (tab_tracker_->ContainsHandle(handle)) {
2134 NavigationController* tab = tab_tracker_->GetResource(handle);
2135 NavigationEntry* entry = tab->GetActiveEntry();
2136 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), true,
[email protected]eb34392b2008-08-19 15:42:202137 entry->ssl().security_style(), entry->ssl().cert_status(),
2138 entry->ssl().content_status()));
initial.commit09911bf2008-07-26 23:55:292139 } else {
2140 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), false,
2141 SECURITY_STYLE_UNKNOWN,
2142 0, 0));
2143 }
2144}
2145
2146void AutomationProvider::GetPageType(const IPC::Message& message, int handle) {
2147 if (tab_tracker_->ContainsHandle(handle)) {
2148 NavigationController* tab = tab_tracker_->GetResource(handle);
2149 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072150 NavigationEntry::PageType page_type = entry->page_type();
initial.commit09911bf2008-07-26 23:55:292151 // In order to return the proper result when an interstitial is shown and
2152 // no navigation entry were created for it we need to ask the WebContents.
2153 if (page_type == NavigationEntry::NORMAL_PAGE &&
2154 tab->active_contents()->AsWebContents() &&
[email protected]b6e09ac2008-08-12 16:11:092155 tab->active_contents()->AsWebContents()->showing_interstitial_page())
initial.commit09911bf2008-07-26 23:55:292156 page_type = NavigationEntry::INTERSTITIAL_PAGE;
2157
2158 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), true,
2159 page_type));
2160 } else {
2161 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), false,
2162 NavigationEntry::NORMAL_PAGE));
2163 }
2164}
2165
2166void AutomationProvider::ActionOnSSLBlockingPage(const IPC::Message& message,
2167 int handle, bool proceed) {
2168 if (tab_tracker_->ContainsHandle(handle)) {
2169 NavigationController* tab = tab_tracker_->GetResource(handle);
2170 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072171 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
initial.commit09911bf2008-07-26 23:55:292172 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
[email protected]cbab76d2008-10-13 22:42:472173 InterstitialPage* ssl_blocking_page =
[email protected]a3a1d142008-12-19 00:42:302174 InterstitialPage::GetInterstitialPage(tab_contents->AsWebContents());
initial.commit09911bf2008-07-26 23:55:292175 if (ssl_blocking_page) {
2176 if (proceed) {
2177 AddNavigationStatusListener(tab,
2178 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2179 message.routing_id(), true),
2180 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2181 message.routing_id(), true));
2182 ssl_blocking_page->Proceed();
2183 return;
2184 }
2185 ssl_blocking_page->DontProceed();
2186 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(
2187 message.routing_id(), true));
2188 return;
2189 }
2190 }
2191 }
2192 // We failed.
2193 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(message.routing_id(),
2194 false));
2195}
2196
2197void AutomationProvider::BringBrowserToFront(const IPC::Message& message,
2198 int browser_handle) {
2199 if (browser_tracker_->ContainsHandle(browser_handle)) {
2200 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062201 browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:292202 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2203 true));
2204 } else {
2205 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2206 false));
2207 }
2208}
2209
2210void AutomationProvider::IsPageMenuCommandEnabled(const IPC::Message& message,
2211 int browser_handle,
2212 int message_num) {
2213 if (browser_tracker_->ContainsHandle(browser_handle)) {
2214 Browser* browser = browser_tracker_->GetResource(browser_handle);
2215 bool menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142216 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292217 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2218 message.routing_id(), menu_item_enabled));
2219 } else {
2220 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2221 message.routing_id(), false));
2222 }
2223}
2224
2225void AutomationProvider::PrintNow(const IPC::Message& message, int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572226 NavigationController* tab = NULL;
2227 WebContents* web_contents = GetWebContentsForHandle(tab_handle, &tab);
2228 if (web_contents) {
initial.commit09911bf2008-07-26 23:55:292229 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572230 notification_observer_list_.AddObserver(
2231 new DocumentPrintedNotificationObserver(this, message.routing_id()));
2232 if (web_contents->PrintNow())
2233 return;
initial.commit09911bf2008-07-26 23:55:292234 }
2235 Send(new AutomationMsg_PrintNowResponse(message.routing_id(), false));
2236}
2237
2238void AutomationProvider::SavePage(const IPC::Message& message,
2239 int tab_handle,
2240 const std::wstring& file_name,
2241 const std::wstring& dir_path,
2242 int type) {
2243 if (!tab_tracker_->ContainsHandle(tab_handle)) {
2244 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2245 return;
2246 }
2247
2248 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2249 Browser* browser = FindAndActivateTab(nav);
2250 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142251 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
initial.commit09911bf2008-07-26 23:55:292252 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2253 return;
2254 }
2255
2256 TabContents* tab_contents = nav->active_contents();
2257 if (tab_contents->type() != TAB_CONTENTS_WEB) {
2258 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2259 return;
2260 }
2261
2262 SavePackage::SavePackageType save_type =
2263 static_cast<SavePackage::SavePackageType>(type);
2264 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2265 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
2266 tab_contents->AsWebContents()->SavePage(file_name, dir_path, save_type);
2267
2268 Send(new AutomationMsg_SavePageResponse(
2269 message.routing_id(), true));
2270}
2271
2272void AutomationProvider::GetAutocompleteEditText(const IPC::Message& message,
2273 int autocomplete_edit_handle) {
2274 bool success = false;
2275 std::wstring text;
2276 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522277 text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2278 GetText();
initial.commit09911bf2008-07-26 23:55:292279 success = true;
2280 }
2281 Send(new AutomationMsg_AutocompleteEditGetTextResponse(message.routing_id(),
2282 success, text));
2283}
2284
2285void AutomationProvider::SetAutocompleteEditText(const IPC::Message& message,
2286 int autocomplete_edit_handle,
2287 const std::wstring& text) {
2288 bool success = false;
2289 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522290 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2291 SetUserText(text);
initial.commit09911bf2008-07-26 23:55:292292 success = true;
2293 }
2294 Send(new AutomationMsg_AutocompleteEditSetTextResponse(
2295 message.routing_id(), success));
2296}
2297
2298void AutomationProvider::AutocompleteEditGetMatches(
2299 const IPC::Message& message,
2300 int autocomplete_edit_handle) {
2301 bool success = false;
2302 std::vector<AutocompleteMatchData> matches;
2303 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272304 const AutocompleteResult& result = autocomplete_edit_tracker_->
2305 GetResource(autocomplete_edit_handle)->model()->result();
2306 for (AutocompleteResult::const_iterator i = result.begin();
2307 i != result.end(); ++i)
initial.commit09911bf2008-07-26 23:55:292308 matches.push_back(AutocompleteMatchData(*i));
2309 success = true;
2310 }
2311 Send(new AutomationMsg_AutocompleteEditGetMatchesResponse(
2312 message.routing_id(), success, matches));
2313}
2314
2315void AutomationProvider::AutocompleteEditIsQueryInProgress(
2316 const IPC::Message& message,
2317 int autocomplete_edit_handle) {
2318 bool success = false;
2319 bool query_in_progress = false;
2320 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522321 query_in_progress = autocomplete_edit_tracker_->
2322 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
initial.commit09911bf2008-07-26 23:55:292323 success = true;
2324 }
2325 Send(new AutomationMsg_AutocompleteEditIsQueryInProgressResponse(
2326 message.routing_id(), success, query_in_progress));
2327}
2328
[email protected]18cb2572008-08-21 20:34:452329void AutomationProvider::OnMessageFromExternalHost(
2330 int handle, const std::string& target, const std::string& message) {
[email protected]fa83e762008-08-15 21:41:392331 if (tab_tracker_->ContainsHandle(handle)) {
2332 NavigationController* tab = tab_tracker_->GetResource(handle);
2333 if (!tab) {
2334 NOTREACHED();
2335 return;
2336 }
2337 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2338 if (!tab_contents) {
2339 NOTREACHED();
2340 return;
2341 }
2342
2343 WebContents* web_contents = tab_contents->AsWebContents();
2344 if (!web_contents) {
2345 NOTREACHED();
2346 return;
2347 }
2348
2349 RenderViewHost* view_host = web_contents->render_view_host();
2350 if (!view_host) {
2351 return;
2352 }
2353
[email protected]18cb2572008-08-21 20:34:452354 view_host->ForwardMessageFromExternalHost(target, message);
[email protected]fa83e762008-08-15 21:41:392355 }
2356}
2357
[email protected]20e93d12008-08-28 16:31:572358WebContents* AutomationProvider::GetWebContentsForHandle(
2359 int handle, NavigationController** tab) {
2360 WebContents* web_contents = NULL;
2361 if (tab_tracker_->ContainsHandle(handle)) {
2362 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2363 TabContents* tab_contents = nav_controller->active_contents();
2364 if (tab_contents && tab_contents->type() == TAB_CONTENTS_WEB) {
2365 web_contents = tab_contents->AsWebContents();
2366 if (tab)
2367 *tab = nav_controller;
2368 }
2369 }
2370 return web_contents;
2371}
2372
initial.commit09911bf2008-07-26 23:55:292373TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2374 : AutomationProvider(profile) {
2375 BrowserList::AddObserver(this);
2376 NotificationService::current()->AddObserver(this, NOTIFY_SESSION_END,
2377 NotificationService::AllSources());
2378}
2379
2380TestingAutomationProvider::~TestingAutomationProvider() {
2381 NotificationService::current()->RemoveObserver(this, NOTIFY_SESSION_END,
2382 NotificationService::AllSources());
2383 BrowserList::RemoveObserver(this);
2384}
2385
2386void TestingAutomationProvider::OnChannelError() {
2387 BrowserList::CloseAllBrowsers(true);
2388 AutomationProvider::OnChannelError();
2389}
2390
2391void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2392 // For backwards compatibility with the testing automation interface, we
2393 // want the automation provider (and hence the process) to go away when the
2394 // last browser goes away.
2395 if (BrowserList::size() == 1) {
2396 // If you change this, update Observer for NOTIFY_SESSION_END below.
[email protected]295039bd2008-08-15 04:32:572397 MessageLoop::current()->PostTask(FROM_HERE,
2398 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292399 }
2400}
2401
2402void TestingAutomationProvider::Observe(NotificationType type,
2403 const NotificationSource& source,
2404 const NotificationDetails& details) {
2405 DCHECK(type == NOTIFY_SESSION_END);
2406 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2407 // before the task runs resulting in this object not being deleted. This
2408 // Release balance out the Release scheduled by OnBrowserRemoving.
2409 Release();
2410}
[email protected]295039bd2008-08-15 04:32:572411
2412void TestingAutomationProvider::OnRemoveProvider() {
2413 AutomationProviderList::GetInstance()->RemoveProvider(this);
2414}
[email protected]8a3422c92008-09-24 17:42:422415
2416void AutomationProvider::GetSSLInfoBarCount(const IPC::Message& message,
2417 int handle) {
2418 int count = -1; // -1 means error.
2419 if (tab_tracker_->ContainsHandle(handle)) {
2420 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342421 if (nav_controller)
2422 count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422423 }
2424 Send(new AutomationMsg_GetSSLInfoBarCountResponse(message.routing_id(),
2425 count));
2426}
2427
2428void AutomationProvider::ClickSSLInfoBarLink(const IPC::Message& message,
2429 int handle,
2430 int info_bar_index,
2431 bool wait_for_navigation) {
2432 bool success = false;
2433 if (tab_tracker_->ContainsHandle(handle)) {
2434 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2435 if (nav_controller) {
[email protected]eb9ba192008-12-02 02:41:342436 int count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422437 if (info_bar_index >= 0 && info_bar_index < count) {
2438 if (wait_for_navigation) {
2439 AddNavigationStatusListener(nav_controller,
2440 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2441 message.routing_id(), true),
2442 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2443 message.routing_id(), true));
2444 }
[email protected]eb9ba192008-12-02 02:41:342445 InfoBarDelegate* delegate =
2446 nav_controller->active_contents()->GetInfoBarDelegateAt(
2447 info_bar_index);
2448 if (delegate->AsConfirmInfoBarDelegate())
2449 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422450 success = true;
2451 }
2452 }
2453 }
2454 if (!wait_for_navigation || !success)
2455 Send(new AutomationMsg_ClickSSLInfoBarLinkResponse(message.routing_id(),
2456 success));
2457}
2458
2459void AutomationProvider::GetLastNavigationTime(const IPC::Message& message,
2460 int handle) {
2461 Time time = tab_tracker_->GetLastNavigationTime(handle);
2462 Send(new AutomationMsg_GetLastNavigationTimeResponse(message.routing_id(),
2463 time.ToInternalValue()));
2464}
2465
2466void AutomationProvider::WaitForNavigation(const IPC::Message& message,
2467 int handle,
2468 int64 last_navigation_time) {
2469 NavigationController* controller = NULL;
2470 if (tab_tracker_->ContainsHandle(handle))
2471 controller = tab_tracker_->GetResource(handle);
2472
2473 Time time = tab_tracker_->GetLastNavigationTime(handle);
2474 if (time.ToInternalValue() > last_navigation_time || !controller) {
2475 Send(new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2476 controller != NULL));
2477 return;
2478 }
2479
2480 AddNavigationStatusListener(controller,
2481 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2482 true),
2483 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2484 true));
2485}
2486
2487void AutomationProvider::SetIntPreference(const IPC::Message& message,
2488 int handle,
[email protected]97fa6ce32008-12-19 01:48:162489 const std::wstring& name,
[email protected]8a3422c92008-09-24 17:42:422490 int value) {
2491 bool success = false;
2492 if (browser_tracker_->ContainsHandle(handle)) {
2493 Browser* browser = browser_tracker_->GetResource(handle);
2494 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
2495 success = true;
2496 }
2497 Send(new AutomationMsg_SetIntPreferenceResponse(message.routing_id(),
2498 success));
2499}
[email protected]97fa6ce32008-12-19 01:48:162500
2501void AutomationProvider::SetStringPreference(const IPC::Message& message,
2502 int handle,
2503 const std::wstring& name,
2504 const std::wstring& value) {
2505 bool success = false;
2506 if (browser_tracker_->ContainsHandle(handle)) {
2507 Browser* browser = browser_tracker_->GetResource(handle);
2508 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
2509 success = true;
2510 }
2511 Send(new AutomationMsg_SetStringPreferenceResponse(message.routing_id(),
2512 success));
2513}
2514
2515void AutomationProvider::GetBooleanPreference(const IPC::Message& message,
2516 int handle,
2517 const std::wstring& name) {
2518 bool success = false;
2519 bool value = false;
2520 if (browser_tracker_->ContainsHandle(handle)) {
2521 Browser* browser = browser_tracker_->GetResource(handle);
2522 value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2523 success = true;
2524 }
2525 Send(new AutomationMsg_GetBooleanPreferenceResponse(message.routing_id(),
2526 success, value));
2527}
2528
2529void AutomationProvider::SetBooleanPreference(const IPC::Message& message,
2530 int handle,
2531 const std::wstring& name,
2532 bool value) {
2533 bool success = false;
2534 if (browser_tracker_->ContainsHandle(handle)) {
2535 Browser* browser = browser_tracker_->GetResource(handle);
2536 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
2537 success = true;
2538 }
2539 Send(new AutomationMsg_SetBooleanPreferenceResponse(message.routing_id(),
2540 success));
2541}
2542
2543// Gets the current used encoding name of the page in the specified tab.
2544void AutomationProvider::GetPageCurrentEncoding(const IPC::Message& message,
2545 int tab_handle) {
2546 std::wstring current_encoding;
2547 if (tab_tracker_->ContainsHandle(tab_handle)) {
2548 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2549 Browser* browser = FindAndActivateTab(nav);
2550 DCHECK(browser);
2551
[email protected]1fc025202009-01-20 23:03:142552 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162553 TabContents* tab_contents = nav->active_contents();
2554 DCHECK(tab_contents->type() == TAB_CONTENTS_WEB);
2555 current_encoding = tab_contents->AsWebContents()->encoding();
2556 }
2557 }
2558 Send(new AutomationMsg_GetPageCurrentEncodingResponse(message.routing_id(),
2559 current_encoding));
2560}
2561
2562// Gets the current used encoding name of the page in the specified tab.
2563void AutomationProvider::OverrideEncoding(const IPC::Message& message,
2564 int tab_handle,
2565 const std::wstring& encoding_name) {
2566 bool succeed = false;
2567 if (tab_tracker_->ContainsHandle(tab_handle)) {
2568 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2569 Browser* browser = FindAndActivateTab(nav);
2570 DCHECK(browser);
2571
[email protected]1fc025202009-01-20 23:03:142572 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162573 TabContents* tab_contents = nav->active_contents();
2574 DCHECK(tab_contents->type() == TAB_CONTENTS_WEB);
2575 int selected_encoding_id =
2576 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2577 if (selected_encoding_id) {
2578 browser->OverrideEncoding(selected_encoding_id);
2579 succeed = true;
2580 }
2581 }
2582 }
2583 Send(new AutomationMsg_OverrideEncodingResponse(message.routing_id(),
2584 succeed));
2585}
[email protected]5bcdb312009-01-07 21:43:202586
2587void AutomationProvider::SavePackageShouldPromptUser(
2588 const IPC::Message& message, bool should_prompt) {
2589 SavePackage::SetShouldPromptUser(should_prompt);
2590}