blob: f38696068548ca364415dc524cd1c8a4adefd35f [file] [log] [blame]
[email protected]4801ecc2009-04-05 04:52:581// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]202e7a72009-06-15 03:48:367#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:318#include "app/message_box_flags.h"
[email protected]c6cb1992009-04-13 16:45:299#include "base/file_version_info.h"
[email protected]a9024892009-06-16 23:13:5510#include "base/json_reader.h"
[email protected]5fac9622009-02-04 21:49:3811#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/path_service.h"
[email protected]f44265b2009-05-19 18:52:5013#include "base/stl_util-inl.h"
[email protected]4c4d8d22009-03-04 05:29:2714#include "base/string_util.h"
[email protected]5fac9622009-02-04 21:49:3815#include "base/thread.h"
[email protected]a7eee32f2009-05-22 18:08:1716#include "base/values.h"
[email protected]4f3dc372009-02-24 00:10:2917#include "chrome/app/chrome_dll_resource.h"
[email protected]0bfa713f2009-04-07 20:18:2818#include "chrome/browser/app_modal_dialog.h"
[email protected]464146e2009-04-09 18:17:0919#include "chrome/browser/app_modal_dialog_queue.h"
[email protected]b83e4602009-05-15 22:58:3320#include "chrome/browser/automation/automation_extension_function.h"
initial.commit09911bf2008-07-26 23:55:2921#include "chrome/browser/automation/automation_provider_list.h"
[email protected]a9024892009-06-16 23:13:5522#include "chrome/browser/automation/extension_automation_constants.h"
[email protected]f44265b2009-05-19 18:52:5023#include "chrome/browser/automation/extension_port_container.h"
initial.commit09911bf2008-07-26 23:55:2924#include "chrome/browser/automation/url_request_failed_dns_job.h"
25#include "chrome/browser/automation/url_request_mock_http_job.h"
26#include "chrome/browser/automation/url_request_slow_download_job.h"
[email protected]66ba4932009-06-04 19:22:1327#include "chrome/browser/blocked_popup_container.h"
[email protected]5c238752009-06-13 10:29:0728#include "chrome/browser/browser_process.h"
[email protected]f3e99e32008-07-30 04:48:3929#include "chrome/browser/browser_window.h"
initial.commit09911bf2008-07-26 23:55:2930#include "chrome/browser/dom_operation_notification_details.h"
[email protected]d9f9b792009-06-24 13:17:1231#include "chrome/browser/debugger/devtools_manager.h"
[email protected]cdaa8652008-09-13 02:48:5932#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2233#include "chrome/browser/download/download_shelf.h"
[email protected]a9024892009-06-16 23:13:5534#include "chrome/browser/extensions/extension_message_service.h"
[email protected]4801ecc2009-04-05 04:52:5835#include "chrome/browser/find_bar.h"
36#include "chrome/browser/find_bar_controller.h"
initial.commit09911bf2008-07-26 23:55:2937#include "chrome/browser/find_notification_details.h"
[email protected]13869dd2009-05-05 00:40:0638#include "chrome/browser/location_bar.h"
[email protected]a7eee32f2009-05-22 18:08:1739#include "chrome/browser/profile_manager.h"
[email protected]6524b5f92009-01-22 17:48:2540#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]3b073b22009-01-16 03:29:0341#include "chrome/browser/ssl/ssl_manager.h"
42#include "chrome/browser/ssl/ssl_blocking_page.h"
[email protected]57c6a652009-05-04 07:58:3443#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4544#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]a7eee32f2009-05-22 18:08:1745#include "chrome/common/automation_constants.h"
initial.commit09911bf2008-07-26 23:55:2946#include "chrome/common/chrome_paths.h"
[email protected]a7eee32f2009-05-22 18:08:1747#include "chrome/common/json_value_serializer.h"
[email protected]1c58a5c2009-05-21 18:47:1448#include "chrome/common/notification_service.h"
[email protected]3753f522009-04-14 23:15:4749#include "chrome/common/platform_util.h"
[email protected]8a3422c92008-09-24 17:42:4250#include "chrome/common/pref_service.h"
[email protected]71f65dd2009-02-11 19:14:5651#include "chrome/test/automation/automation_messages.h"
initial.commit09911bf2008-07-26 23:55:2952#include "net/base/cookie_monster.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"
initial.commit09911bf2008-07-26 23:55:2956#include "net/url_request/url_request_filter.h"
57
[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/automation/ui_controls.h"
61#include "chrome/browser/character_encoding.h"
62#include "chrome/browser/download/save_package.h"
63#include "chrome/browser/external_tab_container.h"
[email protected]de246f52009-02-25 18:25:4564#include "chrome/browser/printing/print_job.h"
[email protected]de246f52009-02-25 18:25:4565#endif // defined(OS_WIN)
66
[email protected]e8382172009-06-19 22:16:2867#if defined(OS_WIN) || defined(OS_LINUX)
68// TODO(port): Port these to the mac.
69#include "chrome/browser/login_prompt.h"
70#endif
71
[email protected]13869dd2009-05-05 00:40:0672#if defined(OS_WIN)
73#include "chrome/browser/views/bookmark_bar_view.h"
[email protected]9095e982009-05-27 17:28:2474#include "views/widget/root_view.h"
[email protected]2362e4f2009-05-08 00:34:0575#include "views/widget/widget_win.h"
76#include "views/window/window.h"
[email protected]13869dd2009-05-05 00:40:0677#endif
78
[email protected]e1acf6f2008-10-27 20:43:3379using base::Time;
80
initial.commit09911bf2008-07-26 23:55:2981class InitialLoadObserver : public NotificationObserver {
82 public:
83 InitialLoadObserver(size_t tab_count, AutomationProvider* automation)
[email protected]66791d22009-02-24 20:11:3384 : automation_(automation),
85 outstanding_tab_count_(tab_count) {
initial.commit09911bf2008-07-26 23:55:2986 if (outstanding_tab_count_ > 0) {
[email protected]bfd04a62009-02-01 18:16:5687 registrar_.Add(this, NotificationType::LOAD_START,
[email protected]6a02963e2009-01-06 16:58:0388 NotificationService::AllSources());
[email protected]bfd04a62009-02-01 18:16:5689 registrar_.Add(this, NotificationType::LOAD_STOP,
[email protected]6a02963e2009-01-06 16:58:0390 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:2991 }
92 }
93
94 ~InitialLoadObserver() {
initial.commit09911bf2008-07-26 23:55:2995 }
96
97 void ConditionMet() {
[email protected]6a02963e2009-01-06 16:58:0398 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:2999 automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
100 }
101
initial.commit09911bf2008-07-26 23:55:29102 virtual void Observe(NotificationType type,
103 const NotificationSource& source,
104 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56105 if (type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29106 if (outstanding_tab_count_ > loading_tabs_.size())
107 loading_tabs_.insert(source.map_key());
[email protected]bfd04a62009-02-01 18:16:56108 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29109 if (outstanding_tab_count_ > finished_tabs_.size()) {
110 if (loading_tabs_.find(source.map_key()) != loading_tabs_.end())
111 finished_tabs_.insert(source.map_key());
112 if (outstanding_tab_count_ == finished_tabs_.size())
113 ConditionMet();
114 }
115 } else {
116 NOTREACHED();
117 }
118 }
119
120 private:
121 typedef std::set<uintptr_t> TabSet;
122
[email protected]6a02963e2009-01-06 16:58:03123 NotificationRegistrar registrar_;
124
initial.commit09911bf2008-07-26 23:55:29125 AutomationProvider* automation_;
126 size_t outstanding_tab_count_;
127 TabSet loading_tabs_;
128 TabSet finished_tabs_;
129};
130
131// Watches for NewTabUI page loads for performance timing purposes.
132class NewTabUILoadObserver : public NotificationObserver {
133 public:
134 explicit NewTabUILoadObserver(AutomationProvider* automation)
135 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14136 registrar_.Add(this, NotificationType::INITIAL_NEW_TAB_UI_LOAD,
137 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29138 }
139
140 ~NewTabUILoadObserver() {
initial.commit09911bf2008-07-26 23:55:29141 }
142
143 virtual void Observe(NotificationType type,
144 const NotificationSource& source,
145 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56146 if (type == NotificationType::INITIAL_NEW_TAB_UI_LOAD) {
initial.commit09911bf2008-07-26 23:55:29147 Details<int> load_time(details);
148 automation_->Send(
149 new AutomationMsg_InitialNewTabUILoadComplete(0, *load_time.ptr()));
150 } else {
151 NOTREACHED();
152 }
153 }
154
155 private:
[email protected]1c58a5c2009-05-21 18:47:14156 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29157 AutomationProvider* automation_;
158};
159
160class NavigationControllerRestoredObserver : public NotificationObserver {
161 public:
162 NavigationControllerRestoredObserver(AutomationProvider* automation,
163 NavigationController* controller,
[email protected]71f65dd2009-02-11 19:14:56164 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29165 : automation_(automation),
166 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56167 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29168 if (FinishedRestoring()) {
initial.commit09911bf2008-07-26 23:55:29169 SendDone();
170 } else {
[email protected]1c58a5c2009-05-21 18:47:14171 registrar_.Add(this, NotificationType::LOAD_STOP,
172 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29173 }
174 }
175
176 ~NavigationControllerRestoredObserver() {
initial.commit09911bf2008-07-26 23:55:29177 }
178
179 virtual void Observe(NotificationType type,
180 const NotificationSource& source,
181 const NotificationDetails& details) {
182 if (FinishedRestoring()) {
183 SendDone();
[email protected]1c58a5c2009-05-21 18:47:14184 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29185 }
186 }
187
188 private:
initial.commit09911bf2008-07-26 23:55:29189 bool FinishedRestoring() {
[email protected]7f0005a2009-04-15 03:25:11190 return (!controller_->needs_reload() && !controller_->pending_entry() &&
191 !controller_->tab_contents()->is_loading());
initial.commit09911bf2008-07-26 23:55:29192 }
193
194 void SendDone() {
[email protected]71f65dd2009-02-11 19:14:56195 DCHECK(reply_message_ != NULL);
196 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29197 }
198
[email protected]1c58a5c2009-05-21 18:47:14199 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29200 AutomationProvider* automation_;
201 NavigationController* controller_;
[email protected]71f65dd2009-02-11 19:14:56202 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29203
[email protected]5a52f162008-08-27 04:15:31204 DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
initial.commit09911bf2008-07-26 23:55:29205};
206
[email protected]71f65dd2009-02-11 19:14:56207template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29208class NavigationNotificationObserver : public NotificationObserver {
209 public:
210 NavigationNotificationObserver(NavigationController* controller,
211 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56212 IPC::Message* reply_message,
213 NavigationCodeType success_code,
214 NavigationCodeType auth_needed_code,
215 NavigationCodeType failed_code)
initial.commit09911bf2008-07-26 23:55:29216 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56217 reply_message_(reply_message),
initial.commit09911bf2008-07-26 23:55:29218 controller_(controller),
[email protected]71f65dd2009-02-11 19:14:56219 navigation_started_(false),
220 success_code_(success_code),
221 auth_needed_code_(auth_needed_code),
222 failed_code_(failed_code) {
[email protected]1c58a5c2009-05-21 18:47:14223 Source<NavigationController> source(controller_);
224 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, source);
225 registrar_.Add(this, NotificationType::LOAD_START, source);
226 registrar_.Add(this, NotificationType::LOAD_STOP, source);
227 registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
228 registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
initial.commit09911bf2008-07-26 23:55:29229 }
230
231 ~NavigationNotificationObserver() {
[email protected]1c58a5c2009-05-21 18:47:14232 if (reply_message_) {
233 // This means we did not receive a notification for this navigation.
234 // Send over a failed navigation status back to the caller to ensure that
235 // the caller does not hang waiting for the response.
236 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
237 failed_code_);
238 automation_->Send(reply_message_);
239 reply_message_ = NULL;
240 }
241
242 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29243 }
244
[email protected]71f65dd2009-02-11 19:14:56245 void ConditionMet(NavigationCodeType navigation_result) {
246 DCHECK(reply_message_ != NULL);
247
248 IPC::ParamTraits<NavigationCodeType>::Write(reply_message_,
249 navigation_result);
250 automation_->Send(reply_message_);
251 reply_message_ = NULL;
252
initial.commit09911bf2008-07-26 23:55:29253 delete this;
254 }
255
initial.commit09911bf2008-07-26 23:55:29256 virtual void Observe(NotificationType type,
257 const NotificationSource& source,
258 const NotificationDetails& details) {
[email protected]8a3422c92008-09-24 17:42:42259 // We listen for 2 events to determine when the navigation started because:
260 // - when this is used by the WaitForNavigation method, we might be invoked
261 // afer the load has started (but not after the entry was committed, as
262 // WaitForNavigation compares times of the last navigation).
263 // - when this is used with a page requiring authentication, we will not get
[email protected]4f3dc372009-02-24 00:10:29264 // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
265 // we need the NotificationType::LOAD_START.
[email protected]bfd04a62009-02-01 18:16:56266 if (type == NotificationType::NAV_ENTRY_COMMITTED ||
267 type == NotificationType::LOAD_START) {
initial.commit09911bf2008-07-26 23:55:29268 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56269 } else if (type == NotificationType::LOAD_STOP) {
initial.commit09911bf2008-07-26 23:55:29270 if (navigation_started_) {
271 navigation_started_ = false;
[email protected]71f65dd2009-02-11 19:14:56272 ConditionMet(success_code_);
initial.commit09911bf2008-07-26 23:55:29273 }
[email protected]bfd04a62009-02-01 18:16:56274 } else if (type == NotificationType::AUTH_SUPPLIED) {
initial.commit09911bf2008-07-26 23:55:29275 // The LoginHandler for this tab is no longer valid.
276 automation_->RemoveLoginHandler(controller_);
277
278 // Treat this as if navigation started again, since load start/stop don't
279 // occur while authentication is ongoing.
280 navigation_started_ = true;
[email protected]bfd04a62009-02-01 18:16:56281 } else if (type == NotificationType::AUTH_NEEDED) {
[email protected]de246f52009-02-25 18:25:45282#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29283 if (navigation_started_) {
284 // Remember the login handler that wants authentication.
285 LoginHandler* handler =
286 Details<LoginNotificationDetails>(details)->handler();
287 automation_->AddLoginHandler(controller_, handler);
288
289 // Respond that authentication is needed.
290 navigation_started_ = false;
[email protected]71f65dd2009-02-11 19:14:56291 ConditionMet(auth_needed_code_);
initial.commit09911bf2008-07-26 23:55:29292 } else {
293 NOTREACHED();
294 }
[email protected]de246f52009-02-25 18:25:45295#else
296 // TODO(port): Enable when we have LoginNotificationDetails etc.
297 NOTIMPLEMENTED();
298#endif
initial.commit09911bf2008-07-26 23:55:29299 } else {
300 NOTREACHED();
301 }
302 }
303
304 private:
[email protected]1c58a5c2009-05-21 18:47:14305 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29306 AutomationProvider* automation_;
[email protected]71f65dd2009-02-11 19:14:56307 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29308 NavigationController* controller_;
309 bool navigation_started_;
[email protected]71f65dd2009-02-11 19:14:56310 NavigationCodeType success_code_;
311 NavigationCodeType auth_needed_code_;
312 NavigationCodeType failed_code_;
initial.commit09911bf2008-07-26 23:55:29313};
314
315class TabStripNotificationObserver : public NotificationObserver {
316 public:
[email protected]1c58a5c2009-05-21 18:47:14317 TabStripNotificationObserver(NotificationType notification,
318 AutomationProvider* automation)
319 : automation_(automation),
320 notification_(notification) {
321 registrar_.Add(this, notification_, NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29322 }
323
324 virtual ~TabStripNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29325 }
326
327 virtual void Observe(NotificationType type,
328 const NotificationSource& source,
329 const NotificationDetails& details) {
330 if (type == notification_) {
331 ObserveTab(Source<NavigationController>(source).ptr());
332
333 // If verified, no need to observe anymore
334 automation_->RemoveTabStripObserver(this);
335 delete this;
336 } else {
337 NOTREACHED();
338 }
339 }
340
341 virtual void ObserveTab(NavigationController* controller) = 0;
342
343 protected:
[email protected]1c58a5c2009-05-21 18:47:14344 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29345 AutomationProvider* automation_;
initial.commit09911bf2008-07-26 23:55:29346 NotificationType notification_;
initial.commit09911bf2008-07-26 23:55:29347};
348
349class TabAppendedNotificationObserver : public TabStripNotificationObserver {
350 public:
351 TabAppendedNotificationObserver(Browser* parent,
[email protected]1c58a5c2009-05-21 18:47:14352 AutomationProvider* automation,
353 IPC::Message* reply_message)
354 : TabStripNotificationObserver(NotificationType::TAB_PARENTED,
355 automation),
356 parent_(parent),
[email protected]71f65dd2009-02-11 19:14:56357 reply_message_(reply_message) {
initial.commit09911bf2008-07-26 23:55:29358 }
359
360 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14361 if (automation_->GetIndexForNavigationController(controller, parent_) ==
362 TabStripModel::kNoTab) {
363 // This tab notification doesn't belong to the parent_.
initial.commit09911bf2008-07-26 23:55:29364 return;
365 }
366
367 // Give the same response even if auth is needed, since it doesn't matter.
[email protected]71f65dd2009-02-11 19:14:56368 automation_->AddNavigationStatusListener<int>(
369 controller, reply_message_, AUTOMATION_MSG_NAVIGATION_SUCCESS,
370 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED, AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:29371 }
[email protected]71f65dd2009-02-11 19:14:56372
373 protected:
[email protected]1c58a5c2009-05-21 18:47:14374 Browser* parent_;
[email protected]71f65dd2009-02-11 19:14:56375 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29376};
377
378class TabClosedNotificationObserver : public TabStripNotificationObserver {
379 public:
[email protected]1c58a5c2009-05-21 18:47:14380 TabClosedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56381 bool wait_until_closed,
382 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:14383 : TabStripNotificationObserver(wait_until_closed ?
384 NotificationType::TAB_CLOSED : NotificationType::TAB_CLOSING,
385 automation),
386 reply_message_(reply_message),
387 for_browser_command_(false) {
initial.commit09911bf2008-07-26 23:55:29388 }
389
390 virtual void ObserveTab(NavigationController* controller) {
[email protected]1c58a5c2009-05-21 18:47:14391 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42392 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
393 true);
[email protected]1c58a5c2009-05-21 18:47:14394 } else {
[email protected]d79ffea2009-05-07 20:51:42395 AutomationMsg_CloseTab::WriteReplyParams(reply_message_, true);
[email protected]1c58a5c2009-05-21 18:47:14396 }
[email protected]71f65dd2009-02-11 19:14:56397 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29398 }
[email protected]71f65dd2009-02-11 19:14:56399
[email protected]d79ffea2009-05-07 20:51:42400 void set_for_browser_command(bool for_browser_command) {
401 for_browser_command_ = for_browser_command;
402 }
[email protected]1c58a5c2009-05-21 18:47:14403
[email protected]71f65dd2009-02-11 19:14:56404 protected:
405 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42406 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29407};
408
[email protected]14c0a032009-04-13 18:15:14409class BrowserOpenedNotificationObserver : public NotificationObserver {
410 public:
411 BrowserOpenedNotificationObserver(AutomationProvider* automation,
412 IPC::Message* reply_message)
413 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42414 reply_message_(reply_message),
415 for_browser_command_(false) {
[email protected]14c0a032009-04-13 18:15:14416 registrar_.Add(this, NotificationType::BROWSER_OPENED,
417 NotificationService::AllSources());
418 }
419
420 ~BrowserOpenedNotificationObserver() {
421 }
422
423 virtual void Observe(NotificationType type,
424 const NotificationSource& source,
425 const NotificationDetails& details) {
426 if (type == NotificationType::BROWSER_OPENED) {
[email protected]1c58a5c2009-05-21 18:47:14427 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42428 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
429 true);
[email protected]1c58a5c2009-05-21 18:47:14430 }
[email protected]14c0a032009-04-13 18:15:14431 automation_->Send(reply_message_);
432 delete this;
433 } else {
434 NOTREACHED();
435 }
436 }
437
[email protected]d79ffea2009-05-07 20:51:42438 void set_for_browser_command(bool for_browser_command) {
439 for_browser_command_ = for_browser_command;
440 }
[email protected]1c58a5c2009-05-21 18:47:14441
[email protected]14c0a032009-04-13 18:15:14442 private:
[email protected]1c58a5c2009-05-21 18:47:14443 NotificationRegistrar registrar_;
[email protected]14c0a032009-04-13 18:15:14444 AutomationProvider* automation_;
445 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42446 bool for_browser_command_;
[email protected]14c0a032009-04-13 18:15:14447};
448
initial.commit09911bf2008-07-26 23:55:29449class BrowserClosedNotificationObserver : public NotificationObserver {
450 public:
451 BrowserClosedNotificationObserver(Browser* browser,
452 AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56453 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29454 : automation_(automation),
[email protected]d79ffea2009-05-07 20:51:42455 reply_message_(reply_message),
456 for_browser_command_(false) {
[email protected]c300deb32009-05-08 21:26:07457 registrar_.Add(this, NotificationType::BROWSER_CLOSED,
458 Source<Browser>(browser));
initial.commit09911bf2008-07-26 23:55:29459 }
460
461 virtual void Observe(NotificationType type,
462 const NotificationSource& source,
463 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56464 DCHECK(type == NotificationType::BROWSER_CLOSED);
initial.commit09911bf2008-07-26 23:55:29465 Details<bool> close_app(details);
[email protected]71f65dd2009-02-11 19:14:56466 DCHECK(reply_message_ != NULL);
[email protected]1c58a5c2009-05-21 18:47:14467 if (for_browser_command_) {
[email protected]d79ffea2009-05-07 20:51:42468 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
469 true);
[email protected]1c58a5c2009-05-21 18:47:14470 } else {
[email protected]d79ffea2009-05-07 20:51:42471 AutomationMsg_CloseBrowser::WriteReplyParams(reply_message_, true,
472 *(close_app.ptr()));
[email protected]1c58a5c2009-05-21 18:47:14473 }
[email protected]71f65dd2009-02-11 19:14:56474 automation_->Send(reply_message_);
475 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29476 delete this;
477 }
478
[email protected]d79ffea2009-05-07 20:51:42479 void set_for_browser_command(bool for_browser_command) {
480 for_browser_command_ = for_browser_command;
481 }
[email protected]1c58a5c2009-05-21 18:47:14482
initial.commit09911bf2008-07-26 23:55:29483 private:
[email protected]c300deb32009-05-08 21:26:07484 NotificationRegistrar registrar_;
[email protected]1c58a5c2009-05-21 18:47:14485 AutomationProvider* automation_;
486 IPC::Message* reply_message_;
[email protected]d79ffea2009-05-07 20:51:42487 bool for_browser_command_;
initial.commit09911bf2008-07-26 23:55:29488};
489
[email protected]4e41709d2009-04-08 00:04:27490namespace {
491
492// Define mapping from command to notification
493struct CommandNotification {
494 int command;
495 NotificationType::Type notification_type;
496};
497
498const struct CommandNotification command_notifications[] = {
[email protected]14c0a032009-04-13 18:15:14499 {IDC_DUPLICATE_TAB, NotificationType::TAB_PARENTED},
[email protected]f8fc5882009-05-06 04:23:43500 {IDC_NEW_TAB, NotificationType::TAB_PARENTED},
[email protected]d79ffea2009-05-07 20:51:42501 // Returns as soon as the restored tab is created. To further wait until
502 // the content page is loaded, use WaitForTabToBeRestored.
[email protected]f8fc5882009-05-06 04:23:43503 {IDC_RESTORE_TAB, NotificationType::TAB_PARENTED}
[email protected]4e41709d2009-04-08 00:04:27504};
505
506} // namespace
507
[email protected]56e71b7c2009-03-27 03:05:56508class ExecuteBrowserCommandObserver : public NotificationObserver {
509 public:
[email protected]56e71b7c2009-03-27 03:05:56510 ~ExecuteBrowserCommandObserver() {
511 }
512
[email protected]d79ffea2009-05-07 20:51:42513 static bool CreateAndRegisterObserver(AutomationProvider* automation,
514 Browser* browser,
515 int command,
516 IPC::Message* reply_message) {
517 bool result = true;
518 switch (command) {
519 case IDC_NEW_WINDOW:
520 case IDC_NEW_INCOGNITO_WINDOW: {
521 BrowserOpenedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14522 new BrowserOpenedNotificationObserver(automation, reply_message);
[email protected]d79ffea2009-05-07 20:51:42523 observer->set_for_browser_command(true);
524 break;
525 }
526 case IDC_CLOSE_WINDOW: {
527 BrowserClosedNotificationObserver* observer =
528 new BrowserClosedNotificationObserver(browser, automation,
[email protected]d79ffea2009-05-07 20:51:42529 reply_message);
530 observer->set_for_browser_command(true);
531 break;
532 }
533 case IDC_CLOSE_TAB: {
534 TabClosedNotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14535 new TabClosedNotificationObserver(automation, true, reply_message);
[email protected]d79ffea2009-05-07 20:51:42536 observer->set_for_browser_command(true);
537 break;
538 }
[email protected]27e1c9e02009-05-13 18:41:39539 case IDC_BACK:
540 case IDC_FORWARD:
541 case IDC_RELOAD: {
542 automation->
543 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
544 &browser->GetSelectedTabContents()->controller(),
545 reply_message,
546 AUTOMATION_MSG_NAVIGATION_SUCCESS,
547 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
548 AUTOMATION_MSG_NAVIGATION_ERROR);
549 break;
550 }
[email protected]d79ffea2009-05-07 20:51:42551 default: {
552 ExecuteBrowserCommandObserver* observer =
553 new ExecuteBrowserCommandObserver(automation, reply_message);
554 if (!observer->Register(command)) {
555 delete observer;
556 result = false;
557 }
558 break;
559 }
560 }
561 return result;
[email protected]4e41709d2009-04-08 00:04:27562 }
563
[email protected]56e71b7c2009-03-27 03:05:56564 virtual void Observe(NotificationType type,
565 const NotificationSource& source,
566 const NotificationDetails& details) {
567 if (type == notification_type_) {
[email protected]49a14a82009-03-31 04:16:44568 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message_,
569 true);
[email protected]56e71b7c2009-03-27 03:05:56570 automation_->Send(reply_message_);
571 delete this;
572 } else {
573 NOTREACHED();
574 }
575 }
576
577 private:
[email protected]d79ffea2009-05-07 20:51:42578 ExecuteBrowserCommandObserver(AutomationProvider* automation,
579 IPC::Message* reply_message)
580 : automation_(automation),
581 reply_message_(reply_message) {
582 }
583
584 bool Register(int command) {
585 if (!GetNotificationType(command, &notification_type_))
586 return false;
[email protected]1c58a5c2009-05-21 18:47:14587 registrar_.Add(this, notification_type_, NotificationService::AllSources());
[email protected]d79ffea2009-05-07 20:51:42588 return true;
589 }
590
[email protected]4e41709d2009-04-08 00:04:27591 bool GetNotificationType(int command, NotificationType::Type* type) {
592 if (!type)
593 return false;
594 bool found = false;
595 for (unsigned int i = 0; i < arraysize(command_notifications); i++) {
596 if (command_notifications[i].command == command) {
597 *type = command_notifications[i].notification_type;
598 found = true;
599 break;
600 }
601 }
602 return found;
603 }
604
[email protected]1c58a5c2009-05-21 18:47:14605 NotificationRegistrar registrar_;
[email protected]56e71b7c2009-03-27 03:05:56606 AutomationProvider* automation_;
607 NotificationType::Type notification_type_;
608 IPC::Message* reply_message_;
[email protected]56e71b7c2009-03-27 03:05:56609};
610
initial.commit09911bf2008-07-26 23:55:29611class FindInPageNotificationObserver : public NotificationObserver {
612 public:
613 FindInPageNotificationObserver(AutomationProvider* automation,
614 TabContents* parent_tab,
[email protected]71f65dd2009-02-11 19:14:56615 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29616 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56617 active_match_ordinal_(-1),
618 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14619 registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
620 Source<TabContents>(parent_tab));
initial.commit09911bf2008-07-26 23:55:29621 }
622
623 ~FindInPageNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29624 }
625
[email protected]1c58a5c2009-05-21 18:47:14626 virtual void Observe(NotificationType type,
627 const NotificationSource& source,
628 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56629 if (type == NotificationType::FIND_RESULT_AVAILABLE) {
initial.commit09911bf2008-07-26 23:55:29630 Details<FindNotificationDetails> find_details(details);
631 if (find_details->request_id() == kFindInPageRequestId) {
[email protected]aedd85a2008-12-04 19:32:49632 // We get multiple responses and one of those will contain the ordinal.
633 // This message comes to us before the final update is sent.
634 if (find_details->active_match_ordinal() > -1)
635 active_match_ordinal_ = find_details->active_match_ordinal();
initial.commit09911bf2008-07-26 23:55:29636 if (find_details->final_update()) {
[email protected]71f65dd2009-02-11 19:14:56637 DCHECK(reply_message_ != NULL);
638
[email protected]1c58a5c2009-05-21 18:47:14639 AutomationMsg_FindInPage::WriteReplyParams(reply_message_,
640 active_match_ordinal_, find_details->number_of_matches());
[email protected]71f65dd2009-02-11 19:14:56641
642 automation_->Send(reply_message_);
643 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:29644 } else {
645 DLOG(INFO) << "Ignoring, since we only care about the final message";
646 }
647 }
648 } else {
649 NOTREACHED();
650 }
651 }
652
653 // The Find mechanism is over asynchronous IPC, so a search is kicked off and
654 // we wait for notification to find out what the results are. As the user is
655 // typing, new search requests can be issued and the Request ID helps us make
656 // sense of whether this is the current request or an old one. The unit tests,
657 // however, which uses this constant issues only one search at a time, so we
658 // don't need a rolling id to identify each search. But, we still need to
659 // specify one, so we just use a fixed one - its value does not matter.
660 static const int kFindInPageRequestId;
[email protected]1c58a5c2009-05-21 18:47:14661
initial.commit09911bf2008-07-26 23:55:29662 private:
[email protected]1c58a5c2009-05-21 18:47:14663 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29664 AutomationProvider* automation_;
[email protected]aedd85a2008-12-04 19:32:49665 // We will at some point (before final update) be notified of the ordinal and
666 // we need to preserve it so we can send it later.
667 int active_match_ordinal_;
[email protected]71f65dd2009-02-11 19:14:56668 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29669};
670
671const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
672
673class DomOperationNotificationObserver : public NotificationObserver {
674 public:
675 explicit DomOperationNotificationObserver(AutomationProvider* automation)
676 : automation_(automation) {
[email protected]1c58a5c2009-05-21 18:47:14677 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
678 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29679 }
680
681 ~DomOperationNotificationObserver() {
initial.commit09911bf2008-07-26 23:55:29682 }
683
[email protected]1c58a5c2009-05-21 18:47:14684 virtual void Observe(NotificationType type,
685 const NotificationSource& source,
686 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:56687 if (NotificationType::DOM_OPERATION_RESPONSE == type) {
initial.commit09911bf2008-07-26 23:55:29688 Details<DomOperationNotificationDetails> dom_op_details(details);
[email protected]71f65dd2009-02-11 19:14:56689
690 IPC::Message* reply_message = automation_->reply_message_release();
691 DCHECK(reply_message != NULL);
692
[email protected]1c58a5c2009-05-21 18:47:14693 AutomationMsg_DomOperation::WriteReplyParams(reply_message,
694 dom_op_details->json());
[email protected]71f65dd2009-02-11 19:14:56695 automation_->Send(reply_message);
initial.commit09911bf2008-07-26 23:55:29696 }
697 }
[email protected]1c58a5c2009-05-21 18:47:14698
initial.commit09911bf2008-07-26 23:55:29699 private:
[email protected]1c58a5c2009-05-21 18:47:14700 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29701 AutomationProvider* automation_;
702};
703
[email protected]de246f52009-02-25 18:25:45704#if defined(OS_WIN)
705// TODO(port): Enable when printing is ported.
initial.commit09911bf2008-07-26 23:55:29706class DocumentPrintedNotificationObserver : public NotificationObserver {
707 public:
708 DocumentPrintedNotificationObserver(AutomationProvider* automation,
[email protected]71f65dd2009-02-11 19:14:56709 IPC::Message* reply_message)
initial.commit09911bf2008-07-26 23:55:29710 : automation_(automation),
[email protected]71f65dd2009-02-11 19:14:56711 success_(false),
712 reply_message_(reply_message) {
[email protected]1c58a5c2009-05-21 18:47:14713 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
714 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29715 }
716
717 ~DocumentPrintedNotificationObserver() {
[email protected]71f65dd2009-02-11 19:14:56718 DCHECK(reply_message_ != NULL);
719 AutomationMsg_PrintNow::WriteReplyParams(reply_message_, success_);
720 automation_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:29721 automation_->RemoveNavigationStatusListener(this);
initial.commit09911bf2008-07-26 23:55:29722 }
723
724 virtual void Observe(NotificationType type, const NotificationSource& source,
725 const NotificationDetails& details) {
726 using namespace printing;
[email protected]bfd04a62009-02-01 18:16:56727 DCHECK(type == NotificationType::PRINT_JOB_EVENT);
initial.commit09911bf2008-07-26 23:55:29728 switch (Details<JobEventDetails>(details)->type()) {
729 case JobEventDetails::JOB_DONE: {
730 // Succeeded.
731 success_ = true;
732 delete this;
733 break;
734 }
735 case JobEventDetails::USER_INIT_CANCELED:
736 case JobEventDetails::FAILED: {
737 // Failed.
738 delete this;
739 break;
740 }
741 case JobEventDetails::NEW_DOC:
742 case JobEventDetails::USER_INIT_DONE:
743 case JobEventDetails::DEFAULT_INIT_DONE:
744 case JobEventDetails::NEW_PAGE:
745 case JobEventDetails::PAGE_DONE:
746 case JobEventDetails::DOC_DONE:
747 case JobEventDetails::ALL_PAGES_REQUESTED: {
748 // Don't care.
749 break;
750 }
751 default: {
752 NOTREACHED();
753 break;
754 }
755 }
756 }
757
758 private:
[email protected]1c58a5c2009-05-21 18:47:14759 NotificationRegistrar registrar_;
initial.commit09911bf2008-07-26 23:55:29760 scoped_refptr<AutomationProvider> automation_;
initial.commit09911bf2008-07-26 23:55:29761 bool success_;
[email protected]71f65dd2009-02-11 19:14:56762 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:29763};
[email protected]de246f52009-02-25 18:25:45764#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29765
[email protected]cbab76d2008-10-13 22:42:47766class AutomationInterstitialPage : public InterstitialPage {
767 public:
[email protected]57c6a652009-05-04 07:58:34768 AutomationInterstitialPage(TabContents* tab,
[email protected]cbab76d2008-10-13 22:42:47769 const GURL& url,
770 const std::string& contents)
771 : InterstitialPage(tab, true, url),
772 contents_(contents) {
773 }
774
775 virtual std::string GetHTMLContents() { return contents_; }
776
777 private:
778 std::string contents_;
[email protected]4f3dc372009-02-24 00:10:29779
[email protected]cbab76d2008-10-13 22:42:47780 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
781};
782
initial.commit09911bf2008-07-26 23:55:29783AutomationProvider::AutomationProvider(Profile* profile)
[email protected]295039bd2008-08-15 04:32:57784 : redirect_query_(0),
[email protected]71f65dd2009-02-11 19:14:56785 profile_(profile),
786 reply_message_(NULL) {
initial.commit09911bf2008-07-26 23:55:29787 browser_tracker_.reset(new AutomationBrowserTracker(this));
initial.commit09911bf2008-07-26 23:55:29788 tab_tracker_.reset(new AutomationTabTracker(this));
[email protected]0e9f4ee2009-04-08 01:44:20789 window_tracker_.reset(new AutomationWindowTracker(this));
initial.commit09911bf2008-07-26 23:55:29790 autocomplete_edit_tracker_.reset(
791 new AutomationAutocompleteEditTracker(this));
initial.commit09911bf2008-07-26 23:55:29792 new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
793 dom_operation_observer_.reset(new DomOperationNotificationObserver(this));
initial.commit09911bf2008-07-26 23:55:29794}
795
796AutomationProvider::~AutomationProvider() {
[email protected]f44265b2009-05-19 18:52:50797 STLDeleteContainerPairSecondPointers(port_containers_.begin(),
798 port_containers_.end());
799 port_containers_.clear();
800
[email protected]0da050b92008-08-19 19:29:47801 // Make sure that any outstanding NotificationObservers also get destroyed.
802 ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
[email protected]5a52f162008-08-27 04:15:31803 NotificationObserver* observer;
[email protected]0da050b92008-08-19 19:29:47804 while ((observer = it.GetNext()) != NULL)
805 delete observer;
initial.commit09911bf2008-07-26 23:55:29806}
807
[email protected]9a3a293b2009-06-04 22:28:16808void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
[email protected]2e4633c2009-07-09 16:58:06809 automation_resource_message_filter_ = new AutomationResourceMessageFilter;
[email protected]295039bd2008-08-15 04:32:57810 channel_.reset(
[email protected]2e4633c2009-07-09 16:58:06811 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
812 automation_resource_message_filter_,
813 g_browser_process->io_thread()->message_loop(),
814 true, g_browser_process->shutdown_event()));
[email protected]79e966832009-04-21 14:23:05815 scoped_ptr<FileVersionInfo> file_version_info(
816 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
[email protected]cf620752009-04-24 17:05:40817 std::string version_string;
818 if (file_version_info != NULL) {
819 version_string = WideToASCII(file_version_info->file_version());
820 }
[email protected]c6cb1992009-04-13 16:45:29821
822 // Send a hello message with our current automation protocol version.
823 channel_->Send(new AutomationMsg_Hello(0, version_string.c_str()));
initial.commit09911bf2008-07-26 23:55:29824}
825
826void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
827 if (expected_tabs == 0) {
828 Send(new AutomationMsg_InitialLoadsComplete(0));
829 } else {
830 initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
831 }
832}
833
[email protected]71f65dd2009-02-11 19:14:56834template<class NavigationCodeType>
initial.commit09911bf2008-07-26 23:55:29835NotificationObserver* AutomationProvider::AddNavigationStatusListener(
[email protected]71f65dd2009-02-11 19:14:56836 NavigationController* tab, IPC::Message* reply_message,
837 NavigationCodeType success_code,
838 NavigationCodeType auth_needed_code,
839 NavigationCodeType failed_code) {
initial.commit09911bf2008-07-26 23:55:29840 NotificationObserver* observer =
[email protected]71f65dd2009-02-11 19:14:56841 new NavigationNotificationObserver<NavigationCodeType>(
842 tab, this, reply_message, success_code, auth_needed_code,
843 failed_code);
initial.commit09911bf2008-07-26 23:55:29844
[email protected]71f65dd2009-02-11 19:14:56845 notification_observer_list_.AddObserver(observer);
initial.commit09911bf2008-07-26 23:55:29846 return observer;
847}
848
849void AutomationProvider::RemoveNavigationStatusListener(
850 NotificationObserver* obs) {
851 notification_observer_list_.RemoveObserver(obs);
852}
853
854NotificationObserver* AutomationProvider::AddTabStripObserver(
[email protected]1c58a5c2009-05-21 18:47:14855 Browser* parent,
856 IPC::Message* reply_message) {
[email protected]71f65dd2009-02-11 19:14:56857 NotificationObserver* observer =
[email protected]1c58a5c2009-05-21 18:47:14858 new TabAppendedNotificationObserver(parent, this, reply_message);
initial.commit09911bf2008-07-26 23:55:29859 notification_observer_list_.AddObserver(observer);
860
861 return observer;
862}
863
864void AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
865 notification_observer_list_.RemoveObserver(obs);
866}
867
868void AutomationProvider::AddLoginHandler(NavigationController* tab,
869 LoginHandler* handler) {
870 login_handler_map_[tab] = handler;
871}
872
873void AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
874 DCHECK(login_handler_map_[tab]);
875 login_handler_map_.erase(tab);
876}
877
[email protected]f44265b2009-05-19 18:52:50878void AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
879 int port_id = port->port_id();
880 DCHECK_NE(-1, port_id);
881 DCHECK(port_containers_.find(port_id) == port_containers_.end());
882
883 port_containers_[port_id] = port;
884}
885
886void AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
887 int port_id = port->port_id();
888 DCHECK_NE(-1, port_id);
889
890 PortContainerMap::iterator it = port_containers_.find(port_id);
891 DCHECK(it != port_containers_.end());
892
893 if (it != port_containers_.end()) {
894 delete it->second;
895 port_containers_.erase(it);
896 }
897}
898
899ExtensionPortContainer* AutomationProvider::GetPortContainer(
900 int port_id) const {
901 PortContainerMap::const_iterator it = port_containers_.find(port_id);
902 if (it == port_containers_.end())
903 return NULL;
904
905 return it->second;
906}
907
initial.commit09911bf2008-07-26 23:55:29908int AutomationProvider::GetIndexForNavigationController(
909 const NavigationController* controller, const Browser* parent) const {
910 DCHECK(parent);
[email protected]902cdf772009-05-06 15:08:12911 return parent->GetIndexOfController(controller);
initial.commit09911bf2008-07-26 23:55:29912}
913
914void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
915 IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
[email protected]1c58a5c2009-05-21 18:47:14916 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
[email protected]71f65dd2009-02-11 19:14:56917 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
918 CloseBrowserAsync)
919 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
920 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
921 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
922 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
923 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
924 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
[email protected]1c58a5c2009-05-21 18:47:14925 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_NavigateToURL, NavigateToURL)
[email protected]71f65dd2009-02-11 19:14:56926 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
927 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoBack, GoBack)
928 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_GoForward, GoForward)
929 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
930 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
[email protected]1c58a5c2009-05-21 18:47:14931 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
[email protected]71f65dd2009-02-11 19:14:56932 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
933 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
934 GetRedirectsFrom)
[email protected]1c58a5c2009-05-21 18:47:14935 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
[email protected]24497032009-05-01 17:00:29936 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
937 GetNormalBrowserWindowCount)
[email protected]71f65dd2009-02-11 19:14:56938 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
[email protected]202e7a72009-06-15 03:48:36939 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
[email protected]71f65dd2009-02-11 19:14:56940 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
initial.commit09911bf2008-07-26 23:55:29941 GetLastActiveBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56942 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
[email protected]24497032009-05-01 17:00:29943 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
944 FindNormalBrowserWindow)
[email protected]71f65dd2009-02-11 19:14:56945 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
[email protected]1c58a5c2009-05-21 18:47:14946 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
[email protected]de246f52009-02-25 18:25:45947#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56948 IPC_MESSAGE_HANDLER(AutomationMsg_WindowHWND, GetWindowHWND)
[email protected]de246f52009-02-25 18:25:45949#endif // defined(OS_WIN)
[email protected]49a14a82009-03-31 04:16:44950 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
[email protected]4f6381ee2009-04-16 02:46:33951 ExecuteBrowserCommandAsync)
[email protected]49a14a82009-03-31 04:16:44952 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
[email protected]4f6381ee2009-04-16 02:46:33953 ExecuteBrowserCommand)
[email protected]1c58a5c2009-05-21 18:47:14954 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
[email protected]8f04ff92009-07-08 02:37:15955 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
[email protected]1c58a5c2009-05-21 18:47:14956 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
[email protected]de246f52009-02-25 18:25:45957#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56958 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
[email protected]1c58a5c2009-05-21 18:47:14959 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
[email protected]71f65dd2009-02-11 19:14:56960 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
961 WindowSimulateDrag)
[email protected]d7fa7552009-03-20 21:06:37962#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56963 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
964 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
[email protected]d7fa7552009-03-20 21:06:37965#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56966 IPC_MESSAGE_HANDLER(AutomationMsg_TabHWND, GetTabHWND)
[email protected]de246f52009-02-25 18:25:45967#endif // defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:56968 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
969 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
[email protected]77bc6732009-04-20 22:01:03970 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
[email protected]71f65dd2009-02-11 19:14:56971 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
[email protected]1c58a5c2009-05-21 18:47:14972 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
initial.commit09911bf2008-07-26 23:55:29973 IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
[email protected]1c58a5c2009-05-21 18:47:14974 IPC_MESSAGE_HANDLER(AutomationMsg_ApplyAccelerator, ApplyAccelerator)
[email protected]71f65dd2009-02-11 19:14:56975 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
976 ExecuteJavascript)
977 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
initial.commit09911bf2008-07-26 23:55:29978 GetConstrainedWindowCount)
[email protected]1c58a5c2009-05-21 18:47:14979 IPC_MESSAGE_HANDLER(AutomationMsg_FindInPage, HandleFindInPageRequest)
980 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
[email protected]71f65dd2009-02-11 19:14:56981 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
982 HandleInspectElementRequest)
[email protected]1c58a5c2009-05-21 18:47:14983 IPC_MESSAGE_HANDLER(AutomationMsg_SetFilteredInet, SetFilteredInet)
984 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
[email protected]a7eee32f2009-05-22 18:08:17985 IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
[email protected]14c0a032009-04-13 18:15:14986 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindow,
[email protected]1c58a5c2009-05-21 18:47:14987 OpenNewBrowserWindow)
988 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
[email protected]71f65dd2009-02-11 19:14:56989 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
[email protected]1c58a5c2009-05-21 18:47:14990 GetAutocompleteEditForBrowser)
991 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
[email protected]de246f52009-02-25 18:25:45992#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29993 IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
[email protected]d2cc6ed2009-04-24 00:26:17994#endif
[email protected]71f65dd2009-02-11 19:14:56995 IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
initial.commit09911bf2008-07-26 23:55:29996 NavigateInExternalTab)
[email protected]71f65dd2009-02-11 19:14:56997 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:14998 ShowInterstitialPage)
[email protected]71f65dd2009-02-11 19:14:56999 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
[email protected]1c58a5c2009-05-21 18:47:141000 HideInterstitialPage)
[email protected]d2cc6ed2009-04-24 00:26:171001#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291002 IPC_MESSAGE_HANDLER(AutomationMsg_SetAcceleratorsForTab,
1003 SetAcceleratorsForTab)
1004 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
1005 ProcessUnhandledAccelerator)
[email protected]d2cc6ed2009-04-24 00:26:171006#endif
[email protected]71f65dd2009-02-11 19:14:561007 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
1008 WaitForTabToBeRestored)
[email protected]1c58a5c2009-05-21 18:47:141009 IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
[email protected]d2cc6ed2009-04-24 00:26:171010#if defined(OS_WIN)
[email protected]87eab222009-03-13 00:47:451011 IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
[email protected]e943d6662009-06-12 03:50:391012 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
1013 OnForwardContextMenuCommandToChrome)
[email protected]d2cc6ed2009-04-24 00:26:171014#endif
[email protected]1c58a5c2009-05-21 18:47:141015 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
1016 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
[email protected]71f65dd2009-02-11 19:14:561017 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
1018 ActionOnSSLBlockingPage)
initial.commit09911bf2008-07-26 23:55:291019 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
1020 IPC_MESSAGE_HANDLER(AutomationMsg_IsPageMenuCommandEnabled,
1021 IsPageMenuCommandEnabled)
[email protected]71f65dd2009-02-11 19:14:561022 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
1023 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
1024 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
initial.commit09911bf2008-07-26 23:55:291025 GetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561026 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
initial.commit09911bf2008-07-26 23:55:291027 SetAutocompleteEditText)
[email protected]71f65dd2009-02-11 19:14:561028 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
initial.commit09911bf2008-07-26 23:55:291029 AutocompleteEditIsQueryInProgress)
[email protected]71f65dd2009-02-11 19:14:561030 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
initial.commit09911bf2008-07-26 23:55:291031 AutocompleteEditGetMatches)
[email protected]71f65dd2009-02-11 19:14:561032 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
[email protected]5f8af2a2008-08-06 22:49:451033 HandleOpenFindInPageRequest)
[email protected]18cb2572008-08-21 20:34:451034 IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
1035 OnMessageFromExternalHost)
[email protected]1c58a5c2009-05-21 18:47:141036 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
[email protected]71f65dd2009-02-11 19:14:561037 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
[email protected]20e93d12008-08-28 16:31:571038 GetFindWindowVisibility)
[email protected]71f65dd2009-02-11 19:14:561039 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
[email protected]20e93d12008-08-28 16:31:571040 HandleFindWindowLocationRequest)
[email protected]71f65dd2009-02-11 19:14:561041 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
1042 GetBookmarkBarVisibility)
[email protected]1c58a5c2009-05-21 18:47:141043 IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCount, GetSSLInfoBarCount)
[email protected]71f65dd2009-02-11 19:14:561044 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickSSLInfoBarLink,
1045 ClickSSLInfoBarLink)
1046 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
[email protected]8a3422c92008-09-24 17:42:421047 GetLastNavigationTime)
[email protected]71f65dd2009-02-11 19:14:561048 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
1049 WaitForNavigation)
[email protected]1c58a5c2009-05-21 18:47:141050 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
[email protected]71f65dd2009-02-11 19:14:561051 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
[email protected]c274acc2008-11-11 20:13:441052 GetShowingAppModalDialog)
[email protected]71f65dd2009-02-11 19:14:561053 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
[email protected]fad84eab2008-12-05 00:37:201054 ClickAppModalDialogButton)
[email protected]1c58a5c2009-05-21 18:47:141055 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
[email protected]71f65dd2009-02-11 19:14:561056 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161057 GetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561058 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
[email protected]97fa6ce32008-12-19 01:48:161059 SetBooleanPreference)
[email protected]71f65dd2009-02-11 19:14:561060 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
[email protected]97fa6ce32008-12-19 01:48:161061 GetPageCurrentEncoding)
[email protected]1c58a5c2009-05-21 18:47:141062 IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
[email protected]5bcdb312009-01-07 21:43:201063 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
1064 SavePackageShouldPromptUser)
[email protected]1c58a5c2009-05-21 18:47:141065 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
[email protected]b83e4602009-05-15 22:58:331066 IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
1067 SetEnableExtensionAutomation)
[email protected]59560e0b2009-06-04 03:30:221068 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
[email protected]66ba4932009-06-04 19:22:131069 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
initial.commit09911bf2008-07-26 23:55:291070 IPC_END_MESSAGE_MAP()
1071}
1072
[email protected]71f65dd2009-02-11 19:14:561073void AutomationProvider::ActivateTab(int handle, int at_index, int* status) {
1074 *status = -1;
initial.commit09911bf2008-07-26 23:55:291075 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
1076 Browser* browser = browser_tracker_->GetResource(handle);
1077 if (at_index >= 0 && at_index < browser->tab_count()) {
1078 browser->SelectTabContentsAt(at_index, true);
[email protected]71f65dd2009-02-11 19:14:561079 *status = 0;
initial.commit09911bf2008-07-26 23:55:291080 }
1081 }
initial.commit09911bf2008-07-26 23:55:291082}
1083
[email protected]71f65dd2009-02-11 19:14:561084void AutomationProvider::AppendTab(int handle, const GURL& url,
1085 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291086 int append_tab_response = -1; // -1 is the error code
1087 NotificationObserver* observer = NULL;
1088
1089 if (browser_tracker_->ContainsHandle(handle)) {
1090 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1c58a5c2009-05-21 18:47:141091 observer = AddTabStripObserver(browser, reply_message);
[email protected]22735af62009-04-07 21:09:581092 TabContents* tab_contents = browser->AddTabWithURL(url, GURL(),
1093 PageTransition::TYPED,
[email protected]5a4940be2009-05-06 06:44:391094 true, -1, false, NULL);
initial.commit09911bf2008-07-26 23:55:291095 if (tab_contents) {
1096 append_tab_response =
[email protected]ce3fa3c2009-04-20 19:55:571097 GetIndexForNavigationController(&tab_contents->controller(), browser);
initial.commit09911bf2008-07-26 23:55:291098 }
1099 }
1100
1101 if (append_tab_response < 0) {
1102 // The append tab failed. Remove the TabStripObserver
1103 if (observer) {
1104 RemoveTabStripObserver(observer);
1105 delete observer;
1106 }
1107
[email protected]71f65dd2009-02-11 19:14:561108 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
1109 append_tab_response);
1110 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291111 }
1112}
1113
[email protected]71f65dd2009-02-11 19:14:561114void AutomationProvider::NavigateToURL(int handle, const GURL& url,
1115 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291116 if (tab_tracker_->ContainsHandle(handle)) {
1117 NavigationController* tab = tab_tracker_->GetResource(handle);
1118
1119 // Simulate what a user would do. Activate the tab and then navigate.
1120 // We could allow navigating in a background tab in future.
1121 Browser* browser = FindAndActivateTab(tab);
1122
1123 if (browser) {
[email protected]71f65dd2009-02-11 19:14:561124 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1125 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1126 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1127 AUTOMATION_MSG_NAVIGATION_ERROR);
1128
initial.commit09911bf2008-07-26 23:55:291129 // TODO(darin): avoid conversion to GURL
[email protected]c0588052008-10-27 23:01:501130 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
initial.commit09911bf2008-07-26 23:55:291131 return;
1132 }
1133 }
[email protected]71f65dd2009-02-11 19:14:561134
1135 AutomationMsg_NavigateToURL::WriteReplyParams(
1136 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1137 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291138}
1139
[email protected]71f65dd2009-02-11 19:14:561140void AutomationProvider::NavigationAsync(int handle, const GURL& url,
1141 bool* status) {
1142 *status = false;
initial.commit09911bf2008-07-26 23:55:291143
1144 if (tab_tracker_->ContainsHandle(handle)) {
1145 NavigationController* tab = tab_tracker_->GetResource(handle);
1146
1147 // Simulate what a user would do. Activate the tab and then navigate.
1148 // We could allow navigating in a background tab in future.
1149 Browser* browser = FindAndActivateTab(tab);
1150
1151 if (browser) {
1152 // Don't add any listener unless a callback mechanism is desired.
1153 // TODO(vibhor): Do this if such a requirement arises in future.
[email protected]c0588052008-10-27 23:01:501154 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:561155 *status = true;
initial.commit09911bf2008-07-26 23:55:291156 }
1157 }
initial.commit09911bf2008-07-26 23:55:291158}
1159
[email protected]71f65dd2009-02-11 19:14:561160void AutomationProvider::GoBack(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291161 if (tab_tracker_->ContainsHandle(handle)) {
1162 NavigationController* tab = tab_tracker_->GetResource(handle);
1163 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141164 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
[email protected]71f65dd2009-02-11 19:14:561165 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1166 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1167 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1168 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291169 browser->GoBack(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291170 return;
1171 }
1172 }
[email protected]71f65dd2009-02-11 19:14:561173
1174 AutomationMsg_GoBack::WriteReplyParams(
1175 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1176 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291177}
1178
[email protected]71f65dd2009-02-11 19:14:561179void AutomationProvider::GoForward(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291180 if (tab_tracker_->ContainsHandle(handle)) {
1181 NavigationController* tab = tab_tracker_->GetResource(handle);
1182 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141183 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
[email protected]71f65dd2009-02-11 19:14:561184 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1185 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1186 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1187 AUTOMATION_MSG_NAVIGATION_ERROR);
[email protected]485fba42009-03-24 23:27:291188 browser->GoForward(CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:291189 return;
1190 }
1191 }
[email protected]71f65dd2009-02-11 19:14:561192
1193 AutomationMsg_GoForward::WriteReplyParams(
1194 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1195 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291196}
1197
[email protected]71f65dd2009-02-11 19:14:561198void AutomationProvider::Reload(int handle, IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291199 if (tab_tracker_->ContainsHandle(handle)) {
1200 NavigationController* tab = tab_tracker_->GetResource(handle);
1201 Browser* browser = FindAndActivateTab(tab);
[email protected]1fc025202009-01-20 23:03:141202 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
[email protected]71f65dd2009-02-11 19:14:561203 AddNavigationStatusListener<AutomationMsg_NavigationResponseValues>(
1204 tab, reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS,
1205 AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
1206 AUTOMATION_MSG_NAVIGATION_ERROR);
initial.commit09911bf2008-07-26 23:55:291207 browser->Reload();
1208 return;
1209 }
1210 }
[email protected]71f65dd2009-02-11 19:14:561211
1212 AutomationMsg_Reload::WriteReplyParams(
1213 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1214 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291215}
1216
[email protected]71f65dd2009-02-11 19:14:561217void AutomationProvider::SetAuth(int tab_handle,
initial.commit09911bf2008-07-26 23:55:291218 const std::wstring& username,
[email protected]71f65dd2009-02-11 19:14:561219 const std::wstring& password,
1220 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291221 int status = -1;
1222
1223 if (tab_tracker_->ContainsHandle(tab_handle)) {
1224 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1225 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1226
1227 if (iter != login_handler_map_.end()) {
1228 // If auth is needed again after this, assume login has failed. This is
1229 // not strictly correct, because a navigation can require both proxy and
1230 // server auth, but it should be OK for now.
1231 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561232 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291233 handler->SetAuth(username, password);
1234 status = 0;
1235 }
1236 }
[email protected]de246f52009-02-25 18:25:451237
initial.commit09911bf2008-07-26 23:55:291238 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561239 AutomationMsg_SetAuth::WriteReplyParams(reply_message, status);
1240 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291241 }
1242}
1243
[email protected]71f65dd2009-02-11 19:14:561244void AutomationProvider::CancelAuth(int tab_handle,
1245 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291246 int status = -1;
1247
1248 if (tab_tracker_->ContainsHandle(tab_handle)) {
1249 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1250 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1251
1252 if (iter != login_handler_map_.end()) {
1253 // If auth is needed again after this, something is screwy.
1254 LoginHandler* handler = iter->second;
[email protected]71f65dd2009-02-11 19:14:561255 AddNavigationStatusListener<int>(tab, reply_message, 0, -1, -1);
initial.commit09911bf2008-07-26 23:55:291256 handler->CancelAuth();
1257 status = 0;
1258 }
1259 }
[email protected]de246f52009-02-25 18:25:451260
initial.commit09911bf2008-07-26 23:55:291261 if (status < 0) {
[email protected]71f65dd2009-02-11 19:14:561262 AutomationMsg_CancelAuth::WriteReplyParams(reply_message, status);
1263 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291264 }
1265}
1266
[email protected]71f65dd2009-02-11 19:14:561267void AutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
1268 *needs_auth = false;
initial.commit09911bf2008-07-26 23:55:291269
1270 if (tab_tracker_->ContainsHandle(tab_handle)) {
1271 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1272 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
1273
1274 if (iter != login_handler_map_.end()) {
1275 // The LoginHandler will be in our map IFF the tab needs auth.
[email protected]71f65dd2009-02-11 19:14:561276 *needs_auth = true;
initial.commit09911bf2008-07-26 23:55:291277 }
1278 }
initial.commit09911bf2008-07-26 23:55:291279}
1280
[email protected]71f65dd2009-02-11 19:14:561281void AutomationProvider::GetRedirectsFrom(int tab_handle,
1282 const GURL& source_url,
1283 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291284 DCHECK(!redirect_query_) << "Can only handle one redirect query at once.";
1285 if (tab_tracker_->ContainsHandle(tab_handle)) {
1286 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1287 HistoryService* history_service =
1288 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
1289
1290 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
1291 "has no history service";
1292 if (history_service) {
[email protected]71f65dd2009-02-11 19:14:561293 DCHECK(reply_message_ == NULL);
1294 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291295 // Schedule a history query for redirects. The response will be sent
1296 // asynchronously from the callback the history system uses to notify us
1297 // that it's done: OnRedirectQueryComplete.
initial.commit09911bf2008-07-26 23:55:291298 redirect_query_ = history_service->QueryRedirectsFrom(
1299 source_url, &consumer_,
1300 NewCallback(this, &AutomationProvider::OnRedirectQueryComplete));
1301 return; // Response will be sent when query completes.
1302 }
1303 }
1304
1305 // Send failure response.
[email protected]deb57402009-02-06 01:35:301306 std::vector<GURL> empty;
[email protected]71f65dd2009-02-11 19:14:561307 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
1308 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291309}
1310
[email protected]71f65dd2009-02-11 19:14:561311void AutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) {
1312 *active_tab_index = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291313 if (browser_tracker_->ContainsHandle(handle)) {
1314 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561315 *active_tab_index = browser->selected_index();
initial.commit09911bf2008-07-26 23:55:291316 }
initial.commit09911bf2008-07-26 23:55:291317}
1318
[email protected]202e7a72009-06-15 03:48:361319void AutomationProvider::GetBrowserLocale(string16* locale) {
1320 DCHECK(g_browser_process);
[email protected]d70539de2009-06-24 22:17:061321 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
[email protected]202e7a72009-06-15 03:48:361322}
1323
[email protected]71f65dd2009-02-11 19:14:561324void AutomationProvider::GetBrowserWindowCount(int* window_count) {
1325 *window_count = static_cast<int>(BrowserList::size());
initial.commit09911bf2008-07-26 23:55:291326}
1327
[email protected]24497032009-05-01 17:00:291328void AutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
1329 *window_count = static_cast<int>(
1330 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
1331}
1332
[email protected]71f65dd2009-02-11 19:14:561333void AutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1334 int* dialog_button) {
[email protected]1f460072009-05-28 17:02:071335 AppModalDialog* dialog_delegate =
1336 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501337 *showing_dialog = (dialog_delegate != NULL);
1338 if (*showing_dialog)
1339 *dialog_button = dialog_delegate->GetDialogButtons();
1340 else
[email protected]478ff2ed2009-04-21 23:49:181341 *dialog_button = MessageBoxFlags::DIALOGBUTTON_NONE;
[email protected]fad84eab2008-12-05 00:37:201342}
1343
[email protected]71f65dd2009-02-11 19:14:561344void AutomationProvider::ClickAppModalDialogButton(int button, bool* success) {
1345 *success = false;
[email protected]fad84eab2008-12-05 00:37:201346
[email protected]1f460072009-05-28 17:02:071347 AppModalDialog* dialog_delegate =
1348 Singleton<AppModalDialogQueue>()->active_dialog();
[email protected]b3a70332009-02-25 02:40:501349 if (dialog_delegate &&
1350 (dialog_delegate->GetDialogButtons() & button) == button) {
[email protected]478ff2ed2009-04-21 23:49:181351 if ((button & MessageBoxFlags::DIALOGBUTTON_OK) ==
1352 MessageBoxFlags::DIALOGBUTTON_OK) {
[email protected]0bfa713f2009-04-07 20:18:281353 dialog_delegate->AcceptWindow();
[email protected]71f65dd2009-02-11 19:14:561354 *success = true;
[email protected]fad84eab2008-12-05 00:37:201355 }
[email protected]478ff2ed2009-04-21 23:49:181356 if ((button & MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
1357 MessageBoxFlags::DIALOGBUTTON_CANCEL) {
[email protected]71f65dd2009-02-11 19:14:561358 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
[email protected]0bfa713f2009-04-07 20:18:281359 dialog_delegate->CancelWindow();
[email protected]71f65dd2009-02-11 19:14:561360 *success = true;
[email protected]fad84eab2008-12-05 00:37:201361 }
1362 }
[email protected]c274acc2008-11-11 20:13:441363}
1364
[email protected]71f65dd2009-02-11 19:14:561365void AutomationProvider::GetBrowserWindow(int index, int* handle) {
1366 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291367 if (index >= 0) {
1368 BrowserList::const_iterator iter = BrowserList::begin();
[email protected]24497032009-05-01 17:00:291369 for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index);
initial.commit09911bf2008-07-26 23:55:291370 if (iter != BrowserList::end()) {
[email protected]71f65dd2009-02-11 19:14:561371 *handle = browser_tracker_->Add(*iter);
initial.commit09911bf2008-07-26 23:55:291372 }
1373 }
initial.commit09911bf2008-07-26 23:55:291374}
1375
[email protected]24497032009-05-01 17:00:291376void AutomationProvider::FindNormalBrowserWindow(int* handle) {
1377 *handle = 0;
1378 Browser* browser = BrowserList::FindBrowserWithType(profile_,
1379 Browser::TYPE_NORMAL);
1380 if (browser)
1381 *handle = browser_tracker_->Add(browser);
1382}
1383
[email protected]71f65dd2009-02-11 19:14:561384void AutomationProvider::GetLastActiveBrowserWindow(int* handle) {
1385 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291386 Browser* browser = BrowserList::GetLastActive();
1387 if (browser)
[email protected]71f65dd2009-02-11 19:14:561388 *handle = browser_tracker_->Add(browser);
initial.commit09911bf2008-07-26 23:55:291389}
1390
[email protected]de246f52009-02-25 18:25:451391#if defined(OS_WIN)
1392// TODO(port): Remove windowsisms.
initial.commit09911bf2008-07-26 23:55:291393BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM l_param) {
1394 if (hwnd == reinterpret_cast<HWND>(l_param)) {
1395 return FALSE;
1396 }
1397 return TRUE;
1398}
1399
[email protected]71f65dd2009-02-11 19:14:561400void AutomationProvider::GetActiveWindow(int* handle) {
initial.commit09911bf2008-07-26 23:55:291401 HWND window = GetForegroundWindow();
1402
1403 // Let's make sure this window belongs to our process.
1404 if (EnumThreadWindows(::GetCurrentThreadId(),
1405 EnumThreadWndProc,
1406 reinterpret_cast<LPARAM>(window))) {
1407 // We enumerated all the windows and did not find the foreground window,
1408 // it is not our window, ignore it.
[email protected]71f65dd2009-02-11 19:14:561409 *handle = 0;
initial.commit09911bf2008-07-26 23:55:291410 return;
1411 }
1412
[email protected]71f65dd2009-02-11 19:14:561413 *handle = window_tracker_->Add(window);
initial.commit09911bf2008-07-26 23:55:291414}
1415
[email protected]71f65dd2009-02-11 19:14:561416void AutomationProvider::GetWindowHWND(int handle, HWND* win32_handle) {
1417 *win32_handle = window_tracker_->GetResource(handle);
initial.commit09911bf2008-07-26 23:55:291418}
[email protected]de246f52009-02-25 18:25:451419#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291420
[email protected]4f6381ee2009-04-16 02:46:331421void AutomationProvider::ExecuteBrowserCommandAsync(int handle, int command,
1422 bool* success) {
[email protected]71f65dd2009-02-11 19:14:561423 *success = false;
[email protected]4ae62752008-08-04 23:28:471424 if (browser_tracker_->ContainsHandle(handle)) {
1425 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]1fc025202009-01-20 23:03:141426 if (browser->command_updater()->SupportsCommand(command) &&
1427 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]4ae62752008-08-04 23:28:471428 browser->ExecuteCommand(command);
[email protected]71f65dd2009-02-11 19:14:561429 *success = true;
[email protected]4ae62752008-08-04 23:28:471430 }
1431 }
[email protected]4ae62752008-08-04 23:28:471432}
1433
[email protected]4f6381ee2009-04-16 02:46:331434void AutomationProvider::ExecuteBrowserCommand(
[email protected]56e71b7c2009-03-27 03:05:561435 int handle, int command, IPC::Message* reply_message) {
1436 if (browser_tracker_->ContainsHandle(handle)) {
1437 Browser* browser = browser_tracker_->GetResource(handle);
1438 if (browser->command_updater()->SupportsCommand(command) &&
1439 browser->command_updater()->IsCommandEnabled(command)) {
[email protected]d79ffea2009-05-07 20:51:421440 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
1441 this, browser, command, reply_message)) {
[email protected]4e41709d2009-04-08 00:04:271442 browser->ExecuteCommand(command);
[email protected]d79ffea2009-05-07 20:51:421443 return;
1444 }
[email protected]56e71b7c2009-03-27 03:05:561445 }
1446 }
[email protected]49a14a82009-03-31 04:16:441447 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
[email protected]56e71b7c2009-03-27 03:05:561448 Send(reply_message);
1449}
1450
[email protected]71f65dd2009-02-11 19:14:561451void AutomationProvider::WindowGetViewBounds(int handle, int view_id,
1452 bool screen_coordinates,
1453 bool* success,
1454 gfx::Rect* bounds) {
1455 *success = false;
initial.commit09911bf2008-07-26 23:55:291456
[email protected]de246f52009-02-25 18:25:451457#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291458 void* iter = NULL;
1459 if (window_tracker_->ContainsHandle(handle)) {
1460 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]a0dde122008-11-21 20:51:201461 views::RootView* root_view = views::WidgetWin::FindRootView(hwnd);
initial.commit09911bf2008-07-26 23:55:291462 if (root_view) {
[email protected]c2dacc92008-10-16 23:51:381463 views::View* view = root_view->GetViewByID(view_id);
initial.commit09911bf2008-07-26 23:55:291464 if (view) {
[email protected]71f65dd2009-02-11 19:14:561465 *success = true;
[email protected]96b667d2008-10-14 20:58:441466 gfx::Point point;
initial.commit09911bf2008-07-26 23:55:291467 if (screen_coordinates)
[email protected]c2dacc92008-10-16 23:51:381468 views::View::ConvertPointToScreen(view, &point);
initial.commit09911bf2008-07-26 23:55:291469 else
[email protected]c2dacc92008-10-16 23:51:381470 views::View::ConvertPointToView(view, root_view, &point);
[email protected]71f65dd2009-02-11 19:14:561471 *bounds = view->GetLocalBounds(false);
1472 bounds->set_origin(point);
initial.commit09911bf2008-07-26 23:55:291473 }
1474 }
1475 }
[email protected]de246f52009-02-25 18:25:451476#else
1477 // TODO(port): Enable when window_tracker is ported.
1478 NOTIMPLEMENTED();
1479#endif
initial.commit09911bf2008-07-26 23:55:291480}
1481
[email protected]de246f52009-02-25 18:25:451482#if defined(OS_WIN)
1483// TODO(port): Use portable replacement for POINT.
1484
initial.commit09911bf2008-07-26 23:55:291485// This task enqueues a mouse event on the event loop, so that the view
1486// that it's being sent to can do the requisite post-processing.
1487class MouseEventTask : public Task {
1488 public:
[email protected]c2dacc92008-10-16 23:51:381489 MouseEventTask(views::View* view,
1490 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291491 POINT point,
1492 int flags)
1493 : view_(view), type_(type), point_(point), flags_(flags) {}
1494 virtual ~MouseEventTask() {}
1495
1496 virtual void Run() {
[email protected]c2dacc92008-10-16 23:51:381497 views::MouseEvent event(type_, point_.x, point_.y, flags_);
initial.commit09911bf2008-07-26 23:55:291498 // We need to set the cursor position before we process the event because
1499 // some code (tab dragging, for instance) queries the actual cursor location
1500 // rather than the location of the mouse event. Note that the reason why
1501 // the drag code moved away from using mouse event locations was because
1502 // our conversion to screen location doesn't work well with multiple
1503 // monitors, so this only works reliably in a single monitor setup.
[email protected]96b667d2008-10-14 20:58:441504 gfx::Point screen_location(point_.x, point_.y);
initial.commit09911bf2008-07-26 23:55:291505 view_->ConvertPointToScreen(view_, &screen_location);
[email protected]96b667d2008-10-14 20:58:441506 ::SetCursorPos(screen_location.x(), screen_location.y());
initial.commit09911bf2008-07-26 23:55:291507 switch (type_) {
[email protected]c2dacc92008-10-16 23:51:381508 case views::Event::ET_MOUSE_PRESSED:
initial.commit09911bf2008-07-26 23:55:291509 view_->OnMousePressed(event);
1510 break;
1511
[email protected]c2dacc92008-10-16 23:51:381512 case views::Event::ET_MOUSE_DRAGGED:
initial.commit09911bf2008-07-26 23:55:291513 view_->OnMouseDragged(event);
1514 break;
1515
[email protected]c2dacc92008-10-16 23:51:381516 case views::Event::ET_MOUSE_RELEASED:
initial.commit09911bf2008-07-26 23:55:291517 view_->OnMouseReleased(event, false);
1518 break;
1519
1520 default:
1521 NOTREACHED();
1522 }
1523 }
1524
1525 private:
[email protected]c2dacc92008-10-16 23:51:381526 views::View* view_;
1527 views::Event::EventType type_;
initial.commit09911bf2008-07-26 23:55:291528 POINT point_;
1529 int flags_;
1530
[email protected]5a52f162008-08-27 04:15:311531 DISALLOW_COPY_AND_ASSIGN(MouseEventTask);
initial.commit09911bf2008-07-26 23:55:291532};
1533
[email protected]c2dacc92008-10-16 23:51:381534void AutomationProvider::ScheduleMouseEvent(views::View* view,
1535 views::Event::EventType type,
initial.commit09911bf2008-07-26 23:55:291536 POINT point,
1537 int flags) {
1538 MessageLoop::current()->PostTask(FROM_HERE,
1539 new MouseEventTask(view, type, point, flags));
1540}
[email protected]de246f52009-02-25 18:25:451541#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291542
1543// This task just adds another task to the event queue. This is useful if
1544// you want to ensure that any tasks added to the event queue after this one
1545// have already been processed by the time |task| is run.
1546class InvokeTaskLaterTask : public Task {
1547 public:
1548 explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
1549 virtual ~InvokeTaskLaterTask() {}
1550
1551 virtual void Run() {
1552 MessageLoop::current()->PostTask(FROM_HERE, task_);
1553 }
1554
1555 private:
1556 Task* task_;
1557
[email protected]5a52f162008-08-27 04:15:311558 DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
initial.commit09911bf2008-07-26 23:55:291559};
1560
[email protected]de246f52009-02-25 18:25:451561#if defined(OS_WIN)
1562// TODO(port): Replace POINT and other windowsisms.
1563
initial.commit09911bf2008-07-26 23:55:291564// This task sends a WindowDragResponse message with the appropriate
1565// routing ID to the automation proxy. This is implemented as a task so that
1566// we know that the mouse events (and any tasks that they spawn on the message
1567// loop) have been processed by the time this is sent.
1568class WindowDragResponseTask : public Task {
1569 public:
[email protected]1c58a5c2009-05-21 18:47:141570 WindowDragResponseTask(AutomationProvider* provider,
[email protected]71f65dd2009-02-11 19:14:561571 IPC::Message* reply_message)
[email protected]1c58a5c2009-05-21 18:47:141572 : provider_(provider), reply_message_(reply_message) {}
initial.commit09911bf2008-07-26 23:55:291573 virtual ~WindowDragResponseTask() {}
1574
1575 virtual void Run() {
[email protected]71f65dd2009-02-11 19:14:561576 DCHECK(reply_message_ != NULL);
1577 AutomationMsg_WindowDrag::WriteReplyParams(reply_message_, true);
1578 provider_->Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291579 }
1580
1581 private:
1582 AutomationProvider* provider_;
[email protected]71f65dd2009-02-11 19:14:561583 IPC::Message* reply_message_;
initial.commit09911bf2008-07-26 23:55:291584
[email protected]5a52f162008-08-27 04:15:311585 DISALLOW_COPY_AND_ASSIGN(WindowDragResponseTask);
initial.commit09911bf2008-07-26 23:55:291586};
1587
1588void AutomationProvider::WindowSimulateClick(const IPC::Message& message,
1589 int handle,
1590 POINT click,
1591 int flags) {
1592 HWND hwnd = 0;
1593
1594 if (window_tracker_->ContainsHandle(handle)) {
1595 hwnd = window_tracker_->GetResource(handle);
1596
initial.commit09911bf2008-07-26 23:55:291597 ui_controls::SendMouseMove(click.x, click.y);
1598
1599 ui_controls::MouseButton button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381600 if ((flags & views::Event::EF_LEFT_BUTTON_DOWN) ==
1601 views::Event::EF_LEFT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291602 button = ui_controls::LEFT;
[email protected]c2dacc92008-10-16 23:51:381603 } else if ((flags & views::Event::EF_RIGHT_BUTTON_DOWN) ==
1604 views::Event::EF_RIGHT_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291605 button = ui_controls::RIGHT;
[email protected]c2dacc92008-10-16 23:51:381606 } else if ((flags & views::Event::EF_MIDDLE_BUTTON_DOWN) ==
1607 views::Event::EF_MIDDLE_BUTTON_DOWN) {
initial.commit09911bf2008-07-26 23:55:291608 button = ui_controls::MIDDLE;
1609 } else {
1610 NOTREACHED();
1611 }
1612 ui_controls::SendMouseClick(button);
1613 }
1614}
1615
[email protected]71f65dd2009-02-11 19:14:561616void AutomationProvider::WindowSimulateDrag(int handle,
[email protected]fe92e4e2008-11-18 21:31:321617 std::vector<POINT> drag_path,
[email protected]5e0f30c2008-08-14 22:52:441618 int flags,
[email protected]71f65dd2009-02-11 19:14:561619 bool press_escape_en_route,
1620 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291621 bool succeeded = false;
[email protected]fe92e4e2008-11-18 21:31:321622 if (browser_tracker_->ContainsHandle(handle) && (drag_path.size() > 1)) {
1623 succeeded = true;
1624
1625 UINT down_message = 0;
1626 UINT up_message = 0;
1627 WPARAM wparam_flags = 0;
1628 if (flags & views::Event::EF_SHIFT_DOWN)
1629 wparam_flags |= MK_SHIFT;
1630 if (flags & views::Event::EF_CONTROL_DOWN)
1631 wparam_flags |= MK_CONTROL;
1632 if (flags & views::Event::EF_LEFT_BUTTON_DOWN) {
1633 wparam_flags |= MK_LBUTTON;
1634 down_message = WM_LBUTTONDOWN;
1635 up_message = WM_LBUTTONUP;
1636 }
1637 if (flags & views::Event::EF_MIDDLE_BUTTON_DOWN) {
1638 wparam_flags |= MK_MBUTTON;
1639 down_message = WM_MBUTTONDOWN;
1640 up_message = WM_MBUTTONUP;
1641 }
1642 if (flags & views::Event::EF_RIGHT_BUTTON_DOWN) {
1643 wparam_flags |= MK_RBUTTON;
1644 down_message = WM_LBUTTONDOWN;
1645 up_message = WM_LBUTTONUP;
1646 }
1647
initial.commit09911bf2008-07-26 23:55:291648 Browser* browser = browser_tracker_->GetResource(handle);
1649 DCHECK(browser);
[email protected]0a6fb3f2008-11-18 21:39:551650 HWND top_level_hwnd =
1651 reinterpret_cast<HWND>(browser->window()->GetNativeHandle());
[email protected]fe92e4e2008-11-18 21:31:321652 POINT temp = drag_path[0];
1653 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1654 SetCursorPos(temp.x, temp.y);
1655 SendMessage(top_level_hwnd, down_message, wparam_flags,
1656 MAKELPARAM(drag_path[0].x, drag_path[0].y));
1657 for (int i = 1; i < static_cast<int>(drag_path.size()); ++i) {
1658 temp = drag_path[i];
1659 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &temp, 1);
1660 SetCursorPos(temp.x, temp.y);
1661 SendMessage(top_level_hwnd, WM_MOUSEMOVE, wparam_flags,
1662 MAKELPARAM(drag_path[i].x, drag_path[i].y));
[email protected]f7a391a12008-11-10 21:29:341663 }
[email protected]fe92e4e2008-11-18 21:31:321664 POINT end = drag_path[drag_path.size() - 1];
1665 MapWindowPoints(top_level_hwnd, HWND_DESKTOP, &end, 1);
1666 SetCursorPos(end.x, end.y);
1667
1668 if (press_escape_en_route) {
1669 // Press Escape.
1670 ui_controls::SendKeyPress(VK_ESCAPE,
1671 ((flags & views::Event::EF_CONTROL_DOWN)
1672 == views::Event::EF_CONTROL_DOWN),
1673 ((flags & views::Event::EF_SHIFT_DOWN) ==
1674 views::Event::EF_SHIFT_DOWN),
1675 ((flags & views::Event::EF_ALT_DOWN) ==
1676 views::Event::EF_ALT_DOWN));
1677 }
1678 SendMessage(top_level_hwnd, up_message, wparam_flags,
1679 MAKELPARAM(end.x, end.y));
1680
[email protected]1c58a5c2009-05-21 18:47:141681 MessageLoop::current()->PostTask(FROM_HERE, new InvokeTaskLaterTask(
1682 new WindowDragResponseTask(this, reply_message)));
initial.commit09911bf2008-07-26 23:55:291683 } else {
[email protected]71f65dd2009-02-11 19:14:561684 AutomationMsg_WindowDrag::WriteReplyParams(reply_message, true);
1685 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291686 }
1687}
1688
1689void AutomationProvider::WindowSimulateKeyPress(const IPC::Message& message,
1690 int handle,
1691 wchar_t key,
1692 int flags) {
1693 if (!window_tracker_->ContainsHandle(handle))
1694 return;
1695
1696 // The key event is sent to whatever window is active.
1697 ui_controls::SendKeyPress(key,
[email protected]c2dacc92008-10-16 23:51:381698 ((flags & views::Event::EF_CONTROL_DOWN) ==
1699 views::Event::EF_CONTROL_DOWN),
1700 ((flags & views::Event::EF_SHIFT_DOWN) ==
1701 views::Event::EF_SHIFT_DOWN),
1702 ((flags & views::Event::EF_ALT_DOWN) ==
1703 views::Event::EF_ALT_DOWN));
initial.commit09911bf2008-07-26 23:55:291704}
1705
[email protected]71f65dd2009-02-11 19:14:561706void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
1707 *view_id = -1;
initial.commit09911bf2008-07-26 23:55:291708 if (window_tracker_->ContainsHandle(handle)) {
1709 HWND hwnd = window_tracker_->GetResource(handle);
[email protected]c2dacc92008-10-16 23:51:381710 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:001711 views::FocusManager::GetFocusManagerForNativeView(hwnd);
initial.commit09911bf2008-07-26 23:55:291712 DCHECK(focus_manager);
[email protected]c2dacc92008-10-16 23:51:381713 views::View* focused_view = focus_manager->GetFocusedView();
initial.commit09911bf2008-07-26 23:55:291714 if (focused_view)
[email protected]71f65dd2009-02-11 19:14:561715 *view_id = focused_view->GetID();
initial.commit09911bf2008-07-26 23:55:291716 }
initial.commit09911bf2008-07-26 23:55:291717}
1718
[email protected]8f04ff92009-07-08 02:37:151719void AutomationProvider::SetWindowBounds(int handle, const gfx::Rect& bounds,
1720 bool* success) {
1721 *success = false;
1722 if (window_tracker_->ContainsHandle(handle)) {
1723 HWND hwnd = window_tracker_->GetResource(handle);
1724 if (::MoveWindow(hwnd, bounds.x(), bounds.y(), bounds.width(),
1725 bounds.height(), true)) {
1726 *success = true;
1727 }
1728 }
1729}
1730
[email protected]71f65dd2009-02-11 19:14:561731void AutomationProvider::SetWindowVisible(int handle, bool visible,
1732 bool* result) {
initial.commit09911bf2008-07-26 23:55:291733 if (window_tracker_->ContainsHandle(handle)) {
1734 HWND hwnd = window_tracker_->GetResource(handle);
1735 ::ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
[email protected]71f65dd2009-02-11 19:14:561736 *result = true;
initial.commit09911bf2008-07-26 23:55:291737 } else {
[email protected]71f65dd2009-02-11 19:14:561738 *result = false;
initial.commit09911bf2008-07-26 23:55:291739 }
1740}
[email protected]d2cc6ed2009-04-24 00:26:171741#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291742
[email protected]71f65dd2009-02-11 19:14:561743void AutomationProvider::IsWindowActive(int handle, bool* success,
1744 bool* is_active) {
initial.commit09911bf2008-07-26 23:55:291745 if (window_tracker_->ContainsHandle(handle)) {
[email protected]d2cc6ed2009-04-24 00:26:171746 *is_active =
1747 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
[email protected]71f65dd2009-02-11 19:14:561748 *success = true;
initial.commit09911bf2008-07-26 23:55:291749 } else {
[email protected]71f65dd2009-02-11 19:14:561750 *success = false;
1751 *is_active = false;
initial.commit09911bf2008-07-26 23:55:291752 }
1753}
1754
[email protected]d2cc6ed2009-04-24 00:26:171755// TODO(port): port this.
1756#if defined(OS_WIN)
[email protected]659d0e82009-02-13 22:43:281757void AutomationProvider::ActivateWindow(int handle) {
initial.commit09911bf2008-07-26 23:55:291758 if (window_tracker_->ContainsHandle(handle)) {
1759 ::SetActiveWindow(window_tracker_->GetResource(handle));
1760 }
1761}
[email protected]d2cc6ed2009-04-24 00:26:171762#endif
initial.commit09911bf2008-07-26 23:55:291763
[email protected]71f65dd2009-02-11 19:14:561764void AutomationProvider::GetTabCount(int handle, int* tab_count) {
1765 *tab_count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291766
1767 if (browser_tracker_->ContainsHandle(handle)) {
1768 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561769 *tab_count = browser->tab_count();
initial.commit09911bf2008-07-26 23:55:291770 }
initial.commit09911bf2008-07-26 23:55:291771}
1772
[email protected]71f65dd2009-02-11 19:14:561773void AutomationProvider::GetTab(int win_handle, int tab_index,
1774 int* tab_handle) {
[email protected]71f65dd2009-02-11 19:14:561775 *tab_handle = 0;
initial.commit09911bf2008-07-26 23:55:291776 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1777 Browser* browser = browser_tracker_->GetResource(win_handle);
1778 if (tab_index < browser->tab_count()) {
1779 TabContents* tab_contents =
1780 browser->GetTabContentsAt(tab_index);
[email protected]ce3fa3c2009-04-20 19:55:571781 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
initial.commit09911bf2008-07-26 23:55:291782 }
1783 }
initial.commit09911bf2008-07-26 23:55:291784}
1785
[email protected]71f65dd2009-02-11 19:14:561786void AutomationProvider::GetTabTitle(int handle, int* title_string_size,
1787 std::wstring* title) {
1788 *title_string_size = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291789 if (tab_tracker_->ContainsHandle(handle)) {
1790 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c100dbd2009-04-29 23:44:361791 NavigationEntry* entry = tab->GetActiveEntry();
1792 if (entry != NULL) {
1793 *title = UTF16ToWideHack(entry->title());
1794 } else {
1795 *title = std::wstring();
1796 }
[email protected]71f65dd2009-02-11 19:14:561797 *title_string_size = static_cast<int>(title->size());
initial.commit09911bf2008-07-26 23:55:291798 }
initial.commit09911bf2008-07-26 23:55:291799}
1800
[email protected]77bc6732009-04-20 22:01:031801void AutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1802 *tabstrip_index = -1; // -1 is the error code
1803
1804 if (tab_tracker_->ContainsHandle(handle)) {
1805 NavigationController* tab = tab_tracker_->GetResource(handle);
1806 Browser* browser = Browser::GetBrowserForController(tab, NULL);
[email protected]902cdf772009-05-06 15:08:121807 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
[email protected]77bc6732009-04-20 22:01:031808 }
1809}
1810
initial.commit09911bf2008-07-26 23:55:291811void AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
1812 if (window_tracker_->ContainsHandle(handle)) {
1813 window_tracker_->Remove(window_tracker_->GetResource(handle));
1814 }
1815}
1816
1817void AutomationProvider::OnChannelError() {
1818 LOG(ERROR) << "AutomationProxy went away, shutting down app.";
[email protected]295039bd2008-08-15 04:32:571819 AutomationProviderList::GetInstance()->RemoveProvider(this);
initial.commit09911bf2008-07-26 23:55:291820}
1821
1822// TODO(brettw) change this to accept GURLs when history supports it
1823void AutomationProvider::OnRedirectQueryComplete(
1824 HistoryService::Handle request_handle,
1825 GURL from_url,
1826 bool success,
[email protected]379c2b12009-07-01 21:50:331827 history::RedirectList* redirects) {
initial.commit09911bf2008-07-26 23:55:291828 DCHECK(request_handle == redirect_query_);
[email protected]71f65dd2009-02-11 19:14:561829 DCHECK(reply_message_ != NULL);
initial.commit09911bf2008-07-26 23:55:291830
[email protected]deb57402009-02-06 01:35:301831 std::vector<GURL> redirects_gurl;
initial.commit09911bf2008-07-26 23:55:291832 if (success) {
[email protected]71f65dd2009-02-11 19:14:561833 reply_message_->WriteBool(true);
initial.commit09911bf2008-07-26 23:55:291834 for (size_t i = 0; i < redirects->size(); i++)
[email protected]deb57402009-02-06 01:35:301835 redirects_gurl.push_back(redirects->at(i));
initial.commit09911bf2008-07-26 23:55:291836 } else {
[email protected]71f65dd2009-02-11 19:14:561837 reply_message_->WriteInt(-1); // Negative count indicates failure.
initial.commit09911bf2008-07-26 23:55:291838 }
1839
[email protected]4f3dc372009-02-24 00:10:291840 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
[email protected]deb57402009-02-06 01:35:301841
[email protected]71f65dd2009-02-11 19:14:561842 Send(reply_message_);
initial.commit09911bf2008-07-26 23:55:291843 redirect_query_ = NULL;
[email protected]71f65dd2009-02-11 19:14:561844 reply_message_ = NULL;
initial.commit09911bf2008-07-26 23:55:291845}
1846
1847bool AutomationProvider::Send(IPC::Message* msg) {
[email protected]295039bd2008-08-15 04:32:571848 DCHECK(channel_.get());
1849 return channel_->Send(msg);
initial.commit09911bf2008-07-26 23:55:291850}
1851
1852Browser* AutomationProvider::FindAndActivateTab(
1853 NavigationController* controller) {
1854 int tab_index;
1855 Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
1856 if (browser)
1857 browser->SelectTabContentsAt(tab_index, true);
1858
1859 return browser;
1860}
1861
[email protected]71f65dd2009-02-11 19:14:561862void AutomationProvider::GetCookies(const GURL& url, int handle,
1863 int* value_size,
1864 std::string* value) {
1865 *value_size = -1;
initial.commit09911bf2008-07-26 23:55:291866 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1867 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:561868 *value =
initial.commit09911bf2008-07-26 23:55:291869 tab->profile()->GetRequestContext()->cookie_store()->GetCookies(url);
[email protected]71f65dd2009-02-11 19:14:561870 *value_size = static_cast<int>(value->size());
initial.commit09911bf2008-07-26 23:55:291871 }
initial.commit09911bf2008-07-26 23:55:291872}
1873
[email protected]71f65dd2009-02-11 19:14:561874void AutomationProvider::SetCookie(const GURL& url,
initial.commit09911bf2008-07-26 23:55:291875 const std::string value,
[email protected]71f65dd2009-02-11 19:14:561876 int handle,
1877 int* response_value) {
1878 *response_value = -1;
initial.commit09911bf2008-07-26 23:55:291879
1880 if (url.is_valid() && tab_tracker_->ContainsHandle(handle)) {
1881 NavigationController* tab = tab_tracker_->GetResource(handle);
1882 URLRequestContext* context = tab->profile()->GetRequestContext();
1883 if (context->cookie_store()->SetCookie(url, value))
[email protected]71f65dd2009-02-11 19:14:561884 *response_value = 1;
initial.commit09911bf2008-07-26 23:55:291885 }
initial.commit09911bf2008-07-26 23:55:291886}
1887
[email protected]71f65dd2009-02-11 19:14:561888void AutomationProvider::GetTabURL(int handle, bool* success, GURL* url) {
1889 *success = false;
initial.commit09911bf2008-07-26 23:55:291890 if (tab_tracker_->ContainsHandle(handle)) {
1891 NavigationController* tab = tab_tracker_->GetResource(handle);
1892 // Return what the user would see in the location bar.
[email protected]71f65dd2009-02-11 19:14:561893 *url = tab->GetActiveEntry()->display_url();
1894 *success = true;
initial.commit09911bf2008-07-26 23:55:291895 }
initial.commit09911bf2008-07-26 23:55:291896}
1897
[email protected]de246f52009-02-25 18:25:451898#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:561899void AutomationProvider::GetTabHWND(int handle, HWND* tab_hwnd) {
1900 *tab_hwnd = NULL;
initial.commit09911bf2008-07-26 23:55:291901
1902 if (tab_tracker_->ContainsHandle(handle)) {
1903 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111904 *tab_hwnd = tab->tab_contents()->GetNativeView();
initial.commit09911bf2008-07-26 23:55:291905 }
initial.commit09911bf2008-07-26 23:55:291906}
[email protected]de246f52009-02-25 18:25:451907#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291908
[email protected]71f65dd2009-02-11 19:14:561909void AutomationProvider::GetTabProcessID(int handle, int* process_id) {
1910 *process_id = -1;
initial.commit09911bf2008-07-26 23:55:291911
1912 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:561913 *process_id = 0;
[email protected]57c6a652009-05-04 07:58:341914 TabContents* tab_contents =
1915 tab_tracker_->GetResource(handle)->tab_contents();
1916 if (tab_contents->process())
1917 *process_id = tab_contents->process()->process().pid();
initial.commit09911bf2008-07-26 23:55:291918 }
initial.commit09911bf2008-07-26 23:55:291919}
1920
1921void AutomationProvider::ApplyAccelerator(int handle, int id) {
[email protected]4f6381ee2009-04-16 02:46:331922 NOTREACHED() << "This function has been deprecated. "
1923 << "Please use ExecuteBrowserCommandAsync instead.";
initial.commit09911bf2008-07-26 23:55:291924}
1925
[email protected]71f65dd2009-02-11 19:14:561926void AutomationProvider::ExecuteJavascript(int handle,
initial.commit09911bf2008-07-26 23:55:291927 const std::wstring& frame_xpath,
[email protected]71f65dd2009-02-11 19:14:561928 const std::wstring& script,
1929 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:291930 bool succeeded = false;
[email protected]57c6a652009-05-04 07:58:341931 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1932 if (tab_contents) {
[email protected]20e93d12008-08-28 16:31:571933 // Set the routing id of this message with the controller.
1934 // This routing id needs to be remembered for the reverse
1935 // communication while sending back the response of
1936 // this javascript execution.
[email protected]f29acf52008-11-03 20:08:331937 std::wstring set_automation_id;
1938 SStringPrintf(&set_automation_id,
1939 L"window.domAutomationController.setAutomationId(%d);",
[email protected]71f65dd2009-02-11 19:14:561940 reply_message->routing_id());
1941
1942 DCHECK(reply_message_ == NULL);
1943 reply_message_ = reply_message;
initial.commit09911bf2008-07-26 23:55:291944
[email protected]57c6a652009-05-04 07:58:341945 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]f29acf52008-11-03 20:08:331946 frame_xpath, set_automation_id);
[email protected]57c6a652009-05-04 07:58:341947 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
[email protected]1f5af4442008-09-25 22:11:061948 frame_xpath, script);
[email protected]20e93d12008-08-28 16:31:571949 succeeded = true;
initial.commit09911bf2008-07-26 23:55:291950 }
1951
1952 if (!succeeded) {
[email protected]71f65dd2009-02-11 19:14:561953 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1954 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:291955 }
1956}
1957
[email protected]71f65dd2009-02-11 19:14:561958void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1959 *visible = false;
[email protected]20e93d12008-08-28 16:31:571960
[email protected]59560e0b2009-06-04 03:30:221961 if (browser_tracker_->ContainsHandle(handle)) {
1962 Browser* browser = browser_tracker_->GetResource(handle);
1963 if (browser) {
1964 *visible = browser->window()->IsDownloadShelfVisible();
1965 }
1966 }
initial.commit09911bf2008-07-26 23:55:291967}
1968
[email protected]59560e0b2009-06-04 03:30:221969void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
1970 if (browser_tracker_->ContainsHandle(handle)) {
1971 Browser* browser = browser_tracker_->GetResource(handle);
1972 if (browser) {
1973 if (visible)
1974 browser->window()->GetDownloadShelf()->Show();
1975 else
1976 browser->window()->GetDownloadShelf()->Close();
1977 }
1978 }
1979}
1980
1981
[email protected]71f65dd2009-02-11 19:14:561982void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
1983 *count = -1; // -1 is the error code
initial.commit09911bf2008-07-26 23:55:291984 if (tab_tracker_->ContainsHandle(handle)) {
1985 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:111986 TabContents* tab_contents = nav_controller->tab_contents();
initial.commit09911bf2008-07-26 23:55:291987 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:561988 *count = static_cast<int>(tab_contents->child_windows_.size());
initial.commit09911bf2008-07-26 23:55:291989 }
1990 }
initial.commit09911bf2008-07-26 23:55:291991}
1992
initial.commit09911bf2008-07-26 23:55:291993void AutomationProvider::HandleFindInPageRequest(
[email protected]71f65dd2009-02-11 19:14:561994 int handle, const std::wstring& find_request,
1995 int forward, int match_case, int* active_ordinal, int* matches_found) {
[email protected]5a52f162008-08-27 04:15:311996 NOTREACHED() << "This function has been deprecated."
1997 << "Please use HandleFindRequest instead.";
[email protected]71f65dd2009-02-11 19:14:561998 *matches_found = -1;
[email protected]5a52f162008-08-27 04:15:311999 return;
2000}
2001
[email protected]4f999132009-03-31 18:08:402002void AutomationProvider::HandleFindRequest(
2003 int handle,
2004 const AutomationMsg_Find_Params& params,
2005 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292006 if (!tab_tracker_->ContainsHandle(handle)) {
[email protected]71f65dd2009-02-11 19:14:562007 AutomationMsg_FindInPage::WriteReplyParams(reply_message, -1, -1);
2008 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292009 return;
2010 }
2011
2012 NavigationController* nav = tab_tracker_->GetResource(handle);
[email protected]7f0005a2009-04-15 03:25:112013 TabContents* tab_contents = nav->tab_contents();
initial.commit09911bf2008-07-26 23:55:292014
2015 find_in_page_observer_.reset(new
[email protected]1c58a5c2009-05-21 18:47:142016 FindInPageNotificationObserver(this, tab_contents, reply_message));
initial.commit09911bf2008-07-26 23:55:292017
[email protected]57c6a652009-05-04 07:58:342018 tab_contents->set_current_find_request_id(
2019 FindInPageNotificationObserver::kFindInPageRequestId);
2020 tab_contents->render_view_host()->StartFinding(
2021 FindInPageNotificationObserver::kFindInPageRequestId,
2022 params.search_string, params.forward, params.match_case,
2023 params.find_next);
initial.commit09911bf2008-07-26 23:55:292024}
2025
[email protected]5f8af2a2008-08-06 22:49:452026void AutomationProvider::HandleOpenFindInPageRequest(
2027 const IPC::Message& message, int handle) {
[email protected]4f3dc372009-02-24 00:10:292028 if (browser_tracker_->ContainsHandle(handle)) {
2029 Browser* browser = browser_tracker_->GetResource(handle);
2030 browser->FindInPage(false, false);
[email protected]5f8af2a2008-08-06 22:49:452031 }
2032}
2033
[email protected]71f65dd2009-02-11 19:14:562034void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
[email protected]9e0534b2008-10-21 15:03:012035 gfx::Point position;
[email protected]71f65dd2009-02-11 19:14:562036 *visible = false;
[email protected]4f3dc372009-02-24 00:10:292037 if (browser_tracker_->ContainsHandle(handle)) {
2038 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582039 FindBarTesting* find_bar =
2040 browser->find_bar()->find_bar()->GetFindBarTesting();
2041 find_bar->GetFindBarWindowInfo(&position, visible);
[email protected]4f3dc372009-02-24 00:10:292042 }
[email protected]20e93d12008-08-28 16:31:572043}
2044
[email protected]71f65dd2009-02-11 19:14:562045void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
2046 int* y) {
[email protected]9e0534b2008-10-21 15:03:012047 gfx::Point position(0, 0);
2048 bool visible = false;
[email protected]4f3dc372009-02-24 00:10:292049 if (browser_tracker_->ContainsHandle(handle)) {
2050 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]4801ecc2009-04-05 04:52:582051 FindBarTesting* find_bar =
2052 browser->find_bar()->find_bar()->GetFindBarTesting();
2053 find_bar->GetFindBarWindowInfo(&position, &visible);
[email protected]4f3dc372009-02-24 00:10:292054 }
[email protected]20e93d12008-08-28 16:31:572055
[email protected]71f65dd2009-02-11 19:14:562056 *x = position.x();
2057 *y = position.y();
[email protected]20e93d12008-08-28 16:31:572058}
2059
[email protected]71f65dd2009-02-11 19:14:562060void AutomationProvider::GetBookmarkBarVisibility(int handle, bool* visible,
2061 bool* animating) {
2062 *visible = false;
2063 *animating = false;
[email protected]c2cbeb92008-09-05 21:36:572064
[email protected]de246f52009-02-25 18:25:452065#if defined(OS_WIN)
[email protected]c2cbeb92008-09-05 21:36:572066 if (browser_tracker_->ContainsHandle(handle)) {
2067 Browser* browser = browser_tracker_->GetResource(handle);
2068 if (browser) {
[email protected]0ba1f5302009-01-22 01:34:522069 BrowserWindowTesting* testing =
2070 browser->window()->GetBrowserWindowTesting();
2071 BookmarkBarView* bookmark_bar = testing->GetBookmarkBarView();
[email protected]c2cbeb92008-09-05 21:36:572072 if (bookmark_bar) {
[email protected]71f65dd2009-02-11 19:14:562073 *animating = bookmark_bar->IsAnimating();
2074 *visible = browser->window()->IsBookmarkBarVisible();
[email protected]c2cbeb92008-09-05 21:36:572075 }
2076 }
2077 }
[email protected]de246f52009-02-25 18:25:452078#else
2079 // TODO(port): Enable when bookmarks ui is ported.
2080 NOTIMPLEMENTED();
2081#endif
[email protected]c2cbeb92008-09-05 21:36:572082}
2083
initial.commit09911bf2008-07-26 23:55:292084void AutomationProvider::HandleInspectElementRequest(
[email protected]71f65dd2009-02-11 19:14:562085 int handle, int x, int y, IPC::Message* reply_message) {
[email protected]57c6a652009-05-04 07:58:342086 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
2087 if (tab_contents) {
[email protected]71f65dd2009-02-11 19:14:562088 DCHECK(reply_message_ == NULL);
2089 reply_message_ = reply_message;
2090
[email protected]d9f9b792009-06-24 13:17:122091 DevToolsManager::GetInstance()->InspectElement(
2092 tab_contents->render_view_host(), x, y);
initial.commit09911bf2008-07-26 23:55:292093 } else {
[email protected]71f65dd2009-02-11 19:14:562094 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
2095 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292096 }
2097}
2098
2099void AutomationProvider::ReceivedInspectElementResponse(int num_resources) {
[email protected]396c3b32009-03-12 22:26:092100 if (reply_message_) {
2101 AutomationMsg_InspectElement::WriteReplyParams(reply_message_,
2102 num_resources);
2103 Send(reply_message_);
2104 reply_message_ = NULL;
2105 }
initial.commit09911bf2008-07-26 23:55:292106}
2107
2108// Helper class for making changes to the URLRequest ProtocolFactory on the
2109// IO thread.
2110class SetFilteredInetTask : public Task {
2111 public:
2112 explicit SetFilteredInetTask(bool enabled) : enabled_(enabled) { }
2113 virtual void Run() {
2114 if (enabled_) {
2115 URLRequestFilter::GetInstance()->ClearHandlers();
2116
2117 URLRequestFailedDnsJob::AddUITestUrls();
2118 URLRequestSlowDownloadJob::AddUITestUrls();
2119
2120 std::wstring root_http;
2121 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
2122 URLRequestMockHTTPJob::AddUITestUrls(root_http);
2123 } else {
2124 // Revert to the default handlers.
2125 URLRequestFilter::GetInstance()->ClearHandlers();
2126 }
2127 }
2128 private:
2129 bool enabled_;
2130};
2131
2132void AutomationProvider::SetFilteredInet(const IPC::Message& message,
2133 bool enabled) {
2134 // Since this involves changing the URLRequest ProtocolFactory, we want to
2135 // run on the main thread.
2136 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
2137 new SetFilteredInetTask(enabled));
2138}
2139
[email protected]a7eee32f2009-05-22 18:08:172140class SetProxyConfigTask : public Task {
2141 public:
2142 explicit SetProxyConfigTask(net::ProxyService* proxy_service,
2143 const std::string& new_proxy_config)
2144 : proxy_service_(proxy_service), proxy_config_(new_proxy_config) {}
2145 virtual void Run() {
2146 // First, deserialize the JSON string. If this fails, log and bail.
2147 JSONStringValueSerializer deserializer(proxy_config_);
2148 std::string error_message;
2149 scoped_ptr<Value> root(deserializer.Deserialize(&error_message));
2150 if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
2151 DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
2152 << error_message;
2153 return;
2154 }
2155
2156 scoped_ptr<DictionaryValue> dict(
2157 static_cast<DictionaryValue*>(root.release()));
2158 // Now put together a proxy configuration from the deserialized string.
2159 net::ProxyConfig pc;
2160 PopulateProxyConfig(*dict.get(), &pc);
2161
2162 DCHECK(proxy_service_);
2163 scoped_ptr<net::ProxyConfigService> proxy_config_service(
2164 new net::ProxyConfigServiceFixed(pc));
2165 proxy_service_->ResetConfigService(proxy_config_service.release());
2166 }
2167
2168 void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
2169 DCHECK(pc);
2170 bool no_proxy = false;
2171 if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
2172 // Make no changes to the ProxyConfig.
2173 return;
2174 }
2175 bool auto_config;
2176 if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
2177 pc->auto_detect = true;
2178 }
2179 std::string pac_url;
2180 if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
2181 pc->pac_url = GURL(pac_url);
2182 }
2183 std::string proxy_bypass_list;
2184 if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
2185 pc->ParseNoProxyList(proxy_bypass_list);
2186 }
2187 std::string proxy_server;
2188 if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
2189 pc->proxy_rules.ParseFromString(proxy_server);
2190 }
2191 }
2192
2193 private:
2194 net::ProxyService* proxy_service_;
2195 std::string proxy_config_;
2196};
2197
2198
2199void AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
2200 URLRequestContext* context = Profile::GetDefaultRequestContext();
2201 // If we don't have a default request context yet then we have to create
2202 // one.
2203 bool run_on_ui_thread = false;
2204 if (!context) {
2205 FilePath user_data_dir;
2206 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
2207 ProfileManager* profile_manager = g_browser_process->profile_manager();
2208 DCHECK(profile_manager);
2209 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
2210 DCHECK(profile);
2211 context = profile->GetRequestContext();
2212 run_on_ui_thread = true;
2213 }
2214 DCHECK(context);
2215 // Every URLRequestContext should have a proxy service.
2216 net::ProxyService* proxy_service = context->proxy_service();
2217 DCHECK(proxy_service);
2218
2219 // If we just now created the URLRequestContext then we can immediately
2220 // set the proxy settings on this (the UI) thread. If there was already
2221 // a URLRequestContext, then run the reset on the IO thread.
2222 if (run_on_ui_thread) {
2223 SetProxyConfigTask set_proxy_config_task(proxy_service, new_proxy_config);
2224 set_proxy_config_task.Run();
2225 } else {
2226 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
2227 new SetProxyConfigTask(proxy_service, new_proxy_config));
2228 }
2229}
2230
[email protected]4f3dc372009-02-24 00:10:292231void AutomationProvider::GetDownloadDirectory(
2232 int handle, std::wstring* download_directory) {
initial.commit09911bf2008-07-26 23:55:292233 DLOG(INFO) << "Handling download directory request";
initial.commit09911bf2008-07-26 23:55:292234 if (tab_tracker_->ContainsHandle(handle)) {
2235 NavigationController* tab = tab_tracker_->GetResource(handle);
2236 DownloadManager* dlm = tab->profile()->GetDownloadManager();
2237 DCHECK(dlm);
[email protected]71f65dd2009-02-11 19:14:562238 *download_directory = dlm->download_path().ToWStringHack();
initial.commit09911bf2008-07-26 23:55:292239 }
initial.commit09911bf2008-07-26 23:55:292240}
2241
[email protected]14c0a032009-04-13 18:15:142242void AutomationProvider::OpenNewBrowserWindow(bool show,
2243 IPC::Message* reply_message) {
2244 new BrowserOpenedNotificationObserver(this, reply_message);
initial.commit09911bf2008-07-26 23:55:292245 // We may have no current browser windows open so don't rely on
2246 // asking an existing browser to execute the IDC_NEWWINDOW command
[email protected]15952e462008-11-14 00:29:052247 Browser* browser = Browser::Create(profile_);
2248 browser->AddBlankTab(true);
[email protected]3683cbb2009-04-09 21:46:152249 if (show)
[email protected]15952e462008-11-14 00:29:052250 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:292251}
2252
[email protected]71f65dd2009-02-11 19:14:562253void AutomationProvider::GetWindowForBrowser(int browser_handle,
2254 bool* success,
2255 int* handle) {
2256 *success = false;
2257 *handle = 0;
initial.commit09911bf2008-07-26 23:55:292258
2259 if (browser_tracker_->ContainsHandle(browser_handle)) {
2260 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]0e9f4ee2009-04-08 01:44:202261 gfx::NativeWindow win = browser->window()->GetNativeHandle();
initial.commit09911bf2008-07-26 23:55:292262 // Add() returns the existing handle for the resource if any.
[email protected]0e9f4ee2009-04-08 01:44:202263 *handle = window_tracker_->Add(win);
[email protected]71f65dd2009-02-11 19:14:562264 *success = true;
initial.commit09911bf2008-07-26 23:55:292265 }
initial.commit09911bf2008-07-26 23:55:292266}
2267
[email protected]13869dd2009-05-05 00:40:062268#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292269void AutomationProvider::GetAutocompleteEditForBrowser(
[email protected]71f65dd2009-02-11 19:14:562270 int browser_handle,
2271 bool* success,
2272 int* autocomplete_edit_handle) {
2273 *success = false;
2274 *autocomplete_edit_handle = 0;
initial.commit09911bf2008-07-26 23:55:292275
2276 if (browser_tracker_->ContainsHandle(browser_handle)) {
2277 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]13869dd2009-05-05 00:40:062278 LocationBar* loc_bar = browser->window()->GetLocationBar();
2279 AutocompleteEditView* edit_view = loc_bar->location_entry();
initial.commit09911bf2008-07-26 23:55:292280 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562281 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
2282 *success = true;
initial.commit09911bf2008-07-26 23:55:292283 }
initial.commit09911bf2008-07-26 23:55:292284}
[email protected]13869dd2009-05-05 00:40:062285#endif // defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:292286
[email protected]13869dd2009-05-05 00:40:062287#if defined(OS_WIN)
2288// TODO(port): Remove windowsisms.
[email protected]71f65dd2009-02-11 19:14:562289void AutomationProvider::GetBrowserForWindow(int window_handle,
2290 bool* success,
2291 int* browser_handle) {
2292 *success = false;
2293 *browser_handle = 0;
initial.commit09911bf2008-07-26 23:55:292294
2295 if (window_tracker_->ContainsHandle(window_handle)) {
2296 HWND window = window_tracker_->GetResource(window_handle);
2297 BrowserList::const_iterator iter = BrowserList::begin();
2298 Browser* browser = NULL;
2299 for (;iter != BrowserList::end(); ++iter) {
[email protected]2d46c842008-11-14 19:24:312300 HWND hwnd = reinterpret_cast<HWND>((*iter)->window()->GetNativeHandle());
2301 if (window == hwnd) {
initial.commit09911bf2008-07-26 23:55:292302 browser = *iter;
2303 break;
2304 }
2305 }
2306 if (browser) {
2307 // Add() returns the existing handle for the resource if any.
[email protected]71f65dd2009-02-11 19:14:562308 *browser_handle = browser_tracker_->Add(browser);
2309 *success = true;
initial.commit09911bf2008-07-26 23:55:292310 }
2311 }
initial.commit09911bf2008-07-26 23:55:292312}
[email protected]de246f52009-02-25 18:25:452313#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292314
[email protected]71f65dd2009-02-11 19:14:562315void AutomationProvider::ShowInterstitialPage(int tab_handle,
2316 const std::string& html_text,
2317 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292318 if (tab_tracker_->ContainsHandle(tab_handle)) {
2319 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
[email protected]7f0005a2009-04-15 03:25:112320 TabContents* tab_contents = controller->tab_contents();
[email protected]965524b2009-04-04 21:32:402321
2322 AddNavigationStatusListener<bool>(controller, reply_message, true,
2323 false, false);
[email protected]965524b2009-04-04 21:32:402324 AutomationInterstitialPage* interstitial =
[email protected]57c6a652009-05-04 07:58:342325 new AutomationInterstitialPage(tab_contents,
[email protected]965524b2009-04-04 21:32:402326 GURL("about:interstitial"),
2327 html_text);
2328 interstitial->Show();
2329 return;
initial.commit09911bf2008-07-26 23:55:292330 }
[email protected]71f65dd2009-02-11 19:14:562331
2332 AutomationMsg_ShowInterstitialPage::WriteReplyParams(reply_message, false);
2333 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292334}
2335
[email protected]71f65dd2009-02-11 19:14:562336void AutomationProvider::HideInterstitialPage(int tab_handle,
2337 bool* success) {
2338 *success = false;
[email protected]57c6a652009-05-04 07:58:342339 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
2340 if (tab_contents && tab_contents->interstitial_page()) {
2341 tab_contents->interstitial_page()->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562342 *success = true;
initial.commit09911bf2008-07-26 23:55:292343 }
initial.commit09911bf2008-07-26 23:55:292344}
2345
[email protected]71f65dd2009-02-11 19:14:562346void AutomationProvider::CloseTab(int tab_handle,
2347 bool wait_until_closed,
2348 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292349 if (tab_tracker_->ContainsHandle(tab_handle)) {
2350 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
2351 int index;
2352 Browser* browser = Browser::GetBrowserForController(controller, &index);
2353 DCHECK(browser);
[email protected]1c58a5c2009-05-21 18:47:142354 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
[email protected]7f0005a2009-04-15 03:25:112355 browser->CloseContents(controller->tab_contents());
[email protected]de246f52009-02-25 18:25:452356 return;
initial.commit09911bf2008-07-26 23:55:292357 }
[email protected]de246f52009-02-25 18:25:452358
2359 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
initial.commit09911bf2008-07-26 23:55:292360}
2361
[email protected]71f65dd2009-02-11 19:14:562362void AutomationProvider::CloseBrowser(int browser_handle,
2363 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292364 if (browser_tracker_->ContainsHandle(browser_handle)) {
2365 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562366 new BrowserClosedNotificationObserver(browser, this,
[email protected]71f65dd2009-02-11 19:14:562367 reply_message);
[email protected]f3e99e32008-07-30 04:48:392368 browser->window()->Close();
initial.commit09911bf2008-07-26 23:55:292369 } else {
2370 NOTREACHED();
2371 }
2372}
2373
[email protected]71f65dd2009-02-11 19:14:562374void AutomationProvider::CloseBrowserAsync(int browser_handle) {
2375 if (browser_tracker_->ContainsHandle(browser_handle)) {
2376 Browser* browser = browser_tracker_->GetResource(browser_handle);
2377 browser->window()->Close();
2378 } else {
2379 NOTREACHED();
2380 }
2381}
2382
[email protected]de246f52009-02-25 18:25:452383#if defined(OS_WIN)
2384// TODO(port): Remove windowsisms.
[email protected]71f65dd2009-02-11 19:14:562385void AutomationProvider::CreateExternalTab(HWND parent,
[email protected]31fb110522009-01-28 21:50:392386 const gfx::Rect& dimensions,
[email protected]71f65dd2009-02-11 19:14:562387 unsigned int style,
[email protected]dd07d60b2009-04-23 18:24:322388 bool incognito,
[email protected]71f65dd2009-02-11 19:14:562389 HWND* tab_container_window,
[email protected]c4e944f2009-06-11 18:22:192390 HWND* tab_window,
[email protected]71f65dd2009-02-11 19:14:562391 int* tab_handle) {
2392 *tab_handle = 0;
2393 *tab_container_window = NULL;
[email protected]c4e944f2009-06-11 18:22:192394 *tab_window = NULL;
[email protected]2e4633c2009-07-09 16:58:062395 ExternalTabContainer* external_tab_container =
2396 new ExternalTabContainer(this, automation_resource_message_filter_);
[email protected]dd07d60b2009-04-23 18:24:322397 Profile* profile = incognito? profile_->GetOffTheRecordProfile() : profile_;
2398 external_tab_container->Init(profile, parent, dimensions, style);
initial.commit09911bf2008-07-26 23:55:292399 TabContents* tab_contents = external_tab_container->tab_contents();
2400 if (tab_contents) {
[email protected]ce3fa3c2009-04-20 19:55:572401 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
[email protected]eac83f02009-05-08 18:44:442402 external_tab_container->set_tab_handle(*tab_handle);
[email protected]9095e982009-05-27 17:28:242403 *tab_container_window = external_tab_container->GetNativeView();
[email protected]c4e944f2009-06-11 18:22:192404 *tab_window = tab_contents->GetNativeView();
[email protected]31fb110522009-01-28 21:50:392405 } else {
2406 delete external_tab_container;
initial.commit09911bf2008-07-26 23:55:292407 }
initial.commit09911bf2008-07-26 23:55:292408}
[email protected]d2cc6ed2009-04-24 00:26:172409#endif
initial.commit09911bf2008-07-26 23:55:292410
[email protected]71f65dd2009-02-11 19:14:562411void AutomationProvider::NavigateInExternalTab(
2412 int handle, const GURL& url,
2413 AutomationMsg_NavigationResponseValues* status) {
2414 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
initial.commit09911bf2008-07-26 23:55:292415
2416 if (tab_tracker_->ContainsHandle(handle)) {
2417 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]c0588052008-10-27 23:01:502418 tab->LoadURL(url, GURL(), PageTransition::TYPED);
[email protected]71f65dd2009-02-11 19:14:562419 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
initial.commit09911bf2008-07-26 23:55:292420 }
initial.commit09911bf2008-07-26 23:55:292421}
2422
[email protected]d2cc6ed2009-04-24 00:26:172423#if defined(OS_WIN)
2424// TODO(port): remove windowisms.
[email protected]71f65dd2009-02-11 19:14:562425void AutomationProvider::SetAcceleratorsForTab(int handle,
initial.commit09911bf2008-07-26 23:55:292426 HACCEL accel_table,
[email protected]71f65dd2009-02-11 19:14:562427 int accel_entry_count,
2428 bool* status) {
2429 *status = false;
2430
[email protected]b9d227492009-02-10 15:20:272431 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2432 if (external_tab) {
2433 external_tab->SetAccelerators(accel_table, accel_entry_count);
[email protected]71f65dd2009-02-11 19:14:562434 *status = true;
initial.commit09911bf2008-07-26 23:55:292435 }
initial.commit09911bf2008-07-26 23:55:292436}
2437
2438void AutomationProvider::ProcessUnhandledAccelerator(
2439 const IPC::Message& message, int handle, const MSG& msg) {
[email protected]b9d227492009-02-10 15:20:272440 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2441 if (external_tab) {
2442 external_tab->ProcessUnhandledAccelerator(msg);
2443 }
2444 // This message expects no response.
2445}
[email protected]d2cc6ed2009-04-24 00:26:172446#endif
[email protected]b9d227492009-02-10 15:20:272447
[email protected]71f65dd2009-02-11 19:14:562448void AutomationProvider::WaitForTabToBeRestored(int tab_handle,
2449 IPC::Message* reply_message) {
2450 if (tab_tracker_->ContainsHandle(tab_handle)) {
2451 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
2452 restore_tracker_.reset(
[email protected]1c58a5c2009-05-21 18:47:142453 new NavigationControllerRestoredObserver(this, tab, reply_message));
[email protected]71f65dd2009-02-11 19:14:562454 }
2455}
2456
[email protected]b9d227492009-02-10 15:20:272457void AutomationProvider::SetInitialFocus(const IPC::Message& message,
2458 int handle, bool reverse) {
[email protected]d2cc6ed2009-04-24 00:26:172459#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272460 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
2461 if (external_tab) {
[email protected]90daadb42009-06-08 21:27:282462 external_tab->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:292463 }
2464 // This message expects no response.
[email protected]d2cc6ed2009-04-24 00:26:172465#elif defined(OS_POSIX)
2466 // TODO(port) enable this function.
2467 NOTIMPLEMENTED();
2468#endif
initial.commit09911bf2008-07-26 23:55:292469}
2470
[email protected]d2cc6ed2009-04-24 00:26:172471// TODO(port): enable these functions.
2472#if defined(OS_WIN)
[email protected]71f65dd2009-02-11 19:14:562473void AutomationProvider::GetSecurityState(int handle, bool* success,
2474 SecurityStyle* security_style,
2475 int* ssl_cert_status,
2476 int* mixed_content_status) {
initial.commit09911bf2008-07-26 23:55:292477 if (tab_tracker_->ContainsHandle(handle)) {
2478 NavigationController* tab = tab_tracker_->GetResource(handle);
2479 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562480 *success = true;
2481 *security_style = entry->ssl().security_style();
2482 *ssl_cert_status = entry->ssl().cert_status();
2483 *mixed_content_status = entry->ssl().content_status();
initial.commit09911bf2008-07-26 23:55:292484 } else {
[email protected]71f65dd2009-02-11 19:14:562485 *success = false;
2486 *security_style = SECURITY_STYLE_UNKNOWN;
2487 *ssl_cert_status = 0;
2488 *mixed_content_status = 0;
initial.commit09911bf2008-07-26 23:55:292489 }
2490}
2491
[email protected]71f65dd2009-02-11 19:14:562492void AutomationProvider::GetPageType(int handle, bool* success,
2493 NavigationEntry::PageType* page_type) {
initial.commit09911bf2008-07-26 23:55:292494 if (tab_tracker_->ContainsHandle(handle)) {
2495 NavigationController* tab = tab_tracker_->GetResource(handle);
2496 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]71f65dd2009-02-11 19:14:562497 *page_type = entry->page_type();
2498 *success = true;
initial.commit09911bf2008-07-26 23:55:292499 // In order to return the proper result when an interstitial is shown and
[email protected]57c6a652009-05-04 07:58:342500 // no navigation entry were created for it we need to ask the TabContents.
[email protected]71f65dd2009-02-11 19:14:562501 if (*page_type == NavigationEntry::NORMAL_PAGE &&
[email protected]57c6a652009-05-04 07:58:342502 tab->tab_contents()->showing_interstitial_page())
[email protected]71f65dd2009-02-11 19:14:562503 *page_type = NavigationEntry::INTERSTITIAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292504 } else {
[email protected]71f65dd2009-02-11 19:14:562505 *success = false;
2506 *page_type = NavigationEntry::NORMAL_PAGE;
initial.commit09911bf2008-07-26 23:55:292507 }
2508}
2509
[email protected]71f65dd2009-02-11 19:14:562510void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
2511 IPC::Message* reply_message) {
initial.commit09911bf2008-07-26 23:55:292512 if (tab_tracker_->ContainsHandle(handle)) {
2513 NavigationController* tab = tab_tracker_->GetResource(handle);
2514 NavigationEntry* entry = tab->GetActiveEntry();
[email protected]1e5645ff2008-08-27 18:09:072515 if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
[email protected]965524b2009-04-04 21:32:402516 TabContents* tab_contents = tab->tab_contents();
[email protected]cbab76d2008-10-13 22:42:472517 InterstitialPage* ssl_blocking_page =
[email protected]57c6a652009-05-04 07:58:342518 InterstitialPage::GetInterstitialPage(tab_contents);
initial.commit09911bf2008-07-26 23:55:292519 if (ssl_blocking_page) {
2520 if (proceed) {
[email protected]71f65dd2009-02-11 19:14:562521 AddNavigationStatusListener<bool>(tab, reply_message, true, true,
2522 false);
2523 ssl_blocking_page->Proceed();
initial.commit09911bf2008-07-26 23:55:292524 return;
2525 }
2526 ssl_blocking_page->DontProceed();
[email protected]71f65dd2009-02-11 19:14:562527 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2528 true);
2529 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292530 return;
2531 }
2532 }
2533 }
2534 // We failed.
[email protected]71f65dd2009-02-11 19:14:562535 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(reply_message,
2536 false);
2537 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292538}
[email protected]de246f52009-02-25 18:25:452539#endif // defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292540
[email protected]71f65dd2009-02-11 19:14:562541void AutomationProvider::BringBrowserToFront(int browser_handle,
2542 bool* success) {
initial.commit09911bf2008-07-26 23:55:292543 if (browser_tracker_->ContainsHandle(browser_handle)) {
2544 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]cd7ffc22008-11-12 00:26:062545 browser->window()->Activate();
[email protected]71f65dd2009-02-11 19:14:562546 *success = true;
initial.commit09911bf2008-07-26 23:55:292547 } else {
[email protected]71f65dd2009-02-11 19:14:562548 *success = false;
initial.commit09911bf2008-07-26 23:55:292549 }
2550}
2551
[email protected]71f65dd2009-02-11 19:14:562552void AutomationProvider::IsPageMenuCommandEnabled(int browser_handle,
2553 int message_num,
2554 bool* menu_item_enabled) {
initial.commit09911bf2008-07-26 23:55:292555 if (browser_tracker_->ContainsHandle(browser_handle)) {
2556 Browser* browser = browser_tracker_->GetResource(browser_handle);
[email protected]71f65dd2009-02-11 19:14:562557 *menu_item_enabled =
[email protected]1fc025202009-01-20 23:03:142558 browser->command_updater()->IsCommandEnabled(message_num);
initial.commit09911bf2008-07-26 23:55:292559 } else {
[email protected]71f65dd2009-02-11 19:14:562560 *menu_item_enabled = false;
initial.commit09911bf2008-07-26 23:55:292561 }
2562}
2563
[email protected]de246f52009-02-25 18:25:452564#if defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:472565// TODO(port): Enable this.
[email protected]71f65dd2009-02-11 19:14:562566void AutomationProvider::PrintNow(int tab_handle,
2567 IPC::Message* reply_message) {
[email protected]20e93d12008-08-28 16:31:572568 NavigationController* tab = NULL;
[email protected]57c6a652009-05-04 07:58:342569 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
2570 if (tab_contents) {
initial.commit09911bf2008-07-26 23:55:292571 FindAndActivateTab(tab);
[email protected]20e93d12008-08-28 16:31:572572 notification_observer_list_.AddObserver(
[email protected]1c58a5c2009-05-21 18:47:142573 new DocumentPrintedNotificationObserver(this, reply_message));
[email protected]57c6a652009-05-04 07:58:342574 if (tab_contents->PrintNow())
[email protected]20e93d12008-08-28 16:31:572575 return;
initial.commit09911bf2008-07-26 23:55:292576 }
[email protected]71f65dd2009-02-11 19:14:562577 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
2578 Send(reply_message);
initial.commit09911bf2008-07-26 23:55:292579}
[email protected]3753f522009-04-14 23:15:472580#endif
initial.commit09911bf2008-07-26 23:55:292581
[email protected]71f65dd2009-02-11 19:14:562582void AutomationProvider::SavePage(int tab_handle,
initial.commit09911bf2008-07-26 23:55:292583 const std::wstring& file_name,
2584 const std::wstring& dir_path,
[email protected]71f65dd2009-02-11 19:14:562585 int type,
2586 bool* success) {
initial.commit09911bf2008-07-26 23:55:292587 if (!tab_tracker_->ContainsHandle(tab_handle)) {
[email protected]71f65dd2009-02-11 19:14:562588 *success = false;
initial.commit09911bf2008-07-26 23:55:292589 return;
2590 }
2591
2592 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2593 Browser* browser = FindAndActivateTab(nav);
2594 DCHECK(browser);
[email protected]1fc025202009-01-20 23:03:142595 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
[email protected]71f65dd2009-02-11 19:14:562596 *success = false;
initial.commit09911bf2008-07-26 23:55:292597 return;
2598 }
2599
initial.commit09911bf2008-07-26 23:55:292600 SavePackage::SavePackageType save_type =
2601 static_cast<SavePackage::SavePackageType>(type);
2602 DCHECK(save_type >= SavePackage::SAVE_AS_ONLY_HTML &&
2603 save_type <= SavePackage::SAVE_AS_COMPLETE_HTML);
[email protected]57c6a652009-05-04 07:58:342604 nav->tab_contents()->SavePage(file_name, dir_path, save_type);
initial.commit09911bf2008-07-26 23:55:292605
[email protected]71f65dd2009-02-11 19:14:562606 *success = true;
initial.commit09911bf2008-07-26 23:55:292607}
2608
[email protected]13869dd2009-05-05 00:40:062609#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]3753f522009-04-14 23:15:472610// TODO(port): Enable these.
[email protected]71f65dd2009-02-11 19:14:562611void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
2612 bool* success,
2613 std::wstring* text) {
2614 *success = false;
initial.commit09911bf2008-07-26 23:55:292615 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562616 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
[email protected]81c21222008-09-10 19:35:522617 GetText();
[email protected]71f65dd2009-02-11 19:14:562618 *success = true;
initial.commit09911bf2008-07-26 23:55:292619 }
initial.commit09911bf2008-07-26 23:55:292620}
2621
[email protected]71f65dd2009-02-11 19:14:562622void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
2623 const std::wstring& text,
2624 bool* success) {
2625 *success = false;
initial.commit09911bf2008-07-26 23:55:292626 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]81c21222008-09-10 19:35:522627 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
2628 SetUserText(text);
[email protected]71f65dd2009-02-11 19:14:562629 *success = true;
initial.commit09911bf2008-07-26 23:55:292630 }
initial.commit09911bf2008-07-26 23:55:292631}
2632
2633void AutomationProvider::AutocompleteEditGetMatches(
[email protected]71f65dd2009-02-11 19:14:562634 int autocomplete_edit_handle,
2635 bool* success,
2636 std::vector<AutocompleteMatchData>* matches) {
2637 *success = false;
initial.commit09911bf2008-07-26 23:55:292638 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]8deeb952008-10-09 18:21:272639 const AutocompleteResult& result = autocomplete_edit_tracker_->
2640 GetResource(autocomplete_edit_handle)->model()->result();
2641 for (AutocompleteResult::const_iterator i = result.begin();
2642 i != result.end(); ++i)
[email protected]71f65dd2009-02-11 19:14:562643 matches->push_back(AutocompleteMatchData(*i));
2644 *success = true;
initial.commit09911bf2008-07-26 23:55:292645 }
initial.commit09911bf2008-07-26 23:55:292646}
2647
2648void AutomationProvider::AutocompleteEditIsQueryInProgress(
[email protected]71f65dd2009-02-11 19:14:562649 int autocomplete_edit_handle,
2650 bool* success,
2651 bool* query_in_progress) {
2652 *success = false;
2653 *query_in_progress = false;
initial.commit09911bf2008-07-26 23:55:292654 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
[email protected]71f65dd2009-02-11 19:14:562655 *query_in_progress = autocomplete_edit_tracker_->
[email protected]81c21222008-09-10 19:35:522656 GetResource(autocomplete_edit_handle)->model()->query_in_progress();
[email protected]71f65dd2009-02-11 19:14:562657 *success = true;
initial.commit09911bf2008-07-26 23:55:292658 }
initial.commit09911bf2008-07-26 23:55:292659}
2660
[email protected]28790922009-03-09 19:48:372661void AutomationProvider::OnMessageFromExternalHost(int handle,
2662 const std::string& message,
2663 const std::string& origin,
2664 const std::string& target) {
[email protected]fa83e762008-08-15 21:41:392665 if (tab_tracker_->ContainsHandle(handle)) {
2666 NavigationController* tab = tab_tracker_->GetResource(handle);
2667 if (!tab) {
2668 NOTREACHED();
2669 return;
2670 }
[email protected]f44265b2009-05-19 18:52:502671
[email protected]965524b2009-04-04 21:32:402672 TabContents* tab_contents = tab->tab_contents();
[email protected]fa83e762008-08-15 21:41:392673 if (!tab_contents) {
2674 NOTREACHED();
2675 return;
2676 }
2677
[email protected]57c6a652009-05-04 07:58:342678 RenderViewHost* view_host = tab_contents->render_view_host();
[email protected]fa83e762008-08-15 21:41:392679 if (!view_host) {
2680 return;
2681 }
2682
[email protected]f44265b2009-05-19 18:52:502683 if (AutomationExtensionFunction::InterceptMessageFromExternalHost(
[email protected]a9024892009-06-16 23:13:552684 view_host, message, origin, target)) {
[email protected]f44265b2009-05-19 18:52:502685 // Message was diverted.
2686 return;
[email protected]b83e4602009-05-15 22:58:332687 }
[email protected]f44265b2009-05-19 18:52:502688
2689 if (ExtensionPortContainer::InterceptMessageFromExternalHost(message,
[email protected]a9024892009-06-16 23:13:552690 origin, target, this, view_host, handle)) {
2691 // Message was diverted.
2692 return;
2693 }
2694
2695 if (InterceptBrowserEventMessageFromExternalHost(message, origin, target)) {
[email protected]f44265b2009-05-19 18:52:502696 // Message was diverted.
2697 return;
2698 }
2699
2700 view_host->ForwardMessageFromExternalHost(message, origin, target);
[email protected]fa83e762008-08-15 21:41:392701 }
2702}
[email protected]a9024892009-06-16 23:13:552703
2704bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
2705 const std::string& message, const std::string& origin,
2706 const std::string& target) {
2707 if (target !=
2708 extension_automation_constants::kAutomationBrowserEventRequestTarget)
2709 return false;
2710
2711 if (origin != extension_automation_constants::kAutomationOrigin) {
2712 LOG(WARNING) << "Wrong origin on automation browser event " << origin;
2713 return false;
2714 }
2715
2716 // The message is a JSON-encoded array with two elements, both strings. The
2717 // first is the name of the event to dispatch. The second is a JSON-encoding
2718 // of the arguments specific to that event.
2719 scoped_ptr<Value> message_value(JSONReader::Read(message, false));
2720 if (!message_value.get() || !message_value->IsType(Value::TYPE_LIST)) {
2721 LOG(WARNING) << "Invalid browser event specified through automation";
2722 return false;
2723 }
2724
2725 const ListValue* args = static_cast<const ListValue*>(message_value.get());
2726
2727 std::string event_name;
2728 if (!args->GetString(0, &event_name)) {
2729 LOG(WARNING) << "No browser event name specified through automation";
2730 return false;
2731 }
2732
2733 std::string json_args;
2734 if (!args->GetString(1, &json_args)) {
2735 LOG(WARNING) << "No browser event args specified through automation";
2736 return false;
2737 }
2738
2739 ExtensionMessageService::GetInstance(profile()->GetRequestContext())->
2740 DispatchEventToRenderers(event_name.c_str(), json_args);
2741
2742 return true;
2743}
[email protected]13869dd2009-05-05 00:40:062744#endif // defined(OS_WIN) || defined(OS_LINUX)
[email protected]fa83e762008-08-15 21:41:392745
[email protected]57c6a652009-05-04 07:58:342746TabContents* AutomationProvider::GetTabContentsForHandle(
[email protected]20e93d12008-08-28 16:31:572747 int handle, NavigationController** tab) {
[email protected]20e93d12008-08-28 16:31:572748 if (tab_tracker_->ContainsHandle(handle)) {
2749 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]57c6a652009-05-04 07:58:342750 if (tab)
2751 *tab = nav_controller;
2752 return nav_controller->tab_contents();
[email protected]20e93d12008-08-28 16:31:572753 }
[email protected]57c6a652009-05-04 07:58:342754 return NULL;
[email protected]20e93d12008-08-28 16:31:572755}
2756
[email protected]5cc063692009-04-07 23:21:312757#if defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272758ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
2759 if (tab_tracker_->ContainsHandle(handle)) {
2760 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]965524b2009-04-04 21:32:402761 return ExternalTabContainer::GetContainerForTab(
2762 tab->tab_contents()->GetNativeView());
[email protected]b9d227492009-02-10 15:20:272763 }
2764
2765 return NULL;
2766}
[email protected]de246f52009-02-25 18:25:452767#endif // defined(OS_WIN)
[email protected]b9d227492009-02-10 15:20:272768
initial.commit09911bf2008-07-26 23:55:292769TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
2770 : AutomationProvider(profile) {
2771 BrowserList::AddObserver(this);
[email protected]1c58a5c2009-05-21 18:47:142772 registrar_.Add(this, NotificationType::SESSION_END,
2773 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:292774}
2775
2776TestingAutomationProvider::~TestingAutomationProvider() {
initial.commit09911bf2008-07-26 23:55:292777 BrowserList::RemoveObserver(this);
2778}
2779
2780void TestingAutomationProvider::OnChannelError() {
2781 BrowserList::CloseAllBrowsers(true);
2782 AutomationProvider::OnChannelError();
2783}
2784
2785void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
2786 // For backwards compatibility with the testing automation interface, we
2787 // want the automation provider (and hence the process) to go away when the
2788 // last browser goes away.
2789 if (BrowserList::size() == 1) {
[email protected]4f3dc372009-02-24 00:10:292790 // If you change this, update Observer for NotificationType::SESSION_END
2791 // below.
[email protected]295039bd2008-08-15 04:32:572792 MessageLoop::current()->PostTask(FROM_HERE,
2793 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
initial.commit09911bf2008-07-26 23:55:292794 }
2795}
2796
2797void TestingAutomationProvider::Observe(NotificationType type,
2798 const NotificationSource& source,
2799 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:562800 DCHECK(type == NotificationType::SESSION_END);
initial.commit09911bf2008-07-26 23:55:292801 // OnBrowserRemoving does a ReleaseLater. When session end is received we exit
2802 // before the task runs resulting in this object not being deleted. This
2803 // Release balance out the Release scheduled by OnBrowserRemoving.
2804 Release();
2805}
[email protected]295039bd2008-08-15 04:32:572806
2807void TestingAutomationProvider::OnRemoveProvider() {
2808 AutomationProviderList::GetInstance()->RemoveProvider(this);
2809}
[email protected]8a3422c92008-09-24 17:42:422810
[email protected]71f65dd2009-02-11 19:14:562811void AutomationProvider::GetSSLInfoBarCount(int handle, int* count) {
2812 *count = -1; // -1 means error.
[email protected]8a3422c92008-09-24 17:42:422813 if (tab_tracker_->ContainsHandle(handle)) {
2814 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
[email protected]eb9ba192008-12-02 02:41:342815 if (nav_controller)
[email protected]7f0005a2009-04-15 03:25:112816 *count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422817 }
[email protected]8a3422c92008-09-24 17:42:422818}
2819
[email protected]71f65dd2009-02-11 19:14:562820void AutomationProvider::ClickSSLInfoBarLink(int handle,
[email protected]8a3422c92008-09-24 17:42:422821 int info_bar_index,
[email protected]71f65dd2009-02-11 19:14:562822 bool wait_for_navigation,
2823 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422824 bool success = false;
2825 if (tab_tracker_->ContainsHandle(handle)) {
2826 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2827 if (nav_controller) {
[email protected]7f0005a2009-04-15 03:25:112828 int count = nav_controller->tab_contents()->infobar_delegate_count();
[email protected]8a3422c92008-09-24 17:42:422829 if (info_bar_index >= 0 && info_bar_index < count) {
2830 if (wait_for_navigation) {
[email protected]71f65dd2009-02-11 19:14:562831 AddNavigationStatusListener<bool>(nav_controller, reply_message,
2832 true, true, false);
[email protected]8a3422c92008-09-24 17:42:422833 }
[email protected]eb9ba192008-12-02 02:41:342834 InfoBarDelegate* delegate =
[email protected]7f0005a2009-04-15 03:25:112835 nav_controller->tab_contents()->GetInfoBarDelegateAt(
[email protected]eb9ba192008-12-02 02:41:342836 info_bar_index);
2837 if (delegate->AsConfirmInfoBarDelegate())
2838 delegate->AsConfirmInfoBarDelegate()->Accept();
[email protected]8a3422c92008-09-24 17:42:422839 success = true;
2840 }
2841 }
[email protected]4f3dc372009-02-24 00:10:292842 }
[email protected]8a3422c92008-09-24 17:42:422843 if (!wait_for_navigation || !success)
[email protected]71f65dd2009-02-11 19:14:562844 AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(reply_message,
2845 success);
[email protected]8a3422c92008-09-24 17:42:422846}
2847
[email protected]71f65dd2009-02-11 19:14:562848void AutomationProvider::GetLastNavigationTime(int handle,
2849 int64* last_navigation_time) {
[email protected]8a3422c92008-09-24 17:42:422850 Time time = tab_tracker_->GetLastNavigationTime(handle);
[email protected]71f65dd2009-02-11 19:14:562851 *last_navigation_time = time.ToInternalValue();
[email protected]8a3422c92008-09-24 17:42:422852}
2853
[email protected]71f65dd2009-02-11 19:14:562854void AutomationProvider::WaitForNavigation(int handle,
2855 int64 last_navigation_time,
2856 IPC::Message* reply_message) {
[email protected]8a3422c92008-09-24 17:42:422857 NavigationController* controller = NULL;
2858 if (tab_tracker_->ContainsHandle(handle))
2859 controller = tab_tracker_->GetResource(handle);
2860
2861 Time time = tab_tracker_->GetLastNavigationTime(handle);
2862 if (time.ToInternalValue() > last_navigation_time || !controller) {
[email protected]71f65dd2009-02-11 19:14:562863 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
2864 controller != NULL);
[email protected]4f3dc372009-02-24 00:10:292865 return;
[email protected]8a3422c92008-09-24 17:42:422866 }
2867
[email protected]71f65dd2009-02-11 19:14:562868 AddNavigationStatusListener<bool>(controller, reply_message, true, true,
2869 false);
[email protected]8a3422c92008-09-24 17:42:422870}
2871
[email protected]71f65dd2009-02-11 19:14:562872void AutomationProvider::SetIntPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162873 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562874 int value,
2875 bool* success) {
2876 *success = false;
[email protected]8a3422c92008-09-24 17:42:422877 if (browser_tracker_->ContainsHandle(handle)) {
2878 Browser* browser = browser_tracker_->GetResource(handle);
2879 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562880 *success = true;
[email protected]8a3422c92008-09-24 17:42:422881 }
[email protected]8a3422c92008-09-24 17:42:422882}
[email protected]97fa6ce32008-12-19 01:48:162883
[email protected]71f65dd2009-02-11 19:14:562884void AutomationProvider::SetStringPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162885 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562886 const std::wstring& value,
2887 bool* success) {
2888 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162889 if (browser_tracker_->ContainsHandle(handle)) {
2890 Browser* browser = browser_tracker_->GetResource(handle);
2891 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562892 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162893 }
[email protected]97fa6ce32008-12-19 01:48:162894}
2895
[email protected]71f65dd2009-02-11 19:14:562896void AutomationProvider::GetBooleanPreference(int handle,
2897 const std::wstring& name,
2898 bool* success,
2899 bool* value) {
2900 *success = false;
2901 *value = false;
[email protected]97fa6ce32008-12-19 01:48:162902 if (browser_tracker_->ContainsHandle(handle)) {
2903 Browser* browser = browser_tracker_->GetResource(handle);
[email protected]71f65dd2009-02-11 19:14:562904 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
2905 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162906 }
[email protected]97fa6ce32008-12-19 01:48:162907}
2908
[email protected]71f65dd2009-02-11 19:14:562909void AutomationProvider::SetBooleanPreference(int handle,
[email protected]97fa6ce32008-12-19 01:48:162910 const std::wstring& name,
[email protected]71f65dd2009-02-11 19:14:562911 bool value,
2912 bool* success) {
2913 *success = false;
[email protected]97fa6ce32008-12-19 01:48:162914 if (browser_tracker_->ContainsHandle(handle)) {
2915 Browser* browser = browser_tracker_->GetResource(handle);
2916 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
[email protected]71f65dd2009-02-11 19:14:562917 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162918 }
[email protected]97fa6ce32008-12-19 01:48:162919}
2920
2921// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562922void AutomationProvider::GetPageCurrentEncoding(
2923 int tab_handle, std::wstring* current_encoding) {
[email protected]97fa6ce32008-12-19 01:48:162924 if (tab_tracker_->ContainsHandle(tab_handle)) {
2925 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2926 Browser* browser = FindAndActivateTab(nav);
2927 DCHECK(browser);
2928
[email protected]57c6a652009-05-04 07:58:342929 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
2930 *current_encoding = nav->tab_contents()->encoding();
[email protected]97fa6ce32008-12-19 01:48:162931 }
[email protected]97fa6ce32008-12-19 01:48:162932}
2933
2934// Gets the current used encoding name of the page in the specified tab.
[email protected]71f65dd2009-02-11 19:14:562935void AutomationProvider::OverrideEncoding(int tab_handle,
2936 const std::wstring& encoding_name,
2937 bool* success) {
2938 *success = false;
[email protected]de246f52009-02-25 18:25:452939#if defined(OS_WIN)
[email protected]97fa6ce32008-12-19 01:48:162940 if (tab_tracker_->ContainsHandle(tab_handle)) {
2941 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
2942 Browser* browser = FindAndActivateTab(nav);
2943 DCHECK(browser);
2944
[email protected]1fc025202009-01-20 23:03:142945 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
[email protected]7f0005a2009-04-15 03:25:112946 TabContents* tab_contents = nav->tab_contents();
[email protected]97fa6ce32008-12-19 01:48:162947 int selected_encoding_id =
2948 CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
2949 if (selected_encoding_id) {
2950 browser->OverrideEncoding(selected_encoding_id);
[email protected]71f65dd2009-02-11 19:14:562951 *success = true;
[email protected]97fa6ce32008-12-19 01:48:162952 }
2953 }
2954 }
[email protected]de246f52009-02-25 18:25:452955#else
2956 // TODO(port): Enable when encoding-related parts of Browser are ported.
2957 NOTIMPLEMENTED();
2958#endif
[email protected]97fa6ce32008-12-19 01:48:162959}
[email protected]5bcdb312009-01-07 21:43:202960
[email protected]4d434a1a2009-02-11 21:06:572961void AutomationProvider::SavePackageShouldPromptUser(bool should_prompt) {
[email protected]5bcdb312009-01-07 21:43:202962 SavePackage::SetShouldPromptUser(should_prompt);
2963}
[email protected]87eab222009-03-13 00:47:452964
[email protected]b83e4602009-05-15 22:58:332965void AutomationProvider::SetEnableExtensionAutomation(bool automation_enabled) {
2966 AutomationExtensionFunction::SetEnabled(automation_enabled);
2967}
2968
[email protected]d2cc6ed2009-04-24 00:26:172969#if defined(OS_WIN)
2970// TODO(port): Reposition_Params is win-specific. We'll need to port it.
[email protected]87eab222009-03-13 00:47:452971void AutomationProvider::OnTabReposition(
2972 int tab_handle, const IPC::Reposition_Params& params) {
2973 if (!tab_tracker_->ContainsHandle(tab_handle))
2974 return;
2975
2976 if (!IsWindow(params.window))
2977 return;
2978
2979 unsigned long process_id = 0;
2980 unsigned long thread_id = 0;
2981
2982 thread_id = GetWindowThreadProcessId(params.window, &process_id);
2983
2984 if (thread_id != GetCurrentThreadId()) {
2985 NOTREACHED();
2986 return;
2987 }
2988
[email protected]a9233d0f2009-04-20 05:39:332989 SetWindowPos(params.window, params.window_insert_after, params.left,
2990 params.top, params.width, params.height, params.flags);
2991
[email protected]a2c5a9892009-04-07 16:13:452992 if (params.set_parent) {
2993 if (IsWindow(params.parent_window)) {
2994 if (!SetParent(params.window, params.parent_window))
2995 DLOG(WARNING) << "SetParent failed. Error 0x%x" << GetLastError();
2996 }
2997 }
[email protected]87eab222009-03-13 00:47:452998}
[email protected]e943d6662009-06-12 03:50:392999
3000void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle,
3001 int command) {
3002 if (tab_tracker_->ContainsHandle(tab_handle)) {
3003 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
3004 if (!tab) {
3005 NOTREACHED();
3006 return;
3007 }
3008
3009 TabContents* tab_contents = tab->tab_contents();
3010 if (!tab_contents || !tab_contents->delegate()) {
3011 NOTREACHED();
3012 return;
3013 }
3014
3015 tab_contents->delegate()->ExecuteContextMenuCommand(command);
3016 }
3017}
3018
3019#endif // defined(OS_WIN)
[email protected]3753f522009-04-14 23:15:473020
3021void AutomationProvider::GetWindowTitle(int handle, string16* text) {
3022 gfx::NativeWindow window = window_tracker_->GetResource(handle);
3023 text->assign(platform_util::GetWindowTitle(window));
3024}
[email protected]66ba4932009-06-04 19:22:133025
3026void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
3027 *count = -1; // -1 is the error code
3028 if (tab_tracker_->ContainsHandle(handle)) {
3029 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
3030 TabContents* tab_contents = nav_controller->tab_contents();
3031 if (tab_contents) {
3032 BlockedPopupContainer* container =
3033 tab_contents->blocked_popup_container();
3034 if (container) {
3035 *count = static_cast<int>(container->GetBlockedPopupCount());
3036 } else {
3037 // If we don't have a container, we don't have any blocked popups to
3038 // contain!
3039 *count = 0;
3040 }
3041 }
3042 }
3043}