172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/trace_event.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_writer.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/string_escape.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_number_conversions.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/synchronization/waitable_event.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h"
26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/autocomplete/autocomplete_edit.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_manager.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_browser_tracker.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_extension_tracker.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider_list.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_provider_observers.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_resource_message_filter.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_tab_tracker.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_window_tracker.h"
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/automation/ui_controls.h"
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/blocked_content_container.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_storage.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browsing_data_remover.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/character_encoding.h"
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/content_settings/host_content_settings_map.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_manager.h"
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/dom_operation_notification_details.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_shelf.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/save_package.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/crx_installer.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_browser_event_router.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_install_ui.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_message_service.h"
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_service.h"
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_tabs_module.h"
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_toolbar_model.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/user_script_master.h"
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/io_thread.h"
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_request_mock_util.h"
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/printing/print_job.h"
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_blocking_page.h"
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ssl/ssl_manager.h"
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/download/download_tab_helper.h"
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar.h"
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar_controller.h"
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_notification_details.h"
75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/find_bar/find_tab_helper.h"
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/login/login_prompt.h"
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/omnibox/location_bar.h"
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/automation_constants.h"
804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/automation_messages.h"
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/automation/tab_proxy.h"
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/json_value_serializer.h"
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/proxy_config_service_fixed.h"
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/proxy/proxy_service.h"
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/password_form.h"
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/external_tab_container_win.h"
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // defined(OS_WIN)
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutomationProvider::AutomationProvider(Profile* profile)
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : profile_(profile),
110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      reply_message_(NULL),
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      reinitialize_on_channel_error_(false),
112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      is_connected_(false),
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      initial_tab_loads_complete_(false),
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      network_library_initialized_(true) {
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TRACE_EVENT_BEGIN("AutomationProvider::AutomationProvider", 0, "");
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_tracker_.reset(new AutomationBrowserTracker(this));
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_tracker_.reset(new AutomationExtensionTracker(this));
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_tracker_.reset(new AutomationTabTracker(this));
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_tracker_.reset(new AutomationWindowTracker(this));
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  autocomplete_edit_tracker_.reset(
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new AutomationAutocompleteEditTracker(this));
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  metric_event_duration_observer_.reset(new MetricEventDurationObserver());
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_test_result_observer_.reset(
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionTestResultNotificationObserver(this));
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_browser_process->AddRefModule();
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TRACE_EVENT_END("AutomationProvider::AutomationProvider", 0, "");
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutomationProvider::~AutomationProvider() {
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (channel_.get())
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    channel_->Close();
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_browser_process->ReleaseModule();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool AutomationProvider::InitializeChannel(const std::string& channel_id) {
142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TRACE_EVENT_BEGIN("AutomationProvider::InitializeChannel", 0, "");
143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  channel_id_ = channel_id;
145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string effective_channel_id = channel_id;
146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // If the channel_id starts with kNamedInterfacePrefix, create a named IPC
148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // server and listen on it, else connect as client to an existing IPC server
149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool use_named_interface =
150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      channel_id.find(automation::kNamedInterfacePrefix) == 0;
151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (use_named_interface) {
152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    effective_channel_id = channel_id.substr(
153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        strlen(automation::kNamedInterfacePrefix));
154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (effective_channel_id.length() <= 0)
155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return false;
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    reinitialize_on_channel_error_ = true;
158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!automation_resource_message_filter_.get()) {
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    automation_resource_message_filter_ = new AutomationResourceMessageFilter;
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  channel_.reset(new IPC::SyncChannel(
165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      effective_channel_id,
166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      use_named_interface ? IPC::Channel::MODE_NAMED_SERVER
167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                          : IPC::Channel::MODE_CLIENT,
168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      this,
169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      g_browser_process->io_thread()->message_loop(),
170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      true, g_browser_process->shutdown_event()));
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  channel_->AddFilter(automation_resource_message_filter_);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Wait for the network manager to initialize.
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The observer will delete itself when done.
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  network_library_initialized_ = false;
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NetworkManagerInitObserver* observer = new NetworkManagerInitObserver(this);
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!observer->Init())
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete observer;
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TRACE_EVENT_END("AutomationProvider::InitializeChannel", 0, "");
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return true;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string AutomationProvider::GetProtocolVersion() {
188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chrome::VersionInfo version_info;
189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return version_info.Version().c_str();
190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (expected_tabs == 0)
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    OnInitialTabLoadsComplete();
195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  else
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutomationProvider::OnInitialTabLoadsComplete() {
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  initial_tab_loads_complete_ = true;
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (is_connected_ && network_library_initialized_)
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Send(new AutomationMsg_InitialLoadsComplete());
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutomationProvider::OnNetworkLibraryInit() {
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  network_library_initialized_ = true;
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (is_connected_ && initial_tab_loads_complete_)
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Send(new AutomationMsg_InitialLoadsComplete());
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::AddLoginHandler(NavigationController* tab,
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         LoginHandler* handler) {
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  login_handler_map_[tab] = handler;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(login_handler_map_[tab]);
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  login_handler_map_.erase(tab);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint AutomationProvider::GetIndexForNavigationController(
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NavigationController* controller, const Browser* parent) const {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(parent);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return parent->GetIndexOfController(controller);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint AutomationProvider::AddExtension(const Extension* extension) {
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return extension_tracker_->Add(extension);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(phajdan.jr): move to TestingAutomationProvider.
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDictionaryValue* AutomationProvider::GetDictionaryFromDownloadItem(
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const DownloadItem* download) {
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::map<DownloadItem::DownloadState, std::string> state_to_string;
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state_to_string[DownloadItem::INTERRUPTED] = std::string("INTERRUPTED");
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      std::string("DANGEROUS_BUT_VALIDATED");
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dl_item_value = new DictionaryValue;
2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetInteger("id", static_cast<int>(download->id()));
2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetString("url", download->url().spec());
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetString("referrer_url", download->referrer_url().spec());
252513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  dl_item_value->SetString("file_name",
253513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                           download->GetFileNameToReportUser().value());
254513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  dl_item_value->SetString("full_path",
255513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                           download->GetTargetFilePath().value());
2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetBoolean("is_paused", download->is_paused());
2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetBoolean("open_when_complete",
2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            download->open_when_complete());
2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetBoolean("is_extension_install",
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            download->is_extension_install());
2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetBoolean("is_temporary", download->is_temporary());
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  dl_item_value->SetBoolean("is_otr", download->is_otr());  // incognito
2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetString("state", state_to_string[download->state()]);
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetString("safety_state",
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           safety_state_to_string[download->safety_state()]);
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  dl_item_value->SetInteger("PercentComplete", download->PercentComplete());
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return dl_item_value;
2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
271513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst Extension* AutomationProvider::GetExtension(int extension_handle) {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return extension_tracker_->GetResource(extension_handle);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension =
277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      extension_tracker_->GetResource(extension_handle);
27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service &&
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service->GetExtensionById(extension->id(), false))
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return extension;
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst Extension* AutomationProvider::GetDisabledExtension(
286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    int extension_handle) {
287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension =
288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      extension_tracker_->GetResource(extension_handle);
28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service &&
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service->GetExtensionById(extension->id(), true) &&
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !service->GetExtensionById(extension->id(), false))
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return extension;
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid AutomationProvider::OnChannelConnected(int pid) {
298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  is_connected_ = true;
299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  LOG(INFO) << "Testing channel connected, sending hello message";
300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Send a hello message with our current automation protocol version.
30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  channel_->Send(new AutomationMsg_Hello(GetProtocolVersion()));
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (initial_tab_loads_complete_ && network_library_initialized_)
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Send(new AutomationMsg_InitialLoadsComplete());
305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool AutomationProvider::OnMessageReceived(const IPC::Message& message) {
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool handled = true;
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool deserialize_success = true;
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  IPC_BEGIN_MESSAGE_MAP_EX(AutomationProvider, message, deserialize_success)
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    WindowSimulateDrag)
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // !defined(OS_MACOSX)
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig)
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    InstallExtension)
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    WaitForExtensionTestResult)
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutomationMsg_InstallExtensionAndGetHandle,
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        InstallExtensionAndGetHandle)
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        UninstallExtension)
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    EnableExtension)
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        DisableExtension)
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER_DELAY_REPLY(
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ExecuteExtensionActionInActiveTabAsync)
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        MoveExtensionBrowserAction)
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        GetExtensionProperty)
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_HANDLER(AutomationMsg_JavaScriptStressTestControl,
35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        JavaScriptStressTestControl)
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These are for use with external tabs.
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        ProcessUnhandledAccelerator)
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        OnForwardContextMenuCommandToChrome)
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        NavigateInExternalTab)
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        NavigateExternalTabAtIndex)
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        OnMessageFromExternalHost)
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RunUnloadHandlers,
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    OnRunUnloadHandlers)
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    IPC_MESSAGE_HANDLER(AutomationMsg_SetZoomLevel, OnSetZoomLevel)
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // defined(OS_WIN)
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC_MESSAGE_UNHANDLED(handled = false; OnUnhandledMessage())
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  IPC_END_MESSAGE_MAP_EX()
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!deserialize_success)
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    OnMessageDeserializationFailure();
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return handled;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProvider::OnUnhandledMessage() {
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We should not hang here. Print a message to indicate what's going on,
3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // and disconnect the channel to notify the caller about the error
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // in a way it can't ignore, and make any further attempts to send
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // messages fail fast.
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  LOG(ERROR) << "AutomationProvider received a message it can't handle. "
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick             << "Please make sure that you use switches::kTestingChannelID "
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick             << "for test code (TestingAutomationProvider), and "
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick             << "switches::kAutomationClientChannelID for everything else "
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick             << "(like ChromeFrame). Closing the automation channel.";
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  channel_->Close();
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutomationProvider::OnMessageDeserializationFailure() {
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LOG(ERROR) << "Failed to deserialize IPC message. "
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             << "Closing the automation channel.";
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  channel_->Close();
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This task just adds another task to the event queue.  This is useful if
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// you want to ensure that any tasks added to the event queue after this one
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// have already been processed by the time |task| is run.
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass InvokeTaskLaterTask : public Task {
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~InvokeTaskLaterTask() {}
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE, task_);
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Task* task_;
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (window_tracker_->ContainsHandle(handle)) {
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window_tracker_->Remove(window_tracker_->GetResource(handle));
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutomationProvider::ReinitializeChannel() {
423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io;
424dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Make sure any old channels are cleaned up before starting up a new one.
426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  channel_.reset();
427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return InitializeChannel(channel_id_);
428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::OnChannelError() {
431dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (reinitialize_on_channel_error_) {
432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VLOG(1) << "AutomationProxy disconnected, resetting AutomationProvider.";
433dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (ReinitializeChannel())
434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return;
435dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VLOG(1) << "Error reinitializing AutomationProvider channel.";
436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
437513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  VLOG(1) << "AutomationProxy went away, shutting down app.";
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutomationProviderList::GetInstance()->RemoveProvider(this);
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutomationProvider::Send(IPC::Message* msg) {
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(channel_.get());
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return channel_->Send(msg);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser* AutomationProvider::FindAndActivateTab(
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* controller) {
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int tab_index;
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser)
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    browser->ActivateTabAt(tab_index, true);
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid AutomationProvider::HandleFindRequest(
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    int handle,
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const AutomationMsg_Find_Params& params,
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    IPC::Message* reply_message) {
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!tab_tracker_->ContainsHandle(handle)) {
461731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    AutomationMsg_Find::WriteReplyParams(reply_message, -1, -1);
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    Send(reply_message);
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NavigationController* nav = tab_tracker_->GetResource(handle);
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TabContents* tab_contents = nav->tab_contents();
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SendFindRequest(tab_contents,
470731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  false,
471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  params.search_string,
472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  params.forward,
473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  params.match_case,
474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  params.find_next,
475731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  reply_message);
476731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
478731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AutomationProvider::SendFindRequest(
479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* tab_contents,
480731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool with_json,
481731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const string16& search_string,
482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool forward,
483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool match_case,
484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool find_next,
485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    IPC::Message* reply_message) {
486731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int request_id = FindInPageNotificationObserver::kFindInPageRequestId;
487731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  FindInPageNotificationObserver* observer =
488731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new FindInPageNotificationObserver(this,
489731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         tab_contents,
490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         with_json,
491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         reply_message);
492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!with_json) {
493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    find_in_page_observer_.reset(observer);
494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TabContentsWrapper* wrapper =
49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (wrapper)
498dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    wrapper->find_tab_helper()->set_current_find_request_id(request_id);
49972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_contents->render_view_host()->StartFinding(
5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      FindInPageNotificationObserver::kFindInPageRequestId,
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      search_string,
503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      forward,
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      match_case,
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      find_next);
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SetProxyConfigTask : public Task {
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetProxyConfigTask(net::URLRequestContextGetter* request_context_getter,
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     const std::string& new_proxy_config)
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : request_context_getter_(request_context_getter),
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        proxy_config_(new_proxy_config) {}
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // First, deserialize the JSON string. If this fails, log and bail.
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    JSONStringValueSerializer deserializer(proxy_config_);
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string error_msg;
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    << error_msg;
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<DictionaryValue> dict(
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<DictionaryValue*>(root.release()));
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now put together a proxy configuration from the deserialized string.
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::ProxyConfig pc;
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PopulateProxyConfig(*dict.get(), &pc);
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::ProxyService* proxy_service =
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        request_context_getter_->GetURLRequestContext()->proxy_service();
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(proxy_service);
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<net::ProxyConfigService> proxy_config_service(
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new net::ProxyConfigServiceFixed(pc));
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    proxy_service->ResetConfigService(proxy_config_service.release());
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(pc);
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool no_proxy = false;
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Make no changes to the ProxyConfig.
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool auto_config;
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pc->set_auto_detect(true);
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string pac_url;
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pc->set_pac_url(GURL(pac_url));
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string proxy_bypass_list;
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string proxy_server;
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pc->proxy_rules().ParseFromString(proxy_server);
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string proxy_config_;
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::URLRequestContextGetter* context_getter =
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Profile::GetDefaultRequestContext();
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!context_getter) {
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath user_data_dir;
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProfileManager* profile_manager = g_browser_process->profile_manager();
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(profile_manager);
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(profile);
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_getter = profile->GetRequestContext();
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(context_getter);
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::IO, FROM_HERE,
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new SetProxyConfigTask(context_getter, new_proxy_config));
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContents* AutomationProvider::GetTabContentsForHandle(
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int handle, NavigationController** tab) {
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_tracker_->ContainsHandle(handle)) {
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* nav_controller = tab_tracker_->GetResource(handle);
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (tab)
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *tab = nav_controller;
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return nav_controller->tab_contents();
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Gets the current used encoding name of the page in the specified tab.
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::OverrideEncoding(int tab_handle,
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          const std::string& encoding_name,
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          bool* success) {
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *success = false;
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_tracker_->ContainsHandle(tab_handle)) {
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* nav = tab_tracker_->GetResource(tab_handle);
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!nav)
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* browser = FindAndActivateTab(nav);
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the browser has UI, simulate what a user would do.
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Activate the tab and then click the encoding menu.
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (browser &&
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int selected_encoding_id =
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (selected_encoding_id) {
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        browser->OverrideEncoding(selected_encoding_id);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *success = true;
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // There is no UI, Chrome probably runs as Chrome-Frame mode.
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Try to get TabContents and call its override_encoding method.
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabContents* contents = nav->tab_contents();
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!contents)
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const std::string selected_encoding =
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (selected_encoding.empty())
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents->SetOverrideEncoding(selected_encoding);
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::SelectAll(int tab_handle) {
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* view = GetViewForTab(tab_handle);
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!view) {
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->SelectAll();
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::Cut(int tab_handle) {
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* view = GetViewForTab(tab_handle);
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!view) {
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->Cut();
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::Copy(int tab_handle) {
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* view = GetViewForTab(tab_handle);
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!view) {
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->Copy();
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::Paste(int tab_handle) {
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* view = GetViewForTab(tab_handle);
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!view) {
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->Paste();
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::ReloadAsync(int tab_handle) {
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_tracker_->ContainsHandle(tab_handle)) {
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!tab) {
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const bool check_for_repost = true;
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab->Reload(check_for_repost);
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::StopAsync(int tab_handle) {
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* view = GetViewForTab(tab_handle);
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!view) {
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We tolerate StopAsync being called even before a view has been created.
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // So just log a warning instead of a NOTREACHED().
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->Stop();
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::OnSetPageFontSize(int tab_handle,
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           int font_size) {
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutomationPageFontSize automation_font_size =
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<AutomationPageFontSize>(font_size);
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (automation_font_size < SMALLEST_FONT ||
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      automation_font_size > LARGEST_FONT) {
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DLOG(ERROR) << "Invalid font size specified : "
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  << font_size;
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_tracker_->ContainsHandle(tab_handle)) {
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(tab != NULL);
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (tab && tab->tab_contents()) {
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(tab->tab_contents()->profile() != NULL);
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab->tab_contents()->profile()->GetPrefs()->SetInteger(
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          prefs::kWebKitDefaultFontSize, font_size);
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::RemoveBrowsingData(int remove_mask) {
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowsingDataRemover* remover;
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  remover = new BrowsingDataRemover(profile(),
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BrowsingDataRemover::EVERYTHING,  // All time periods.
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::Time());
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  remover->Remove(remove_mask);
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // BrowsingDataRemover deletes itself.
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid AutomationProvider::JavaScriptStressTestControl(int tab_handle,
73472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                     int cmd,
73572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                     int param) {
73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RenderViewHost* view = GetViewForTab(tab_handle);
73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!view) {
73872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NOTREACHED();
73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
74072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
74272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  view->JavaScriptStressTestControl(cmd, param);
74372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
74472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_tracker_->ContainsHandle(tab_handle)) {
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!tab) {
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NULL;
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* tab_contents = tab->tab_contents();
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!tab_contents) {
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NULL;
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderViewHost* view_host = tab_contents->render_view_host();
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return view_host;
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::InstallExtension(const FilePath& crx_path,
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          IPC::Message* reply_message) {
76821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service) {
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The observer will delete itself when done.
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new ExtensionInstallNotificationObserver(this,
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             AutomationMsg_InstallExtension::ID,
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             reply_message);
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_refptr<CrxInstaller> installer(
776201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        new CrxInstaller(service, NULL));  // silent install, no UI
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    installer->InstallCrx(crx_path);
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_InstallExtension::WriteReplyParams(
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Send(reply_message);
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::WaitForExtensionTestResult(
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message) {
787dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(!reply_message_);
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  reply_message_ = reply_message;
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Call MaybeSendResult, because the result might have come in before
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we were waiting on it.
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_test_result_observer_->MaybeSendResult();
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::InstallExtensionAndGetHandle(
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
79621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service && manager) {
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The observer will delete itself when done.
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new ExtensionReadyNotificationObserver(
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        manager,
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this,
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutomationMsg_InstallExtensionAndGetHandle::ID,
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reply_message);
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionInstallUI* client =
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (with_ui ? new ExtensionInstallUI(profile_) : NULL);
808201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    scoped_refptr<CrxInstaller> installer(new CrxInstaller(service, client));
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    installer->InstallCrx(crx_path);
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reply_message, 0);
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Send(reply_message);
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::UninstallExtension(int extension_handle,
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            bool* success) {
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *success = false;
820513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetExtension(extension_handle);
82121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service) {
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionUnloadNotificationObserver observer;
824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service->UninstallExtension(extension->id(), false, NULL);
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The extension unload notification should have been sent synchronously
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // with the uninstall. Just to be safe, check that it was received.
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *success = observer.did_receive_unload_notification();
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::EnableExtension(int extension_handle,
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         IPC::Message* reply_message) {
833513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetDisabledExtension(extension_handle);
83421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only enable if this extension is disabled.
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service && manager) {
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The observer will delete itself when done.
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new ExtensionReadyNotificationObserver(
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        manager,
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this,
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutomationMsg_EnableExtension::ID,
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reply_message);
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service->EnableExtension(extension->id());
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Send(reply_message);
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::DisableExtension(int extension_handle,
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          bool* success) {
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *success = false;
854513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetEnabledExtension(extension_handle);
85521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service) {
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionUnloadNotificationObserver observer;
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service->DisableExtension(extension->id());
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The extension unload notification should have been sent synchronously
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // with the disable. Just to be safe, check that it was received.
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *success = observer.did_receive_unload_notification();
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int extension_handle, int browser_handle,
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC::Message* reply_message) {
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success = false;
869513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetEnabledExtension(extension_handle);
87021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionMessageService* message_service =
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetExtensionMessageService();
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = browser_tracker_->GetResource(browser_handle);
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service && message_service && browser) {
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension->page_action()) {
87772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service->browser_event_router()->PageActionExecuted(
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser->profile(), extension->id(), "action", tab_id, "", 1);
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success = true;
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (extension->browser_action()) {
88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service->browser_event_router()->BrowserActionExecuted(
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser->profile(), extension->id(), browser);
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success = true;
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reply_message, success);
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Send(reply_message);
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::MoveExtensionBrowserAction(
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int extension_handle, int index, bool* success) {
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *success = false;
894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetEnabledExtension(extension_handle);
89521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service) {
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionToolbarModel* toolbar = service->toolbar_model();
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (toolbar) {
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (index >= 0 && index < static_cast<int>(toolbar->size())) {
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        toolbar->MoveBrowserAction(extension, index);
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *success = true;
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DLOG(WARNING) << "Attempted to move browser action to invalid index.";
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::GetExtensionProperty(
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int extension_handle,
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationMsg_ExtensionProperty type,
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool* success,
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string* value) {
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *success = false;
915513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetExtension(extension_handle);
91621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension && service) {
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionToolbarModel* toolbar = service->toolbar_model();
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int found_index = -1;
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int index = 0;
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type) {
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case AUTOMATION_MSG_EXTENSION_ID:
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *value = extension->id();
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *success = true;
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case AUTOMATION_MSG_EXTENSION_NAME:
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *value = extension->name();
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *success = true;
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case AUTOMATION_MSG_EXTENSION_VERSION:
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *value = extension->VersionString();
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *success = true;
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (toolbar) {
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          for (ExtensionList::const_iterator iter = toolbar->begin();
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               iter != toolbar->end(); iter++) {
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            // Skip this extension if we are in incognito mode
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            // and it is not incognito-enabled.
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            if (profile_->IsOffTheRecord() &&
941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                !service->IsIncognitoEnabled((*iter)->id()))
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              continue;
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            if (*iter == extension) {
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              found_index = index;
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              break;
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            }
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            index++;
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          *value = base::IntToString(found_index);
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          *success = true;
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        LOG(WARNING) << "Trying to get undefined extension property";
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutomationProvider::SaveAsAsync(int tab_handle) {
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController* tab = NULL;
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents) {
964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContentsWrapper* wrapper =
965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    wrapper->download_tab_helper()->OnSavePage();
967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
969