blob: 7f364cb7d85fd96054ee0b08db2ea1629eaa5715 [file] [log] [blame]
[email protected]5ae5bed2009-08-21 18:52:441// Copyright (c) 2009 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]5ae5bed2009-08-21 18:52:447#include <set>
8
[email protected]202e7a72009-06-15 03:48:369#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3110#include "app/message_box_flags.h"
[email protected]c6cb1992009-04-13 16:45:2911#include "base/file_version_info.h"
[email protected]a9024892009-06-16 23:13:5512#include "base/json_reader.h"
[email protected]5fac9622009-02-04 21:49:3813#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2914#include "base/path_service.h"
[email protected]f44265b2009-05-19 18:52:5015#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2716#include "base/string_util.h"
[email protected]5fac9622009-02-04 21:49:3817#include "base/thread.h"
[email protected]a7eee32f2009-05-22 18:08:1718#include "base/values.h"
[email protected]4f3dc372009-02-24 00:10:2919#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2820#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0921#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]b83e4602009-05-15 22:58:3322#include "chrome/browser/automation/automation_extension_function.h"
initial.commit09911bf2008-07-26 23:55:2923#include "chrome/browser/automation/automation_provider_list.h"
[email protected]a9024892009-06-16 23:13:5524#include "chrome/browser/automation/extension_automation_constants.h"
[email protected]f44265b2009-05-19 18:52:5025#include "chrome/browser/automation/extension_port_container.h"
[email protected]66ba4932009-06-04 19:22:1326#include "chrome/browser/blocked_popup_container.h"
[email protected]5c238752009-06-13 10:29:0727#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3928#include "chrome/browser/browser_window.h"
initial.commit09911bf2008-07-26 23:55:2929#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1230#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5931#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2232#include "chrome/browser/download/download_shelf.h"
[email protected]a9024892009-06-16 23:13:5533#include "chrome/browser/extensions/extension_message_service.h"
[email protected]4801ecc2009-04-05 04:52:5834#include "chrome/browser/find_bar.h"
35#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2936#include "chrome/browser/find_notification_details.h"
[email protected]13869dd2009-05-05 00:40:0637#include "chrome/browser/location_bar.h"
[email protected]3fcac682009-08-13 02:28:0138#include "chrome/browser/login_prompt.h"
[email protected]f732c1e2009-07-30 15:48:5339#include "chrome/browser/net/url_request_mock_util.h"
[email protected]a7eee32f2009-05-22 18:08:1740#include "chrome/browser/profile_manager.h"
[email protected]6524b5f92009-01-22 17:48:2541#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0342#include "chrome/browser/ssl/ssl_manager.h"
43#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3444#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4545#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1746#include "chrome/common/automation_constants.h"
initial.commit09911bf2008-07-26 23:55:2947#include "chrome/common/chrome_paths.h"
[email protected]a7eee32f2009-05-22 18:08:1748#include "chrome/common/json_value_serializer.h"
[email protected]1c58a5c2009-05-21 18:47:1449#include "chrome/common/notification_service.h"
[email protected]3753f522009-04-14 23:15:4750#include "chrome/common/platform_util.h"
[email protected]8a3422c92008-09-24 17:42:4251#include "chrome/common/pref_service.h"
[email protected]71f65dd2009-02-11 19:14:5652#include "chrome/test/automation/automation_messages.h"
[email protected]a7eee32f2009-05-22 18:08:1753#include "net/proxy/proxy_service.h"
54#include "net/proxy/proxy_config_service_fixed.h"
[email protected]319d9e6f2009-02-18 19:47:2155#include "net/url_request/url_request_context.h"
[email protected]9a08bcf2009-08-12 19:56:2856#include "views/event.h"
initial.commit09911bf2008-07-26 23:55:2957
[email protected]de246f52009-02-25 18:25:4558#if defined(OS_WIN)
59// TODO(port): Port these headers.
[email protected]de246f52009-02-25 18:25:4560#include "chrome/browser/character_encoding.h"
61#include "chrome/browser/download/save_package.h"
62#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4563#include "chrome/browser/printing/print_job.h"
[email protected]de246f52009-02-25 18:25:4564#endif // defined(OS_WIN)
65
[email protected]5ae5bed2009-08-21 18:52:4466#if !defined(OS_MACOSX)
[email protected]e8382172009-06-19 22:16:2867// TODO(port): Port these to the mac.
[email protected]9a08bcf2009-08-12 19:56:2868#include "chrome/browser/automation/ui_controls.h"
[email protected]5ae5bed2009-08-21 18:52:4469#endif // !defined(OS_MACOSX)
[email protected]13869dd2009-05-05 00:40:0670
[email protected]e1acf6f2008-10-27 20:43:3371using base::Time;
72
initial.commit09911bf2008-07-26 23:55:2973class InitialLoadObserver : public NotificationObserver {
74 public:
75 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
[email protected]66791d22009-02-24 20:11:3376 : automation_(automation),
77 outstanding_tab_count_(tab_count) {
initial.commit09911bf2008-07-26 23:55:2978 if (outstanding_tab_count_ > 0) {
[email protected]bfd04a62009-02-01 18:16:5679 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:0380 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:5681 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:0382 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:2983 }
84 }
85
86 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:2987 }
88
89 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:0390 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:2991 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
92 }
93
initial.commit09911bf2008-07-26 23:55:2994 virtual void Observe(NotificationType type,
95 const NotificationSource& source,
96 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:5697 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:2998 if (outstanding_tab_count_ > loading_tabs_.size())
99 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:56100 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29101 if (outstanding_tab_count_ > finished_tabs_.size()) {
102 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
103 finished_tabs_.insert(source.map_key());
104 if (outstanding_tab_count_ == finished_tabs_.size())
105 ConditionMet();
106 }
107 } else {
108 NOTREACHED();
109 }
110 }
111
112 private:
113 typedef std::set<uintptr_t> TabSet;
114
[email protected]6a02963e2009-01-06 16:58:03115 NotificationRegistrar registrar_;
116
initial.commit09911bf2008-07-26 23:55:29117 AutomationProvider* automation_;
118 size_t outstanding_tab_count_;
119 TabSet loading_tabs_;
120 TabSet finished_tabs_;
121};
122
123// Watches for NewTabUI page loads for performance timing purposes.
124class NewTabUILoadObserver : public NotificationObserver {
125 public:
126 explicit NewTabUILoadObserver(AutomationProvider* automation)
127 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14128 registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
129 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29130 }
131
132 ~NewTabUILoadObserver() {
initial.commit09911bf2008-07-26 23:55:29133 }
134
135 virtual void Observe(NotificationType type,
136 const NotificationSource& source,
137 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56138 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29139 Details<int> load_time(details);
140 automation_->Send(
141 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
142 } else {
143 NOTREACHED();
144 }
145 }
146
147 private:
[email protected]1c58a5c2009-05-21 18:47:14148 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29149 AutomationProvider* automation_;
150};
151
152class NavigationControllerRestoredObserver : public NotificationObserver {
153 public:
154 NavigationControllerRestoredObserver(AutomationProvider* automation,
155 NavigationController* controller,
[email protected]71f65dd2009-02-11 19:14:56156 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29157 : automation_(automation),
158 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56159 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29160 if (FinishedRestoring()) {
initial.commit09911bf2008-07-26 23:55:29161 SendDone();
162 } else {
[email protected]1c58a5c2009-05-21 18:47:14163 registrar_.Add(this, NotificationType::LOAD_STOP,
164 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29165 }
166 }
167
168 ~NavigationControllerRestoredObserver() {
initial.commit09911bf2008-07-26 23:55:29169 }
170
171 virtual void Observe(NotificationType type,
172 const NotificationSource& source,
173 const NotificationDetails& details) {
174 if (FinishedRestoring()) {
175 SendDone();
[email protected]1c58a5c2009-05-21 18:47:14176 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29177 }
178 }
179
180 private:
initial.commit09911bf2008-07-26 23:55:29181 bool FinishedRestoring() {
[email protected]7f0005a2009-04-15 03:25:11182 return (!controller_->needs_reload() && !controller_->pending_entry() &&
183 !controller_->tab_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29184 }
185
186 void SendDone() {
[email protected]71f65dd2009-02-11 19:14:56187 DCHECK(reply_message_ != NULL);
188 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29189 }
190
[email protected]1c58a5c2009-05-21 18:47:14191 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29192 AutomationProvider* automation_;
193 NavigationController* controller_;
[email protected]71f65dd2009-02-11 19:14:56194 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29195
[email protected]5a52f162008-08-27 04:15:31196 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29197};
198
initial.commit09911bf2008-07-26 23:55:29199class NavigationNotificationObserver : public NotificationObserver {
200 public:
201 NavigationNotificationObserver(NavigationController* controller,
202 AutomationProvider* automation,
[email protected]2e028a082009-08-19 20:32:58203 IPC::Message* reply_message,
204 int number_of_navigations)
initial.commit09911bf2008-07-26 23:55:29205 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56206 reply_message_(reply_message),
initial.commit09911bf2008-07-26 23:55:29207 controller_(controller),
[email protected]2e028a082009-08-19 20:32:58208 navigations_remaining_(number_of_navigations),
[email protected]457f5cf2009-08-18 16:37:52209 navigation_started_(false) {
[email protected]2e028a082009-08-19 20:32:58210 DCHECK_LT(0, navigations_remaining_);
[email protected]1c58a5c2009-05-21 18:47:14211 Source<NavigationController> source(controller_);
212 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
213 registrar_.Add(this, NotificationType::LOAD_START, source);
214 registrar_.Add(this, NotificationType::LOAD_STOP, source);
215 registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
216 registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
initial.commit09911bf2008-07-26 23:55:29217 }
218
219 ~NavigationNotificationObserver() {
[email protected]1c58a5c2009-05-21 18:47:14220 if (reply_message_) {
221 // This means we did not receive a notification for this navigation.
222 // Send over a failed navigation status back to the caller to ensure that
223 // the caller does not hang waiting for the response.
[email protected]457f5cf2009-08-18 16:37:52224 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
225 reply_message_, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]1c58a5c2009-05-21 18:47:14226 automation_->Send(reply_message_);
227 reply_message_ = NULL;
228 }
229
230 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29231 }
232
[email protected]457f5cf2009-08-18 16:37:52233 void ConditionMet(AutomationMsg_NavigationResponseValues navigation_result) {
[email protected]71f65dd2009-02-11 19:14:56234 DCHECK(reply_message_ != NULL);
235
[email protected]457f5cf2009-08-18 16:37:52236 IPC::ParamTraits<AutomationMsg_NavigationResponseValues>::Write(
237 reply_message_, navigation_result);
[email protected]71f65dd2009-02-11 19:14:56238 automation_->Send(reply_message_);
239 reply_message_ = NULL;
240
initial.commit09911bf2008-07-26 23:55:29241 delete this;
242 }
243
initial.commit09911bf2008-07-26 23:55:29244 virtual void Observe(NotificationType type,
245 const NotificationSource& source,
246 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42247 // We listen for 2 events to determine when the navigation started because:
248 // - when this is used by the WaitForNavigation method, we might be invoked
249 // afer the load has started (but not after the entry was committed, as
250 // WaitForNavigation compares times of the last navigation).
251 // - when this is used with a page requiring authentication, we will not get
[email protected]4f3dc372009-02-24 00:10:29252 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
253 // we need the NotificationType::LOAD_START.
[email protected]bfd04a62009-02-01 18:16:56254 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
255 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29256 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56257 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29258 if (navigation_started_) {
259 navigation_started_ = false;
[email protected]2e028a082009-08-19 20:32:58260 if (--navigations_remaining_ == 0)
261 ConditionMet(AUTOMATION_MSG_NAVIGATION_SUCCESS);
initial.commit09911bf2008-07-26 23:55:29262 }
[email protected]bfd04a62009-02-01 18:16:56263 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29264 // The LoginHandler for this tab is no longer valid.
265 automation_->RemoveLoginHandler(controller_);
266
267 // Treat this as if navigation started again, since load start/stop don't
268 // occur while authentication is ongoing.
269 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56270 } else if (type == NotificationType::AUTH_NEEDED) {
[email protected]de246f52009-02-25 18:25:45271#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29272 if (navigation_started_) {
273 // Remember the login handler that wants authentication.
274 LoginHandler* handler =
275 Details<LoginNotificationDetails>(details)->handler();
276 automation_->AddLoginHandler(controller_, handler);
277
278 // Respond that authentication is needed.
279 navigation_started_ = false;
[email protected]457f5cf2009-08-18 16:37:52280 ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
initial.commit09911bf2008-07-26 23:55:29281 } else {
282 NOTREACHED();
283 }
[email protected]de246f52009-02-25 18:25:45284#else
285 // TODO(port): Enable when we have LoginNotificationDetails etc.
286 NOTIMPLEMENTED();
287#endif
initial.commit09911bf2008-07-26 23:55:29288 } else {
289 NOTREACHED();
290 }
291 }
292
293 private:
[email protected]1c58a5c2009-05-21 18:47:14294 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29295 AutomationProvider* automation_;
[email protected]71f65dd2009-02-11 19:14:56296 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29297 NavigationController* controller_;
[email protected]2e028a082009-08-19 20:32:58298 int navigations_remaining_;
initial.commit09911bf2008-07-26 23:55:29299 bool navigation_started_;
initial.commit09911bf2008-07-26 23:55:29300};
301
302class TabStripNotificationObserver : public NotificationObserver {
303 public:
[email protected]1c58a5c2009-05-21 18:47:14304 TabStripNotificationObserver(NotificationType notification,
305 AutomationProvider* automation)
306 : automation_(automation),
307 notification_(notification) {
308 registrar_.Add(this, notification_, NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29309 }
310
311 virtual ~TabStripNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29312 }
313
314 virtual void Observe(NotificationType type,
315 const NotificationSource& source,
316 const NotificationDetails& details) {
317 if (type == notification_) {
318 ObserveTab(Source<NavigationController>(source).ptr());
319
320 // If verified, no need to observe anymore
321 automation_->RemoveTabStripObserver(this);
322 delete this;
323 } else {
324 NOTREACHED();
325 }
326 }
327
328 virtual void ObserveTab(NavigationController* controller) = 0;
329
330 protected:
[email protected]1c58a5c2009-05-21 18:47:14331 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29332 AutomationProvider* automation_;
initial.commit09911bf2008-07-26 23:55:29333 NotificationType notification_;
initial.commit09911bf2008-07-26 23:55:29334};
335
336class TabAppendedNotificationObserver : public TabStripNotificationObserver {
337 public:
338 TabAppendedNotificationObserver(Browser* parent,
[email protected]1c58a5c2009-05-21 18:47:14339 AutomationProvider* automation,
340 IPC::Message* reply_message)
341 : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
342 automation),
343 parent_(parent),
[email protected]71f65dd2009-02-11 19:14:56344 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29345 }
346
347 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14348 if (automation_->GetIndexForNavigationController(controller, parent_) ==
349 TabStripModel::kNoTab) {
350 // This tab notification doesn't belong to the parent_.
initial.commit09911bf2008-07-26 23:55:29351 return;
352 }
353
[email protected]2e028a082009-08-19 20:32:58354 automation_->AddNavigationStatusListener(controller, reply_message_, 1);
initial.commit09911bf2008-07-26 23:55:29355 }
[email protected]71f65dd2009-02-11 19:14:56356
357 protected:
[email protected]1c58a5c2009-05-21 18:47:14358 Browser* parent_;
[email protected]71f65dd2009-02-11 19:14:56359 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29360};
361
362class TabClosedNotificationObserver : public TabStripNotificationObserver {
363 public:
[email protected]1c58a5c2009-05-21 18:47:14364 TabClosedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56365 bool wait_until_closed,
366 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:14367 : TabStripNotificationObserver(wait_until_closed ?
368 NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
369 automation),
370 reply_message_(reply_message),
371 for_browser_command_(false) {
initial.commit09911bf2008-07-26 23:55:29372 }
373
374 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14375 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42376 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
377 true);
[email protected]1c58a5c2009-05-21 18:47:14378 } else {
[email protected]d79ffea2009-05-07 20:51:42379 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
[email protected]1c58a5c2009-05-21 18:47:14380 }
[email protected]71f65dd2009-02-11 19:14:56381 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29382 }
[email protected]71f65dd2009-02-11 19:14:56383
[email protected]d79ffea2009-05-07 20:51:42384 void set_for_browser_command(bool for_browser_command) {
385 for_browser_command_ = for_browser_command;
386 }
[email protected]1c58a5c2009-05-21 18:47:14387
[email protected]71f65dd2009-02-11 19:14:56388 protected:
389 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42390 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29391};
392
[email protected]14c0a032009-04-13 18:15:14393class BrowserOpenedNotificationObserver : public NotificationObserver {
394 public:
395 BrowserOpenedNotificationObserver(AutomationProvider* automation,
396 IPC::Message* reply_message)
397 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42398 reply_message_(reply_message),
399 for_browser_command_(false) {
[email protected]14c0a032009-04-13 18:15:14400 registrar_.Add(this, NotificationType::BROWSER_OPENED,
401 NotificationService::AllSources());
402 }
403
404 ~BrowserOpenedNotificationObserver() {
405 }
406
407 virtual void Observe(NotificationType type,
408 const NotificationSource& source,
409 const NotificationDetails& details) {
410 if (type == NotificationType::BROWSER_OPENED) {
[email protected]1c58a5c2009-05-21 18:47:14411 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42412 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
413 true);
[email protected]1c58a5c2009-05-21 18:47:14414 }
[email protected]14c0a032009-04-13 18:15:14415 automation_->Send(reply_message_);
416 delete this;
417 } else {
418 NOTREACHED();
419 }
420 }
421
[email protected]d79ffea2009-05-07 20:51:42422 void set_for_browser_command(bool for_browser_command) {
423 for_browser_command_ = for_browser_command;
424 }
[email protected]1c58a5c2009-05-21 18:47:14425
[email protected]14c0a032009-04-13 18:15:14426 private:
[email protected]1c58a5c2009-05-21 18:47:14427 NotificationRegistrar registrar_;
[email protected]14c0a032009-04-13 18:15:14428 AutomationProvider* automation_;
429 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42430 bool for_browser_command_;
[email protected]14c0a032009-04-13 18:15:14431};
432
initial.commit09911bf2008-07-26 23:55:29433class BrowserClosedNotificationObserver : public NotificationObserver {
434 public:
435 BrowserClosedNotificationObserver(Browser* browser,
436 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56437 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29438 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42439 reply_message_(reply_message),
440 for_browser_command_(false) {
[email protected]c300deb32009-05-08 21:26:07441 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
442 Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29443 }
444
445 virtual void Observe(NotificationType type,
446 const NotificationSource& source,
447 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56448 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29449 Details<bool> close_app(details);
[email protected]71f65dd2009-02-11 19:14:56450 DCHECK(reply_message_ != NULL);
[email protected]1c58a5c2009-05-21 18:47:14451 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42452 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
453 true);
[email protected]1c58a5c2009-05-21 18:47:14454 } else {
[email protected]d79ffea2009-05-07 20:51:42455 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
456 *(close_app.ptr()));
[email protected]1c58a5c2009-05-21 18:47:14457 }
[email protected]71f65dd2009-02-11 19:14:56458 automation_->Send(reply_message_);
459 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29460 delete this;
461 }
462
[email protected]d79ffea2009-05-07 20:51:42463 void set_for_browser_command(bool for_browser_command) {
464 for_browser_command_ = for_browser_command;
465 }
[email protected]1c58a5c2009-05-21 18:47:14466
initial.commit09911bf2008-07-26 23:55:29467 private:
[email protected]c300deb32009-05-08 21:26:07468 NotificationRegistrar registrar_;
[email protected]1c58a5c2009-05-21 18:47:14469 AutomationProvider* automation_;
470 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42471 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29472};
473
[email protected]2949e90d2009-08-21 15:32:52474class BrowserCountChangeNotificationObserver : public NotificationObserver {
475 public:
476 BrowserCountChangeNotificationObserver(int target_count,
477 AutomationProvider* automation,
478 IPC::Message* reply_message)
479 : target_count_(target_count),
480 automation_(automation),
481 reply_message_(reply_message) {
482 registrar_.Add(this, NotificationType::BROWSER_OPENED,
483 NotificationService::AllSources());
484 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
485 NotificationService::AllSources());
486 }
487
488 virtual void Observe(NotificationType type,
489 const NotificationSource& source,
490 const NotificationDetails& details) {
491 DCHECK(type == NotificationType::BROWSER_OPENED ||
492 type == NotificationType::BROWSER_CLOSED);
493 int current_count = static_cast<int>(BrowserList::size());
494 if (type == NotificationType::BROWSER_CLOSED) {
495 // At the time of the notification the browser being closed is not removed
496 // from the list. The real count is one less than the reported count.
497 DCHECK_LT(0, current_count);
498 current_count--;
499 }
500 if (current_count == target_count_) {
501 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
502 reply_message_, true);
503 automation_->Send(reply_message_);
504 reply_message_ = NULL;
505 delete this;
506 }
507 }
508
509 private:
510 int target_count_;
511 NotificationRegistrar registrar_;
512 AutomationProvider* automation_;
513 IPC::Message* reply_message_;
514};
515
516class AppModalDialogShownObserver : public NotificationObserver {
517 public:
518 AppModalDialogShownObserver(AutomationProvider* automation,
519 IPC::Message* reply_message)
520 : automation_(automation),
521 reply_message_(reply_message) {
522 registrar_.Add(this, NotificationType::APP_MODAL_DIALOG_SHOWN,
523 NotificationService::AllSources());
524 }
525
526 ~AppModalDialogShownObserver() {
527 }
528
529 virtual void Observe(NotificationType type,
530 const NotificationSource& source,
531 const NotificationDetails& details) {
532 DCHECK(type == NotificationType::APP_MODAL_DIALOG_SHOWN);
533 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
534 reply_message_, true);
535 automation_->Send(reply_message_);
536 reply_message_ = NULL;
537 delete this;
538 }
539
540 private:
541 NotificationRegistrar registrar_;
542 AutomationProvider* automation_;
543 IPC::Message* reply_message_;
544};
545
[email protected]4e41709d2009-04-08 00:04:27546namespace {
547
548// Define mapping from command to notification
549struct CommandNotification {
550 int command;
551 NotificationType::Type notification_type;
552};
553
554const struct CommandNotification command_notifications[] = {
[email protected]14c0a032009-04-13 18:15:14555 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
[email protected]f8fc5882009-05-06 04:23:43556 {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
[email protected]d79ffea2009-05-07 20:51:42557 // Returns as soon as the restored tab is created. To further wait until
558 // the content page is loaded, use WaitForTabToBeRestored.
[email protected]f8fc5882009-05-06 04:23:43559 {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
[email protected]4e41709d2009-04-08 00:04:27560};
561
562} // namespace
563
[email protected]56e71b7c2009-03-27 03:05:56564class ExecuteBrowserCommandObserver : public NotificationObserver {
565 public:
[email protected]56e71b7c2009-03-27 03:05:56566 ~ExecuteBrowserCommandObserver() {
567 }
568
[email protected]d79ffea2009-05-07 20:51:42569 static bool CreateAndRegisterObserver(AutomationProvider* automation,
570 Browser* browser,
571 int command,
572 IPC::Message* reply_message) {
573 bool result = true;
574 switch (command) {
575 case IDC_NEW_WINDOW:
576 case IDC_NEW_INCOGNITO_WINDOW: {
577 BrowserOpenedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14578 new BrowserOpenedNotificationObserver(automation, reply_message);
[email protected]d79ffea2009-05-07 20:51:42579 observer->set_for_browser_command(true);
580 break;
581 }
582 case IDC_CLOSE_WINDOW: {
583 BrowserClosedNotificationObserver* observer =
584 new BrowserClosedNotificationObserver(browser, automation,
[email protected]d79ffea2009-05-07 20:51:42585 reply_message);
586 observer->set_for_browser_command(true);
587 break;
588 }
589 case IDC_CLOSE_TAB: {
590 TabClosedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14591 new TabClosedNotificationObserver(automation, true, reply_message);
[email protected]d79ffea2009-05-07 20:51:42592 observer->set_for_browser_command(true);
593 break;
594 }
[email protected]27e1c9e02009-05-13 18:41:39595 case IDC_BACK:
596 case IDC_FORWARD:
597 case IDC_RELOAD: {
[email protected]457f5cf2009-08-18 16:37:52598 automation->AddNavigationStatusListener(
[email protected]27e1c9e02009-05-13 18:41:39599 &browser->GetSelectedTabContents()->controller(),
[email protected]2e028a082009-08-19 20:32:58600 reply_message, 1);
[email protected]27e1c9e02009-05-13 18:41:39601 break;
602 }
[email protected]d79ffea2009-05-07 20:51:42603 default: {
604 ExecuteBrowserCommandObserver* observer =
605 new ExecuteBrowserCommandObserver(automation, reply_message);
606 if (!observer->Register(command)) {
607 delete observer;
608 result = false;
609 }
610 break;
611 }
612 }
613 return result;
[email protected]4e41709d2009-04-08 00:04:27614 }
615
[email protected]56e71b7c2009-03-27 03:05:56616 virtual void Observe(NotificationType type,
617 const NotificationSource& source,
618 const NotificationDetails& details) {
619 if (type == notification_type_) {
[email protected]49a14a82009-03-31 04:16:44620 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
621 true);
[email protected]56e71b7c2009-03-27 03:05:56622 automation_->Send(reply_message_);
623 delete this;
624 } else {
625 NOTREACHED();
626 }
627 }
628
629 private:
[email protected]d79ffea2009-05-07 20:51:42630 ExecuteBrowserCommandObserver(AutomationProvider* automation,
631 IPC::Message* reply_message)
632 : automation_(automation),
633 reply_message_(reply_message) {
634 }
635
636 bool Register(int command) {
637 if (!GetNotificationType(command, &notification_type_))
638 return false;
[email protected]1c58a5c2009-05-21 18:47:14639 registrar_.Add(this, notification_type_, NotificationService::AllSources());
[email protected]d79ffea2009-05-07 20:51:42640 return true;
641 }
642
[email protected]4e41709d2009-04-08 00:04:27643 bool GetNotificationType(int command, NotificationType::Type* type) {
644 if (!type)
645 return false;
646 bool found = false;
647 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
648 if (command_notifications[i].command == command) {
649 *type = command_notifications[i].notification_type;
650 found = true;
651 break;
652 }
653 }
654 return found;
655 }
656
[email protected]1c58a5c2009-05-21 18:47:14657 NotificationRegistrar registrar_;
[email protected]56e71b7c2009-03-27 03:05:56658 AutomationProvider* automation_;
659 NotificationType::Type notification_type_;
660 IPC::Message* reply_message_;
[email protected]56e71b7c2009-03-27 03:05:56661};
662
initial.commit09911bf2008-07-26 23:55:29663class FindInPageNotificationObserver : public NotificationObserver {
664 public:
665 FindInPageNotificationObserver(AutomationProvider* automation,
666 TabContents* parent_tab,
[email protected]71f65dd2009-02-11 19:14:56667 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29668 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56669 active_match_ordinal_(-1),
670 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14671 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
672 Source<TabContents>(parent_tab));
initial.commit09911bf2008-07-26 23:55:29673 }
674
675 ~FindInPageNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29676 }
677
[email protected]1c58a5c2009-05-21 18:47:14678 virtual void Observe(NotificationType type,
679 const NotificationSource& source,
680 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56681 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29682 Details<FindNotificationDetails> find_details(details);
683 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49684 // We get multiple responses and one of those will contain the ordinal.
685 // This message comes to us before the final update is sent.
686 if (find_details->active_match_ordinal() > -1)
687 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29688 if (find_details->final_update()) {
[email protected]d97a5642009-07-16 19:33:26689 if (reply_message_ != NULL) {
690 AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
691 active_match_ordinal_, find_details->number_of_matches());
692 automation_->Send(reply_message_);
693 reply_message_ = NULL;
694 } else {
695 DLOG(WARNING) << "Multiple final Find messages observed.";
696 }
initial.commit09911bf2008-07-26 23:55:29697 } else {
698 DLOG(INFO) << "Ignoring, since we only care about the final message";
699 }
700 }
701 } else {
702 NOTREACHED();
703 }
704 }
705
706 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
707 // we wait for notification to find out what the results are. As the user is
708 // typing, new search requests can be issued and the Request ID helps us make
709 // sense of whether this is the current request or an old one. The unit tests,
710 // however, which uses this constant issues only one search at a time, so we
711 // don't need a rolling id to identify each search. But, we still need to
712 // specify one, so we just use a fixed one - its value does not matter.
713 static const int kFindInPageRequestId;
[email protected]1c58a5c2009-05-21 18:47:14714
initial.commit09911bf2008-07-26 23:55:29715 private:
[email protected]1c58a5c2009-05-21 18:47:14716 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29717 AutomationProvider* automation_;
[email protected]aedd85a2008-12-04 19:32:49718 // We will at some point (before final update) be notified of the ordinal and
719 // we need to preserve it so we can send it later.
720 int active_match_ordinal_;
[email protected]71f65dd2009-02-11 19:14:56721 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29722};
723
724const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
725
726class DomOperationNotificationObserver : public NotificationObserver {
727 public:
728 explicit DomOperationNotificationObserver(AutomationProvider* automation)
729 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14730 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
731 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29732 }
733
734 ~DomOperationNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29735 }
736
[email protected]1c58a5c2009-05-21 18:47:14737 virtual void Observe(NotificationType type,
738 const NotificationSource& source,
739 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56740 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29741 Details<DomOperationNotificationDetails> dom_op_details(details);
[email protected]71f65dd2009-02-11 19:14:56742
743 IPC::Message* reply_message = automation_->reply_message_release();
744 DCHECK(reply_message != NULL);
745
[email protected]1c58a5c2009-05-21 18:47:14746 AutomationMsg_DomOperation::WriteReplyParams(reply_message,
747 dom_op_details->json());
[email protected]71f65dd2009-02-11 19:14:56748 automation_->Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29749 }
750 }
[email protected]1c58a5c2009-05-21 18:47:14751
initial.commit09911bf2008-07-26 23:55:29752 private:
[email protected]1c58a5c2009-05-21 18:47:14753 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29754 AutomationProvider* automation_;
755};
756
[email protected]de246f52009-02-25 18:25:45757#if defined(OS_WIN)
758// TODO(port): Enable when printing is ported.
initial.commit09911bf2008-07-26 23:55:29759class DocumentPrintedNotificationObserver : public NotificationObserver {
760 public:
761 DocumentPrintedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56762 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29763 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56764 success_(false),
765 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14766 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
767 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29768 }
769
770 ~DocumentPrintedNotificationObserver() {
[email protected]71f65dd2009-02-11 19:14:56771 DCHECK(reply_message_ != NULL);
772 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
773 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29774 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29775 }
776
777 virtual void Observe(NotificationType type, const NotificationSource& source,
778 const NotificationDetails& details) {
779 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56780 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29781 switch (Details<JobEventDetails>(details)->type()) {
782 case JobEventDetails::JOB_DONE: {
783 // Succeeded.
784 success_ = true;
785 delete this;
786 break;
787 }
788 case JobEventDetails::USER_INIT_CANCELED:
789 case JobEventDetails::FAILED: {
790 // Failed.
791 delete this;
792 break;
793 }
794 case JobEventDetails::NEW_DOC:
795 case JobEventDetails::USER_INIT_DONE:
796 case JobEventDetails::DEFAULT_INIT_DONE:
797 case JobEventDetails::NEW_PAGE:
798 case JobEventDetails::PAGE_DONE:
799 case JobEventDetails::DOC_DONE:
800 case JobEventDetails::ALL_PAGES_REQUESTED: {
801 // Don't care.
802 break;
803 }
804 default: {
805 NOTREACHED();
806 break;
807 }
808 }
809 }
810
811 private:
[email protected]1c58a5c2009-05-21 18:47:14812 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29813 scoped_refptr<AutomationProvider> automation_;
initial.commit09911bf2008-07-26 23:55:29814 bool success_;
[email protected]71f65dd2009-02-11 19:14:56815 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29816};
[email protected]de246f52009-02-25 18:25:45817#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29818
[email protected]cbab76d2008-10-13 22:42:47819class AutomationInterstitialPage : public InterstitialPage {
820 public:
[email protected]57c6a652009-05-04 07:58:34821 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47822 const GURL& url,
823 const std::string& contents)
824 : InterstitialPage(tab, true, url),
825 contents_(contents) {
826 }
827
828 virtual std::string GetHTMLContents() { return contents_; }
829
830 private:
831 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29832
[email protected]cbab76d2008-10-13 22:42:47833 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
834};
835
[email protected]c2cb8542009-08-20 21:16:51836#if !defined(OS_MACOSX)
837class ClickTask : public Task {
838 public:
839 ClickTask(gfx::Point point, int flags) : point_(point), flags_(flags) {}
840 virtual ~ClickTask() {}
841
842 virtual void Run() {
843 ui_controls::MouseButton button = ui_controls::LEFT;
844 if ((flags_ & views::Event::EF_LEFT_BUTTON_DOWN) ==
845 views::Event::EF_LEFT_BUTTON_DOWN) {
846 button = ui_controls::LEFT;
847 } else if ((flags_ & views::Event::EF_RIGHT_BUTTON_DOWN) ==
848 views::Event::EF_RIGHT_BUTTON_DOWN) {
849 button = ui_controls::RIGHT;
850 } else if ((flags_ & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
851 views::Event::EF_MIDDLE_BUTTON_DOWN) {
852 button = ui_controls::MIDDLE;
853 } else {
854 NOTREACHED();
855 }
856
857 ui_controls::SendMouseClick(point_, button);
858 }
859
860 private:
861 gfx::Point point_;
862 int flags_;
863
864 DISALLOW_COPY_AND_ASSIGN(ClickTask);
865};
866#endif
867
initial.commit09911bf2008-07-26 23:55:29868AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57869 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56870 profile_(profile),
871 reply_message_(NULL) {
initial.commit09911bf2008-07-26 23:55:29872 browser_tracker_.reset(new AutomationBrowserTracker(this));
initial.commit09911bf2008-07-26 23:55:29873 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20874 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29875 autocomplete_edit_tracker_.reset(
876 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29877 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
878 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
initial.commit09911bf2008-07-26 23:55:29879}
880
881AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50882 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
883 port_containers_.end());
884 port_containers_.clear();
885
[email protected]0da050b92008-08-19 19:29:47886 // Make sure that any outstanding NotificationObservers also get destroyed.
887 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31888 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47889 while ((observer = it.GetNext()) != NULL)
890 delete observer;
initial.commit09911bf2008-07-26 23:55:29891}
892
[email protected]9a3a293b2009-06-04 22:28:16893void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06894 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57895 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06896 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
897 automation_resource_message_filter_,
898 g_browser_process->io_thread()->message_loop(),
899 true, g_browser_process->shutdown_event()));
[email protected]79e966832009-04-21 14:23:05900 scoped_ptr<FileVersionInfo> file_version_info(
901 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
[email protected]cf620752009-04-24 17:05:40902 std::string version_string;
903 if (file_version_info != NULL) {
904 version_string = WideToASCII(file_version_info->file_version());
905 }
[email protected]c6cb1992009-04-13 16:45:29906
907 // Send a hello message with our current automation protocol version.
908 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29909}
910
911void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
912 if (expected_tabs == 0) {
913 Send(new AutomationMsg_InitialLoadsComplete(0));
914 } else {
915 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
916 }
917}
918
initial.commit09911bf2008-07-26 23:55:29919NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]2e028a082009-08-19 20:32:58920 NavigationController* tab, IPC::Message* reply_message,
921 int number_of_navigations) {
initial.commit09911bf2008-07-26 23:55:29922 NotificationObserver* observer =
[email protected]2e028a082009-08-19 20:32:58923 new NavigationNotificationObserver(tab, this, reply_message,
924 number_of_navigations);
initial.commit09911bf2008-07-26 23:55:29925
[email protected]71f65dd2009-02-11 19:14:56926 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29927 return observer;
928}
929
930void AutomationProvider::RemoveNavigationStatusListener(
931 NotificationObserver* obs) {
932 notification_observer_list_.RemoveObserver(obs);
933}
934
935NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14936 Browser* parent,
937 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56938 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14939 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29940 notification_observer_list_.AddObserver(observer);
941
942 return observer;
943}
944
945void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
946 notification_observer_list_.RemoveObserver(obs);
947}
948
949void AutomationProvider::AddLoginHandler(NavigationController* tab,
950 LoginHandler* handler) {
951 login_handler_map_[tab] = handler;
952}
953
954void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
955 DCHECK(login_handler_map_[tab]);
956 login_handler_map_.erase(tab);
957}
958
[email protected]f44265b2009-05-19 18:52:50959void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
960 int port_id = port->port_id();
961 DCHECK_NE(-1, port_id);
962 DCHECK(port_containers_.find(port_id) == port_containers_.end());
963
964 port_containers_[port_id] = port;
965}
966
967void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
968 int port_id = port->port_id();
969 DCHECK_NE(-1, port_id);
970
971 PortContainerMap::iterator it = port_containers_.find(port_id);
972 DCHECK(it != port_containers_.end());
973
974 if (it != port_containers_.end()) {
975 delete it->second;
976 port_containers_.erase(it);
977 }
978}
979
980ExtensionPortContainer* AutomationProvider::GetPortContainer(
981 int port_id) const {
982 PortContainerMap::const_iterator it = port_containers_.find(port_id);
983 if (it == port_containers_.end())
984 return NULL;
985
986 return it->second;
987}
988
initial.commit09911bf2008-07-26 23:55:29989int AutomationProvider::GetIndexForNavigationController(
990 const NavigationController* controller, const Browser* parent) const {
991 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12992 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29993}
994
995void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
996 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14997 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56998 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
999 CloseBrowserAsync)
1000 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
1001 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
1002 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
1003 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
1004 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
1005 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]1c58a5c2009-05-21 18:47:141006 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]2e028a082009-08-19 20:32:581007 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1008 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
1009 NavigateToURLBlockUntilNavigationsComplete)
[email protected]71f65dd2009-02-11 19:14:561010 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
1011 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
1012 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
1013 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
1014 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:141015 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:561016 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
1017 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
1018 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:141019 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:291020 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
1021 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:561022 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:361023 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:561024 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:291025 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:561026 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:291027 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
1028 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:561029 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:141030 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]de246f52009-02-25 18:25:451031#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561032 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWND, GetWindowHWND)
[email protected]de246f52009-02-25 18:25:451033#endif // defined(OS_WIN)
[email protected]49a14a82009-03-31 04:16:441034 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:331035 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:441036 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:331037 ExecuteBrowserCommand)
[email protected]1c58a5c2009-05-21 18:47:141038 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8f04ff92009-07-08 02:37:151039 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:141040 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]5ae5bed2009-08-21 18:52:441041#if !defined(OS_MACOSX)
[email protected]d1a5941e2009-08-13 23:34:241042 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]1c58a5c2009-05-21 18:47:141043 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]5ae5bed2009-08-21 18:52:441044#endif // !defined(OS_MACOSX)
[email protected]9a08bcf2009-08-12 19:56:281045#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561046 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
1047 WindowSimulateDrag)
[email protected]d7fa7552009-03-20 21:06:371048#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561049 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
1050 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:371051#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561052 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:451053#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561054 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
1055 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:031056 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:561057 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:141058 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
initial.commit09911bf2008-07-26 23:55:291059 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:141060 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:561061 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
1062 ExecuteJavascript)
1063 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:291064 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:141065 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
1066 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:561067 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
1068 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:141069 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:171070 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:141071 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:141072 OpenNewBrowserWindow)
1073 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:561074 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:141075 GetAutocompleteEditForBrowser)
1076 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:451077#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291078 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:171079#endif
[email protected]71f65dd2009-02-11 19:14:561080 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:291081 NavigateInExternalTab)
[email protected]4150ef02009-08-19 23:14:261082 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
1083 NavigateExternalTabAtIndex)
[email protected]71f65dd2009-02-11 19:14:561084 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141085 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:561086 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141087 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:171088#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291089 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
1090 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:171091#endif
[email protected]71f65dd2009-02-11 19:14:561092 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
1093 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:141094 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:171095#if defined(OS_WIN)
[email protected]87eab222009-03-13 00:47:451096 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:391097 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
1098 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:171099#endif
[email protected]1c58a5c2009-05-21 18:47:141100 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
1101 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]71f65dd2009-02-11 19:14:561102 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
1103 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:291104 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
1105 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
1106 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:561107 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
[email protected]d301c952009-07-13 15:02:411108 IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
[email protected]71f65dd2009-02-11 19:14:561109 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
1110 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:291111 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561112 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:291113 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561114 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:291115 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:561116 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:291117 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:561118 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:451119 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:451120 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
1121 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:141122 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:561123 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:571124 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:561125 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:571126 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:561127 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
1128 GetBookmarkBarVisibility)
[email protected]1c58a5c2009-05-21 18:47:141129 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCount, GetSSLInfoBarCount)
[email protected]71f65dd2009-02-11 19:14:561130 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickSSLInfoBarLink,
1131 ClickSSLInfoBarLink)
1132 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:421133 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:561134 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
1135 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:141136 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:561137 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:441138 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:561139 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:201140 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:141141 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:561142 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161143 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561144 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161145 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561146 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:161147 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:141148 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:201149 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
1150 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:141151 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]b83e4602009-05-15 22:58:331152 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
1153 SetEnableExtensionAutomation)
[email protected]59560e0b2009-06-04 03:30:221154 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:131155 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
[email protected]f7a68432009-07-29 23:18:191156 IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
1157 IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
1158 IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
1159 IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
1160 IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
1161 IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
[email protected]2949e90d2009-08-21 15:32:521162 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1163 AutomationMsg_WaitForBrowserWindowCountToBecome,
1164 WaitForBrowserWindowCountToBecome)
1165 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1166 AutomationMsg_WaitForAppModalDialogToBeShown,
1167 WaitForAppModalDialogToBeShown)
initial.commit09911bf2008-07-26 23:55:291168 IPC_END_MESSAGE_MAP()
1169}
1170
[email protected]71f65dd2009-02-11 19:14:561171void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
1172 *status = -1;
initial.commit09911bf2008-07-26 23:55:291173 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
1174 Browser* browser = browser_tracker_->GetResource(handle);
1175 if (at_index >= 0 && at_index < browser->tab_count()) {
1176 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:561177 *status = 0;
initial.commit09911bf2008-07-26 23:55:291178 }
1179 }
initial.commit09911bf2008-07-26 23:55:291180}
1181
[email protected]71f65dd2009-02-11 19:14:561182void AutomationProvider::AppendTab(int handle, const GURL& url,
1183 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291184 int append_tab_response = -1; // -1 is the error code
1185 NotificationObserver* observer = NULL;
1186
1187 if (browser_tracker_->ContainsHandle(handle)) {
1188 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:141189 observer = AddTabStripObserver(browser, reply_message);
[email protected]22735af62009-04-07 21:09:581190 TabContents* tab_contents = browser->AddTabWithURL(url, GURL(),
1191 PageTransition::TYPED,
[email protected]5a4940be2009-05-06 06:44:391192 true, -1, false, NULL);
initial.commit09911bf2008-07-26 23:55:291193 if (tab_contents) {
1194 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:571195 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:291196 }
1197 }
1198
1199 if (append_tab_response < 0) {
1200 // The append tab failed. Remove the TabStripObserver
1201 if (observer) {
1202 RemoveTabStripObserver(observer);
1203 delete observer;
1204 }
1205
[email protected]71f65dd2009-02-11 19:14:561206 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
1207 append_tab_response);
1208 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291209 }
1210}
1211
[email protected]71f65dd2009-02-11 19:14:561212void AutomationProvider::NavigateToURL(int handle, const GURL& url,
1213 IPC::Message* reply_message) {
[email protected]2e028a082009-08-19 20:32:581214 NavigateToURLBlockUntilNavigationsComplete(handle, url, 1, reply_message);
1215}
1216
1217void AutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
1218 int handle, const GURL& url, int number_of_navigations,
1219 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291220 if (tab_tracker_->ContainsHandle(handle)) {
1221 NavigationController* tab = tab_tracker_->GetResource(handle);
1222
1223 // Simulate what a user would do. Activate the tab and then navigate.
1224 // We could allow navigating in a background tab in future.
1225 Browser* browser = FindAndActivateTab(tab);
1226
1227 if (browser) {
[email protected]2e028a082009-08-19 20:32:581228 AddNavigationStatusListener(tab, reply_message, number_of_navigations);
[email protected]71f65dd2009-02-11 19:14:561229
initial.commit09911bf2008-07-26 23:55:291230 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:501231 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:291232 return;
1233 }
1234 }
[email protected]71f65dd2009-02-11 19:14:561235
1236 AutomationMsg_NavigateToURL::WriteReplyParams(
1237 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1238 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291239}
[email protected]2949e90d2009-08-21 15:32:521240
[email protected]71f65dd2009-02-11 19:14:561241void AutomationProvider::NavigationAsync(int handle, const GURL& url,
1242 bool* status) {
1243 *status = false;
initial.commit09911bf2008-07-26 23:55:291244
1245 if (tab_tracker_->ContainsHandle(handle)) {
1246 NavigationController* tab = tab_tracker_->GetResource(handle);
1247
1248 // Simulate what a user would do. Activate the tab and then navigate.
1249 // We could allow navigating in a background tab in future.
1250 Browser* browser = FindAndActivateTab(tab);
1251
1252 if (browser) {
1253 // Don't add any listener unless a callback mechanism is desired.
1254 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:501255 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:561256 *status = true;
initial.commit09911bf2008-07-26 23:55:291257 }
1258 }
initial.commit09911bf2008-07-26 23:55:291259}
1260
[email protected]71f65dd2009-02-11 19:14:561261void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291262 if (tab_tracker_->ContainsHandle(handle)) {
1263 NavigationController* tab = tab_tracker_->GetResource(handle);
1264 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141265 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]2e028a082009-08-19 20:32:581266 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]485fba42009-03-24 23:27:291267 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291268 return;
1269 }
1270 }
[email protected]71f65dd2009-02-11 19:14:561271
1272 AutomationMsg_GoBack::WriteReplyParams(
1273 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1274 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291275}
1276
[email protected]71f65dd2009-02-11 19:14:561277void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291278 if (tab_tracker_->ContainsHandle(handle)) {
1279 NavigationController* tab = tab_tracker_->GetResource(handle);
1280 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141281 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]2e028a082009-08-19 20:32:581282 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]485fba42009-03-24 23:27:291283 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291284 return;
1285 }
1286 }
[email protected]71f65dd2009-02-11 19:14:561287
1288 AutomationMsg_GoForward::WriteReplyParams(
1289 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1290 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291291}
1292
[email protected]71f65dd2009-02-11 19:14:561293void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291294 if (tab_tracker_->ContainsHandle(handle)) {
1295 NavigationController* tab = tab_tracker_->GetResource(handle);
1296 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141297 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]2e028a082009-08-19 20:32:581298 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291299 browser->Reload();
1300 return;
1301 }
1302 }
[email protected]71f65dd2009-02-11 19:14:561303
1304 AutomationMsg_Reload::WriteReplyParams(
1305 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1306 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291307}
1308
[email protected]71f65dd2009-02-11 19:14:561309void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:291310 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:561311 const std::wstring& password,
1312 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291313 if (tab_tracker_->ContainsHandle(tab_handle)) {
1314 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1315 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1316
1317 if (iter != login_handler_map_.end()) {
1318 // If auth is needed again after this, assume login has failed. This is
1319 // not strictly correct, because a navigation can require both proxy and
1320 // server auth, but it should be OK for now.
1321 LoginHandler* handler = iter->second;
[email protected]2e028a082009-08-19 20:32:581322 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291323 handler->SetAuth(username, password);
[email protected]457f5cf2009-08-18 16:37:521324 return;
initial.commit09911bf2008-07-26 23:55:291325 }
1326 }
[email protected]de246f52009-02-25 18:25:451327
[email protected]457f5cf2009-08-18 16:37:521328 AutomationMsg_SetAuth::WriteReplyParams(
1329 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
1330 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291331}
1332
[email protected]71f65dd2009-02-11 19:14:561333void AutomationProvider::CancelAuth(int tab_handle,
1334 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291335 if (tab_tracker_->ContainsHandle(tab_handle)) {
1336 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1337 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1338
1339 if (iter != login_handler_map_.end()) {
1340 // If auth is needed again after this, something is screwy.
1341 LoginHandler* handler = iter->second;
[email protected]2e028a082009-08-19 20:32:581342 AddNavigationStatusListener(tab, reply_message, 1);
initial.commit09911bf2008-07-26 23:55:291343 handler->CancelAuth();
[email protected]457f5cf2009-08-18 16:37:521344 return;
initial.commit09911bf2008-07-26 23:55:291345 }
1346 }
[email protected]de246f52009-02-25 18:25:451347
[email protected]457f5cf2009-08-18 16:37:521348 AutomationMsg_CancelAuth::WriteReplyParams(
1349 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
1350 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291351}
1352
[email protected]71f65dd2009-02-11 19:14:561353void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
1354 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:291355
1356 if (tab_tracker_->ContainsHandle(tab_handle)) {
1357 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1358 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1359
1360 if (iter != login_handler_map_.end()) {
1361 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:561362 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:291363 }
1364 }
initial.commit09911bf2008-07-26 23:55:291365}
1366
[email protected]71f65dd2009-02-11 19:14:561367void AutomationProvider::GetRedirectsFrom(int tab_handle,
1368 const GURL& source_url,
1369 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291370 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1371 if (tab_tracker_->ContainsHandle(tab_handle)) {
1372 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1373 HistoryService* history_service =
1374 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1375
1376 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1377 "has no history service";
1378 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:561379 DCHECK(reply_message_ == NULL);
1380 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291381 // Schedule a history query for redirects. The response will be sent
1382 // asynchronously from the callback the history system uses to notify us
1383 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:291384 redirect_query_ = history_service->QueryRedirectsFrom(
1385 source_url, &consumer_,
1386 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1387 return; // Response will be sent when query completes.
1388 }
1389 }
1390
1391 // Send failure response.
[email protected]deb57402009-02-06 01:35:301392 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:561393 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
1394 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291395}
1396
[email protected]71f65dd2009-02-11 19:14:561397void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
1398 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291399 if (browser_tracker_->ContainsHandle(handle)) {
1400 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561401 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:291402 }
initial.commit09911bf2008-07-26 23:55:291403}
1404
[email protected]202e7a72009-06-15 03:48:361405void AutomationProvider::GetBrowserLocale(string16* locale) {
1406 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:061407 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:361408}
1409
[email protected]71f65dd2009-02-11 19:14:561410void AutomationProvider::GetBrowserWindowCount(int* window_count) {
1411 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:291412}
1413
[email protected]24497032009-05-01 17:00:291414void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
1415 *window_count = static_cast<int>(
1416 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
1417}
1418
[email protected]71f65dd2009-02-11 19:14:561419void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1420 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:071421 AppModalDialog* dialog_delegate =
1422 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501423 *showing_dialog = (dialog_delegate != NULL);
1424 if (*showing_dialog)
1425 *dialog_button = dialog_delegate->GetDialogButtons();
1426 else
[email protected]478ff2ed2009-04-21 23:49:181427 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:201428}
1429
[email protected]71f65dd2009-02-11 19:14:561430void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
1431 *success = false;
[email protected]fad84eab2008-12-05 00:37:201432
[email protected]1f460072009-05-28 17:02:071433 AppModalDialog* dialog_delegate =
1434 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501435 if (dialog_delegate &&
1436 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:181437 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
1438 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:281439 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:561440 *success = true;
[email protected]fad84eab2008-12-05 00:37:201441 }
[email protected]478ff2ed2009-04-21 23:49:181442 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
1443 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:561444 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:281445 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:561446 *success = true;
[email protected]fad84eab2008-12-05 00:37:201447 }
1448 }
[email protected]c274acc2008-11-11 20:13:441449}
1450
[email protected]71f65dd2009-02-11 19:14:561451void AutomationProvider::GetBrowserWindow(int index, int* handle) {
1452 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291453 if (index >= 0) {
1454 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:291455 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:291456 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:561457 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:291458 }
1459 }
initial.commit09911bf2008-07-26 23:55:291460}
1461
[email protected]24497032009-05-01 17:00:291462void AutomationProvider::FindNormalBrowserWindow(int* handle) {
1463 *handle = 0;
1464 Browser* browser = BrowserList::FindBrowserWithType(profile_,
1465 Browser::TYPE_NORMAL);
1466 if (browser)
1467 *handle = browser_tracker_->Add(browser);
1468}
1469
[email protected]71f65dd2009-02-11 19:14:561470void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
1471 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291472 Browser* browser = BrowserList::GetLastActive();
1473 if (browser)
[email protected]71f65dd2009-02-11 19:14:561474 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:291475}
1476
[email protected]9a08bcf2009-08-12 19:56:281477#if defined(OS_LINUX)
1478// TODO(estade): use this implementation for all platforms?
1479void AutomationProvider::GetActiveWindow(int* handle) {
1480 gfx::NativeWindow window =
1481 BrowserList::GetLastActive()->window()->GetNativeHandle();
1482 *handle = window_tracker_->Add(window);
1483}
1484#endif
1485
[email protected]4f6381ee2009-04-16 02:46:331486void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
1487 bool* success) {
[email protected]71f65dd2009-02-11 19:14:561488 *success = false;
[email protected]4ae62752008-08-04 23:28:471489 if (browser_tracker_->ContainsHandle(handle)) {
1490 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141491 if (browser->command_updater()->SupportsCommand(command) &&
1492 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471493 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:561494 *success = true;
[email protected]4ae62752008-08-04 23:28:471495 }
1496 }
[email protected]4ae62752008-08-04 23:28:471497}
1498
[email protected]4f6381ee2009-04-16 02:46:331499void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:561500 int handle, int command, IPC::Message* reply_message) {
1501 if (browser_tracker_->ContainsHandle(handle)) {
1502 Browser* browser = browser_tracker_->GetResource(handle);
1503 if (browser->command_updater()->SupportsCommand(command) &&
1504 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]d79ffea2009-05-07 20:51:421505 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
1506 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:271507 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:421508 return;
1509 }
[email protected]56e71b7c2009-03-27 03:05:561510 }
1511 }
[email protected]49a14a82009-03-31 04:16:441512 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:561513 Send(reply_message);
1514}
1515
[email protected]5ae5bed2009-08-21 18:52:441516#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:291517void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1518 int handle,
[email protected]d1a5941e2009-08-13 23:34:241519 const gfx::Point& click,
initial.commit09911bf2008-07-26 23:55:291520 int flags) {
[email protected]b410bc32009-08-14 01:11:141521 if (window_tracker_->ContainsHandle(handle)) {
[email protected]c2cb8542009-08-20 21:16:511522 ui_controls::SendMouseMoveNotifyWhenDone(click.x(), click.y(),
1523 new ClickTask(click, flags));
initial.commit09911bf2008-07-26 23:55:291524 }
1525}
initial.commit09911bf2008-07-26 23:55:291526
initial.commit09911bf2008-07-26 23:55:291527void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1528 int handle,
1529 wchar_t key,
1530 int flags) {
[email protected]b410bc32009-08-14 01:11:141531 if (!window_tracker_->ContainsHandle(handle))
initial.commit09911bf2008-07-26 23:55:291532 return;
1533
[email protected]b410bc32009-08-14 01:11:141534 gfx::NativeWindow window = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291535 // The key event is sent to whatever window is active.
[email protected]d1a5941e2009-08-13 23:34:241536 ui_controls::SendKeyPress(window, key,
[email protected]c2dacc92008-10-16 23:51:381537 ((flags & views::Event::EF_CONTROL_DOWN) ==
1538 views::Event::EF_CONTROL_DOWN),
1539 ((flags & views::Event::EF_SHIFT_DOWN) ==
1540 views::Event::EF_SHIFT_DOWN),
1541 ((flags & views::Event::EF_ALT_DOWN) ==
1542 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291543}
[email protected]5ae5bed2009-08-21 18:52:441544#endif // !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:291545
[email protected]71f65dd2009-02-11 19:14:561546void AutomationProvider::IsWindowActive(int handle, bool* success,
1547 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291548 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171549 *is_active =
1550 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561551 *success = true;
initial.commit09911bf2008-07-26 23:55:291552 } else {
[email protected]71f65dd2009-02-11 19:14:561553 *success = false;
1554 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291555 }
1556}
1557
[email protected]71f65dd2009-02-11 19:14:561558void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1559 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291560
1561 if (browser_tracker_->ContainsHandle(handle)) {
1562 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561563 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291564 }
initial.commit09911bf2008-07-26 23:55:291565}
1566
[email protected]71f65dd2009-02-11 19:14:561567void AutomationProvider::GetTab(int win_handle, int tab_index,
1568 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561569 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291570 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1571 Browser* browser = browser_tracker_->GetResource(win_handle);
1572 if (tab_index < browser->tab_count()) {
1573 TabContents* tab_contents =
1574 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571575 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291576 }
1577 }
initial.commit09911bf2008-07-26 23:55:291578}
1579
[email protected]71f65dd2009-02-11 19:14:561580void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1581 std::wstring* title) {
1582 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291583 if (tab_tracker_->ContainsHandle(handle)) {
1584 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361585 NavigationEntry* entry = tab->GetActiveEntry();
1586 if (entry != NULL) {
1587 *title = UTF16ToWideHack(entry->title());
1588 } else {
1589 *title = std::wstring();
1590 }
[email protected]71f65dd2009-02-11 19:14:561591 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291592 }
initial.commit09911bf2008-07-26 23:55:291593}
1594
[email protected]77bc6732009-04-20 22:01:031595void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1596 *tabstrip_index = -1; // -1 is the error code
1597
1598 if (tab_tracker_->ContainsHandle(handle)) {
1599 NavigationController* tab = tab_tracker_->GetResource(handle);
1600 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121601 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031602 }
1603}
1604
initial.commit09911bf2008-07-26 23:55:291605void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1606 if (window_tracker_->ContainsHandle(handle)) {
1607 window_tracker_->Remove(window_tracker_->GetResource(handle));
1608 }
1609}
1610
1611void AutomationProvider::OnChannelError() {
1612 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571613 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291614}
1615
1616// TODO(brettw) change this to accept GURLs when history supports it
1617void AutomationProvider::OnRedirectQueryComplete(
1618 HistoryService::Handle request_handle,
[email protected]3e377c52009-08-06 07:46:371619 GURL from_url,
initial.commit09911bf2008-07-26 23:55:291620 bool success,
[email protected]379c2b12009-07-01 21:50:331621 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291622 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561623 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291624
[email protected]deb57402009-02-06 01:35:301625 std::vector<GURL> redirects_gurl;
initial.commit09911bf2008-07-26 23:55:291626 if (success) {
[email protected]71f65dd2009-02-11 19:14:561627 reply_message_->WriteBool(true);
initial.commit09911bf2008-07-26 23:55:291628 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301629 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291630 } else {
[email protected]71f65dd2009-02-11 19:14:561631 reply_message_->WriteInt(-1); // Negative count indicates failure.
initial.commit09911bf2008-07-26 23:55:291632 }
1633
[email protected]4f3dc372009-02-24 00:10:291634 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301635
[email protected]71f65dd2009-02-11 19:14:561636 Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291637 redirect_query_ = NULL;
[email protected]71f65dd2009-02-11 19:14:561638 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291639}
1640
1641bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571642 DCHECK(channel_.get());
1643 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291644}
1645
1646Browser* AutomationProvider::FindAndActivateTab(
1647 NavigationController* controller) {
1648 int tab_index;
1649 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1650 if (browser)
1651 browser->SelectTabContentsAt(tab_index, true);
1652
1653 return browser;
1654}
1655
[email protected]71f65dd2009-02-11 19:14:561656void AutomationProvider::GetCookies(const GURL& url, int handle,
1657 int* value_size,
1658 std::string* value) {
1659 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291660 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1661 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561662 *value =
initial.commit09911bf2008-07-26 23:55:291663 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561664 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291665 }
initial.commit09911bf2008-07-26 23:55:291666}
1667
[email protected]71f65dd2009-02-11 19:14:561668void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291669 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561670 int handle,
1671 int* response_value) {
1672 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291673
1674 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1675 NavigationController* tab = tab_tracker_->GetResource(handle);
1676 URLRequestContext* context = tab->profile()->GetRequestContext();
1677 if (context->cookie_store()->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561678 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291679 }
initial.commit09911bf2008-07-26 23:55:291680}
1681
[email protected]71f65dd2009-02-11 19:14:561682void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1683 *success = false;
initial.commit09911bf2008-07-26 23:55:291684 if (tab_tracker_->ContainsHandle(handle)) {
1685 NavigationController* tab = tab_tracker_->GetResource(handle);
1686 // Return what the user would see in the location bar.
[email protected]ebe89e062009-08-13 23:16:541687 *url = tab->GetActiveEntry()->virtual_url();
[email protected]71f65dd2009-02-11 19:14:561688 *success = true;
initial.commit09911bf2008-07-26 23:55:291689 }
initial.commit09911bf2008-07-26 23:55:291690}
1691
[email protected]71f65dd2009-02-11 19:14:561692void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1693 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291694
1695 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561696 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341697 TabContents* tab_contents =
1698 tab_tracker_->GetResource(handle)->tab_contents();
1699 if (tab_contents->process())
1700 *process_id = tab_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291701 }
initial.commit09911bf2008-07-26 23:55:291702}
1703
1704void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331705 NOTREACHED() << "This function has been deprecated. "
1706 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291707}
1708
[email protected]71f65dd2009-02-11 19:14:561709void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291710 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561711 const std::wstring& script,
1712 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291713 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341714 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1715 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571716 // Set the routing id of this message with the controller.
1717 // This routing id needs to be remembered for the reverse
1718 // communication while sending back the response of
1719 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331720 std::wstring set_automation_id;
1721 SStringPrintf(&set_automation_id,
1722 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561723 reply_message->routing_id());
1724
1725 DCHECK(reply_message_ == NULL);
1726 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291727
[email protected]57c6a652009-05-04 07:58:341728 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331729 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341730 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061731 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571732 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291733 }
1734
1735 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561736 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1737 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291738 }
1739}
1740
[email protected]71f65dd2009-02-11 19:14:561741void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1742 *visible = false;
[email protected]20e93d12008-08-28 16:31:571743
[email protected]59560e0b2009-06-04 03:30:221744 if (browser_tracker_->ContainsHandle(handle)) {
1745 Browser* browser = browser_tracker_->GetResource(handle);
1746 if (browser) {
1747 *visible = browser->window()->IsDownloadShelfVisible();
1748 }
1749 }
initial.commit09911bf2008-07-26 23:55:291750}
1751
[email protected]59560e0b2009-06-04 03:30:221752void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1753 if (browser_tracker_->ContainsHandle(handle)) {
1754 Browser* browser = browser_tracker_->GetResource(handle);
1755 if (browser) {
1756 if (visible)
1757 browser->window()->GetDownloadShelf()->Show();
1758 else
1759 browser->window()->GetDownloadShelf()->Close();
1760 }
1761 }
1762}
1763
1764
[email protected]71f65dd2009-02-11 19:14:561765void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1766 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291767 if (tab_tracker_->ContainsHandle(handle)) {
1768 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111769 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291770 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561771 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291772 }
1773 }
initial.commit09911bf2008-07-26 23:55:291774}
1775
initial.commit09911bf2008-07-26 23:55:291776void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561777 int handle, const std::wstring& find_request,
1778 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311779 NOTREACHED() << "This function has been deprecated."
1780 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561781 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311782 return;
1783}
1784
[email protected]4f999132009-03-31 18:08:401785void AutomationProvider::HandleFindRequest(
1786 int handle,
1787 const AutomationMsg_Find_Params& params,
1788 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291789 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561790 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
1791 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291792 return;
1793 }
1794
1795 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111796 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:291797
1798 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:141799 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:291800
[email protected]57c6a652009-05-04 07:58:341801 tab_contents->set_current_find_request_id(
1802 FindInPageNotificationObserver::kFindInPageRequestId);
1803 tab_contents->render_view_host()->StartFinding(
1804 FindInPageNotificationObserver::kFindInPageRequestId,
1805 params.search_string, params.forward, params.match_case,
1806 params.find_next);
initial.commit09911bf2008-07-26 23:55:291807}
1808
[email protected]5f8af2a2008-08-06 22:49:451809void AutomationProvider::HandleOpenFindInPageRequest(
1810 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:291811 if (browser_tracker_->ContainsHandle(handle)) {
1812 Browser* browser = browser_tracker_->GetResource(handle);
1813 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:451814 }
1815}
1816
[email protected]71f65dd2009-02-11 19:14:561817void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]9e0534b2008-10-21 15:03:011818 gfx::Point position;
[email protected]71f65dd2009-02-11 19:14:561819 *visible = false;
[email protected]4f3dc372009-02-24 00:10:291820 if (browser_tracker_->ContainsHandle(handle)) {
1821 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581822 FindBarTesting* find_bar =
1823 browser->find_bar()->find_bar()->GetFindBarTesting();
1824 find_bar->GetFindBarWindowInfo(&position, visible);
[email protected]4f3dc372009-02-24 00:10:291825 }
[email protected]20e93d12008-08-28 16:31:571826}
1827
[email protected]71f65dd2009-02-11 19:14:561828void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
1829 int* y) {
[email protected]9e0534b2008-10-21 15:03:011830 gfx::Point position(0, 0);
1831 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:291832 if (browser_tracker_->ContainsHandle(handle)) {
1833 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:581834 FindBarTesting* find_bar =
1835 browser->find_bar()->find_bar()->GetFindBarTesting();
1836 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:291837 }
[email protected]20e93d12008-08-28 16:31:571838
[email protected]71f65dd2009-02-11 19:14:561839 *x = position.x();
1840 *y = position.y();
[email protected]20e93d12008-08-28 16:31:571841}
1842
initial.commit09911bf2008-07-26 23:55:291843void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:561844 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:341845 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1846 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561847 DCHECK(reply_message_ == NULL);
1848 reply_message_ = reply_message;
1849
[email protected]d9f9b792009-06-24 13:17:121850 DevToolsManager::GetInstance()->InspectElement(
1851 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:291852 } else {
[email protected]71f65dd2009-02-11 19:14:561853 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
1854 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291855 }
1856}
1857
1858void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:091859 if (reply_message_) {
1860 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
1861 num_resources);
1862 Send(reply_message_);
1863 reply_message_ = NULL;
1864 }
initial.commit09911bf2008-07-26 23:55:291865}
1866
[email protected]a7eee32f2009-05-22 18:08:171867class SetProxyConfigTask : public Task {
1868 public:
1869 explicit SetProxyConfigTask(net::ProxyService* proxy_service,
1870 const std::string& new_proxy_config)
1871 : proxy_service_(proxy_service), proxy_config_(new_proxy_config) {}
1872 virtual void Run() {
1873 // First, deserialize the JSON string. If this fails, log and bail.
1874 JSONStringValueSerializer deserializer(proxy_config_);
1875 std::string error_message;
1876 scoped_ptr<Value> root(deserializer.Deserialize(&error_message));
1877 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
1878 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
1879 << error_message;
1880 return;
1881 }
1882
1883 scoped_ptr<DictionaryValue> dict(
1884 static_cast<DictionaryValue*>(root.release()));
1885 // Now put together a proxy configuration from the deserialized string.
1886 net::ProxyConfig pc;
1887 PopulateProxyConfig(*dict.get(), &pc);
1888
1889 DCHECK(proxy_service_);
1890 scoped_ptr<net::ProxyConfigService> proxy_config_service(
1891 new net::ProxyConfigServiceFixed(pc));
1892 proxy_service_->ResetConfigService(proxy_config_service.release());
1893 }
1894
1895 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
1896 DCHECK(pc);
1897 bool no_proxy = false;
1898 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
1899 // Make no changes to the ProxyConfig.
1900 return;
1901 }
1902 bool auto_config;
1903 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
1904 pc->auto_detect = true;
1905 }
1906 std::string pac_url;
1907 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
1908 pc->pac_url = GURL(pac_url);
1909 }
1910 std::string proxy_bypass_list;
1911 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
1912 pc->ParseNoProxyList(proxy_bypass_list);
1913 }
1914 std::string proxy_server;
1915 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
1916 pc->proxy_rules.ParseFromString(proxy_server);
1917 }
1918 }
1919
1920 private:
1921 net::ProxyService* proxy_service_;
1922 std::string proxy_config_;
1923};
1924
1925
1926void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
1927 URLRequestContext* context = Profile::GetDefaultRequestContext();
[email protected]a7eee32f2009-05-22 18:08:171928 if (!context) {
1929 FilePath user_data_dir;
1930 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
1931 ProfileManager* profile_manager = g_browser_process->profile_manager();
1932 DCHECK(profile_manager);
1933 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
1934 DCHECK(profile);
1935 context = profile->GetRequestContext();
[email protected]a7eee32f2009-05-22 18:08:171936 }
1937 DCHECK(context);
1938 // Every URLRequestContext should have a proxy service.
1939 net::ProxyService* proxy_service = context->proxy_service();
1940 DCHECK(proxy_service);
1941
[email protected]81ae0a92009-08-06 02:16:161942 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
1943 new SetProxyConfigTask(proxy_service, new_proxy_config));
[email protected]a7eee32f2009-05-22 18:08:171944}
1945
[email protected]4f3dc372009-02-24 00:10:291946void AutomationProvider::GetDownloadDirectory(
1947 int handle, std::wstring* download_directory) {
initial.commit09911bf2008-07-26 23:55:291948 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:291949 if (tab_tracker_->ContainsHandle(handle)) {
1950 NavigationController* tab = tab_tracker_->GetResource(handle);
1951 DownloadManager* dlm = tab->profile()->GetDownloadManager();
1952 DCHECK(dlm);
[email protected]71f65dd2009-02-11 19:14:561953 *download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:291954 }
initial.commit09911bf2008-07-26 23:55:291955}
1956
[email protected]14c0a032009-04-13 18:15:141957void AutomationProvider::OpenNewBrowserWindow(bool show,
1958 IPC::Message* reply_message) {
1959 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:291960 // We may have no current browser windows open so don't rely on
1961 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:051962 Browser* browser = Browser::Create(profile_);
1963 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:151964 if (show)
[email protected]15952e462008-11-14 00:29:051965 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:291966}
1967
[email protected]71f65dd2009-02-11 19:14:561968void AutomationProvider::GetWindowForBrowser(int browser_handle,
1969 bool* success,
1970 int* handle) {
1971 *success = false;
1972 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291973
1974 if (browser_tracker_->ContainsHandle(browser_handle)) {
1975 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:201976 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:291977 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:201978 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:561979 *success = true;
initial.commit09911bf2008-07-26 23:55:291980 }
initial.commit09911bf2008-07-26 23:55:291981}
1982
[email protected]5ae5bed2009-08-21 18:52:441983#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:291984void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:561985 int browser_handle,
1986 bool* success,
1987 int* autocomplete_edit_handle) {
1988 *success = false;
1989 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:291990
1991 if (browser_tracker_->ContainsHandle(browser_handle)) {
1992 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:061993 LocationBar* loc_bar = browser->window()->GetLocationBar();
1994 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:291995 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:561996 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
1997 *success = true;
initial.commit09911bf2008-07-26 23:55:291998 }
initial.commit09911bf2008-07-26 23:55:291999}
[email protected]5ae5bed2009-08-21 18:52:442000#endif // !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:292001
[email protected]71f65dd2009-02-11 19:14:562002void AutomationProvider::ShowInterstitialPage(int tab_handle,
2003 const std::string& html_text,
2004 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292005 if (tab_tracker_->ContainsHandle(tab_handle)) {
2006 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112007 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402008
[email protected]2e028a082009-08-19 20:32:582009 AddNavigationStatusListener(controller, reply_message, 1);
[email protected]965524b2009-04-04 21:32:402010 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342011 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402012 GURL("about:interstitial"),
2013 html_text);
2014 interstitial->Show();
2015 return;
initial.commit09911bf2008-07-26 23:55:292016 }
[email protected]71f65dd2009-02-11 19:14:562017
[email protected]457f5cf2009-08-18 16:37:522018 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
2019 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562020 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292021}
2022
[email protected]71f65dd2009-02-11 19:14:562023void AutomationProvider::HideInterstitialPage(int tab_handle,
2024 bool* success) {
2025 *success = false;
[email protected]57c6a652009-05-04 07:58:342026 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2027 if (tab_contents && tab_contents->interstitial_page()) {
2028 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562029 *success = true;
initial.commit09911bf2008-07-26 23:55:292030 }
initial.commit09911bf2008-07-26 23:55:292031}
2032
[email protected]71f65dd2009-02-11 19:14:562033void AutomationProvider::CloseTab(int tab_handle,
2034 bool wait_until_closed,
2035 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292036 if (tab_tracker_->ContainsHandle(tab_handle)) {
2037 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2038 int index;
2039 Browser* browser = Browser::GetBrowserForController(controller, &index);
2040 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142041 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112042 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452043 return;
initial.commit09911bf2008-07-26 23:55:292044 }
[email protected]de246f52009-02-25 18:25:452045
2046 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
initial.commit09911bf2008-07-26 23:55:292047}
2048
[email protected]71f65dd2009-02-11 19:14:562049void AutomationProvider::CloseBrowser(int browser_handle,
2050 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292051 if (browser_tracker_->ContainsHandle(browser_handle)) {
2052 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562053 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562054 reply_message);
[email protected]f3e99e32008-07-30 04:48:392055 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292056 } else {
2057 NOTREACHED();
2058 }
2059}
2060
[email protected]71f65dd2009-02-11 19:14:562061void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2062 if (browser_tracker_->ContainsHandle(browser_handle)) {
2063 Browser* browser = browser_tracker_->GetResource(browser_handle);
2064 browser->window()->Close();
2065 } else {
2066 NOTREACHED();
2067 }
2068}
2069
[email protected]71f65dd2009-02-11 19:14:562070void AutomationProvider::NavigateInExternalTab(
2071 int handle, const GURL& url,
2072 AutomationMsg_NavigationResponseValues* status) {
2073 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292074
2075 if (tab_tracker_->ContainsHandle(handle)) {
2076 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502077 tab->LoadURL(url, GURL(), PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562078 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292079 }
initial.commit09911bf2008-07-26 23:55:292080}
2081
[email protected]4150ef02009-08-19 23:14:262082void AutomationProvider::NavigateExternalTabAtIndex(
2083 int handle, int navigation_index,
2084 AutomationMsg_NavigationResponseValues* status) {
2085 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
2086
2087 if (tab_tracker_->ContainsHandle(handle)) {
2088 NavigationController* tab = tab_tracker_->GetResource(handle);
2089 tab->GoToIndex(navigation_index);
2090 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
2091 }
2092}
2093
[email protected]71f65dd2009-02-11 19:14:562094void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2095 IPC::Message* reply_message) {
2096 if (tab_tracker_->ContainsHandle(tab_handle)) {
2097 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2098 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142099 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562100 }
2101}
2102
[email protected]71f65dd2009-02-11 19:14:562103void AutomationProvider::GetSecurityState(int handle, bool* success,
2104 SecurityStyle* security_style,
2105 int* ssl_cert_status,
2106 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292107 if (tab_tracker_->ContainsHandle(handle)) {
2108 NavigationController* tab = tab_tracker_->GetResource(handle);
2109 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562110 *success = true;
2111 *security_style = entry->ssl().security_style();
2112 *ssl_cert_status = entry->ssl().cert_status();
2113 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292114 } else {
[email protected]71f65dd2009-02-11 19:14:562115 *success = false;
2116 *security_style = SECURITY_STYLE_UNKNOWN;
2117 *ssl_cert_status = 0;
2118 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292119 }
2120}
2121
[email protected]71f65dd2009-02-11 19:14:562122void AutomationProvider::GetPageType(int handle, bool* success,
2123 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292124 if (tab_tracker_->ContainsHandle(handle)) {
2125 NavigationController* tab = tab_tracker_->GetResource(handle);
2126 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562127 *page_type = entry->page_type();
2128 *success = true;
initial.commit09911bf2008-07-26 23:55:292129 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342130 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562131 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342132 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562133 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292134 } else {
[email protected]71f65dd2009-02-11 19:14:562135 *success = false;
2136 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292137 }
2138}
2139
[email protected]71f65dd2009-02-11 19:14:562140void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2141 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292142 if (tab_tracker_->ContainsHandle(handle)) {
2143 NavigationController* tab = tab_tracker_->GetResource(handle);
2144 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072145 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402146 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472147 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342148 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292149 if (ssl_blocking_page) {
2150 if (proceed) {
[email protected]2e028a082009-08-19 20:32:582151 AddNavigationStatusListener(tab, reply_message, 1);
[email protected]71f65dd2009-02-11 19:14:562152 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292153 return;
2154 }
2155 ssl_blocking_page->DontProceed();
[email protected]457f5cf2009-08-18 16:37:522156 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2157 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]71f65dd2009-02-11 19:14:562158 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292159 return;
2160 }
2161 }
2162 }
2163 // We failed.
[email protected]457f5cf2009-08-18 16:37:522164 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
2165 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]71f65dd2009-02-11 19:14:562166 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292167}
initial.commit09911bf2008-07-26 23:55:292168
[email protected]71f65dd2009-02-11 19:14:562169void AutomationProvider::BringBrowserToFront(int browser_handle,
2170 bool* success) {
initial.commit09911bf2008-07-26 23:55:292171 if (browser_tracker_->ContainsHandle(browser_handle)) {
2172 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062173 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562174 *success = true;
initial.commit09911bf2008-07-26 23:55:292175 } else {
[email protected]71f65dd2009-02-11 19:14:562176 *success = false;
initial.commit09911bf2008-07-26 23:55:292177 }
2178}
2179
[email protected]71f65dd2009-02-11 19:14:562180void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2181 int message_num,
2182 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292183 if (browser_tracker_->ContainsHandle(browser_handle)) {
2184 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562185 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142186 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292187 } else {
[email protected]71f65dd2009-02-11 19:14:562188 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292189 }
2190}
2191
[email protected]71f65dd2009-02-11 19:14:562192void AutomationProvider::PrintNow(int tab_handle,
2193 IPC::Message* reply_message) {
[email protected]5ae5bed2009-08-21 18:52:442194#if defined(OS_WIN)
[email protected]20e93d12008-08-28 16:31:572195 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342196 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2197 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292198 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572199 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142200 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342201 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572202 return;
initial.commit09911bf2008-07-26 23:55:292203 }
[email protected]71f65dd2009-02-11 19:14:562204 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2205 Send(reply_message);
[email protected]5ae5bed2009-08-21 18:52:442206#else
2207 // TODO(port): Remove once DocumentPrintedNotificationObserver is implemented.
2208 NOTIMPLEMENTED();
2209#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292210}
[email protected]d301c952009-07-13 15:02:412211
[email protected]71f65dd2009-02-11 19:14:562212void AutomationProvider::SavePage(int tab_handle,
initial.commit09911bf2008-07-26 23:55:292213 const std::wstring& file_name,
2214 const std::wstring& dir_path,
[email protected]71f65dd2009-02-11 19:14:562215 int type,
2216 bool* success) {
initial.commit09911bf2008-07-26 23:55:292217 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562218 *success = false;
initial.commit09911bf2008-07-26 23:55:292219 return;
2220 }
2221
2222 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2223 Browser* browser = FindAndActivateTab(nav);
2224 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142225 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562226 *success = false;
initial.commit09911bf2008-07-26 23:55:292227 return;
2228 }
2229
initial.commit09911bf2008-07-26 23:55:292230 SavePackage::SavePackageType save_type =
2231 static_cast<SavePackage::SavePackageType>(type);
2232 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2233 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342234 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292235
[email protected]71f65dd2009-02-11 19:14:562236 *success = true;
initial.commit09911bf2008-07-26 23:55:292237}
2238
[email protected]5ae5bed2009-08-21 18:52:442239#if !defined(OS_MACOSX)
[email protected]3753f522009-04-14 23:15:472240// TODO(port): Enable these.
[email protected]71f65dd2009-02-11 19:14:562241void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2242 bool* success,
2243 std::wstring* text) {
2244 *success = false;
initial.commit09911bf2008-07-26 23:55:292245 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562246 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522247 GetText();
[email protected]71f65dd2009-02-11 19:14:562248 *success = true;
initial.commit09911bf2008-07-26 23:55:292249 }
initial.commit09911bf2008-07-26 23:55:292250}
2251
[email protected]71f65dd2009-02-11 19:14:562252void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2253 const std::wstring& text,
2254 bool* success) {
2255 *success = false;
initial.commit09911bf2008-07-26 23:55:292256 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522257 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2258 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562259 *success = true;
initial.commit09911bf2008-07-26 23:55:292260 }
initial.commit09911bf2008-07-26 23:55:292261}
2262
2263void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562264 int autocomplete_edit_handle,
2265 bool* success,
2266 std::vector<AutocompleteMatchData>* matches) {
2267 *success = false;
initial.commit09911bf2008-07-26 23:55:292268 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272269 const AutocompleteResult& result = autocomplete_edit_tracker_->
2270 GetResource(autocomplete_edit_handle)->model()->result();
2271 for (AutocompleteResult::const_iterator i = result.begin();
2272 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562273 matches->push_back(AutocompleteMatchData(*i));
2274 *success = true;
initial.commit09911bf2008-07-26 23:55:292275 }
initial.commit09911bf2008-07-26 23:55:292276}
2277
2278void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562279 int autocomplete_edit_handle,
2280 bool* success,
2281 bool* query_in_progress) {
2282 *success = false;
2283 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292284 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562285 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522286 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562287 *success = true;
initial.commit09911bf2008-07-26 23:55:292288 }
initial.commit09911bf2008-07-26 23:55:292289}
2290
[email protected]28790922009-03-09 19:48:372291void AutomationProvider::OnMessageFromExternalHost(int handle,
2292 const std::string& message,
2293 const std::string& origin,
2294 const std::string& target) {
[email protected]f7a68432009-07-29 23:18:192295 RenderViewHost* view_host = GetViewForTab(handle);
2296 if (!view_host) {
2297 return;
[email protected]fa83e762008-08-15 21:41:392298 }
[email protected]f7a68432009-07-29 23:18:192299
2300 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
2301 view_host, message, origin, target)) {
2302 // Message was diverted.
2303 return;
2304 }
2305
2306 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
2307 origin, target, this, view_host, handle)) {
2308 // Message was diverted.
2309 return;
2310 }
2311
2312 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
2313 // Message was diverted.
2314 return;
2315 }
2316
2317 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392318}
[email protected]a9024892009-06-16 23:13:552319
2320bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2321 const std::string& message, const std::string& origin,
2322 const std::string& target) {
2323 if (target !=
2324 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2325 return false;
2326
2327 if (origin != extension_automation_constants::kAutomationOrigin) {
2328 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2329 return false;
2330 }
2331
2332 // The message is a JSON-encoded array with two elements, both strings. The
2333 // first is the name of the event to dispatch. The second is a JSON-encoding
2334 // of the arguments specific to that event.
2335 scoped_ptr<Value> message_value(JSONReader::Read(message, false));
2336 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2337 LOG(WARNING) << "Invalid browser event specified through automation";
2338 return false;
2339 }
2340
2341 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2342
2343 std::string event_name;
2344 if (!args->GetString(0, &event_name)) {
2345 LOG(WARNING) << "No browser event name specified through automation";
2346 return false;
2347 }
2348
2349 std::string json_args;
2350 if (!args->GetString(1, &json_args)) {
2351 LOG(WARNING) << "No browser event args specified through automation";
2352 return false;
2353 }
2354
[email protected]7120f132009-07-20 21:05:372355 if (profile()->GetExtensionMessageService()) {
2356 profile()->GetExtensionMessageService()->
2357 DispatchEventToRenderers(event_name.c_str(), json_args);
2358 }
[email protected]a9024892009-06-16 23:13:552359
2360 return true;
2361}
[email protected]5ae5bed2009-08-21 18:52:442362#endif // !defined(OS_MACOSX)
[email protected]fa83e762008-08-15 21:41:392363
[email protected]57c6a652009-05-04 07:58:342364TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572365 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572366 if (tab_tracker_->ContainsHandle(handle)) {
2367 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342368 if (tab)
2369 *tab = nav_controller;
2370 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572371 }
[email protected]57c6a652009-05-04 07:58:342372 return NULL;
[email protected]20e93d12008-08-28 16:31:572373}
2374
initial.commit09911bf2008-07-26 23:55:292375TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2376 : AutomationProvider(profile) {
2377 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142378 registrar_.Add(this, NotificationType::SESSION_END,
2379 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292380}
2381
2382TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292383 BrowserList::RemoveObserver(this);
2384}
2385
2386void TestingAutomationProvider::OnChannelError() {
2387 BrowserList::CloseAllBrowsers(true);
2388 AutomationProvider::OnChannelError();
2389}
2390
2391void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2392 // For backwards compatibility with the testing automation interface, we
2393 // want the automation provider (and hence the process) to go away when the
2394 // last browser goes away.
2395 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292396 // If you change this, update Observer for NotificationType::SESSION_END
2397 // below.
[email protected]295039bd2008-08-15 04:32:572398 MessageLoop::current()->PostTask(FROM_HERE,
2399 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292400 }
2401}
2402
2403void TestingAutomationProvider::Observe(NotificationType type,
2404 const NotificationSource& source,
2405 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562406 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292407 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2408 // before the task runs resulting in this object not being deleted. This
2409 // Release balance out the Release scheduled by OnBrowserRemoving.
2410 Release();
2411}
[email protected]295039bd2008-08-15 04:32:572412
2413void TestingAutomationProvider::OnRemoveProvider() {
2414 AutomationProviderList::GetInstance()->RemoveProvider(this);
2415}
[email protected]8a3422c92008-09-24 17:42:422416
[email protected]71f65dd2009-02-11 19:14:562417void AutomationProvider::GetSSLInfoBarCount(int handle, int* count) {
2418 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422419 if (tab_tracker_->ContainsHandle(handle)) {
2420 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342421 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112422 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422423 }
[email protected]8a3422c92008-09-24 17:42:422424}
2425
[email protected]71f65dd2009-02-11 19:14:562426void AutomationProvider::ClickSSLInfoBarLink(int handle,
[email protected]8a3422c92008-09-24 17:42:422427 int info_bar_index,
[email protected]71f65dd2009-02-11 19:14:562428 bool wait_for_navigation,
2429 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422430 bool success = false;
2431 if (tab_tracker_->ContainsHandle(handle)) {
2432 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2433 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112434 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422435 if (info_bar_index >= 0 && info_bar_index < count) {
2436 if (wait_for_navigation) {
[email protected]2e028a082009-08-19 20:32:582437 AddNavigationStatusListener(nav_controller, reply_message, 1);
[email protected]8a3422c92008-09-24 17:42:422438 }
[email protected]eb9ba192008-12-02 02:41:342439 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112440 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342441 info_bar_index);
2442 if (delegate->AsConfirmInfoBarDelegate())
2443 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422444 success = true;
2445 }
2446 }
[email protected]4f3dc372009-02-24 00:10:292447 }
[email protected]8a3422c92008-09-24 17:42:422448 if (!wait_for_navigation || !success)
[email protected]457f5cf2009-08-18 16:37:522449 AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(
2450 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]8a3422c92008-09-24 17:42:422451}
2452
[email protected]71f65dd2009-02-11 19:14:562453void AutomationProvider::GetLastNavigationTime(int handle,
2454 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422455 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562456 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422457}
2458
[email protected]71f65dd2009-02-11 19:14:562459void AutomationProvider::WaitForNavigation(int handle,
2460 int64 last_navigation_time,
2461 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422462 NavigationController* controller = NULL;
2463 if (tab_tracker_->ContainsHandle(handle))
2464 controller = tab_tracker_->GetResource(handle);
2465
2466 Time time = tab_tracker_->GetLastNavigationTime(handle);
2467 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562468 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
[email protected]457f5cf2009-08-18 16:37:522469 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
2470 AUTOMATION_MSG_NAVIGATION_SUCCESS);
[email protected]4f3dc372009-02-24 00:10:292471 return;
[email protected]8a3422c92008-09-24 17:42:422472 }
2473
[email protected]2e028a082009-08-19 20:32:582474 AddNavigationStatusListener(controller, reply_message, 1);
[email protected]8a3422c92008-09-24 17:42:422475}
2476
[email protected]71f65dd2009-02-11 19:14:562477void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162478 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562479 int value,
2480 bool* success) {
2481 *success = false;
[email protected]8a3422c92008-09-24 17:42:422482 if (browser_tracker_->ContainsHandle(handle)) {
2483 Browser* browser = browser_tracker_->GetResource(handle);
2484 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562485 *success = true;
[email protected]8a3422c92008-09-24 17:42:422486 }
[email protected]8a3422c92008-09-24 17:42:422487}
[email protected]97fa6ce32008-12-19 01:48:162488
[email protected]71f65dd2009-02-11 19:14:562489void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162490 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562491 const std::wstring& value,
2492 bool* success) {
2493 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162494 if (browser_tracker_->ContainsHandle(handle)) {
2495 Browser* browser = browser_tracker_->GetResource(handle);
2496 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562497 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162498 }
[email protected]97fa6ce32008-12-19 01:48:162499}
2500
[email protected]71f65dd2009-02-11 19:14:562501void AutomationProvider::GetBooleanPreference(int handle,
2502 const std::wstring& name,
2503 bool* success,
2504 bool* value) {
2505 *success = false;
2506 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162507 if (browser_tracker_->ContainsHandle(handle)) {
2508 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562509 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2510 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162511 }
[email protected]97fa6ce32008-12-19 01:48:162512}
2513
[email protected]71f65dd2009-02-11 19:14:562514void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162515 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562516 bool value,
2517 bool* success) {
2518 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162519 if (browser_tracker_->ContainsHandle(handle)) {
2520 Browser* browser = browser_tracker_->GetResource(handle);
2521 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562522 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162523 }
[email protected]97fa6ce32008-12-19 01:48:162524}
2525
2526// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562527void AutomationProvider::GetPageCurrentEncoding(
2528 int tab_handle, std::wstring* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162529 if (tab_tracker_->ContainsHandle(tab_handle)) {
2530 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2531 Browser* browser = FindAndActivateTab(nav);
2532 DCHECK(browser);
2533
[email protected]57c6a652009-05-04 07:58:342534 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2535 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162536 }
[email protected]97fa6ce32008-12-19 01:48:162537}
2538
2539// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562540void AutomationProvider::OverrideEncoding(int tab_handle,
2541 const std::wstring& encoding_name,
2542 bool* success) {
2543 *success = false;
[email protected]de246f52009-02-25 18:25:452544#if defined(OS_WIN)
[email protected]97fa6ce32008-12-19 01:48:162545 if (tab_tracker_->ContainsHandle(tab_handle)) {
2546 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2547 Browser* browser = FindAndActivateTab(nav);
2548 DCHECK(browser);
2549
[email protected]1fc025202009-01-20 23:03:142550 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:112551 TabContents* tab_contents = nav->tab_contents();
[email protected]97fa6ce32008-12-19 01:48:162552 int selected_encoding_id =
2553 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2554 if (selected_encoding_id) {
2555 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562556 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162557 }
2558 }
2559 }
[email protected]de246f52009-02-25 18:25:452560#else
2561 // TODO(port): Enable when encoding-related parts of Browser are ported.
2562 NOTIMPLEMENTED();
2563#endif
[email protected]97fa6ce32008-12-19 01:48:162564}
[email protected]5bcdb312009-01-07 21:43:202565
[email protected]4d434a1a2009-02-11 21:06:572566void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:202567 SavePackage::SetShouldPromptUser(should_prompt);
2568}
[email protected]87eab222009-03-13 00:47:452569
[email protected]b83e4602009-05-15 22:58:332570void AutomationProvider::SetEnableExtensionAutomation(bool automation_enabled) {
2571 AutomationExtensionFunction::SetEnabled(automation_enabled);
2572}
2573
[email protected]3753f522009-04-14 23:15:472574void AutomationProvider::GetWindowTitle(int handle, string16* text) {
2575 gfx::NativeWindow window = window_tracker_->GetResource(handle);
2576 text->assign(platform_util::GetWindowTitle(window));
2577}
[email protected]66ba4932009-06-04 19:22:132578
2579void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
2580 *count = -1; // -1 is the error code
2581 if (tab_tracker_->ContainsHandle(handle)) {
2582 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2583 TabContents* tab_contents = nav_controller->tab_contents();
2584 if (tab_contents) {
2585 BlockedPopupContainer* container =
2586 tab_contents->blocked_popup_container();
2587 if (container) {
2588 *count = static_cast<int>(container->GetBlockedPopupCount());
2589 } else {
2590 // If we don't have a container, we don't have any blocked popups to
2591 // contain!
2592 *count = 0;
2593 }
2594 }
2595 }
2596}
[email protected]f7a68432009-07-29 23:18:192597
2598void AutomationProvider::SelectAll(int tab_handle) {
2599 RenderViewHost* view = GetViewForTab(tab_handle);
2600 if (!view) {
2601 NOTREACHED();
2602 return;
2603 }
2604
2605 view->SelectAll();
2606}
2607
2608void AutomationProvider::Cut(int tab_handle) {
2609 RenderViewHost* view = GetViewForTab(tab_handle);
2610 if (!view) {
2611 NOTREACHED();
2612 return;
2613 }
2614
2615 view->Cut();
2616}
2617
2618void AutomationProvider::Copy(int tab_handle) {
2619 RenderViewHost* view = GetViewForTab(tab_handle);
2620 if (!view) {
2621 NOTREACHED();
2622 return;
2623 }
2624
2625 view->Copy();
2626}
2627
2628void AutomationProvider::Paste(int tab_handle) {
2629 RenderViewHost* view = GetViewForTab(tab_handle);
2630 if (!view) {
2631 NOTREACHED();
2632 return;
2633 }
2634
2635 view->Paste();
2636}
2637
2638void AutomationProvider::ReloadAsync(int tab_handle) {
2639 if (tab_tracker_->ContainsHandle(tab_handle)) {
2640 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2641 if (!tab) {
2642 NOTREACHED();
2643 return;
2644 }
2645
2646 tab->Reload(false);
2647 }
2648}
2649
2650void AutomationProvider::StopAsync(int tab_handle) {
2651 RenderViewHost* view = GetViewForTab(tab_handle);
2652 if (!view) {
2653 NOTREACHED();
2654 return;
2655 }
2656
2657 view->Stop();
2658}
2659
[email protected]2949e90d2009-08-21 15:32:522660void AutomationProvider::WaitForBrowserWindowCountToBecome(
2661 int target_count, IPC::Message* reply_message) {
2662 if (static_cast<int>(BrowserList::size()) == target_count) {
2663 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
2664 reply_message, true);
2665 Send(reply_message);
2666 return;
2667 }
2668
2669 // Set up an observer (it will delete itself).
2670 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
2671}
2672
2673void AutomationProvider::WaitForAppModalDialogToBeShown(
2674 IPC::Message* reply_message) {
2675 if (Singleton<AppModalDialogQueue>()->HasActiveDialog()) {
2676 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
2677 reply_message, true);
2678 Send(reply_message);
2679 return;
2680 }
2681
2682 // Set up an observer (it will delete itself).
2683 new AppModalDialogShownObserver(this, reply_message);
2684}
2685
[email protected]f7a68432009-07-29 23:18:192686RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
2687 if (tab_tracker_->ContainsHandle(tab_handle)) {
2688 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2689 if (!tab) {
2690 NOTREACHED();
2691 return NULL;
2692 }
2693
2694 TabContents* tab_contents = tab->tab_contents();
2695 if (!tab_contents) {
2696 NOTREACHED();
2697 return NULL;
2698 }
2699
2700 RenderViewHost* view_host = tab_contents->render_view_host();
2701 return view_host;
2702 }
2703
2704 return NULL;
2705}