automation_provider.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// Use of this source code is governed by a BSD-style license that can be
3da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner// found in the LICENSE file.
4da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
5da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "chrome/browser/automation/automation_provider.h"
6da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
7da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include <set>
8da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
9da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "app/message_box_flags.h"
10da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/callback.h"
11da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/debug/trace_event.h"
12da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/file_path.h"
13da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/json/json_reader.h"
14da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/json/json_writer.h"
15da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/json/string_escape.h"
168e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "base/message_loop.h"
17e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "base/path_service.h"
18da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/process_util.h"
19050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "base/stl_util-inl.h"
20da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/string_util.h"
21da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/task.h"
22da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/threading/thread.h"
23da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/string_number_conversions.h"
245be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner#include "base/utf_string_conversions.h"
25da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/values.h"
26da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#include "base/synchronization/waitable_event.h"
27e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/app/chrome_command_ids.h"
28e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/browser/autofill/autofill_manager.h"
29050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
30050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/automation/automation_browser_tracker.h"
31e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/automation/automation_extension_tracker.h"
32e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/automation/automation_provider_list.h"
33e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/automation/automation_provider_observers.h"
348e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/automation/automation_resource_message_filter.h"
358e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/automation/automation_tab_tracker.h"
368e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/automation/automation_window_tracker.h"
374d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner#include "chrome/browser/automation/extension_port_container.h"
388e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/autocomplete/autocomplete_edit.h"
3909b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner#include "chrome/browser/blocked_content_container.h"
4009b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner#include "chrome/browser/bookmarks/bookmark_model.h"
41e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/browser/bookmarks/bookmark_storage.h"
42984e18823e863f2232ccf63f7e84b878dbd55b6fChris Lattner#include "chrome/browser/browser_list.h"
43e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/browser/browser_process.h"
44b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner#include "chrome/browser/browser_thread.h"
458fbad244bd436163296d81d4f182750e000fd16dChris Lattner#include "chrome/browser/browser_window.h"
46050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/browsing_data_remover.h"
474d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner#include "chrome/browser/character_encoding.h"
484d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner#include "chrome/browser/content_settings/host_content_settings_map.h"
4909b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner#include "chrome/browser/dom_operation_notification_details.h"
5009b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner#include "chrome/browser/debugger/devtools_manager.h"
51e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/browser/download/download_item.h"
52d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/browser/download/download_shelf.h"
53984e18823e863f2232ccf63f7e84b878dbd55b6fChris Lattner#include "chrome/browser/download/save_package.h"
54050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/crx_installer.h"
55050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_browser_event_router.h"
56050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_host.h"
57050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_install_ui.h"
58050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_message_service.h"
59050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_tabs_module.h"
60050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_toolbar_model.h"
61050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/extension_service.h"
62050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/extensions/user_script_master.h"
63050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/importer/importer.h"
64050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/importer/importer_data_types.h"
65050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/io_thread.h"
66050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/net/url_request_mock_util.h"
67050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/platform_util.h"
68050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/prefs/pref_service.h"
69050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/printing/print_job.h"
70050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner#include "chrome/browser/profiles/profile_manager.h"
71e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/renderer_host/render_process_host.h"
72e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/renderer_host/render_view_host.h"
73e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/ssl/ssl_manager.h"
74e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/ssl/ssl_blocking_page.h"
75e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/tab_contents/infobar_delegate.h"
76e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/tab_contents/navigation_entry.h"
77e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/tab_contents/tab_contents.h"
78e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/tab_contents/tab_contents_view.h"
79e609a513f3c072bba28412c681465332a2822d9aChris Lattner#include "chrome/browser/translate/translate_infobar_delegate.h"
808e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
818e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
828e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/find_bar/find_bar.h"
838e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/find_bar/find_bar_controller.h"
848e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/find_bar/find_notification_details.h"
858e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/login/login_prompt.h"
868e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/browser/ui/omnibox/location_bar.h"
878e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/common/automation_constants.h"
888e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/common/automation_messages.h"
898e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#include "chrome/common/chrome_constants.h"
90e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/common/chrome_paths.h"
91e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/common/chrome_switches.h"
92e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner#include "chrome/common/chrome_version_info.h"
93d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/common/extensions/extension.h"
94d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/common/json_value_serializer.h"
95d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/common/net/url_request_context_getter.h"
96d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/common/pref_names.h"
97d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/common/url_constants.h"
98d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/test/automation/tab_proxy.h"
99d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "net/proxy/proxy_service.h"
100d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "net/proxy/proxy_config_service_fixed.h"
101d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "net/url_request/url_request_context.h"
102d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "chrome/browser/automation/ui_controls.h"
103d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner#include "views/event.h"
1045007e1e43541114f3737939234104b085fbe4acaChris Lattner#include "webkit/glue/password_form.h"
1055007e1e43541114f3737939234104b085fbe4acaChris Lattner
1065310654dc56c64b726bba7da82d568137ec81bbcChris Lattner#if defined(OS_WIN)
1075007e1e43541114f3737939234104b085fbe4acaChris Lattner#include "chrome/browser/external_tab_container_win.h"
1085007e1e43541114f3737939234104b085fbe4acaChris Lattner#endif  // defined(OS_WIN)
1095007e1e43541114f3737939234104b085fbe4acaChris Lattner
1105007e1e43541114f3737939234104b085fbe4acaChris Lattnerusing base::Time;
1115007e1e43541114f3737939234104b085fbe4acaChris Lattner
1125310654dc56c64b726bba7da82d568137ec81bbcChris LattnerAutomationProvider::AutomationProvider(Profile* profile)
1135007e1e43541114f3737939234104b085fbe4acaChris Lattner    : profile_(profile),
114860d4a787f28f5f31e0c172e2ab80f5ab93cbf9bChris Lattner      reply_message_(NULL),
1155007e1e43541114f3737939234104b085fbe4acaChris Lattner      is_connected_(false),
1165007e1e43541114f3737939234104b085fbe4acaChris Lattner      initial_loads_complete_(false) {
1175007e1e43541114f3737939234104b085fbe4acaChris Lattner  TRACE_EVENT_BEGIN("AutomationProvider::AutomationProvider", 0, "");
1185007e1e43541114f3737939234104b085fbe4acaChris Lattner
1195007e1e43541114f3737939234104b085fbe4acaChris Lattner  browser_tracker_.reset(new AutomationBrowserTracker(this));
1205007e1e43541114f3737939234104b085fbe4acaChris Lattner  extension_tracker_.reset(new AutomationExtensionTracker(this));
1215007e1e43541114f3737939234104b085fbe4acaChris Lattner  tab_tracker_.reset(new AutomationTabTracker(this));
1225007e1e43541114f3737939234104b085fbe4acaChris Lattner  window_tracker_.reset(new AutomationWindowTracker(this));
123da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  autocomplete_edit_tracker_.reset(
124da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      new AutomationAutocompleteEditTracker(this));
125e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner  new_tab_ui_load_observer_.reset(new NewTabUILoadObserver(this));
126d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  dom_operation_observer_.reset(new DomOperationMessageSender(this));
127d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  metric_event_duration_observer_.reset(new MetricEventDurationObserver());
128da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  extension_test_result_observer_.reset(
129da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      new ExtensionTestResultNotificationObserver(this));
130da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  g_browser_process->AddRefModule();
131d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
132d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  TRACE_EVENT_END("AutomationProvider::AutomationProvider", 0, "");
133d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner}
134d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
135d6c84720df0b63e34081e0c7890f3074d8b110b9Chris LattnerAutomationProvider::~AutomationProvider() {
136d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  STLDeleteContainerPairSecondPointers(port_containers_.begin(),
137d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner                                       port_containers_.end());
138d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  port_containers_.clear();
139d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
140d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  // Make sure that any outstanding NotificationObservers also get destroyed.
141d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  ObserverList<NotificationObserver>::Iterator it(notification_observer_list_);
142d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  NotificationObserver* observer;
143d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  while ((observer = it.GetNext()) != NULL)
144d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner    delete observer;
145d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
146d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  if (channel_.get()) {
147d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner    channel_->Close();
148d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  }
149d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  g_browser_process->ReleaseModule();
150d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner}
151d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
152d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattnerbool AutomationProvider::InitializeChannel(const std::string& channel_id) {
153d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  TRACE_EVENT_BEGIN("AutomationProvider::InitializeChannel", 0, "");
154d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
155d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  std::string effective_channel_id = channel_id;
156d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
157d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  // If the channel_id starts with kNamedInterfacePrefix, create a named IPC
158d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  // server and listen on it, else connect as client to an existing IPC server
159d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  bool use_named_interface =
160d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      channel_id.find(automation::kNamedInterfacePrefix) == 0;
161d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  if (use_named_interface) {
162d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner    effective_channel_id = channel_id.substr(
163d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner        strlen(automation::kNamedInterfacePrefix));
164d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner    if (effective_channel_id.length() <= 0)
165d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      return false;
166d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  }
167d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
1685a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner  if (!automation_resource_message_filter_.get()) {
1695a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner    automation_resource_message_filter_ = new AutomationResourceMessageFilter;
1705a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner  }
1715a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner
1725a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner  channel_.reset(new IPC::SyncChannel(
1735a56e5c82aec731cac58db5a86276d526f97a6e2Chris Lattner      effective_channel_id,
174d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      use_named_interface ? IPC::Channel::MODE_NAMED_SERVER
175d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner                          : IPC::Channel::MODE_CLIENT,
176d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      this,
177d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      g_browser_process->io_thread()->message_loop(),
178d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner      true, g_browser_process->shutdown_event()));
179d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  channel_->AddFilter(automation_resource_message_filter_);
180d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
181d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  TRACE_EVENT_END("AutomationProvider::InitializeChannel", 0, "");
182d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner
183d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  return true;
184b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
185845c04273461b2a10754a1455b02916a19ea72aaChris Lattner
1860cebe6181af8a2cf5e6cf9497cda4c47b426a0f8Chris Lattnerstd::string AutomationProvider::GetProtocolVersion() {
1870cebe6181af8a2cf5e6cf9497cda4c47b426a0f8Chris Lattner  chrome::VersionInfo version_info;
188b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  return version_info.Version().c_str();
189da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
19019b5a7590b784f19875b9880ea8838c393431656Chris Lattner
191b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattnervoid AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
192b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  if (expected_tabs == 0)
19319b5a7590b784f19875b9880ea8838c393431656Chris Lattner    OnInitialLoadsComplete();
1940cebe6181af8a2cf5e6cf9497cda4c47b426a0f8Chris Lattner  else
1950cebe6181af8a2cf5e6cf9497cda4c47b426a0f8Chris Lattner    initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
196b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
19719b5a7590b784f19875b9880ea8838c393431656Chris Lattner
1988e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattnervoid AutomationProvider::OnInitialLoadsComplete() {
199b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  initial_loads_complete_ = true;
2008e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  if (is_connected_)
2018e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    Send(new AutomationMsg_InitialLoadsComplete());
2028e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner}
203b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
2048e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris LattnerNotificationObserver* AutomationProvider::AddNavigationStatusListener(
2058e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    NavigationController* tab, IPC::Message* reply_message,
2068e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    int number_of_navigations, bool include_current_navigation) {
207b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  NotificationObserver* observer =
208b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      new NavigationNotificationObserver(tab, this, reply_message,
209da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                                         number_of_navigations,
210da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                                         include_current_navigation);
211b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
212da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  notification_observer_list_.AddObserver(observer);
213da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  return observer;
214da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
215b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
216da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnervoid AutomationProvider::RemoveNavigationStatusListener(
217b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    NotificationObserver* obs) {
218da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  notification_observer_list_.RemoveObserver(obs);
219da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
220b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
221b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris LattnerNotificationObserver* AutomationProvider::AddTabStripObserver(
222050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    Browser* parent,
223050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    IPC::Message* reply_message) {
224da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  NotificationObserver* observer =
225050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      new TabAppendedNotificationObserver(parent, this, reply_message);
226b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  notification_observer_list_.AddObserver(observer);
227b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
228050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  return observer;
229050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner}
230da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
231050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattnervoid AutomationProvider::RemoveTabStripObserver(NotificationObserver* obs) {
232050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  notification_observer_list_.RemoveObserver(obs);
233b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
234da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
235a230f9623d864450d432bb76c397b0cb35a3437eChris Lattnervoid AutomationProvider::AddLoginHandler(NavigationController* tab,
236da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                                         LoginHandler* handler) {
237da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  login_handler_map_[tab] = handler;
238b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
239b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
240a230f9623d864450d432bb76c397b0cb35a3437eChris Lattnervoid AutomationProvider::RemoveLoginHandler(NavigationController* tab) {
241a230f9623d864450d432bb76c397b0cb35a3437eChris Lattner  DCHECK(login_handler_map_[tab]);
242a230f9623d864450d432bb76c397b0cb35a3437eChris Lattner  login_handler_map_.erase(tab);
24312a667c1e8fa57a13ae751164b6dd4412a62dc5dChris Lattner}
244a230f9623d864450d432bb76c397b0cb35a3437eChris Lattner
24512a667c1e8fa57a13ae751164b6dd4412a62dc5dChris Lattnervoid AutomationProvider::AddPortContainer(ExtensionPortContainer* port) {
24612a667c1e8fa57a13ae751164b6dd4412a62dc5dChris Lattner  int port_id = port->port_id();
247b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  DCHECK_NE(-1, port_id);
248da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  DCHECK(port_containers_.find(port_id) == port_containers_.end());
249b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
250da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  port_containers_[port_id] = port;
251b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
25223cfda719e059ce7d761b08fbfb89e676d6c9737Chris Lattner
253b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattnervoid AutomationProvider::RemovePortContainer(ExtensionPortContainer* port) {
254b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  int port_id = port->port_id();
25523cfda719e059ce7d761b08fbfb89e676d6c9737Chris Lattner  DCHECK_NE(-1, port_id);
25623cfda719e059ce7d761b08fbfb89e676d6c9737Chris Lattner
2575310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  PortContainerMap::iterator it = port_containers_.find(port_id);
2585310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  DCHECK(it != port_containers_.end());
2595310654dc56c64b726bba7da82d568137ec81bbcChris Lattner
260b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  if (it != port_containers_.end()) {
261da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    delete it->second;
262b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    port_containers_.erase(it);
263da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
264da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
265b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
266da272d1a704bd564272e88cbdbcf14712e3abbdcChris LattnerExtensionPortContainer* AutomationProvider::GetPortContainer(
267b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    int port_id) const {
268da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  PortContainerMap::const_iterator it = port_containers_.find(port_id);
269da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  if (it == port_containers_.end())
270b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    return NULL;
2715be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner
272b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  return it->second;
2735be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner}
274781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner
275781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattnerint AutomationProvider::GetIndexForNavigationController(
276781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner    const NavigationController* controller, const Browser* parent) const {
277781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner  DCHECK(parent);
278781f359c1a7f590c4f8828ad9d542606c3a0ee12Chris Lattner  return parent->GetIndexOfController(controller);
279da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
2805be6e5990b1da82e31f4236d1b392e52637cbe2eChris Lattner
281da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnerint AutomationProvider::AddExtension(const Extension* extension) {
2825310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  DCHECK(extension);
2835310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  return extension_tracker_->Add(extension);
2845310654dc56c64b726bba7da82d568137ec81bbcChris Lattner}
285da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
2865310654dc56c64b726bba7da82d568137ec81bbcChris Lattner// TODO(phajdan.jr): move to TestingAutomationProvider.
2875310654dc56c64b726bba7da82d568137ec81bbcChris LattnerDictionaryValue* AutomationProvider::GetDictionaryFromDownloadItem(
2885310654dc56c64b726bba7da82d568137ec81bbcChris Lattner    const DownloadItem* download) {
2895310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  std::map<DownloadItem::DownloadState, std::string> state_to_string;
290b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS");
29121390d79843050ae8b3226860cadc16ff51d0dcfChris Lattner  state_to_string[DownloadItem::CANCELLED] = std::string("CANCELLED");
292e39650a805425ffdbd79692c7d1bad80f7332daeChris Lattner  state_to_string[DownloadItem::REMOVING] = std::string("REMOVING");
293b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  state_to_string[DownloadItem::COMPLETE] = std::string("COMPLETE");
2949a747f1305e76025df2323a03b805a284f2cde77Chris Lattner
295b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  std::map<DownloadItem::SafetyState, std::string> safety_state_to_string;
2969a747f1305e76025df2323a03b805a284f2cde77Chris Lattner  safety_state_to_string[DownloadItem::SAFE] = std::string("SAFE");
297845c04273461b2a10754a1455b02916a19ea72aaChris Lattner  safety_state_to_string[DownloadItem::DANGEROUS] = std::string("DANGEROUS");
298b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  safety_state_to_string[DownloadItem::DANGEROUS_BUT_VALIDATED] =
299b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      std::string("DANGEROUS_BUT_VALIDATED");
3005310654dc56c64b726bba7da82d568137ec81bbcChris Lattner
301b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  DictionaryValue* dl_item_value = new DictionaryValue;
3025310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  dl_item_value->SetInteger("id", static_cast<int>(download->id()));
303906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner  dl_item_value->SetString("url", download->url().spec());
304b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  dl_item_value->SetString("referrer_url", download->referrer_url().spec());
305b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  dl_item_value->SetString("file_name",
3068e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                           download->GetFileNameToReportUser().value());
3075310654dc56c64b726bba7da82d568137ec81bbcChris Lattner  dl_item_value->SetString("full_path",
308b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner                           download->GetTargetFilePath().value());
3098e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  dl_item_value->SetBoolean("is_paused", download->is_paused());
3108e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  dl_item_value->SetBoolean("open_when_complete",
3118e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                            download->open_when_complete());
312906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner  dl_item_value->SetBoolean("is_extension_install",
313b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner                            download->is_extension_install());
314906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner  dl_item_value->SetBoolean("is_temporary", download->is_temporary());
315b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  dl_item_value->SetBoolean("is_otr", download->is_otr());  // off-the-record
316b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  dl_item_value->SetString("state", state_to_string[download->state()]);
317906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner  dl_item_value->SetString("safety_state",
318906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner                           safety_state_to_string[download->safety_state()]);
319906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner  dl_item_value->SetInteger("PercentComplete", download->PercentComplete());
320906b4995eeab9e6b6fd11a492498c95bba1ce0afChris Lattner
3218e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  return dl_item_value;
322b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
3238e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner
324b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattnerconst Extension* AutomationProvider::GetExtension(int extension_handle) {
3258e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  return extension_tracker_->GetResource(extension_handle);
3268e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner}
327b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
328b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattnerconst Extension* AutomationProvider::GetEnabledExtension(int extension_handle) {
329b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  const Extension* extension =
3308e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      extension_tracker_->GetResource(extension_handle);
3318e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  ExtensionService* service = profile_->GetExtensionService();
3328e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  if (extension && service &&
3338e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      service->GetExtensionById(extension->id(), false))
3348e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    return extension;
3358e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  return NULL;
336b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
3378e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner
338b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattnerconst Extension* AutomationProvider::GetDisabledExtension(
339b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    int extension_handle) {
3408e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  const Extension* extension =
3418e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      extension_tracker_->GetResource(extension_handle);
342b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  ExtensionService* service = profile_->GetExtensionService();
343b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  if (extension && service &&
3448e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      service->GetExtensionById(extension->id(), true) &&
3458e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      !service->GetExtensionById(extension->id(), false))
3468e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    return extension;
3478e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  return NULL;
3488e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner}
3498e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner
350e86097af5598e44727875f00e492d43c978239beChris Lattnervoid AutomationProvider::OnChannelConnected(int pid) {
3519a21500edc485a2c383a03fba429943f031c1398Chris Lattner  is_connected_ = true;
352e86097af5598e44727875f00e492d43c978239beChris Lattner  LOG(INFO) << "Testing channel connected, sending hello message";
3539a21500edc485a2c383a03fba429943f031c1398Chris Lattner
354e86097af5598e44727875f00e492d43c978239beChris Lattner  // Send a hello message with our current automation protocol version.
3558e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  chrome::VersionInfo version_info;
3568e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  channel_->Send(new AutomationMsg_Hello(version_info.Version()));
357ff7fb60f2a7e2f3efd54df6480aadcb4adf5cab7Chris Lattner  if (initial_loads_complete_)
358ff7fb60f2a7e2f3efd54df6480aadcb4adf5cab7Chris Lattner    Send(new AutomationMsg_InitialLoadsComplete());
3598e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner}
3608e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner
3618e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattnerbool AutomationProvider::OnMessageReceived(const IPC::Message& message) {
3628e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  bool handled = true;
3638e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
3648e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#if !defined(OS_MACOSX)
3658e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
3668e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                                    WindowSimulateDrag)
3678e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner#endif  // !defined(OS_MACOSX)
3688e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
3695007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig)
3705007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
3715007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
3725007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
3735007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SelectAll, SelectAll)
3745007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_Cut, Cut)
3756281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_Copy, Copy)
3766281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_Paste, Paste)
3776281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_ReloadAsync, ReloadAsync)
378ccd23cc2a49f02acbcdd50128a9022477f7cb6a4Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_StopAsync, StopAsync)
3796281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
3806281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
381c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner                                    InstallExtension)
3826281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
3836281cda6737bcda0e924318ddcce28392001691eChris Lattner                                    LoadExpandedExtension)
3846281cda6737bcda0e924318ddcce28392001691eChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions,
3858e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                        GetEnabledExtensions)
386c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForExtensionTestResult,
3879a21500edc485a2c383a03fba429943f031c1398Chris Lattner                                    WaitForExtensionTestResult)
388c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(
389c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner        AutomationMsg_InstallExtensionAndGetHandle,
390c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner        InstallExtensionAndGetHandle)
391c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_UninstallExtension,
392c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner                        UninstallExtension)
393c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_EnableExtension,
394c78f2a39945339752a163949a2d7c27f28635d99Chris Lattner                                    EnableExtension)
3955007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_DisableExtension,
3968e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                        DisableExtension)
397b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(
398b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner        AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
39902f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner        ExecuteExtensionActionInActiveTabAsync)
40002f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_MoveExtensionBrowserAction,
40102f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner                        MoveExtensionBrowserAction)
40202f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_GetExtensionProperty,
40302f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner                        GetExtensionProperty)
40402f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync)
40502f73585f7d018ea3ddcda88c8273ee4e5ea4de3Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBrowsingData, RemoveBrowsingData)
406b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner#if defined(OS_WIN)
407b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    // These are for use with external tabs.
40877f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_CreateExternalTab, CreateExternalTab)
4095007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
41077f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner                        ProcessUnhandledAccelerator)
4115007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
41277f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
41377f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
41477f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner                        OnForwardContextMenuCommandToChrome)
41577f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateInExternalTab,
41677f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner                        NavigateInExternalTab)
4175007e1e43541114f3737939234104b085fbe4acaChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_NavigateExternalTabAtIndex,
418da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                        NavigateExternalTabAtIndex)
41977f2e2724dc488bbf032e87f8f25f333730a0fb5Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
420da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
421da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                        SetEnableExtensionAutomation)
422da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_HandleMessageFromExternalHost,
423da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner                        OnMessageFromExternalHost)
424bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_BrowserMove, OnBrowserMoved)
425e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RunUnloadHandlers,
426b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner                                    OnRunUnloadHandlers)
427984e18823e863f2232ccf63f7e84b878dbd55b6fChris Lattner    IPC_MESSAGE_HANDLER(AutomationMsg_SetZoomLevel, OnSetZoomLevel)
428da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner#endif  // defined(OS_WIN)
4298ef9c7958ad7a23ad15d7ff59e1377aec10ca42aChris Lattner#if defined(OS_CHROMEOS)
43009b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
43109b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner                                    LoginWithUserAndPass)
43209b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner#endif  // defined(OS_CHROMEOS)
43309b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    IPC_MESSAGE_UNHANDLED(handled = false;OnUnhandledMessage())
4348fbad244bd436163296d81d4f182750e000fd16dChris Lattner  IPC_END_MESSAGE_MAP()
435d6c84720df0b63e34081e0c7890f3074d8b110b9Chris Lattner  return handled;
4368fbad244bd436163296d81d4f182750e000fd16dChris Lattner}
4378fbad244bd436163296d81d4f182750e000fd16dChris Lattner
438da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattnervoid AutomationProvider::OnUnhandledMessage() {
439bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner  // We should not hang here. Print a message to indicate what's going on,
440da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  // and disconnect the channel to notify the caller about the error
441bd8227f5298f0ab7b96203a6d3875e5d26573376Chris Lattner  // in a way it can't ignore, and make any further attempts to send
442da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  // messages fail fast.
4438ef9c7958ad7a23ad15d7ff59e1377aec10ca42aChris Lattner  LOG(ERROR) << "AutomationProvider received a message it can't handle. "
444da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner             << "Please make sure that you use switches::kTestingChannelID "
445da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner             << "for test code (TestingAutomationProvider), and "
4464d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner             << "switches::kAutomationClientChannelID for everything else "
4474d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner             << "(like ChromeFrame). Closing the automation channel.";
448b49985a8499e18675db7e9baf920d6ef4e2b65cfChris Lattner  channel_->Close();
449b49985a8499e18675db7e9baf920d6ef4e2b65cfChris Lattner}
450b49985a8499e18675db7e9baf920d6ef4e2b65cfChris Lattner
451e609a513f3c072bba28412c681465332a2822d9aChris Lattner// This task just adds another task to the event queue.  This is useful if
452d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner// you want to ensure that any tasks added to the event queue after this one
453d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner// have already been processed by the time |task| is run.
454d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattnerclass InvokeTaskLaterTask : public Task {
455d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner public:
456d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  explicit InvokeTaskLaterTask(Task* task) : task_(task) {}
457d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  virtual ~InvokeTaskLaterTask() {}
458d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner
459d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  virtual void Run() {
460d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    MessageLoop::current()->PostTask(FROM_HERE, task_);
4614d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  }
462e609a513f3c072bba28412c681465332a2822d9aChris Lattner
4634d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner private:
4644d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  Task* task_;
4654d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4664d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  DISALLOW_COPY_AND_ASSIGN(InvokeTaskLaterTask);
4674d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner};
4684d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4694d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattnervoid AutomationProvider::HandleUnused(const IPC::Message& message, int handle) {
470d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  if (window_tracker_->ContainsHandle(handle)) {
4714d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    window_tracker_->Remove(window_tracker_->GetResource(handle));
472d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  }
473d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner}
4744d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4754d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattnervoid AutomationProvider::OnChannelError() {
4764d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  VLOG(1) << "AutomationProxy went away, shutting down app.";
4774d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  AutomationProviderList::GetInstance()->RemoveProvider(this);
4784d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner}
4794d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4804d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattnerbool AutomationProvider::Send(IPC::Message* msg) {
4814d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  DCHECK(channel_.get());
4824d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  return channel_->Send(msg);
4834d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner}
4844d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4854d0c931ba7758a98864dc7e968a10df7fed7ab70Chris LattnerBrowser* AutomationProvider::FindAndActivateTab(
4864d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    NavigationController* controller) {
4874d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  int tab_index;
4884d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  Browser* browser = Browser::GetBrowserForController(controller, &tab_index);
4894d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  if (browser)
4904d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    browser->SelectTabContentsAt(tab_index, true);
4914d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
4924d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  return browser;
4934d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner}
4944d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
495d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattnervoid AutomationProvider::HandleFindRequest(
496d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    int handle,
497d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    const AutomationMsg_Find_Params& params,
498e609a513f3c072bba28412c681465332a2822d9aChris Lattner    IPC::Message* reply_message) {
499e609a513f3c072bba28412c681465332a2822d9aChris Lattner  if (!tab_tracker_->ContainsHandle(handle)) {
5008e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    AutomationMsg_Find::WriteReplyParams(reply_message, -1, -1);
501d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    Send(reply_message);
502d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    return;
503d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  }
504d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner
505d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  NavigationController* nav = tab_tracker_->GetResource(handle);
506d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  TabContents* tab_contents = nav->tab_contents();
507d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner
508d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  SendFindRequest(tab_contents,
5098e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                  false,
510d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                  params.search_string,
511d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                  params.forward,
512d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                  params.match_case,
513d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                  params.find_next,
514d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                  reply_message);
515d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner}
5168e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner
517d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattnervoid AutomationProvider::SendFindRequest(
518d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    TabContents* tab_contents,
519d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    bool with_json,
520d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    const string16& search_string,
521d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    bool forward,
522d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    bool match_case,
523d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    bool find_next,
524d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    IPC::Message* reply_message) {
525d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  int request_id = FindInPageNotificationObserver::kFindInPageRequestId;
526d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  FindInPageNotificationObserver* observer =
527d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner      new FindInPageNotificationObserver(this,
528e609a513f3c072bba28412c681465332a2822d9aChris Lattner                                         tab_contents,
5298e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner                                         with_json,
5304d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner                                         reply_message);
5318e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  if (!with_json) {
5328e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    find_in_page_observer_.reset(observer);
533d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  }
534d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  tab_contents->set_current_find_request_id(request_id);
535d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner  tab_contents->render_view_host()->StartFinding(
536d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner      FindInPageNotificationObserver::kFindInPageRequestId,
537d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner      search_string,
538d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner      forward,
5394d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner      match_case,
5404d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner      find_next);
5414d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner}
5424d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner
5434d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattnerclass SetProxyConfigTask : public Task {
5444d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner public:
5454d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  SetProxyConfigTask(URLRequestContextGetter* request_context_getter,
5464d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner                     const std::string& new_proxy_config)
5474d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner      : request_context_getter_(request_context_getter),
5484d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner        proxy_config_(new_proxy_config) {}
5494d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  virtual void Run() {
5504d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    // First, deserialize the JSON string. If this fails, log and bail.
5514d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    JSONStringValueSerializer deserializer(proxy_config_);
5524d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    std::string error_msg;
5534d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    scoped_ptr<Value> root(deserializer.Deserialize(NULL, &error_msg));
5544d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
5554d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner      DLOG(WARNING) << "Received bad JSON string for ProxyConfig: "
556d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner                    << error_msg;
557d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner      return;
558d20c0bc5698688f69e52dc4d19cedfcd973a7088Chris Lattner    }
559050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner
560050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    scoped_ptr<DictionaryValue> dict(
56109b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner        static_cast<DictionaryValue*>(root.release()));
56209b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    // Now put together a proxy configuration from the deserialized string.
56309b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    net::ProxyConfig pc;
56409b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    PopulateProxyConfig(*dict.get(), &pc);
565b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
566b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    net::ProxyService* proxy_service =
567b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner        request_context_getter_->GetURLRequestContext()->proxy_service();
568b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    DCHECK(proxy_service);
569b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    scoped_ptr<net::ProxyConfigService> proxy_config_service(
570b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner        new net::ProxyConfigServiceFixed(pc));
571b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    proxy_service->ResetConfigService(proxy_config_service.release());
572b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  }
573b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
574b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  void PopulateProxyConfig(const DictionaryValue& dict, net::ProxyConfig* pc) {
57509b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    DCHECK(pc);
576b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    bool no_proxy = false;
577b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    if (dict.GetBoolean(automation::kJSONProxyNoProxy, &no_proxy)) {
578b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      // Make no changes to the ProxyConfig.
579b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      return;
580b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    }
581b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    bool auto_config;
582b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    if (dict.GetBoolean(automation::kJSONProxyAutoconfig, &auto_config)) {
583b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      pc->set_auto_detect(true);
584b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    }
585b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    std::string pac_url;
586b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    if (dict.GetString(automation::kJSONProxyPacUrl, &pac_url)) {
587b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      pc->set_pac_url(GURL(pac_url));
58809b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    }
589499622b2b1555173006f478bcd8bb8d7c51782f2Chris Lattner    std::string proxy_bypass_list;
590b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
591b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      pc->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_list);
592b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    }
593499622b2b1555173006f478bcd8bb8d7c51782f2Chris Lattner    std::string proxy_server;
594499622b2b1555173006f478bcd8bb8d7c51782f2Chris Lattner    if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
595b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner      pc->proxy_rules().ParseFromString(proxy_server);
596b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner    }
5979a21500edc485a2c383a03fba429943f031c1398Chris Lattner  }
598b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner
599b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner private:
600b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner  scoped_refptr<URLRequestContextGetter> request_context_getter_;
60109b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner  std::string proxy_config_;
60209b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner};
60309b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner
60409b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner
60509b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattnervoid AutomationProvider::SetProxyConfig(const std::string& new_proxy_config) {
60609b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner  URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
60709b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner  if (!context_getter) {
608050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    FilePath user_data_dir;
6094d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
6104d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner    ProfileManager* profile_manager = g_browser_process->profile_manager();
611da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    DCHECK(profile_manager);
612da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
613da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner    DCHECK(profile);
614c84edb7bdd345db280c908583d55bdf4e670a225Chris Lattner    context_getter = profile->GetRequestContext();
615da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner  }
616984e18823e863f2232ccf63f7e84b878dbd55b6fChris Lattner  DCHECK(context_getter);
617e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner
6188e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner  BrowserThread::PostTask(
6198e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner      BrowserThread::IO, FROM_HERE,
620da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner      new SetProxyConfigTask(context_getter, new_proxy_config));
621b21ba71045420b4c0dc5f30e85b9b01c9165eb57Chris Lattner}
622da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner
62309b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris LattnerTabContents* AutomationProvider::GetTabContentsForHandle(
62409b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner    int handle, NavigationController** tab) {
62509b9f3928ee43fdc5af5ee6f4b5ce6d21db0daeeChris Lattner  if (tab_tracker_->ContainsHandle(handle)) {
6268e946bea146c15333ce5f9f1b7a9efe5e75fd892Chris Lattner    NavigationController* nav_controller = tab_tracker_->GetResource(handle);
627e02ea54cfd71dee378ca6b11243710d1760ea7c1Chris Lattner    if (tab)
628050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner      *tab = nav_controller;
629050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner    return nav_controller->tab_contents();
630050a03d0f31ee7033d0459dae3c95b8bf12bff89Chris Lattner  }
6314d0c931ba7758a98864dc7e968a10df7fed7ab70Chris Lattner  return NULL;
632da272d1a704bd564272e88cbdbcf14712e3abbdcChris Lattner}
633
634// Gets the current used encoding name of the page in the specified tab.
635void AutomationProvider::OverrideEncoding(int tab_handle,
636                                          const std::string& encoding_name,
637                                          bool* success) {
638  *success = false;
639  if (tab_tracker_->ContainsHandle(tab_handle)) {
640    NavigationController* nav = tab_tracker_->GetResource(tab_handle);
641    if (!nav)
642      return;
643    Browser* browser = FindAndActivateTab(nav);
644
645    // If the browser has UI, simulate what a user would do.
646    // Activate the tab and then click the encoding menu.
647    if (browser &&
648        browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) {
649      int selected_encoding_id =
650          CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name);
651      if (selected_encoding_id) {
652        browser->OverrideEncoding(selected_encoding_id);
653        *success = true;
654      }
655    } else {
656      // There is no UI, Chrome probably runs as Chrome-Frame mode.
657      // Try to get TabContents and call its override_encoding method.
658      TabContents* contents = nav->tab_contents();
659      if (!contents)
660        return;
661      const std::string selected_encoding =
662          CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name);
663      if (selected_encoding.empty())
664        return;
665      contents->SetOverrideEncoding(selected_encoding);
666    }
667  }
668}
669
670void AutomationProvider::SelectAll(int tab_handle) {
671  RenderViewHost* view = GetViewForTab(tab_handle);
672  if (!view) {
673    NOTREACHED();
674    return;
675  }
676
677  view->SelectAll();
678}
679
680void AutomationProvider::Cut(int tab_handle) {
681  RenderViewHost* view = GetViewForTab(tab_handle);
682  if (!view) {
683    NOTREACHED();
684    return;
685  }
686
687  view->Cut();
688}
689
690void AutomationProvider::Copy(int tab_handle) {
691  RenderViewHost* view = GetViewForTab(tab_handle);
692  if (!view) {
693    NOTREACHED();
694    return;
695  }
696
697  view->Copy();
698}
699
700void AutomationProvider::Paste(int tab_handle) {
701  RenderViewHost* view = GetViewForTab(tab_handle);
702  if (!view) {
703    NOTREACHED();
704    return;
705  }
706
707  view->Paste();
708}
709
710void AutomationProvider::ReloadAsync(int tab_handle) {
711  if (tab_tracker_->ContainsHandle(tab_handle)) {
712    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
713    if (!tab) {
714      NOTREACHED();
715      return;
716    }
717
718    const bool check_for_repost = true;
719    tab->Reload(check_for_repost);
720  }
721}
722
723void AutomationProvider::StopAsync(int tab_handle) {
724  RenderViewHost* view = GetViewForTab(tab_handle);
725  if (!view) {
726    // We tolerate StopAsync being called even before a view has been created.
727    // So just log a warning instead of a NOTREACHED().
728    DLOG(WARNING) << "StopAsync: no view for handle " << tab_handle;
729    return;
730  }
731
732  view->Stop();
733}
734
735void AutomationProvider::OnSetPageFontSize(int tab_handle,
736                                           int font_size) {
737  AutomationPageFontSize automation_font_size =
738      static_cast<AutomationPageFontSize>(font_size);
739
740  if (automation_font_size < SMALLEST_FONT ||
741      automation_font_size > LARGEST_FONT) {
742      DLOG(ERROR) << "Invalid font size specified : "
743                  << font_size;
744      return;
745  }
746
747  if (tab_tracker_->ContainsHandle(tab_handle)) {
748    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
749    DCHECK(tab != NULL);
750    if (tab && tab->tab_contents()) {
751      DCHECK(tab->tab_contents()->profile() != NULL);
752      tab->tab_contents()->profile()->GetPrefs()->SetInteger(
753          prefs::kWebKitDefaultFontSize, font_size);
754    }
755  }
756}
757
758void AutomationProvider::RemoveBrowsingData(int remove_mask) {
759  BrowsingDataRemover* remover;
760  remover = new BrowsingDataRemover(profile(),
761      BrowsingDataRemover::EVERYTHING,  // All time periods.
762      base::Time());
763  remover->Remove(remove_mask);
764  // BrowsingDataRemover deletes itself.
765}
766
767RenderViewHost* AutomationProvider::GetViewForTab(int tab_handle) {
768  if (tab_tracker_->ContainsHandle(tab_handle)) {
769    NavigationController* tab = tab_tracker_->GetResource(tab_handle);
770    if (!tab) {
771      NOTREACHED();
772      return NULL;
773    }
774
775    TabContents* tab_contents = tab->tab_contents();
776    if (!tab_contents) {
777      NOTREACHED();
778      return NULL;
779    }
780
781    RenderViewHost* view_host = tab_contents->render_view_host();
782    return view_host;
783  }
784
785  return NULL;
786}
787
788void AutomationProvider::InstallExtension(const FilePath& crx_path,
789                                          IPC::Message* reply_message) {
790  ExtensionService* service = profile_->GetExtensionService();
791  if (service) {
792    // The observer will delete itself when done.
793    new ExtensionInstallNotificationObserver(this,
794                                             AutomationMsg_InstallExtension::ID,
795                                             reply_message);
796
797    scoped_refptr<CrxInstaller> installer(
798        new CrxInstaller(service, NULL));  // silent install, no UI
799    installer->InstallCrx(crx_path);
800  } else {
801    AutomationMsg_InstallExtension::WriteReplyParams(
802        reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
803    Send(reply_message);
804  }
805}
806
807void AutomationProvider::LoadExpandedExtension(
808    const FilePath& extension_dir,
809    IPC::Message* reply_message) {
810  if (profile_->GetExtensionService()) {
811    // The observer will delete itself when done.
812    new ExtensionInstallNotificationObserver(
813        this,
814        AutomationMsg_LoadExpandedExtension::ID,
815        reply_message);
816
817    profile_->GetExtensionService()->LoadExtension(extension_dir);
818  } else {
819    AutomationMsg_LoadExpandedExtension::WriteReplyParams(
820        reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
821    Send(reply_message);
822  }
823}
824
825void AutomationProvider::GetEnabledExtensions(
826    std::vector<FilePath>* result) {
827  ExtensionService* service = profile_->GetExtensionService();
828  DCHECK(service);
829  if (service->extensions_enabled()) {
830    const ExtensionList* extensions = service->extensions();
831    DCHECK(extensions);
832    for (size_t i = 0; i < extensions->size(); ++i) {
833      const Extension* extension = (*extensions)[i];
834      DCHECK(extension);
835      // AutomationProvider only exposes non app internal/loaded extensions.
836      if (!extension->is_app() &&
837          (extension->location() == Extension::INTERNAL ||
838           extension->location() == Extension::LOAD)) {
839        result->push_back(extension->path());
840      }
841    }
842  }
843}
844
845void AutomationProvider::WaitForExtensionTestResult(
846    IPC::Message* reply_message) {
847  DCHECK(reply_message_ == NULL);
848  reply_message_ = reply_message;
849  // Call MaybeSendResult, because the result might have come in before
850  // we were waiting on it.
851  extension_test_result_observer_->MaybeSendResult();
852}
853
854void AutomationProvider::InstallExtensionAndGetHandle(
855    const FilePath& crx_path, bool with_ui, IPC::Message* reply_message) {
856  ExtensionService* service = profile_->GetExtensionService();
857  ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
858  if (service && manager) {
859    // The observer will delete itself when done.
860    new ExtensionReadyNotificationObserver(
861        manager,
862        this,
863        AutomationMsg_InstallExtensionAndGetHandle::ID,
864        reply_message);
865
866    ExtensionInstallUI* client =
867        (with_ui ? new ExtensionInstallUI(profile_) : NULL);
868    scoped_refptr<CrxInstaller> installer(new CrxInstaller(service, client));
869    installer->InstallCrx(crx_path);
870  } else {
871    AutomationMsg_InstallExtensionAndGetHandle::WriteReplyParams(
872        reply_message, 0);
873    Send(reply_message);
874  }
875}
876
877void AutomationProvider::UninstallExtension(int extension_handle,
878                                            bool* success) {
879  *success = false;
880  const Extension* extension = GetExtension(extension_handle);
881  ExtensionService* service = profile_->GetExtensionService();
882  if (extension && service) {
883    ExtensionUnloadNotificationObserver observer;
884    service->UninstallExtension(extension->id(), false);
885    // The extension unload notification should have been sent synchronously
886    // with the uninstall. Just to be safe, check that it was received.
887    *success = observer.did_receive_unload_notification();
888  }
889}
890
891void AutomationProvider::EnableExtension(int extension_handle,
892                                         IPC::Message* reply_message) {
893  const Extension* extension = GetDisabledExtension(extension_handle);
894  ExtensionService* service = profile_->GetExtensionService();
895  ExtensionProcessManager* manager = profile_->GetExtensionProcessManager();
896  // Only enable if this extension is disabled.
897  if (extension && service && manager) {
898    // The observer will delete itself when done.
899    new ExtensionReadyNotificationObserver(
900        manager,
901        this,
902        AutomationMsg_EnableExtension::ID,
903        reply_message);
904    service->EnableExtension(extension->id());
905  } else {
906    AutomationMsg_EnableExtension::WriteReplyParams(reply_message, false);
907    Send(reply_message);
908  }
909}
910
911void AutomationProvider::DisableExtension(int extension_handle,
912                                          bool* success) {
913  *success = false;
914  const Extension* extension = GetEnabledExtension(extension_handle);
915  ExtensionService* service = profile_->GetExtensionService();
916  if (extension && service) {
917    ExtensionUnloadNotificationObserver observer;
918    service->DisableExtension(extension->id());
919    // The extension unload notification should have been sent synchronously
920    // with the disable. Just to be safe, check that it was received.
921    *success = observer.did_receive_unload_notification();
922  }
923}
924
925void AutomationProvider::ExecuteExtensionActionInActiveTabAsync(
926    int extension_handle, int browser_handle,
927    IPC::Message* reply_message) {
928  bool success = false;
929  const Extension* extension = GetEnabledExtension(extension_handle);
930  ExtensionService* service = profile_->GetExtensionService();
931  ExtensionMessageService* message_service =
932      profile_->GetExtensionMessageService();
933  Browser* browser = browser_tracker_->GetResource(browser_handle);
934  if (extension && service && message_service && browser) {
935    int tab_id = ExtensionTabUtil::GetTabId(browser->GetSelectedTabContents());
936    if (extension->page_action()) {
937      ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
938          browser->profile(), extension->id(), "action", tab_id, "", 1);
939      success = true;
940    } else if (extension->browser_action()) {
941      ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
942          browser->profile(), extension->id(), browser);
943      success = true;
944    }
945  }
946  AutomationMsg_ExecuteExtensionActionInActiveTabAsync::WriteReplyParams(
947      reply_message, success);
948  Send(reply_message);
949}
950
951void AutomationProvider::MoveExtensionBrowserAction(
952    int extension_handle, int index, bool* success) {
953  *success = false;
954  const Extension* extension = GetEnabledExtension(extension_handle);
955  ExtensionService* service = profile_->GetExtensionService();
956  if (extension && service) {
957    ExtensionToolbarModel* toolbar = service->toolbar_model();
958    if (toolbar) {
959      if (index >= 0 && index < static_cast<int>(toolbar->size())) {
960        toolbar->MoveBrowserAction(extension, index);
961        *success = true;
962      } else {
963        DLOG(WARNING) << "Attempted to move browser action to invalid index.";
964      }
965    }
966  }
967}
968
969void AutomationProvider::GetExtensionProperty(
970    int extension_handle,
971    AutomationMsg_ExtensionProperty type,
972    bool* success,
973    std::string* value) {
974  *success = false;
975  const Extension* extension = GetExtension(extension_handle);
976  ExtensionService* service = profile_->GetExtensionService();
977  if (extension && service) {
978    ExtensionToolbarModel* toolbar = service->toolbar_model();
979    int found_index = -1;
980    int index = 0;
981    switch (type) {
982      case AUTOMATION_MSG_EXTENSION_ID:
983        *value = extension->id();
984        *success = true;
985        break;
986      case AUTOMATION_MSG_EXTENSION_NAME:
987        *value = extension->name();
988        *success = true;
989        break;
990      case AUTOMATION_MSG_EXTENSION_VERSION:
991        *value = extension->VersionString();
992        *success = true;
993        break;
994      case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
995        if (toolbar) {
996          for (ExtensionList::const_iterator iter = toolbar->begin();
997               iter != toolbar->end(); iter++) {
998            // Skip this extension if we are in incognito mode
999            // and it is not incognito-enabled.
1000            if (profile_->IsOffTheRecord() &&
1001                !service->IsIncognitoEnabled(*iter))
1002              continue;
1003            if (*iter == extension) {
1004              found_index = index;
1005              break;
1006            }
1007            index++;
1008          }
1009          *value = base::IntToString(found_index);
1010          *success = true;
1011        }
1012        break;
1013      default:
1014        LOG(WARNING) << "Trying to get undefined extension property";
1015        break;
1016    }
1017  }
1018}
1019
1020void AutomationProvider::SaveAsAsync(int tab_handle) {
1021  NavigationController* tab = NULL;
1022  TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
1023  if (tab_contents)
1024    tab_contents->OnSavePage();
1025}
1026