blob: 04ca9d06b15a8e68c0538c444c6c8483db694a42 [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
[email protected]5fac9622009-02-04 21:49:387#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:298#include "base/path_service.h"
[email protected]5fac9622009-02-04 21:49:389#include "base/thread.h"
[email protected]9e0534b2008-10-21 15:03:0110#include "chrome/app/chrome_dll_resource.h"
[email protected]b6ad1cab2009-01-16 22:41:4211#include "chrome/browser/app_modal_dialog_queue.h"
initial.commit09911bf2008-07-26 23:55:2912#include "chrome/browser/automation/automation_provider_list.h"
13#include "chrome/browser/automation/ui_controls.h"
14#include "chrome/browser/automation/url_request_failed_dns_job.h"
15#include "chrome/browser/automation/url_request_mock_http_job.h"
16#include "chrome/browser/automation/url_request_slow_download_job.h"
[email protected]f3e99e32008-07-30 04:48:3917#include "chrome/browser/browser_window.h"
[email protected]97fa6ce32008-12-19 01:48:1618#include "chrome/browser/character_encoding.h"
initial.commit09911bf2008-07-26 23:55:2919#include "chrome/browser/dom_operation_notification_details.h"
[email protected]cdaa8652008-09-13 02:48:5920#include "chrome/browser/download/download_manager.h"
[email protected]37936ee2008-09-14 01:09:5021#include "chrome/browser/download/save_package.h"
initial.commit09911bf2008-07-26 23:55:2922#include "chrome/browser/external_tab_container.h"
23#include "chrome/browser/find_notification_details.h"
24#include "chrome/browser/login_prompt.h"
initial.commit09911bf2008-07-26 23:55:2925#include "chrome/browser/printing/print_job.h"
[email protected]6524b5f92009-01-22 17:48:2526#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0327#include "chrome/browser/ssl/ssl_manager.h"
28#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]f3ec7742009-01-15 00:59:1629#include "chrome/browser/tab_contents/navigation_entry.h"
30#include "chrome/browser/tab_contents/web_contents.h"
31#include "chrome/browser/tab_contents/web_contents_view.h"
[email protected]c2cbeb92008-09-05 21:36:5732#include "chrome/browser/views/bookmark_bar_view.h"
[email protected]195442e2008-07-31 22:41:2833#include "chrome/browser/views/location_bar_view.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/common/chrome_paths.h"
[email protected]6a02963e2009-01-06 16:58:0335#include "chrome/common/notification_registrar.h"
[email protected]8a3422c92008-09-24 17:42:4236#include "chrome/common/pref_service.h"
initial.commit09911bf2008-07-26 23:55:2937#include "chrome/test/automation/automation_messages.h"
[email protected]fad84eab2008-12-05 00:37:2038#include "chrome/views/app_modal_dialog_delegate.h"
39#include "chrome/views/window.h"
initial.commit09911bf2008-07-26 23:55:2940#include "net/base/cookie_monster.h"
41#include "net/url_request/url_request_filter.h"
42
[email protected]e1acf6f2008-10-27 20:43:3343using base::Time;
44
initial.commit09911bf2008-07-26 23:55:2945class InitialLoadObserver : public NotificationObserver {
46 public:
47 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
48 : outstanding_tab_count_(tab_count),
49 automation_(automation) {
50 if (outstanding_tab_count_ > 0) {
51 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:5652 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:0353 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:5654 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:0355 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:2956 }
57 }
58
59 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:2960 }
61
62 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:0363 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:2964 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
65 }
66
initial.commit09911bf2008-07-26 23:55:2967 virtual void Observe(NotificationType type,
68 const NotificationSource& source,
69 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:5670 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:2971 if (outstanding_tab_count_ > loading_tabs_.size())
72 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:5673 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:2974 if (outstanding_tab_count_ > finished_tabs_.size()) {
75 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
76 finished_tabs_.insert(source.map_key());
77 if (outstanding_tab_count_ == finished_tabs_.size())
78 ConditionMet();
79 }
80 } else {
81 NOTREACHED();
82 }
83 }
84
85 private:
86 typedef std::set<uintptr_t> TabSet;
87
[email protected]6a02963e2009-01-06 16:58:0388 NotificationRegistrar registrar_;
89
initial.commit09911bf2008-07-26 23:55:2990 AutomationProvider* automation_;
91 size_t outstanding_tab_count_;
92 TabSet loading_tabs_;
93 TabSet finished_tabs_;
94};
95
96// Watches for NewTabUI page loads for performance timing purposes.
97class NewTabUILoadObserver : public NotificationObserver {
98 public:
99 explicit NewTabUILoadObserver(AutomationProvider* automation)
100 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:56101 NotificationService::current()->AddObserver(
102 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
103 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29104 }
105
106 ~NewTabUILoadObserver() {
107 Unregister();
108 }
109
110 void Unregister() {
[email protected]bfd04a62009-02-01 18:16:56111 NotificationService::current()->RemoveObserver(
112 this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
113 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29114 }
115
116 virtual void Observe(NotificationType type,
117 const NotificationSource& source,
118 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56119 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29120 Details<int> load_time(details);
121 automation_->Send(
122 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
123 } else {
124 NOTREACHED();
125 }
126 }
127
128 private:
129 AutomationProvider* automation_;
130};
131
132class NavigationControllerRestoredObserver : public NotificationObserver {
133 public:
134 NavigationControllerRestoredObserver(AutomationProvider* automation,
135 NavigationController* controller,
136 int32 routing_id)
137 : automation_(automation),
138 controller_(controller),
139 routing_id_(routing_id) {
140 if (FinishedRestoring()) {
141 registered_ = false;
142 SendDone();
143 } else {
144 registered_ = true;
145 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56146 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29147 NotificationService::AllSources());
148 }
149 }
150
151 ~NavigationControllerRestoredObserver() {
152 if (registered_)
153 Unregister();
154 }
155
156 virtual void Observe(NotificationType type,
157 const NotificationSource& source,
158 const NotificationDetails& details) {
159 if (FinishedRestoring()) {
160 SendDone();
161 Unregister();
162 }
163 }
164
165 private:
166 void Unregister() {
167 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56168 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29169 NotificationService::AllSources());
170 registered_ = false;
171 }
172
173 bool FinishedRestoring() {
174 return (!controller_->needs_reload() && !controller_->GetPendingEntry() &&
[email protected]d5f942ba2008-09-26 19:30:34175 !controller_->active_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29176 }
177
178 void SendDone() {
179 automation_->Send(new AutomationMsg_TabFinishedRestoring(routing_id_));
180 }
181
182 bool registered_;
183 AutomationProvider* automation_;
184 NavigationController* controller_;
185 const int routing_id_;
186
[email protected]5a52f162008-08-27 04:15:31187 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29188};
189
initial.commit09911bf2008-07-26 23:55:29190class NavigationNotificationObserver : public NotificationObserver {
191 public:
192 NavigationNotificationObserver(NavigationController* controller,
193 AutomationProvider* automation,
194 IPC::Message* completed_response,
195 IPC::Message* auth_needed_response)
196 : automation_(automation),
197 completed_response_(completed_response),
198 auth_needed_response_(auth_needed_response),
199 controller_(controller),
200 navigation_started_(false) {
201 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56202 service->AddObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42203 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56204 service->AddObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29205 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56206 service->AddObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29207 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56208 service->AddObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29209 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56210 service->AddObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29211 Source<NavigationController>(controller_));
212 }
213
214 ~NavigationNotificationObserver() {
215 if (completed_response_) delete completed_response_;
216 if (auth_needed_response_) delete auth_needed_response_;
217 Unregister();
218 }
219
220 void ConditionMet(IPC::Message** response) {
221 if (*response) {
222 automation_->Send(*response);
223 *response = NULL; // *response is deleted by Send.
224 }
[email protected]d5798082008-09-29 21:02:03225 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29226 delete this;
227 }
228
229 void Unregister() {
230 NotificationService* service = NotificationService::current();
[email protected]bfd04a62009-02-01 18:16:56231 service->RemoveObserver(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]8a3422c92008-09-24 17:42:42232 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56233 service->RemoveObserver(this, NotificationType::LOAD_START,
initial.commit09911bf2008-07-26 23:55:29234 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56235 service->RemoveObserver(this, NotificationType::LOAD_STOP,
initial.commit09911bf2008-07-26 23:55:29236 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56237 service->RemoveObserver(this, NotificationType::AUTH_NEEDED,
initial.commit09911bf2008-07-26 23:55:29238 Source<NavigationController>(controller_));
[email protected]bfd04a62009-02-01 18:16:56239 service->RemoveObserver(this, NotificationType::AUTH_SUPPLIED,
initial.commit09911bf2008-07-26 23:55:29240 Source<NavigationController>(controller_));
241 }
242
243 virtual void Observe(NotificationType type,
244 const NotificationSource& source,
245 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42246 // We listen for 2 events to determine when the navigation started because:
247 // - when this is used by the WaitForNavigation method, we might be invoked
248 // afer the load has started (but not after the entry was committed, as
249 // WaitForNavigation compares times of the last navigation).
250 // - when this is used with a page requiring authentication, we will not get
[email protected]bfd04a62009-02-01 18:16:56251 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so we need the
252 // NotificationType::LOAD_START.
253 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
254 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29255 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56256 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29257 if (navigation_started_) {
258 navigation_started_ = false;
259 ConditionMet(&completed_response_);
260 }
[email protected]bfd04a62009-02-01 18:16:56261 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29262 // The LoginHandler for this tab is no longer valid.
263 automation_->RemoveLoginHandler(controller_);
264
265 // Treat this as if navigation started again, since load start/stop don't
266 // occur while authentication is ongoing.
267 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56268 } else if (type == NotificationType::AUTH_NEEDED) {
initial.commit09911bf2008-07-26 23:55:29269 if (navigation_started_) {
270 // Remember the login handler that wants authentication.
271 LoginHandler* handler =
272 Details<LoginNotificationDetails>(details)->handler();
273 automation_->AddLoginHandler(controller_, handler);
274
275 // Respond that authentication is needed.
276 navigation_started_ = false;
277 ConditionMet(&auth_needed_response_);
278 } else {
279 NOTREACHED();
280 }
281 } else {
282 NOTREACHED();
283 }
284 }
285
286 private:
287 AutomationProvider* automation_;
288 IPC::Message* completed_response_;
289 IPC::Message* auth_needed_response_;
290 NavigationController* controller_;
291 bool navigation_started_;
292};
293
294class TabStripNotificationObserver : public NotificationObserver {
295 public:
296 TabStripNotificationObserver(Browser* parent, NotificationType notification,
297 AutomationProvider* automation, int32 routing_id)
298 : automation_(automation),
299 notification_(notification),
300 parent_(parent),
301 routing_id_(routing_id) {
302 NotificationService::current()->
303 AddObserver(this, notification_, NotificationService::AllSources());
304 }
305
306 virtual ~TabStripNotificationObserver() {
307 Unregister();
308 }
309
310 void Unregister() {
311 NotificationService::current()->
312 RemoveObserver(this, notification_, NotificationService::AllSources());
313 }
314
315 virtual void Observe(NotificationType type,
316 const NotificationSource& source,
317 const NotificationDetails& details) {
318 if (type == notification_) {
319 ObserveTab(Source<NavigationController>(source).ptr());
320
321 // If verified, no need to observe anymore
322 automation_->RemoveTabStripObserver(this);
323 delete this;
324 } else {
325 NOTREACHED();
326 }
327 }
328
329 virtual void ObserveTab(NavigationController* controller) = 0;
330
331 protected:
332 AutomationProvider* automation_;
333 Browser* parent_;
334 NotificationType notification_;
335 int32 routing_id_;
336};
337
338class TabAppendedNotificationObserver : public TabStripNotificationObserver {
339 public:
340 TabAppendedNotificationObserver(Browser* parent,
341 AutomationProvider* automation, int32 routing_id)
[email protected]bfd04a62009-02-01 18:16:56342 : TabStripNotificationObserver(parent, NotificationType::TAB_PARENTED,
343 automation, routing_id) {
initial.commit09911bf2008-07-26 23:55:29344 }
345
346 virtual void ObserveTab(NavigationController* controller) {
347 int tab_index =
348 automation_->GetIndexForNavigationController(controller, parent_);
349 if (tab_index == TabStripModel::kNoTab) {
350 // This tab notification doesn't belong to the parent_
351 return;
352 }
353
354 // Give the same response even if auth is needed, since it doesn't matter.
355 automation_->AddNavigationStatusListener(controller,
356 new AutomationMsg_AppendTabResponse(routing_id_, tab_index),
357 new AutomationMsg_AppendTabResponse(routing_id_, tab_index));
358 }
359};
360
361class TabClosedNotificationObserver : public TabStripNotificationObserver {
362 public:
363 TabClosedNotificationObserver(Browser* parent,
364 AutomationProvider* automation,
365 int32 routing_id,
366 bool wait_until_closed)
367 : TabStripNotificationObserver(parent,
[email protected]bfd04a62009-02-01 18:16:56368 wait_until_closed ? NotificationType::TAB_CLOSED :
369 NotificationType::TAB_CLOSING,
370 automation,
371 routing_id) {
initial.commit09911bf2008-07-26 23:55:29372 }
373
374 virtual void ObserveTab(NavigationController* controller) {
375 automation_->Send(new AutomationMsg_CloseTabResponse(routing_id_, true));
376 }
377};
378
379class BrowserClosedNotificationObserver : public NotificationObserver {
380 public:
381 BrowserClosedNotificationObserver(Browser* browser,
382 AutomationProvider* automation,
383 int32 routing_id)
384 : automation_(automation),
385 routing_id_(routing_id) {
[email protected]bfd04a62009-02-01 18:16:56386 NotificationService::current()->AddObserver(this,
387 NotificationType::BROWSER_CLOSED, Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29388 }
389
390 virtual void Observe(NotificationType type,
391 const NotificationSource& source,
392 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56393 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29394 Details<bool> close_app(details);
395 automation_->Send(
396 new AutomationMsg_CloseBrowserResponse(routing_id_,
397 true,
398 *(close_app.ptr())));
399 delete this;
400 }
401
402 private:
403 AutomationProvider* automation_;
404 int32 routing_id_;
405};
406
407class FindInPageNotificationObserver : public NotificationObserver {
408 public:
409 FindInPageNotificationObserver(AutomationProvider* automation,
410 TabContents* parent_tab,
411 int32 routing_id)
412 : automation_(automation),
413 parent_tab_(parent_tab),
[email protected]aedd85a2008-12-04 19:32:49414 routing_id_(routing_id),
415 active_match_ordinal_(-1) {
[email protected]bfd04a62009-02-01 18:16:56416 NotificationService::current()->AddObserver(
417 this,
418 NotificationType::FIND_RESULT_AVAILABLE,
419 Source<TabContents>(parent_tab_));
initial.commit09911bf2008-07-26 23:55:29420 }
421
422 ~FindInPageNotificationObserver() {
423 Unregister();
424 }
425
426 void Unregister() {
427 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56428 RemoveObserver(this, NotificationType::FIND_RESULT_AVAILABLE,
initial.commit09911bf2008-07-26 23:55:29429 Source<TabContents>(parent_tab_));
430 }
431
432 virtual void Observe(NotificationType type, const NotificationSource& source,
433 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56434 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29435 Details<FindNotificationDetails> find_details(details);
436 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49437 // We get multiple responses and one of those will contain the ordinal.
438 // This message comes to us before the final update is sent.
439 if (find_details->active_match_ordinal() > -1)
440 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29441 if (find_details->final_update()) {
[email protected]aedd85a2008-12-04 19:32:49442 automation_->Send(new AutomationMsg_FindInPageResponse2(routing_id_,
443 active_match_ordinal_,
initial.commit09911bf2008-07-26 23:55:29444 find_details->number_of_matches()));
445 } else {
446 DLOG(INFO) << "Ignoring, since we only care about the final message";
447 }
448 }
449 } else {
450 NOTREACHED();
451 }
452 }
453
454 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
455 // we wait for notification to find out what the results are. As the user is
456 // typing, new search requests can be issued and the Request ID helps us make
457 // sense of whether this is the current request or an old one. The unit tests,
458 // however, which uses this constant issues only one search at a time, so we
459 // don't need a rolling id to identify each search. But, we still need to
460 // specify one, so we just use a fixed one - its value does not matter.
461 static const int kFindInPageRequestId;
462 private:
463 AutomationProvider* automation_;
464 TabContents* parent_tab_;
465 int32 routing_id_;
[email protected]aedd85a2008-12-04 19:32:49466 // We will at some point (before final update) be notified of the ordinal and
467 // we need to preserve it so we can send it later.
468 int active_match_ordinal_;
initial.commit09911bf2008-07-26 23:55:29469};
470
471const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
472
473class DomOperationNotificationObserver : public NotificationObserver {
474 public:
475 explicit DomOperationNotificationObserver(AutomationProvider* automation)
476 : automation_(automation) {
477 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56478 AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29479 NotificationService::AllSources());
480 }
481
482 ~DomOperationNotificationObserver() {
483 NotificationService::current()->
[email protected]bfd04a62009-02-01 18:16:56484 RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE,
initial.commit09911bf2008-07-26 23:55:29485 NotificationService::AllSources());
486 }
487
488 virtual void Observe(NotificationType type, const NotificationSource& source,
489 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56490 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29491 Details<DomOperationNotificationDetails> dom_op_details(details);
492 automation_->Send(new AutomationMsg_DomOperationResponse(
493 dom_op_details->automation_id(),
494 dom_op_details->json()));
495 }
496 }
497 private:
498 AutomationProvider* automation_;
499};
500
501class DomInspectorNotificationObserver : public NotificationObserver {
502 public:
503 explicit DomInspectorNotificationObserver(AutomationProvider* automation)
504 : automation_(automation) {
[email protected]bfd04a62009-02-01 18:16:56505 NotificationService::current()->AddObserver(
506 this,
507 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
508 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29509 }
510
511 ~DomInspectorNotificationObserver() {
[email protected]bfd04a62009-02-01 18:16:56512 NotificationService::current()->RemoveObserver(
513 this,
514 NotificationType::DOM_INSPECT_ELEMENT_RESPONSE,
515 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29516 }
517
518 virtual void Observe(NotificationType type, const NotificationSource& source,
519 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56520 if (NotificationType::DOM_INSPECT_ELEMENT_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29521 Details<int> dom_inspect_details(details);
522 automation_->ReceivedInspectElementResponse(*(dom_inspect_details.ptr()));
523 }
524 }
525
526 private:
527 AutomationProvider* automation_;
528};
529
530class DocumentPrintedNotificationObserver : public NotificationObserver {
531 public:
532 DocumentPrintedNotificationObserver(AutomationProvider* automation,
533 int32 routing_id)
534 : automation_(automation),
535 routing_id_(routing_id),
536 success_(false) {
[email protected]bfd04a62009-02-01 18:16:56537 NotificationService::current()->AddObserver(
538 this,
539 NotificationType::PRINT_JOB_EVENT,
540 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29541 }
542
543 ~DocumentPrintedNotificationObserver() {
544 automation_->Send(
545 new AutomationMsg_PrintNowResponse(routing_id_, success_));
546 automation_->RemoveNavigationStatusListener(this);
[email protected]bfd04a62009-02-01 18:16:56547 NotificationService::current()->RemoveObserver(
548 this,
549 NotificationType::PRINT_JOB_EVENT,
550 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29551 }
552
553 virtual void Observe(NotificationType type, const NotificationSource& source,
554 const NotificationDetails& details) {
555 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56556 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29557 switch (Details<JobEventDetails>(details)->type()) {
558 case JobEventDetails::JOB_DONE: {
559 // Succeeded.
560 success_ = true;
561 delete this;
562 break;
563 }
564 case JobEventDetails::USER_INIT_CANCELED:
565 case JobEventDetails::FAILED: {
566 // Failed.
567 delete this;
568 break;
569 }
570 case JobEventDetails::NEW_DOC:
571 case JobEventDetails::USER_INIT_DONE:
572 case JobEventDetails::DEFAULT_INIT_DONE:
573 case JobEventDetails::NEW_PAGE:
574 case JobEventDetails::PAGE_DONE:
575 case JobEventDetails::DOC_DONE:
576 case JobEventDetails::ALL_PAGES_REQUESTED: {
577 // Don't care.
578 break;
579 }
580 default: {
581 NOTREACHED();
582 break;
583 }
584 }
585 }
586
587 private:
588 scoped_refptr<AutomationProvider> automation_;
589 int32 routing_id_;
590 bool success_;
591};
592
[email protected]cbab76d2008-10-13 22:42:47593class AutomationInterstitialPage : public InterstitialPage {
594 public:
[email protected]a3a1d142008-12-19 00:42:30595 AutomationInterstitialPage(WebContents* tab,
[email protected]cbab76d2008-10-13 22:42:47596 const GURL& url,
597 const std::string& contents)
598 : InterstitialPage(tab, true, url),
599 contents_(contents) {
600 }
601
602 virtual std::string GetHTMLContents() { return contents_; }
603
604 private:
605 std::string contents_;
606
607 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
608};
609
initial.commit09911bf2008-07-26 23:55:29610AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57611 : redirect_query_(0),
initial.commit09911bf2008-07-26 23:55:29612 profile_(profile) {
initial.commit09911bf2008-07-26 23:55:29613 browser_tracker_.reset(new AutomationBrowserTracker(this));
614 window_tracker_.reset(new AutomationWindowTracker(this));
615 tab_tracker_.reset(new AutomationTabTracker(this));
616 autocomplete_edit_tracker_.reset(
617 new AutomationAutocompleteEditTracker(this));
618 cwindow_tracker_.reset(new AutomationConstrainedWindowTracker(this));
619 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
620 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
621 dom_inspector_observer_.reset(new DomInspectorNotificationObserver(this));
622}
623
624AutomationProvider::~AutomationProvider() {
[email protected]0da050b92008-08-19 19:29:47625 // Make sure that any outstanding NotificationObservers also get destroyed.
626 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31627 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47628 while ((observer = it.GetNext()) != NULL)
629 delete observer;
initial.commit09911bf2008-07-26 23:55:29630}
631
632void AutomationProvider::ConnectToChannel(const std::wstring& channel_id) {
[email protected]295039bd2008-08-15 04:32:57633 channel_.reset(
634 new IPC::ChannelProxy(channel_id, IPC::Channel::MODE_CLIENT, this, NULL,
635 g_browser_process->io_thread()->message_loop()));
636 channel_->Send(new AutomationMsg_Hello(0));
initial.commit09911bf2008-07-26 23:55:29637}
638
639void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
640 if (expected_tabs == 0) {
641 Send(new AutomationMsg_InitialLoadsComplete(0));
642 } else {
643 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
644 }
645}
646
647NotificationObserver* AutomationProvider::AddNavigationStatusListener(
648 NavigationController* tab, IPC::Message* completed_response,
649 IPC::Message* auth_needed_response) {
650 NotificationObserver* observer =
651 new NavigationNotificationObserver(tab, this, completed_response,
652 auth_needed_response);
653 notification_observer_list_.AddObserver(observer);
654
655 return observer;
656}
657
658void AutomationProvider::RemoveNavigationStatusListener(
659 NotificationObserver* obs) {
660 notification_observer_list_.RemoveObserver(obs);
661}
662
663NotificationObserver* AutomationProvider::AddTabStripObserver(
664 Browser* parent, int32 routing_id) {
665 NotificationObserver* observer = new
666 TabAppendedNotificationObserver(parent, this, routing_id);
667 notification_observer_list_.AddObserver(observer);
668
669 return observer;
670}
671
672void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
673 notification_observer_list_.RemoveObserver(obs);
674}
675
676void AutomationProvider::AddLoginHandler(NavigationController* tab,
677 LoginHandler* handler) {
678 login_handler_map_[tab] = handler;
679}
680
681void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
682 DCHECK(login_handler_map_[tab]);
683 login_handler_map_.erase(tab);
684}
685
686int AutomationProvider::GetIndexForNavigationController(
687 const NavigationController* controller, const Browser* parent) const {
688 DCHECK(parent);
689 return parent->GetIndexOfController(controller);
690}
691
692void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
693 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
694 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequest, CloseBrowser)
695 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTabRequest, ActivateTab)
696 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndexRequest, GetActiveTabIndex)
697 IPC_MESSAGE_HANDLER(AutomationMsg_AppendTabRequest, AppendTab)
698 IPC_MESSAGE_HANDLER(AutomationMsg_CloseTabRequest, CloseTab)
699 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesRequest, GetCookies)
700 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieRequest, SetCookie)
701 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateToURLRequest, NavigateToURL)
702 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncRequest, NavigationAsync)
703 IPC_MESSAGE_HANDLER(AutomationMsg_GoBackRequest, GoBack)
704 IPC_MESSAGE_HANDLER(AutomationMsg_GoForwardRequest, GoForward)
705 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadRequest, Reload)
706 IPC_MESSAGE_HANDLER(AutomationMsg_SetAuthRequest, SetAuth)
707 IPC_MESSAGE_HANDLER(AutomationMsg_CancelAuthRequest, CancelAuth)
708 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuthRequest, NeedsAuth)
709 IPC_MESSAGE_HANDLER(AutomationMsg_RedirectsFromRequest, GetRedirectsFrom)
710 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCountRequest,
711 GetBrowserWindowCount)
712 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowRequest, GetBrowserWindow)
713 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindowRequest,
714 GetLastActiveBrowserWindow)
715 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindowRequest, GetActiveWindow)
716 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActiveRequest, IsWindowActive)
717 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow);
718 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWNDRequest, GetWindowHWND)
[email protected]4ae62752008-08-04 23:28:47719 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandRequest,
720 ExecuteBrowserCommand)
initial.commit09911bf2008-07-26 23:55:29721 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBoundsRequest,
722 WindowGetViewBounds)
723 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisibleRequest, SetWindowVisible)
724 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClickRequest, WindowSimulateClick)
725 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPressRequest,
726 WindowSimulateKeyPress)
727 IPC_MESSAGE_HANDLER(AutomationMsg_WindowDragRequest, WindowSimulateDrag)
728 IPC_MESSAGE_HANDLER(AutomationMsg_TabCountRequest, GetTabCount)
729 IPC_MESSAGE_HANDLER(AutomationMsg_TabRequest, GetTab)
730 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWNDRequest, GetTabHWND)
731 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessIDRequest, GetTabProcessID)
732 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitleRequest, GetTabTitle)
733 IPC_MESSAGE_HANDLER(AutomationMsg_TabURLRequest, GetTabURL)
734 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibilityRequest,
735 GetShelfVisibility)
736 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
737 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAcceleratorRequest, ApplyAccelerator)
738 IPC_MESSAGE_HANDLER(AutomationMsg_DomOperationRequest, ExecuteJavascript)
739 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCountRequest,
740 GetConstrainedWindowCount)
741 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowRequest,
742 GetConstrainedWindow)
743 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedTitleRequest,
744 GetConstrainedTitle)
745 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPageRequest,
746 HandleFindInPageRequest)
747 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewIDRequest, GetFocusedViewID)
748 IPC_MESSAGE_HANDLER(AutomationMsg_InspectElementRequest,
749 HandleInspectElementRequest)
750 IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet,
751 SetFilteredInet);
752 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectoryRequest,
753 GetDownloadDirectory);
754 IPC_MESSAGE_HANDLER(AutomationMsg_OpenNewBrowserWindow,
755 OpenNewBrowserWindow);
756 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowserRequest,
757 GetWindowForBrowser);
758 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowserRequest,
759 GetAutocompleteEditForBrowser);
760 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindowRequest,
761 GetBrowserForWindow);
762 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
763 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTabRequest,
764 NavigateInExternalTab)
765 IPC_MESSAGE_HANDLER(AutomationMsg_ShowInterstitialPageRequest,
766 ShowInterstitialPage);
767 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPageRequest,
768 HideInterstitialPage);
769 IPC_MESSAGE_HANDLER(AutomationMsg_SetAcceleratorsForTab,
770 SetAcceleratorsForTab)
771 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
772 ProcessUnhandledAccelerator)
773 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForTabToBeRestored,
774 WaitForTabToBeRestored)
775 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState,
776 GetSecurityState)
777 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType,
778 GetPageType)
779 IPC_MESSAGE_HANDLER(AutomationMsg_ActionOnSSLBlockingPage,
780 ActionOnSSLBlockingPage)
781 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
782 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
783 IsPageMenuCommandEnabled)
784 IPC_MESSAGE_HANDLER(AutomationMsg_PrintNowRequest, PrintNow)
785 IPC_MESSAGE_HANDLER(AutomationMsg_SavePageRequest, SavePage)
786 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetTextRequest,
787 GetAutocompleteEditText)
788 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetTextRequest,
789 SetAutocompleteEditText)
790 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgressRequest,
791 AutocompleteEditIsQueryInProgress)
792 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatchesRequest,
793 AutocompleteEditGetMatches)
794 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowBoundsRequest,
795 GetConstrainedWindowBounds)
[email protected]5f8af2a2008-08-06 22:49:45796 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPageRequest,
797 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:45798 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
799 OnMessageFromExternalHost)
[email protected]5a52f162008-08-27 04:15:31800 IPC_MESSAGE_HANDLER(AutomationMsg_FindRequest,
801 HandleFindRequest)
[email protected]20e93d12008-08-28 16:31:57802 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibilityRequest,
803 GetFindWindowVisibility)
804 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocationRequest,
805 HandleFindWindowLocationRequest)
[email protected]c2cbeb92008-09-05 21:36:57806 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibilityRequest,
807 GetBookmarkBarVisitility)
[email protected]8a3422c92008-09-24 17:42:42808 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCountRequest,
809 GetSSLInfoBarCount)
810 IPC_MESSAGE_HANDLER(AutomationMsg_ClickSSLInfoBarLinkRequest,
811 ClickSSLInfoBarLink)
812 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTimeRequest,
813 GetLastNavigationTime)
814 IPC_MESSAGE_HANDLER(AutomationMsg_WaitForNavigationRequest,
815 WaitForNavigation)
816 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreferenceRequest,
817 SetIntPreference)
[email protected]c274acc2008-11-11 20:13:44818 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialogRequest,
819 GetShowingAppModalDialog)
[email protected]fad84eab2008-12-05 00:37:20820 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButtonRequest,
821 ClickAppModalDialogButton)
[email protected]97fa6ce32008-12-19 01:48:16822 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreferenceRequest,
823 SetStringPreference)
824 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreferenceRequest,
825 GetBooleanPreference)
826 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreferenceRequest,
827 SetBooleanPreference)
828 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncodingRequest,
829 GetPageCurrentEncoding)
830 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncodingRequest,
831 OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:20832 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
833 SavePackageShouldPromptUser)
initial.commit09911bf2008-07-26 23:55:29834 IPC_END_MESSAGE_MAP()
835}
836
837void AutomationProvider::ActivateTab(const IPC::Message& message,
838 int handle, int at_index) {
839 int status = -1;
840 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
841 Browser* browser = browser_tracker_->GetResource(handle);
842 if (at_index >= 0 && at_index < browser->tab_count()) {
843 browser->SelectTabContentsAt(at_index, true);
844 status = 0;
845 }
846 }
847 Send(new AutomationMsg_ActivateTabResponse(message.routing_id(), status));
848}
849
850void AutomationProvider::AppendTab(const IPC::Message& message,
851 int handle, const GURL& url) {
852 int append_tab_response = -1; // -1 is the error code
853 NotificationObserver* observer = NULL;
854
855 if (browser_tracker_->ContainsHandle(handle)) {
856 Browser* browser = browser_tracker_->GetResource(handle);
857 observer = AddTabStripObserver(browser, message.routing_id());
858 TabContents* tab_contents =
[email protected]c0588052008-10-27 23:01:50859 browser->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, NULL);
initial.commit09911bf2008-07-26 23:55:29860 if (tab_contents) {
861 append_tab_response =
862 GetIndexForNavigationController(tab_contents->controller(), browser);
863 }
864 }
865
866 if (append_tab_response < 0) {
867 // The append tab failed. Remove the TabStripObserver
868 if (observer) {
869 RemoveTabStripObserver(observer);
870 delete observer;
871 }
872
873 // This will be reached only if the tab could not be appended. In case of a
874 // successful tab append, a successful navigation notification triggers the
875 // send.
876 Send(new AutomationMsg_AppendTabResponse(message.routing_id(),
877 append_tab_response));
878 }
879}
880
881void AutomationProvider::NavigateToURL(const IPC::Message& message,
882 int handle, const GURL& url) {
883 int status = AUTOMATION_MSG_NAVIGATION_ERROR;
884
885 if (tab_tracker_->ContainsHandle(handle)) {
886 NavigationController* tab = tab_tracker_->GetResource(handle);
887
888 // Simulate what a user would do. Activate the tab and then navigate.
889 // We could allow navigating in a background tab in future.
890 Browser* browser = FindAndActivateTab(tab);
891
892 if (browser) {
893 AddNavigationStatusListener(tab,
894 new AutomationMsg_NavigateToURLResponse(
895 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
896 new AutomationMsg_NavigateToURLResponse(
897 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
898 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:50899 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29900 return;
901 }
902 }
903 Send(new AutomationMsg_NavigateToURLResponse(
904 message.routing_id(), AUTOMATION_MSG_NAVIGATION_ERROR));
905}
906
907void AutomationProvider::NavigationAsync(const IPC::Message& message,
908 int handle, const GURL& url) {
909 bool status = false;
910
911 if (tab_tracker_->ContainsHandle(handle)) {
912 NavigationController* tab = tab_tracker_->GetResource(handle);
913
914 // Simulate what a user would do. Activate the tab and then navigate.
915 // We could allow navigating in a background tab in future.
916 Browser* browser = FindAndActivateTab(tab);
917
918 if (browser) {
919 // Don't add any listener unless a callback mechanism is desired.
920 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:50921 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:29922 status = true;
923 }
924 }
925
926 Send(new AutomationMsg_NavigationAsyncResponse(message.routing_id(), status));
927}
928
929void AutomationProvider::GoBack(const IPC::Message& message, int handle) {
930 if (tab_tracker_->ContainsHandle(handle)) {
931 NavigationController* tab = tab_tracker_->GetResource(handle);
932 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14933 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
initial.commit09911bf2008-07-26 23:55:29934 AddNavigationStatusListener(tab,
935 new AutomationMsg_GoBackResponse(
936 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
937 new AutomationMsg_GoBackResponse(
938 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
939 browser->GoBack();
940 return;
941 }
942 }
943 Send(new AutomationMsg_GoBackResponse(message.routing_id(),
944 AUTOMATION_MSG_NAVIGATION_ERROR));
945}
946
947void AutomationProvider::GoForward(const IPC::Message& message, int handle) {
948 if (tab_tracker_->ContainsHandle(handle)) {
949 NavigationController* tab = tab_tracker_->GetResource(handle);
950 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14951 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
initial.commit09911bf2008-07-26 23:55:29952 AddNavigationStatusListener(tab,
953 new AutomationMsg_GoForwardResponse(
954 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
955 new AutomationMsg_GoForwardResponse(
956 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
957 browser->GoForward();
958 return;
959 }
960 }
961 Send(new AutomationMsg_GoForwardResponse(message.routing_id(),
962 AUTOMATION_MSG_NAVIGATION_ERROR));
963}
964
965void AutomationProvider::Reload(const IPC::Message& message, int handle) {
966 if (tab_tracker_->ContainsHandle(handle)) {
967 NavigationController* tab = tab_tracker_->GetResource(handle);
968 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:14969 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
initial.commit09911bf2008-07-26 23:55:29970 AddNavigationStatusListener(tab,
971 new AutomationMsg_ReloadResponse(
972 message.routing_id(), AUTOMATION_MSG_NAVIGATION_SUCCESS),
973 new AutomationMsg_ReloadResponse(
974 message.routing_id(), AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED));
975 browser->Reload();
976 return;
977 }
978 }
979 Send(new AutomationMsg_ReloadResponse(message.routing_id(),
980 AUTOMATION_MSG_NAVIGATION_ERROR));
981}
982
983void AutomationProvider::SetAuth(const IPC::Message& message, int tab_handle,
984 const std::wstring& username,
985 const std::wstring& password) {
986 int status = -1;
987
988 if (tab_tracker_->ContainsHandle(tab_handle)) {
989 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
990 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
991
992 if (iter != login_handler_map_.end()) {
993 // If auth is needed again after this, assume login has failed. This is
994 // not strictly correct, because a navigation can require both proxy and
995 // server auth, but it should be OK for now.
996 LoginHandler* handler = iter->second;
997 AddNavigationStatusListener(tab,
998 new AutomationMsg_SetAuthResponse(message.routing_id(), 0),
999 new AutomationMsg_SetAuthResponse(message.routing_id(), -1));
1000 handler->SetAuth(username, password);
1001 status = 0;
1002 }
1003 }
1004 if (status < 0) {
1005 Send(new AutomationMsg_SetAuthResponse(message.routing_id(), status));
1006 }
1007}
1008
1009void AutomationProvider::CancelAuth(const IPC::Message& message,
1010 int tab_handle) {
1011 int status = -1;
1012
1013 if (tab_tracker_->ContainsHandle(tab_handle)) {
1014 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1015 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1016
1017 if (iter != login_handler_map_.end()) {
1018 // If auth is needed again after this, something is screwy.
1019 LoginHandler* handler = iter->second;
1020 AddNavigationStatusListener(tab,
1021 new AutomationMsg_CancelAuthResponse(message.routing_id(), 0),
1022 new AutomationMsg_CancelAuthResponse(message.routing_id(), -1));
1023 handler->CancelAuth();
1024 status = 0;
1025 }
1026 }
1027 if (status < 0) {
1028 Send(new AutomationMsg_CancelAuthResponse(message.routing_id(), status));
1029 }
1030}
1031
1032void AutomationProvider::NeedsAuth(const IPC::Message& message,
1033 int tab_handle) {
1034 bool needs_auth = false;
1035
1036 if (tab_tracker_->ContainsHandle(tab_handle)) {
1037 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1038 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1039
1040 if (iter != login_handler_map_.end()) {
1041 // The LoginHandler will be in our map IFF the tab needs auth.
1042 needs_auth = true;
1043 }
1044 }
1045
1046 Send(new AutomationMsg_NeedsAuthResponse(message.routing_id(), needs_auth));
1047}
1048
1049void AutomationProvider::GetRedirectsFrom(const IPC::Message& message,
1050 int tab_handle,
1051 const GURL& source_url) {
1052 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1053 if (tab_tracker_->ContainsHandle(tab_handle)) {
1054 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1055 HistoryService* history_service =
1056 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1057
1058 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1059 "has no history service";
1060 if (history_service) {
1061 // Schedule a history query for redirects. The response will be sent
1062 // asynchronously from the callback the history system uses to notify us
1063 // that it's done: OnRedirectQueryComplete.
1064 redirect_query_routing_id_ = message.routing_id();
1065 redirect_query_ = history_service->QueryRedirectsFrom(
1066 source_url, &consumer_,
1067 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1068 return; // Response will be sent when query completes.
1069 }
1070 }
1071
1072 // Send failure response.
1073 IPC::Message* msg = new IPC::Message(
1074 message.routing_id(), AutomationMsg_RedirectsFromResponse::ID,
1075 IPC::Message::PRIORITY_NORMAL);
[email protected]7d5c3ac2009-02-04 08:58:191076 msg->WriteInt(-1); // Negative string count indicates an error.
initial.commit09911bf2008-07-26 23:55:291077 Send(msg);
1078}
1079
1080void AutomationProvider::GetActiveTabIndex(const IPC::Message& message,
1081 int handle) {
1082 int active_tab_index = -1; // -1 is the error code
1083 if (browser_tracker_->ContainsHandle(handle)) {
1084 Browser* browser = browser_tracker_->GetResource(handle);
1085 active_tab_index = browser->selected_index();
1086 }
1087 Send(new AutomationMsg_ActiveTabIndexResponse(message.routing_id(),
1088 active_tab_index));
1089}
1090
1091void AutomationProvider::GetBrowserWindowCount(const IPC::Message& message) {
1092 Send(new AutomationMsg_BrowserWindowCountResponse(
1093 message.routing_id(), static_cast<int>(BrowserList::size())));
1094}
1095
[email protected]c274acc2008-11-11 20:13:441096void AutomationProvider::GetShowingAppModalDialog(const IPC::Message& message) {
[email protected]fad84eab2008-12-05 00:37:201097 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421098 AppModalDialogQueue::active_dialog();
[email protected]c274acc2008-11-11 20:13:441099 Send(new AutomationMsg_ShowingAppModalDialogResponse(
[email protected]fad84eab2008-12-05 00:37:201100 message.routing_id(), dialog_delegate != NULL,
1101 dialog_delegate ? dialog_delegate->GetDialogButtons() :
1102 views::DialogDelegate::DIALOGBUTTON_NONE));
1103}
1104
1105void AutomationProvider::ClickAppModalDialogButton(const IPC::Message& message,
1106 int button) {
1107 bool success = false;
1108
1109 views::AppModalDialogDelegate* dialog_delegate =
[email protected]b6ad1cab2009-01-16 22:41:421110 AppModalDialogQueue::active_dialog();
[email protected]fad84eab2008-12-05 00:37:201111 if (dialog_delegate &&
1112 (dialog_delegate->GetDialogButtons() & button) == button) {
1113 views::DialogClientView* client_view =
1114 dialog_delegate->window()->client_view()->AsDialogClientView();
1115 if ((button & views::DialogDelegate::DIALOGBUTTON_OK) ==
1116 views::DialogDelegate::DIALOGBUTTON_OK) {
1117 client_view->AcceptWindow();
1118 success = true;
1119 }
1120 if ((button & views::DialogDelegate::DIALOGBUTTON_CANCEL) ==
1121 views::DialogDelegate::DIALOGBUTTON_CANCEL) {
1122 DCHECK(!success) << "invalid param, OK and CANCEL specified";
1123 client_view->CancelWindow();
1124 success = true;
1125 }
1126 }
1127 Send(new AutomationMsg_ClickAppModalDialogButtonResponse(
1128 message.routing_id(), success));
[email protected]c274acc2008-11-11 20:13:441129}
1130
initial.commit09911bf2008-07-26 23:55:291131void AutomationProvider::GetBrowserWindow(const IPC::Message& message,
1132 int index) {
1133 int handle = 0;
1134 if (index >= 0) {
1135 BrowserList::const_iterator iter = BrowserList::begin();
1136
1137 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
1138 if (iter != BrowserList::end()) {
1139 handle = browser_tracker_->Add(*iter);
1140 }
1141 }
1142
1143 Send(new AutomationMsg_BrowserWindowResponse(message.routing_id(), handle));
1144}
1145
1146void AutomationProvider::GetLastActiveBrowserWindow(
1147 const IPC::Message& message) {
1148 int handle = 0;
1149 Browser* browser = BrowserList::GetLastActive();
1150 if (browser)
1151 handle = browser_tracker_->Add(browser);
1152 Send(new AutomationMsg_LastActiveBrowserWindowResponse(message.routing_id(),
1153 handle));
1154}
1155
1156BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1157 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1158 return FALSE;
1159 }
1160 return TRUE;
1161}
1162
1163void AutomationProvider::GetActiveWindow(const IPC::Message& message) {
1164 HWND window = GetForegroundWindow();
1165
1166 // Let's make sure this window belongs to our process.
1167 if (EnumThreadWindows(::GetCurrentThreadId(),
1168 EnumThreadWndProc,
1169 reinterpret_cast<LPARAM>(window))) {
1170 // We enumerated all the windows and did not find the foreground window,
1171 // it is not our window, ignore it.
1172 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), 0));
1173 return;
1174 }
1175
1176 int handle = window_tracker_->Add(window);
1177 Send(new AutomationMsg_ActiveWindowResponse(message.routing_id(), handle));
1178}
1179
1180void AutomationProvider::GetWindowHWND(const IPC::Message& message,
1181 int handle) {
1182 HWND win32_handle = window_tracker_->GetResource(handle);
1183 Send(new AutomationMsg_WindowHWNDResponse(message.routing_id(),
1184 win32_handle));
1185}
1186
[email protected]4ae62752008-08-04 23:28:471187void AutomationProvider::ExecuteBrowserCommand(const IPC::Message& message,
1188 int handle,
1189 int command) {
[email protected]4ae62752008-08-04 23:28:471190 bool success = false;
1191 if (browser_tracker_->ContainsHandle(handle)) {
1192 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141193 if (browser->command_updater()->SupportsCommand(command) &&
1194 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471195 browser->ExecuteCommand(command);
1196 success = true;
1197 }
1198 }
1199 Send(new AutomationMsg_WindowExecuteCommandResponse(message.routing_id(),
1200 success));
1201}
1202
initial.commit09911bf2008-07-26 23:55:291203void AutomationProvider::WindowGetViewBounds(const IPC::Message& message,
1204 int handle,
1205 int view_id,
1206 bool screen_coordinates) {
1207 bool succeeded = false;
[email protected]80f8b9f2008-10-16 18:17:471208 gfx::Rect bounds;
initial.commit09911bf2008-07-26 23:55:291209
1210 void* iter = NULL;
1211 if (window_tracker_->ContainsHandle(handle)) {
1212 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201213 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291214 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381215 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291216 if (view) {
1217 succeeded = true;
[email protected]96b667d2008-10-14 20:58:441218 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291219 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381220 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291221 else
[email protected]c2dacc92008-10-16 23:51:381222 views::View::ConvertPointToView(view, root_view, &point);
[email protected]80f8b9f2008-10-16 18:17:471223 bounds = view->GetLocalBounds(false);
1224 bounds.set_origin(point);
initial.commit09911bf2008-07-26 23:55:291225 }
1226 }
1227 }
1228
[email protected]80f8b9f2008-10-16 18:17:471229 Send(new AutomationMsg_WindowViewBoundsResponse(message.routing_id(),
1230 succeeded, bounds));
initial.commit09911bf2008-07-26 23:55:291231}
1232
1233// This task enqueues a mouse event on the event loop, so that the view
1234// that it's being sent to can do the requisite post-processing.
1235class MouseEventTask : public Task {
1236 public:
[email protected]c2dacc92008-10-16 23:51:381237 MouseEventTask(views::View* view,
1238 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291239 POINT point,
1240 int flags)
1241 : view_(view), type_(type), point_(point), flags_(flags) {}
1242 virtual ~MouseEventTask() {}
1243
1244 virtual void Run() {
[email protected]c2dacc92008-10-16 23:51:381245 views::MouseEvent event(type_, point_.x, point_.y, flags_);
initial.commit09911bf2008-07-26 23:55:291246 // We need to set the cursor position before we process the event because
1247 // some code (tab dragging, for instance) queries the actual cursor location
1248 // rather than the location of the mouse event. Note that the reason why
1249 // the drag code moved away from using mouse event locations was because
1250 // our conversion to screen location doesn't work well with multiple
1251 // monitors, so this only works reliably in a single monitor setup.
[email protected]96b667d2008-10-14 20:58:441252 gfx::Point screen_location(point_.x, point_.y);
initial.commit09911bf2008-07-26 23:55:291253 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]96b667d2008-10-14 20:58:441254 ::SetCursorPos(screen_location.x(), screen_location.y());
initial.commit09911bf2008-07-26 23:55:291255 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381256 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291257 view_->OnMousePressed(event);
1258 break;
1259
[email protected]c2dacc92008-10-16 23:51:381260 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291261 view_->OnMouseDragged(event);
1262 break;
1263
[email protected]c2dacc92008-10-16 23:51:381264 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291265 view_->OnMouseReleased(event, false);
1266 break;
1267
1268 default:
1269 NOTREACHED();
1270 }
1271 }
1272
1273 private:
[email protected]c2dacc92008-10-16 23:51:381274 views::View* view_;
1275 views::Event::EventType type_;
initial.commit09911bf2008-07-26 23:55:291276 POINT point_;
1277 int flags_;
1278
[email protected]5a52f162008-08-27 04:15:311279 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291280};
1281
[email protected]c2dacc92008-10-16 23:51:381282void AutomationProvider::ScheduleMouseEvent(views::View* view,
1283 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291284 POINT point,
1285 int flags) {
1286 MessageLoop::current()->PostTask(FROM_HERE,
1287 new MouseEventTask(view, type, point, flags));
1288}
1289
1290// This task just adds another task to the event queue. This is useful if
1291// you want to ensure that any tasks added to the event queue after this one
1292// have already been processed by the time |task| is run.
1293class InvokeTaskLaterTask : public Task {
1294 public:
1295 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1296 virtual ~InvokeTaskLaterTask() {}
1297
1298 virtual void Run() {
1299 MessageLoop::current()->PostTask(FROM_HERE, task_);
1300 }
1301
1302 private:
1303 Task* task_;
1304
[email protected]5a52f162008-08-27 04:15:311305 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291306};
1307
1308// This task sends a WindowDragResponse message with the appropriate
1309// routing ID to the automation proxy. This is implemented as a task so that
1310// we know that the mouse events (and any tasks that they spawn on the message
1311// loop) have been processed by the time this is sent.
1312class WindowDragResponseTask : public Task {
1313 public:
1314 WindowDragResponseTask(AutomationProvider* provider, int routing_id)
1315 : provider_(provider), routing_id_(routing_id) {}
1316 virtual ~WindowDragResponseTask() {}
1317
1318 virtual void Run() {
1319 provider_->Send(new AutomationMsg_WindowDragResponse(routing_id_, true));
1320 }
1321
1322 private:
1323 AutomationProvider* provider_;
1324 int routing_id_;
1325
[email protected]5a52f162008-08-27 04:15:311326 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291327};
1328
1329void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1330 int handle,
1331 POINT click,
1332 int flags) {
1333 HWND hwnd = 0;
1334
1335 if (window_tracker_->ContainsHandle(handle)) {
1336 hwnd = window_tracker_->GetResource(handle);
1337
initial.commit09911bf2008-07-26 23:55:291338 ui_controls::SendMouseMove(click.x, click.y);
1339
1340 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381341 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1342 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291343 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381344 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1345 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291346 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381347 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1348 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291349 button = ui_controls::MIDDLE;
1350 } else {
1351 NOTREACHED();
1352 }
1353 ui_controls::SendMouseClick(button);
1354 }
1355}
1356
1357void AutomationProvider::WindowSimulateDrag(const IPC::Message& message,
1358 int handle,
[email protected]fe92e4e2008-11-18 21:31:321359 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441360 int flags,
1361 bool press_escape_en_route) {
initial.commit09911bf2008-07-26 23:55:291362 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321363 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1364 succeeded = true;
1365
1366 UINT down_message = 0;
1367 UINT up_message = 0;
1368 WPARAM wparam_flags = 0;
1369 if (flags & views::Event::EF_SHIFT_DOWN)
1370 wparam_flags |= MK_SHIFT;
1371 if (flags & views::Event::EF_CONTROL_DOWN)
1372 wparam_flags |= MK_CONTROL;
1373 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1374 wparam_flags |= MK_LBUTTON;
1375 down_message = WM_LBUTTONDOWN;
1376 up_message = WM_LBUTTONUP;
1377 }
1378 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1379 wparam_flags |= MK_MBUTTON;
1380 down_message = WM_MBUTTONDOWN;
1381 up_message = WM_MBUTTONUP;
1382 }
1383 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1384 wparam_flags |= MK_RBUTTON;
1385 down_message = WM_LBUTTONDOWN;
1386 up_message = WM_LBUTTONUP;
1387 }
1388
initial.commit09911bf2008-07-26 23:55:291389 Browser* browser = browser_tracker_->GetResource(handle);
1390 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551391 HWND top_level_hwnd =
1392 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321393 POINT temp = drag_path[0];
1394 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1395 SetCursorPos(temp.x, temp.y);
1396 SendMessage(top_level_hwnd, down_message, wparam_flags,
1397 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1398 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1399 temp = drag_path[i];
1400 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1401 SetCursorPos(temp.x, temp.y);
1402 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1403 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341404 }
[email protected]fe92e4e2008-11-18 21:31:321405 POINT end = drag_path[drag_path.size() - 1];
1406 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
1407 SetCursorPos(end.x, end.y);
1408
1409 if (press_escape_en_route) {
1410 // Press Escape.
1411 ui_controls::SendKeyPress(VK_ESCAPE,
1412 ((flags & views::Event::EF_CONTROL_DOWN)
1413 == views::Event::EF_CONTROL_DOWN),
1414 ((flags & views::Event::EF_SHIFT_DOWN) ==
1415 views::Event::EF_SHIFT_DOWN),
1416 ((flags & views::Event::EF_ALT_DOWN) ==
1417 views::Event::EF_ALT_DOWN));
1418 }
1419 SendMessage(top_level_hwnd, up_message, wparam_flags,
1420 MAKELPARAM(end.x, end.y));
1421
initial.commit09911bf2008-07-26 23:55:291422 MessageLoop::current()->PostTask(FROM_HERE,
1423 new InvokeTaskLaterTask(
1424 new WindowDragResponseTask(this, message.routing_id())));
1425 } else {
1426 Send(new AutomationMsg_WindowDragResponse(message.routing_id(), true));
1427 }
1428}
1429
1430void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1431 int handle,
1432 wchar_t key,
1433 int flags) {
1434 if (!window_tracker_->ContainsHandle(handle))
1435 return;
1436
1437 // The key event is sent to whatever window is active.
1438 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381439 ((flags & views::Event::EF_CONTROL_DOWN) ==
1440 views::Event::EF_CONTROL_DOWN),
1441 ((flags & views::Event::EF_SHIFT_DOWN) ==
1442 views::Event::EF_SHIFT_DOWN),
1443 ((flags & views::Event::EF_ALT_DOWN) ==
1444 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291445}
1446
1447void AutomationProvider::GetFocusedViewID(const IPC::Message& message,
1448 int handle) {
1449 int view_id = -1;
1450 if (window_tracker_->ContainsHandle(handle)) {
1451 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381452 views::FocusManager* focus_manager =
1453 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:291454 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381455 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291456 if (focused_view)
1457 view_id = focused_view->GetID();
1458 }
1459 Send(new AutomationMsg_GetFocusedViewIDResponse(message.routing_id(),
1460 view_id));
1461}
1462
1463void AutomationProvider::SetWindowVisible(const IPC::Message& message,
1464 int handle, bool visible) {
1465 if (window_tracker_->ContainsHandle(handle)) {
1466 HWND hwnd = window_tracker_->GetResource(handle);
1467 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
1468 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1469 true));
1470 } else {
1471 Send(new AutomationMsg_SetWindowVisibleResponse(message.routing_id(),
1472 false));
1473 }
1474}
1475
1476void AutomationProvider::IsWindowActive(const IPC::Message& message,
1477 int handle) {
1478 if (window_tracker_->ContainsHandle(handle)) {
1479 HWND hwnd = window_tracker_->GetResource(handle);
1480 bool is_active = ::GetForegroundWindow() == hwnd;
1481 Send(new AutomationMsg_IsWindowActiveResponse(
1482 message.routing_id(), true, is_active));
1483 } else {
1484 Send(new AutomationMsg_IsWindowActiveResponse(message.routing_id(),
1485 false, false));
1486 }
1487}
1488
1489void AutomationProvider::ActivateWindow(const IPC::Message& message,
1490 int handle) {
1491 if (window_tracker_->ContainsHandle(handle)) {
1492 ::SetActiveWindow(window_tracker_->GetResource(handle));
1493 }
1494}
1495
1496void AutomationProvider::GetTabCount(const IPC::Message& message, int handle) {
1497 int tab_count = -1; // -1 is the error code
1498
1499 if (browser_tracker_->ContainsHandle(handle)) {
1500 Browser* browser = browser_tracker_->GetResource(handle);
1501 tab_count = browser->tab_count();
1502 }
1503
1504 Send(new AutomationMsg_TabCountResponse(message.routing_id(), tab_count));
1505}
1506
1507void AutomationProvider::GetTab(const IPC::Message& message,
1508 int win_handle, int tab_index) {
1509 void* iter = NULL;
1510 int tab_handle = 0;
1511 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1512 Browser* browser = browser_tracker_->GetResource(win_handle);
1513 if (tab_index < browser->tab_count()) {
1514 TabContents* tab_contents =
1515 browser->GetTabContentsAt(tab_index);
1516 tab_handle = tab_tracker_->Add(tab_contents->controller());
1517 }
1518 }
1519
1520 Send(new AutomationMsg_TabResponse(message.routing_id(), tab_handle));
1521}
1522
1523void AutomationProvider::GetTabTitle(const IPC::Message& message, int handle) {
1524 int title_string_size = -1; // -1 is the error code
1525 std::wstring title;
1526 if (tab_tracker_->ContainsHandle(handle)) {
1527 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]1e5645ff2008-08-27 18:09:071528 title = tab->GetActiveEntry()->title();
initial.commit09911bf2008-07-26 23:55:291529 title_string_size = static_cast<int>(title.size());
1530 }
1531
1532 Send(new AutomationMsg_TabTitleResponse(message.routing_id(),
1533 title_string_size, title));
1534}
1535
1536void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1537 if (window_tracker_->ContainsHandle(handle)) {
1538 window_tracker_->Remove(window_tracker_->GetResource(handle));
1539 }
1540}
1541
1542void AutomationProvider::OnChannelError() {
1543 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571544 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291545}
1546
1547// TODO(brettw) change this to accept GURLs when history supports it
1548void AutomationProvider::OnRedirectQueryComplete(
1549 HistoryService::Handle request_handle,
1550 GURL from_url,
1551 bool success,
1552 HistoryService::RedirectList* redirects) {
1553 DCHECK(request_handle == redirect_query_);
1554
1555 // Respond to the pending request for the redirect list.
1556 IPC::Message* msg = new IPC::Message(redirect_query_routing_id_,
1557 AutomationMsg_RedirectsFromResponse::ID,
1558 IPC::Message::PRIORITY_NORMAL);
1559 if (success) {
[email protected]7d5c3ac2009-02-04 08:58:191560 msg->WriteInt(static_cast<int>(redirects->size()));
initial.commit09911bf2008-07-26 23:55:291561 for (size_t i = 0; i < redirects->size(); i++)
[email protected]7d5c3ac2009-02-04 08:58:191562 IPC::ParamTraits<GURL>::Write(msg, redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291563 } else {
1564 msg->WriteInt(-1); // Negative count indicates failure.
1565 }
1566
1567 Send(msg);
1568 redirect_query_ = NULL;
1569}
1570
1571bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571572 DCHECK(channel_.get());
1573 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291574}
1575
1576Browser* AutomationProvider::FindAndActivateTab(
1577 NavigationController* controller) {
1578 int tab_index;
1579 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1580 if (browser)
1581 browser->SelectTabContentsAt(tab_index, true);
1582
1583 return browser;
1584}
1585
1586void AutomationProvider::GetCookies(const IPC::Message& message,
1587 const GURL& url, int handle) {
1588 std::string value;
1589
1590 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1591 NavigationController* tab = tab_tracker_->GetResource(handle);
1592 value =
1593 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
1594 }
1595
1596 Send(new AutomationMsg_GetCookiesResponse(message.routing_id(),
1597 static_cast<int>(value.size()), value));
1598}
1599
1600void AutomationProvider::SetCookie(const IPC::Message& message,
1601 const GURL& url,
1602 const std::string value,
1603 int handle) {
1604 int response_value = -1;
1605
1606 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1607 NavigationController* tab = tab_tracker_->GetResource(handle);
1608 URLRequestContext* context = tab->profile()->GetRequestContext();
1609 if (context->cookie_store()->SetCookie(url, value))
1610 response_value = 1;
1611 }
1612
1613 Send(new AutomationMsg_SetCookieResponse(message.routing_id(),
1614 response_value));
1615}
1616
1617void AutomationProvider::GetTabURL(const IPC::Message& message, int handle) {
1618 bool success = false;
1619 GURL url;
1620 if (tab_tracker_->ContainsHandle(handle)) {
1621 NavigationController* tab = tab_tracker_->GetResource(handle);
1622 // Return what the user would see in the location bar.
[email protected]1e5645ff2008-08-27 18:09:071623 url = tab->GetActiveEntry()->display_url();
initial.commit09911bf2008-07-26 23:55:291624 success = true;
1625 }
1626
1627 Send(new AutomationMsg_TabURLResponse(message.routing_id(), success, url));
1628}
1629
1630void AutomationProvider::GetTabHWND(const IPC::Message& message, int handle) {
1631 HWND tab_hwnd = NULL;
1632
1633 if (tab_tracker_->ContainsHandle(handle)) {
1634 NavigationController* tab = tab_tracker_->GetResource(handle);
1635 tab_hwnd = tab->active_contents()->GetContainerHWND();
1636 }
1637
1638 Send(new AutomationMsg_TabHWNDResponse(message.routing_id(), tab_hwnd));
1639}
1640
1641void AutomationProvider::GetTabProcessID(
1642 const IPC::Message& message, int handle) {
1643 int process_id = -1;
1644
1645 if (tab_tracker_->ContainsHandle(handle)) {
1646 process_id = 0;
1647 NavigationController* tab = tab_tracker_->GetResource(handle);
1648 if (tab->active_contents()->AsWebContents()) {
1649 WebContents* web_contents = tab->active_contents()->AsWebContents();
[email protected]2f15de42008-11-11 22:35:191650 if (web_contents->process())
1651 process_id = web_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291652 }
1653 }
1654
1655 Send(new AutomationMsg_TabProcessIDResponse(message.routing_id(),
1656 process_id));
1657}
1658
1659void AutomationProvider::ApplyAccelerator(int handle, int id) {
1660 if (browser_tracker_->ContainsHandle(handle)) {
1661 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141662 browser->ExecuteCommand(id);
initial.commit09911bf2008-07-26 23:55:291663 }
1664}
1665
1666void AutomationProvider::ExecuteJavascript(const IPC::Message& message,
1667 int handle,
1668 const std::wstring& frame_xpath,
1669 const std::wstring& script) {
1670 bool succeeded = false;
[email protected]20e93d12008-08-28 16:31:571671 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1672 if (web_contents) {
1673 // Set the routing id of this message with the controller.
1674 // This routing id needs to be remembered for the reverse
1675 // communication while sending back the response of
1676 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331677 std::wstring set_automation_id;
1678 SStringPrintf(&set_automation_id,
1679 L"window.domAutomationController.setAutomationId(%d);",
[email protected]20e93d12008-08-28 16:31:571680 message.routing_id());
initial.commit09911bf2008-07-26 23:55:291681
[email protected]1f5af4442008-09-25 22:11:061682 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331683 frame_xpath, set_automation_id);
[email protected]1f5af4442008-09-25 22:11:061684 web_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1685 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571686 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291687 }
1688
1689 if (!succeeded) {
1690 Send(new AutomationMsg_DomOperationResponse(message.routing_id(), ""));
1691 }
1692}
1693
1694void AutomationProvider::GetShelfVisibility(const IPC::Message& message,
1695 int handle) {
1696 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571697
1698 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1699 if (web_contents)
1700 visible = web_contents->IsDownloadShelfVisible();
initial.commit09911bf2008-07-26 23:55:291701
1702 Send(new AutomationMsg_ShelfVisibilityResponse(message.routing_id(),
1703 visible));
1704}
1705
1706void AutomationProvider::GetConstrainedWindowCount(const IPC::Message& message,
1707 int handle) {
1708 int count = -1; // -1 is the error code
1709 if (tab_tracker_->ContainsHandle(handle)) {
1710 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1711 TabContents* tab_contents = nav_controller->active_contents();
1712 if (tab_contents) {
1713 count = static_cast<int>(tab_contents->child_windows_.size());
1714 }
1715 }
1716
1717 Send(new AutomationMsg_ConstrainedWindowCountResponse(message.routing_id(),
1718 count));
1719}
1720
1721void AutomationProvider::GetConstrainedWindow(const IPC::Message& message,
1722 int handle, int index) {
1723 int cwindow_handle = 0;
1724 if (tab_tracker_->ContainsHandle(handle) && index >= 0) {
1725 NavigationController* nav_controller =
1726 tab_tracker_->GetResource(handle);
1727 TabContents* tab = nav_controller->active_contents();
[email protected]d5f942ba2008-09-26 19:30:341728 if (tab && index < static_cast<int>(tab->child_windows_.size())) {
1729 ConstrainedWindow* window = tab->child_windows_[index];
initial.commit09911bf2008-07-26 23:55:291730 cwindow_handle = cwindow_tracker_->Add(window);
1731 }
1732 }
1733
1734 Send(new AutomationMsg_ConstrainedWindowResponse(message.routing_id(),
1735 cwindow_handle));
1736}
1737
1738void AutomationProvider::GetConstrainedTitle(const IPC::Message& message,
1739 int handle) {
1740 int title_string_size = -1; // -1 is the error code
1741 std::wstring title;
1742 if (cwindow_tracker_->ContainsHandle(handle)) {
1743 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1744 title = window->GetWindowTitle();
1745 title_string_size = static_cast<int>(title.size());
1746 }
1747
1748 Send(new AutomationMsg_ConstrainedTitleResponse(message.routing_id(),
1749 title_string_size, title));
1750}
1751
1752void AutomationProvider::GetConstrainedWindowBounds(const IPC::Message& message,
1753 int handle) {
1754 bool exists = false;
1755 gfx::Rect rect(0, 0, 0, 0);
1756 if (cwindow_tracker_->ContainsHandle(handle)) {
1757 ConstrainedWindow* window = cwindow_tracker_->GetResource(handle);
1758 if (window) {
1759 exists = true;
1760 rect = window->GetCurrentBounds();
1761 }
1762 }
1763
1764 Send(new AutomationMsg_ConstrainedWindowBoundsResponse(message.routing_id(),
1765 exists, rect));
1766}
1767
1768void AutomationProvider::HandleFindInPageRequest(
1769 const IPC::Message& message, int handle, const std::wstring& find_request,
1770 int forward, int match_case) {
[email protected]5a52f162008-08-27 04:15:311771 NOTREACHED() << "This function has been deprecated."
1772 << "Please use HandleFindRequest instead.";
[email protected]aedd85a2008-12-04 19:32:491773 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
[email protected]5a52f162008-08-27 04:15:311774 return;
1775}
1776
1777void AutomationProvider::HandleFindRequest(const IPC::Message& message,
1778 int handle, const FindInPageRequest& request) {
initial.commit09911bf2008-07-26 23:55:291779 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]aedd85a2008-12-04 19:32:491780 Send(new AutomationMsg_FindInPageResponse2(message.routing_id(), -1, -1));
initial.commit09911bf2008-07-26 23:55:291781 return;
1782 }
1783
1784 NavigationController* nav = tab_tracker_->GetResource(handle);
1785 TabContents* tab_contents = nav->active_contents();
1786
1787 find_in_page_observer_.reset(new
1788 FindInPageNotificationObserver(this, tab_contents, message.routing_id()));
1789
[email protected]edc28612008-08-14 20:23:361790 // The find in page dialog must be up for us to get the notification that the
[email protected]9e0534b2008-10-21 15:03:011791 // find was complete.
1792 WebContents* web_contents = tab_contents->AsWebContents();
1793 if (web_contents) {
[email protected]edc28612008-08-14 20:23:361794 NavigationController* tab = tab_tracker_->GetResource(handle);
1795 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011796 web_contents->view()->FindInPage(*browser, true, request.forward);
[email protected]edc28612008-08-14 20:23:361797
[email protected]9e0534b2008-10-21 15:03:011798 web_contents->render_view_host()->StartFinding(
1799 FindInPageNotificationObserver::kFindInPageRequestId,
1800 request.search_string, request.forward, request.match_case,
1801 request.find_next);
1802 }
initial.commit09911bf2008-07-26 23:55:291803}
1804
[email protected]5f8af2a2008-08-06 22:49:451805void AutomationProvider::HandleOpenFindInPageRequest(
1806 const IPC::Message& message, int handle) {
[email protected]20e93d12008-08-28 16:31:571807 NavigationController* tab = NULL;
1808 WebContents* web_contents = GetWebContentsForHandle(handle, &tab);
1809 if (web_contents) {
[email protected]5f8af2a2008-08-06 22:49:451810 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]9e0534b2008-10-21 15:03:011811 web_contents->view()->FindInPage(*browser, false, false);
[email protected]5f8af2a2008-08-06 22:49:451812 }
1813}
1814
[email protected]20e93d12008-08-28 16:31:571815void AutomationProvider::GetFindWindowVisibility(const IPC::Message& message,
1816 int handle) {
[email protected]9e0534b2008-10-21 15:03:011817 gfx::Point position;
[email protected]20e93d12008-08-28 16:31:571818 bool visible = false;
1819 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1820 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091821 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571822
1823 Send(new AutomationMsg_FindWindowVisibilityResponse(message.routing_id(),
1824 visible));
1825}
1826
1827void AutomationProvider::HandleFindWindowLocationRequest(
1828 const IPC::Message& message, int handle) {
[email protected]9e0534b2008-10-21 15:03:011829 gfx::Point position(0, 0);
1830 bool visible = false;
[email protected]20e93d12008-08-28 16:31:571831 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1832 if (web_contents)
[email protected]6fd1a4e22008-10-21 18:08:091833 web_contents->view()->GetFindBarWindowInfo(&position, &visible);
[email protected]20e93d12008-08-28 16:31:571834
1835 Send(new AutomationMsg_FindWindowLocationResponse(message.routing_id(),
[email protected]9e0534b2008-10-21 15:03:011836 position.x(),
1837 position.y()));
[email protected]20e93d12008-08-28 16:31:571838}
1839
[email protected]c2cbeb92008-09-05 21:36:571840void AutomationProvider::GetBookmarkBarVisitility(const IPC::Message& message,
1841 int handle) {
1842 bool visible = false;
1843 bool animating = false;
1844
1845 void* iter = NULL;
1846 if (browser_tracker_->ContainsHandle(handle)) {
1847 Browser* browser = browser_tracker_->GetResource(handle);
1848 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:521849 BrowserWindowTesting* testing =
1850 browser->window()->GetBrowserWindowTesting();
1851 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:571852 if (bookmark_bar) {
1853 animating = bookmark_bar->IsAnimating();
1854 visible = browser->window()->IsBookmarkBarVisible();
1855 }
1856 }
1857 }
1858
1859 Send(new AutomationMsg_BookmarkBarVisibilityResponse(message.routing_id(),
1860 visible, animating));
1861}
1862
initial.commit09911bf2008-07-26 23:55:291863void AutomationProvider::HandleInspectElementRequest(
1864 const IPC::Message& message, int handle, int x, int y) {
[email protected]20e93d12008-08-28 16:31:571865 WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
1866 if (web_contents) {
[email protected]1f5af4442008-09-25 22:11:061867 web_contents->render_view_host()->InspectElementAt(x, y);
initial.commit09911bf2008-07-26 23:55:291868 inspect_element_routing_id_ = message.routing_id();
1869 } else {
1870 Send(new AutomationMsg_InspectElementResponse(message.routing_id(), -1));
1871 }
1872}
1873
1874void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
1875 Send(new AutomationMsg_InspectElementResponse(inspect_element_routing_id_,
1876 num_resources));
1877}
1878
1879// Helper class for making changes to the URLRequest ProtocolFactory on the
1880// IO thread.
1881class SetFilteredInetTask : public Task {
1882 public:
1883 explicit SetFilteredInetTask(bool enabled) : enabled_(enabled) { }
1884 virtual void Run() {
1885 if (enabled_) {
1886 URLRequestFilter::GetInstance()->ClearHandlers();
1887
1888 URLRequestFailedDnsJob::AddUITestUrls();
1889 URLRequestSlowDownloadJob::AddUITestUrls();
1890
1891 std::wstring root_http;
1892 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
1893 URLRequestMockHTTPJob::AddUITestUrls(root_http);
1894 } else {
1895 // Revert to the default handlers.
1896 URLRequestFilter::GetInstance()->ClearHandlers();
1897 }
1898 }
1899 private:
1900 bool enabled_;
1901};
1902
1903void AutomationProvider::SetFilteredInet(const IPC::Message& message,
1904 bool enabled) {
1905 // Since this involves changing the URLRequest ProtocolFactory, we want to
1906 // run on the main thread.
1907 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
1908 new SetFilteredInetTask(enabled));
1909}
1910
1911void AutomationProvider::GetDownloadDirectory(const IPC::Message& message,
1912 int handle) {
1913 DLOG(INFO) << "Handling download directory request";
1914 std::wstring download_directory;
1915 if (tab_tracker_->ContainsHandle(handle)) {
1916 NavigationController* tab = tab_tracker_->GetResource(handle);
1917 DownloadManager* dlm = tab->profile()->GetDownloadManager();
1918 DCHECK(dlm);
[email protected]7ae7c2cb2009-01-06 23:31:411919 download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:291920 }
1921
1922 Send(new AutomationMsg_DownloadDirectoryResponse(message.routing_id(),
1923 download_directory));
1924}
1925
1926void AutomationProvider::OpenNewBrowserWindow(int show_command) {
1927 // We may have no current browser windows open so don't rely on
1928 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:051929 Browser* browser = Browser::Create(profile_);
1930 browser->AddBlankTab(true);
1931 if (show_command != SW_HIDE)
1932 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:291933}
1934
1935void AutomationProvider::GetWindowForBrowser(const IPC::Message& message,
1936 int browser_handle) {
1937 bool success = false;
1938 int window_handle = 0;
1939
1940 if (browser_tracker_->ContainsHandle(browser_handle)) {
1941 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]2d46c842008-11-14 19:24:311942 HWND hwnd = reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
initial.commit09911bf2008-07-26 23:55:291943 // Add() returns the existing handle for the resource if any.
1944 window_handle = window_tracker_->Add(hwnd);
1945 success = true;
1946 }
1947 Send(new AutomationMsg_WindowForBrowserResponse(message.routing_id(),
1948 success, window_handle));
1949}
1950
1951void AutomationProvider::GetAutocompleteEditForBrowser(
1952 const IPC::Message& message,
1953 int browser_handle) {
1954 bool success = false;
1955 int autocomplete_edit_handle = 0;
1956
1957 if (browser_tracker_->ContainsHandle(browser_handle)) {
1958 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]7745b822009-01-27 20:15:351959 BrowserWindowTesting* testing_interface =
1960 browser->window()->GetBrowserWindowTesting();
1961 LocationBarView* loc_bar_view = testing_interface->GetLocationBarView();
[email protected]81c21222008-09-10 19:35:521962 AutocompleteEditView* edit_view = loc_bar_view->location_entry();
initial.commit09911bf2008-07-26 23:55:291963 // Add() returns the existing handle for the resource if any.
[email protected]81c21222008-09-10 19:35:521964 autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
initial.commit09911bf2008-07-26 23:55:291965 success = true;
1966 }
1967 Send(new AutomationMsg_AutocompleteEditForBrowserResponse(
1968 message.routing_id(), success, autocomplete_edit_handle));
1969}
1970
1971void AutomationProvider::GetBrowserForWindow(const IPC::Message& message,
1972 int window_handle) {
1973 bool success = false;
1974 int browser_handle = 0;
1975
1976 if (window_tracker_->ContainsHandle(window_handle)) {
1977 HWND window = window_tracker_->GetResource(window_handle);
1978 BrowserList::const_iterator iter = BrowserList::begin();
1979 Browser* browser = NULL;
1980 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:311981 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
1982 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:291983 browser = *iter;
1984 break;
1985 }
1986 }
1987 if (browser) {
1988 // Add() returns the existing handle for the resource if any.
1989 browser_handle = browser_tracker_->Add(browser);
1990 success = true;
1991 }
1992 }
1993 Send(new AutomationMsg_BrowserForWindowResponse(message.routing_id(),
1994 success, browser_handle));
1995}
1996
1997void AutomationProvider::ShowInterstitialPage(const IPC::Message& message,
1998 int tab_handle,
1999 const std::string& html_text) {
2000 if (tab_tracker_->ContainsHandle(tab_handle)) {
2001 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2002 TabContents* tab_contents = controller->active_contents();
2003 if (tab_contents->type() == TAB_CONTENTS_WEB) {
2004 AddNavigationStatusListener(controller,
2005 new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
2006 true),
2007 NULL);
2008 WebContents* web_contents = tab_contents->AsWebContents();
[email protected]cbab76d2008-10-13 22:42:472009 AutomationInterstitialPage* interstitial =
2010 new AutomationInterstitialPage(web_contents,
2011 GURL("about:interstitial"),
2012 html_text);
[email protected]a3a1d142008-12-19 00:42:302013 interstitial->Show();
initial.commit09911bf2008-07-26 23:55:292014 return;
2015 }
2016 }
2017 Send(new AutomationMsg_ShowInterstitialPageResponse(message.routing_id(),
2018 false));
2019}
2020
2021void AutomationProvider::HideInterstitialPage(const IPC::Message& message,
2022 int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572023 WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
[email protected]a3a1d142008-12-19 00:42:302024 if (web_contents && web_contents->interstitial_page()) {
2025 web_contents->interstitial_page()->DontProceed();
[email protected]20e93d12008-08-28 16:31:572026 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2027 true));
2028 return;
initial.commit09911bf2008-07-26 23:55:292029 }
2030 Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
2031 false));
2032}
2033
2034void AutomationProvider::CloseTab(const IPC::Message& message,
2035 int tab_handle,
2036 bool wait_until_closed) {
2037 if (tab_tracker_->ContainsHandle(tab_handle)) {
2038 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2039 int index;
2040 Browser* browser = Browser::GetBrowserForController(controller, &index);
2041 DCHECK(browser);
2042 TabClosedNotificationObserver* observer =
2043 new TabClosedNotificationObserver(browser, this, message.routing_id(),
2044 wait_until_closed);
2045 browser->CloseContents(controller->active_contents());
2046 } else {
2047 Send(new AutomationMsg_CloseTabResponse(message.routing_id(), false));
2048 }
2049}
2050
2051void AutomationProvider::CloseBrowser(const IPC::Message& message,
2052 int browser_handle) {
2053 if (browser_tracker_->ContainsHandle(browser_handle)) {
2054 Browser* browser = browser_tracker_->GetResource(browser_handle);
2055 new BrowserClosedNotificationObserver(browser, this, message.routing_id());
[email protected]f3e99e32008-07-30 04:48:392056 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292057 } else {
2058 NOTREACHED();
2059 }
2060}
2061
[email protected]31fb110522009-01-28 21:50:392062void AutomationProvider::CreateExternalTab(const IPC::Message& message,
2063 HWND parent,
2064 const gfx::Rect& dimensions,
2065 unsigned int style) {
initial.commit09911bf2008-07-26 23:55:292066 int tab_handle = 0;
2067 HWND tab_container_window = NULL;
2068 ExternalTabContainer *external_tab_container =
2069 new ExternalTabContainer(this);
[email protected]31fb110522009-01-28 21:50:392070 external_tab_container->Init(profile_, parent, dimensions, style);
initial.commit09911bf2008-07-26 23:55:292071 TabContents* tab_contents = external_tab_container->tab_contents();
2072 if (tab_contents) {
2073 tab_handle = tab_tracker_->Add(tab_contents->controller());
2074 tab_container_window = *external_tab_container;
[email protected]31fb110522009-01-28 21:50:392075 } else {
2076 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292077 }
[email protected]31fb110522009-01-28 21:50:392078
initial.commit09911bf2008-07-26 23:55:292079 Send(new AutomationMsg_CreateExternalTabResponse(message.routing_id(),
2080 tab_container_window,
2081 tab_handle));
2082}
2083
2084void AutomationProvider::NavigateInExternalTab(const IPC::Message& message,
2085 int handle, const GURL& url) {
2086 bool status = false;
2087
2088 if (tab_tracker_->ContainsHandle(handle)) {
2089 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502090 tab->LoadURL(url, GURL(), PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:292091 status = true;
2092 }
2093
2094 Send(new AutomationMsg_NavigateInExternalTabResponse(message.routing_id(),
2095 status));
2096}
2097
2098void AutomationProvider::SetAcceleratorsForTab(const IPC::Message& message,
2099 int handle,
2100 HACCEL accel_table,
2101 int accel_entry_count) {
2102 bool status = false;
2103 if (tab_tracker_->ContainsHandle(handle)) {
2104 NavigationController* tab = tab_tracker_->GetResource(handle);
2105 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2106 ExternalTabContainer* external_tab_container =
2107 ExternalTabContainer::GetContainerForTab(
2108 tab_contents->GetContainerHWND());
2109 // This call is only valid on an externally hosted tab
2110 if (external_tab_container) {
2111 external_tab_container->SetAccelerators(accel_table,
2112 accel_entry_count);
2113 status = true;
2114 }
2115 }
2116 Send(new AutomationMsg_SetAcceleratorsForTabResponse(message.routing_id(),
2117 status));
2118}
2119
2120void AutomationProvider::ProcessUnhandledAccelerator(
2121 const IPC::Message& message, int handle, const MSG& msg) {
2122 if (tab_tracker_->ContainsHandle(handle)) {
2123 NavigationController* tab = tab_tracker_->GetResource(handle);
2124 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2125 ExternalTabContainer* external_tab_container =
2126 ExternalTabContainer::GetContainerForTab(
2127 tab_contents->GetContainerHWND());
2128 // This call is only valid on an externally hosted tab
2129 if (external_tab_container) {
2130 external_tab_container->ProcessUnhandledAccelerator(msg);
2131 }
2132 }
2133 // This message expects no response.
2134}
2135
2136void AutomationProvider::WaitForTabToBeRestored(
2137 const IPC::Message& message,
2138 int tab_handle) {
2139 if (tab_tracker_->ContainsHandle(tab_handle)) {
2140 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2141 restore_tracker_.reset(
2142 new NavigationControllerRestoredObserver(this, tab,
2143 message.routing_id()));
2144 }
2145}
2146
2147void AutomationProvider::GetSecurityState(const IPC::Message& message,
2148 int handle) {
2149 if (tab_tracker_->ContainsHandle(handle)) {
2150 NavigationController* tab = tab_tracker_->GetResource(handle);
2151 NavigationEntry* entry = tab->GetActiveEntry();
2152 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), true,
[email protected]eb34392b2008-08-19 15:42:202153 entry->ssl().security_style(), entry->ssl().cert_status(),
2154 entry->ssl().content_status()));
initial.commit09911bf2008-07-26 23:55:292155 } else {
2156 Send(new AutomationMsg_GetSecurityStateResponse(message.routing_id(), false,
2157 SECURITY_STYLE_UNKNOWN,
2158 0, 0));
2159 }
2160}
2161
2162void AutomationProvider::GetPageType(const IPC::Message& message, int handle) {
2163 if (tab_tracker_->ContainsHandle(handle)) {
2164 NavigationController* tab = tab_tracker_->GetResource(handle);
2165 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072166 NavigationEntry::PageType page_type = entry->page_type();
initial.commit09911bf2008-07-26 23:55:292167 // In order to return the proper result when an interstitial is shown and
2168 // no navigation entry were created for it we need to ask the WebContents.
2169 if (page_type == NavigationEntry::NORMAL_PAGE &&
2170 tab->active_contents()->AsWebContents() &&
[email protected]b6e09ac2008-08-12 16:11:092171 tab->active_contents()->AsWebContents()->showing_interstitial_page())
initial.commit09911bf2008-07-26 23:55:292172 page_type = NavigationEntry::INTERSTITIAL_PAGE;
2173
2174 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), true,
2175 page_type));
2176 } else {
2177 Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), false,
2178 NavigationEntry::NORMAL_PAGE));
2179 }
2180}
2181
2182void AutomationProvider::ActionOnSSLBlockingPage(const IPC::Message& message,
2183 int handle, bool proceed) {
2184 if (tab_tracker_->ContainsHandle(handle)) {
2185 NavigationController* tab = tab_tracker_->GetResource(handle);
2186 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072187 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
initial.commit09911bf2008-07-26 23:55:292188 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
[email protected]cbab76d2008-10-13 22:42:472189 InterstitialPage* ssl_blocking_page =
[email protected]a3a1d142008-12-19 00:42:302190 InterstitialPage::GetInterstitialPage(tab_contents->AsWebContents());
initial.commit09911bf2008-07-26 23:55:292191 if (ssl_blocking_page) {
2192 if (proceed) {
2193 AddNavigationStatusListener(tab,
2194 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2195 message.routing_id(), true),
2196 new AutomationMsg_ActionOnSSLBlockingPageResponse(
2197 message.routing_id(), true));
2198 ssl_blocking_page->Proceed();
2199 return;
2200 }
2201 ssl_blocking_page->DontProceed();
2202 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(
2203 message.routing_id(), true));
2204 return;
2205 }
2206 }
2207 }
2208 // We failed.
2209 Send(new AutomationMsg_ActionOnSSLBlockingPageResponse(message.routing_id(),
2210 false));
2211}
2212
2213void AutomationProvider::BringBrowserToFront(const IPC::Message& message,
2214 int browser_handle) {
2215 if (browser_tracker_->ContainsHandle(browser_handle)) {
2216 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062217 browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:292218 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2219 true));
2220 } else {
2221 Send(new AutomationMsg_BringBrowserToFrontResponse(message.routing_id(),
2222 false));
2223 }
2224}
2225
2226void AutomationProvider::IsPageMenuCommandEnabled(const IPC::Message& message,
2227 int browser_handle,
2228 int message_num) {
2229 if (browser_tracker_->ContainsHandle(browser_handle)) {
2230 Browser* browser = browser_tracker_->GetResource(browser_handle);
2231 bool menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142232 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292233 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2234 message.routing_id(), menu_item_enabled));
2235 } else {
2236 Send(new AutomationMsg_IsPageMenuCommandEnabledResponse(
2237 message.routing_id(), false));
2238 }
2239}
2240
2241void AutomationProvider::PrintNow(const IPC::Message& message, int tab_handle) {
[email protected]20e93d12008-08-28 16:31:572242 NavigationController* tab = NULL;
2243 WebContents* web_contents = GetWebContentsForHandle(tab_handle, &tab);
2244 if (web_contents) {
initial.commit09911bf2008-07-26 23:55:292245 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572246 notification_observer_list_.AddObserver(
2247 new DocumentPrintedNotificationObserver(this, message.routing_id()));
2248 if (web_contents->PrintNow())
2249 return;
initial.commit09911bf2008-07-26 23:55:292250 }
2251 Send(new AutomationMsg_PrintNowResponse(message.routing_id(), false));
2252}
2253
2254void AutomationProvider::SavePage(const IPC::Message& message,
2255 int tab_handle,
2256 const std::wstring& file_name,
2257 const std::wstring& dir_path,
2258 int type) {
2259 if (!tab_tracker_->ContainsHandle(tab_handle)) {
2260 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2261 return;
2262 }
2263
2264 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2265 Browser* browser = FindAndActivateTab(nav);
2266 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142267 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
initial.commit09911bf2008-07-26 23:55:292268 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2269 return;
2270 }
2271
2272 TabContents* tab_contents = nav->active_contents();
2273 if (tab_contents->type() != TAB_CONTENTS_WEB) {
2274 Send(new AutomationMsg_SavePageResponse(message.routing_id(), false));
2275 return;
2276 }
2277
2278 SavePackage::SavePackageType save_type =
2279 static_cast<SavePackage::SavePackageType>(type);
2280 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2281 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
2282 tab_contents->AsWebContents()->SavePage(file_name, dir_path, save_type);
2283
2284 Send(new AutomationMsg_SavePageResponse(
2285 message.routing_id(), true));
2286}
2287
2288void AutomationProvider::GetAutocompleteEditText(const IPC::Message& message,
2289 int autocomplete_edit_handle) {
2290 bool success = false;
2291 std::wstring text;
2292 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522293 text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2294 GetText();
initial.commit09911bf2008-07-26 23:55:292295 success = true;
2296 }
2297 Send(new AutomationMsg_AutocompleteEditGetTextResponse(message.routing_id(),
2298 success, text));
2299}
2300
2301void AutomationProvider::SetAutocompleteEditText(const IPC::Message& message,
2302 int autocomplete_edit_handle,
2303 const std::wstring& text) {
2304 bool success = false;
2305 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522306 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2307 SetUserText(text);
initial.commit09911bf2008-07-26 23:55:292308 success = true;
2309 }
2310 Send(new AutomationMsg_AutocompleteEditSetTextResponse(
2311 message.routing_id(), success));
2312}
2313
2314void AutomationProvider::AutocompleteEditGetMatches(
2315 const IPC::Message& message,
2316 int autocomplete_edit_handle) {
2317 bool success = false;
2318 std::vector<AutocompleteMatchData> matches;
2319 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272320 const AutocompleteResult& result = autocomplete_edit_tracker_->
2321 GetResource(autocomplete_edit_handle)->model()->result();
2322 for (AutocompleteResult::const_iterator i = result.begin();
2323 i != result.end(); ++i)
initial.commit09911bf2008-07-26 23:55:292324 matches.push_back(AutocompleteMatchData(*i));
2325 success = true;
2326 }
2327 Send(new AutomationMsg_AutocompleteEditGetMatchesResponse(
2328 message.routing_id(), success, matches));
2329}
2330
2331void AutomationProvider::AutocompleteEditIsQueryInProgress(
2332 const IPC::Message& message,
2333 int autocomplete_edit_handle) {
2334 bool success = false;
2335 bool query_in_progress = false;
2336 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522337 query_in_progress = autocomplete_edit_tracker_->
2338 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
initial.commit09911bf2008-07-26 23:55:292339 success = true;
2340 }
2341 Send(new AutomationMsg_AutocompleteEditIsQueryInProgressResponse(
2342 message.routing_id(), success, query_in_progress));
2343}
2344
[email protected]18cb2572008-08-21 20:34:452345void AutomationProvider::OnMessageFromExternalHost(
2346 int handle, const std::string& target, const std::string& message) {
[email protected]fa83e762008-08-15 21:41:392347 if (tab_tracker_->ContainsHandle(handle)) {
2348 NavigationController* tab = tab_tracker_->GetResource(handle);
2349 if (!tab) {
2350 NOTREACHED();
2351 return;
2352 }
2353 TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
2354 if (!tab_contents) {
2355 NOTREACHED();
2356 return;
2357 }
2358
2359 WebContents* web_contents = tab_contents->AsWebContents();
2360 if (!web_contents) {
2361 NOTREACHED();
2362 return;
2363 }
2364
2365 RenderViewHost* view_host = web_contents->render_view_host();
2366 if (!view_host) {
2367 return;
2368 }
2369
[email protected]18cb2572008-08-21 20:34:452370 view_host->ForwardMessageFromExternalHost(target, message);
[email protected]fa83e762008-08-15 21:41:392371 }
2372}
2373
[email protected]20e93d12008-08-28 16:31:572374WebContents* AutomationProvider::GetWebContentsForHandle(
2375 int handle, NavigationController** tab) {
2376 WebContents* web_contents = NULL;
2377 if (tab_tracker_->ContainsHandle(handle)) {
2378 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2379 TabContents* tab_contents = nav_controller->active_contents();
2380 if (tab_contents && tab_contents->type() == TAB_CONTENTS_WEB) {
2381 web_contents = tab_contents->AsWebContents();
2382 if (tab)
2383 *tab = nav_controller;
2384 }
2385 }
2386 return web_contents;
2387}
2388
initial.commit09911bf2008-07-26 23:55:292389TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2390 : AutomationProvider(profile) {
2391 BrowserList::AddObserver(this);
[email protected]bfd04a62009-02-01 18:16:562392 NotificationService::current()->AddObserver(
2393 this,
2394 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292395 NotificationService::AllSources());
2396}
2397
2398TestingAutomationProvider::~TestingAutomationProvider() {
[email protected]bfd04a62009-02-01 18:16:562399 NotificationService::current()->RemoveObserver(
2400 this,
2401 NotificationType::SESSION_END,
initial.commit09911bf2008-07-26 23:55:292402 NotificationService::AllSources());
2403 BrowserList::RemoveObserver(this);
2404}
2405
2406void TestingAutomationProvider::OnChannelError() {
2407 BrowserList::CloseAllBrowsers(true);
2408 AutomationProvider::OnChannelError();
2409}
2410
2411void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2412 // For backwards compatibility with the testing automation interface, we
2413 // want the automation provider (and hence the process) to go away when the
2414 // last browser goes away.
2415 if (BrowserList::size() == 1) {
[email protected]bfd04a62009-02-01 18:16:562416 // If you change this, update Observer for NotificationType::SESSION_END below.
[email protected]295039bd2008-08-15 04:32:572417 MessageLoop::current()->PostTask(FROM_HERE,
2418 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292419 }
2420}
2421
2422void TestingAutomationProvider::Observe(NotificationType type,
2423 const NotificationSource& source,
2424 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562425 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292426 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2427 // before the task runs resulting in this object not being deleted. This
2428 // Release balance out the Release scheduled by OnBrowserRemoving.
2429 Release();
2430}
[email protected]295039bd2008-08-15 04:32:572431
2432void TestingAutomationProvider::OnRemoveProvider() {
2433 AutomationProviderList::GetInstance()->RemoveProvider(this);
2434}
[email protected]8a3422c92008-09-24 17:42:422435
2436void AutomationProvider::GetSSLInfoBarCount(const IPC::Message& message,
2437 int handle) {
2438 int count = -1; // -1 means error.
2439 if (tab_tracker_->ContainsHandle(handle)) {
2440 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342441 if (nav_controller)
2442 count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422443 }
2444 Send(new AutomationMsg_GetSSLInfoBarCountResponse(message.routing_id(),
2445 count));
2446}
2447
2448void AutomationProvider::ClickSSLInfoBarLink(const IPC::Message& message,
2449 int handle,
2450 int info_bar_index,
2451 bool wait_for_navigation) {
2452 bool success = false;
2453 if (tab_tracker_->ContainsHandle(handle)) {
2454 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2455 if (nav_controller) {
[email protected]eb9ba192008-12-02 02:41:342456 int count = nav_controller->active_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422457 if (info_bar_index >= 0 && info_bar_index < count) {
2458 if (wait_for_navigation) {
2459 AddNavigationStatusListener(nav_controller,
2460 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2461 message.routing_id(), true),
2462 new AutomationMsg_ClickSSLInfoBarLinkResponse(
2463 message.routing_id(), true));
2464 }
[email protected]eb9ba192008-12-02 02:41:342465 InfoBarDelegate* delegate =
2466 nav_controller->active_contents()->GetInfoBarDelegateAt(
2467 info_bar_index);
2468 if (delegate->AsConfirmInfoBarDelegate())
2469 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422470 success = true;
2471 }
2472 }
2473 }
2474 if (!wait_for_navigation || !success)
2475 Send(new AutomationMsg_ClickSSLInfoBarLinkResponse(message.routing_id(),
2476 success));
2477}
2478
2479void AutomationProvider::GetLastNavigationTime(const IPC::Message& message,
2480 int handle) {
2481 Time time = tab_tracker_->GetLastNavigationTime(handle);
2482 Send(new AutomationMsg_GetLastNavigationTimeResponse(message.routing_id(),
2483 time.ToInternalValue()));
2484}
2485
2486void AutomationProvider::WaitForNavigation(const IPC::Message& message,
2487 int handle,
2488 int64 last_navigation_time) {
2489 NavigationController* controller = NULL;
2490 if (tab_tracker_->ContainsHandle(handle))
2491 controller = tab_tracker_->GetResource(handle);
2492
2493 Time time = tab_tracker_->GetLastNavigationTime(handle);
2494 if (time.ToInternalValue() > last_navigation_time || !controller) {
2495 Send(new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2496 controller != NULL));
2497 return;
2498 }
2499
2500 AddNavigationStatusListener(controller,
2501 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2502 true),
2503 new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
2504 true));
2505}
2506
2507void AutomationProvider::SetIntPreference(const IPC::Message& message,
2508 int handle,
[email protected]97fa6ce32008-12-19 01:48:162509 const std::wstring& name,
[email protected]8a3422c92008-09-24 17:42:422510 int value) {
2511 bool success = false;
2512 if (browser_tracker_->ContainsHandle(handle)) {
2513 Browser* browser = browser_tracker_->GetResource(handle);
2514 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
2515 success = true;
2516 }
2517 Send(new AutomationMsg_SetIntPreferenceResponse(message.routing_id(),
2518 success));
2519}
[email protected]97fa6ce32008-12-19 01:48:162520
2521void AutomationProvider::SetStringPreference(const IPC::Message& message,
2522 int handle,
2523 const std::wstring& name,
2524 const std::wstring& value) {
2525 bool success = false;
2526 if (browser_tracker_->ContainsHandle(handle)) {
2527 Browser* browser = browser_tracker_->GetResource(handle);
2528 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
2529 success = true;
2530 }
2531 Send(new AutomationMsg_SetStringPreferenceResponse(message.routing_id(),
2532 success));
2533}
2534
2535void AutomationProvider::GetBooleanPreference(const IPC::Message& message,
2536 int handle,
2537 const std::wstring& name) {
2538 bool success = false;
2539 bool value = false;
2540 if (browser_tracker_->ContainsHandle(handle)) {
2541 Browser* browser = browser_tracker_->GetResource(handle);
2542 value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2543 success = true;
2544 }
2545 Send(new AutomationMsg_GetBooleanPreferenceResponse(message.routing_id(),
2546 success, value));
2547}
2548
2549void AutomationProvider::SetBooleanPreference(const IPC::Message& message,
2550 int handle,
2551 const std::wstring& name,
2552 bool value) {
2553 bool success = false;
2554 if (browser_tracker_->ContainsHandle(handle)) {
2555 Browser* browser = browser_tracker_->GetResource(handle);
2556 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
2557 success = true;
2558 }
2559 Send(new AutomationMsg_SetBooleanPreferenceResponse(message.routing_id(),
2560 success));
2561}
2562
2563// Gets the current used encoding name of the page in the specified tab.
2564void AutomationProvider::GetPageCurrentEncoding(const IPC::Message& message,
2565 int tab_handle) {
2566 std::wstring current_encoding;
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 current_encoding = tab_contents->AsWebContents()->encoding();
2576 }
2577 }
2578 Send(new AutomationMsg_GetPageCurrentEncodingResponse(message.routing_id(),
2579 current_encoding));
2580}
2581
2582// Gets the current used encoding name of the page in the specified tab.
2583void AutomationProvider::OverrideEncoding(const IPC::Message& message,
2584 int tab_handle,
2585 const std::wstring& encoding_name) {
2586 bool succeed = false;
2587 if (tab_tracker_->ContainsHandle(tab_handle)) {
2588 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2589 Browser* browser = FindAndActivateTab(nav);
2590 DCHECK(browser);
2591
[email protected]1fc025202009-01-20 23:03:142592 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]97fa6ce32008-12-19 01:48:162593 TabContents* tab_contents = nav->active_contents();
2594 DCHECK(tab_contents->type() == TAB_CONTENTS_WEB);
2595 int selected_encoding_id =
2596 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2597 if (selected_encoding_id) {
2598 browser->OverrideEncoding(selected_encoding_id);
2599 succeed = true;
2600 }
2601 }
2602 }
2603 Send(new AutomationMsg_OverrideEncodingResponse(message.routing_id(),
2604 succeed));
2605}
[email protected]5bcdb312009-01-07 21:43:202606
2607void AutomationProvider::SavePackageShouldPromptUser(
2608 const IPC::Message& message, bool should_prompt) {
2609 SavePackage::SetShouldPromptUser(should_prompt);
2610}