blob: 3bf1c129b84198dafe9d913cf1d3c9db5f21d81a [file] [log] [blame]
[email protected]b5717a42012-02-14 19:33:521// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]5ae5bed2009-08-21 18:52:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/automation/automation_provider.h"
6
[email protected]0b8caad2011-11-28 23:33:277#include "base/bind.h"
[email protected]8c6517e52011-10-17 01:20:368#include "base/callback.h"
[email protected]58580352010-10-26 04:07:509#include "base/debug/trace_event.h"
[email protected]52415f842010-06-10 21:51:5210#include "base/json/json_reader.h"
[email protected]8e937c1e2012-06-28 22:57:3011#include "base/run_loop.h"
[email protected]252cad62010-08-18 18:33:5712#include "base/utf_string_conversions.h"
[email protected]679082052010-07-21 21:30:1313#include "chrome/browser/automation/automation_browser_tracker.h"
[email protected]679082052010-07-21 21:30:1314#include "chrome/browser/automation/automation_tab_tracker.h"
15#include "chrome/browser/automation/automation_window_tracker.h"
[email protected]d3708032012-06-21 06:10:3316#include "chrome/browser/external_tab/external_tab_container.h"
[email protected]68761472011-08-31 18:55:1417#include "chrome/browser/printing/print_view_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3318#include "chrome/browser/profiles/profile.h"
[email protected]bde40b822012-08-30 17:28:5619#include "chrome/browser/sessions/session_tab_helper.h"
[email protected]d2912a22011-03-15 15:20:5020#include "chrome/browser/ui/browser.h"
[email protected]00070c732011-04-09 15:31:3321#include "chrome/browser/ui/browser_window.h"
[email protected]a8ba6362010-11-10 20:02:2522#include "chrome/common/automation_messages.h"
[email protected]53a0afa2011-04-28 02:09:3323#include "chrome/common/render_messages.h"
[email protected]cdcb1dee2012-01-04 00:46:2024#include "content/public/browser/navigation_controller.h"
[email protected]9c1662b2012-03-06 15:44:3325#include "content/public/browser/render_view_host.h"
[email protected]ea049a02011-12-25 21:37:0926#include "content/public/browser/web_contents.h"
[email protected]54087fe2011-10-28 22:02:4827#include "content/public/common/page_zoom.h"
[email protected]b6d81262011-01-13 17:36:0928#include "ui/base/keycodes/keyboard_codes.h"
[email protected]477ae052011-11-18 23:53:5729#include "ui/views/focus/accelerator_handler.h"
[email protected]c13be0d2011-11-22 02:09:5830#include "ui/views/widget/root_view.h"
[email protected]5ae5bed2009-08-21 18:52:4431
[email protected]c5eed492012-01-04 17:07:5032using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1133using content::RenderViewHost;
[email protected]ea049a02011-12-25 21:37:0934using content::WebContents;
35
[email protected]5ae5bed2009-08-21 18:52:4436void AutomationProvider::CreateExternalTab(
[email protected]f5494d42010-12-23 22:15:3437 const ExternalTabSettings& settings,
[email protected]ecf59c72013-02-28 21:46:1138 HWND* tab_container_window,
39 HWND* tab_window,
40 int* tab_handle,
41 int* session_id) {
[email protected]366ae242011-05-10 02:23:5842 TRACE_EVENT_BEGIN_ETW("AutomationProvider::CreateExternalTab", 0, "");
[email protected]a872ea1f2010-08-11 04:45:3343
[email protected]5ae5bed2009-08-21 18:52:4444 *tab_handle = 0;
45 *tab_container_window = NULL;
46 *tab_window = NULL;
[email protected]751bf4b2010-11-05 22:06:3147 *session_id = -1;
[email protected]632fbb12009-09-06 15:27:1448 scoped_refptr<ExternalTabContainer> external_tab_container =
[email protected]d3708032012-06-21 06:10:3349 ExternalTabContainer::Create(this, automation_resource_message_filter_);
[email protected]632fbb12009-09-06 15:27:1450
[email protected]6acaea62011-03-17 01:18:3251 Profile* profile = settings.is_incognito ?
[email protected]5ae5bed2009-08-21 18:52:4452 profile_->GetOffTheRecordProfile() : profile_;
[email protected]632fbb12009-09-06 15:27:1453
54 // When the ExternalTabContainer window is created we grab a reference on it
55 // which is released when the window is destroyed.
[email protected]5ae5bed2009-08-21 18:52:4456 external_tab_container->Init(profile, settings.parent, settings.dimensions,
57 settings.style, settings.load_requests_via_automation,
[email protected]7de487c2009-12-18 21:07:5358 settings.handle_top_level_requests, NULL, settings.initial_url,
[email protected]9eeb35e2010-09-30 21:38:5059 settings.referrer, settings.infobars_enabled,
60 settings.route_all_top_level_navigations);
[email protected]5ae5bed2009-08-21 18:52:4461
62 if (AddExternalTab(external_tab_container)) {
[email protected]d3708032012-06-21 06:10:3363 WebContents* web_contents = external_tab_container->GetWebContents();
[email protected]50a9a76b2012-09-12 14:19:3664 SessionTabHelper* session_tab_helper =
65 SessionTabHelper::FromWebContents(web_contents);
[email protected]d3708032012-06-21 06:10:3366 *tab_handle = external_tab_container->GetTabHandle();
[email protected]ecf59c72013-02-28 21:46:1167 *tab_container_window = external_tab_container->GetExternalTabHWND();
68 *tab_window = external_tab_container->GetContentHWND();
[email protected]50a9a76b2012-09-12 14:19:3669 *session_id = session_tab_helper->session_id().id();
[email protected]5ae5bed2009-08-21 18:52:4470 } else {
[email protected]632fbb12009-09-06 15:27:1471 external_tab_container->Uninitialize();
[email protected]5ae5bed2009-08-21 18:52:4472 }
[email protected]a872ea1f2010-08-11 04:45:3373
[email protected]366ae242011-05-10 02:23:5874 TRACE_EVENT_END_ETW("AutomationProvider::CreateExternalTab", 0, "");
[email protected]5ae5bed2009-08-21 18:52:4475}
76
77bool AutomationProvider::AddExternalTab(ExternalTabContainer* external_tab) {
78 DCHECK(external_tab != NULL);
79
[email protected]d3708032012-06-21 06:10:3380 WebContents* web_contents = external_tab->GetWebContents();
[email protected]ea049a02011-12-25 21:37:0981 if (web_contents) {
82 int tab_handle = tab_tracker_->Add(&web_contents->GetController());
[email protected]1a98a932009-11-17 00:12:5283 external_tab->SetTabHandle(tab_handle);
[email protected]5ae5bed2009-08-21 18:52:4484 return true;
85 }
86
87 return false;
88}
89
90void AutomationProvider::ProcessUnhandledAccelerator(
91 const IPC::Message& message, int handle, const MSG& msg) {
92 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
93 if (external_tab) {
94 external_tab->ProcessUnhandledAccelerator(msg);
95 }
96 // This message expects no response.
97}
98
99void AutomationProvider::SetInitialFocus(const IPC::Message& message,
[email protected]1fd45692010-04-19 21:01:18100 int handle, bool reverse,
101 bool restore_focus_to_view) {
[email protected]5ae5bed2009-08-21 18:52:44102 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
103 if (external_tab) {
[email protected]1fd45692010-04-19 21:01:18104 external_tab->FocusThroughTabTraversal(reverse, restore_focus_to_view);
[email protected]5ae5bed2009-08-21 18:52:44105 }
106 // This message expects no response.
107}
108
109void AutomationProvider::PrintAsync(int tab_handle) {
[email protected]ea049a02011-12-25 21:37:09110 WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
111 if (!web_contents)
[email protected]49fe2262011-04-15 20:56:15112 return;
113
[email protected]e3a7e6f2012-09-18 22:44:31114 printing::PrintViewManager* print_view_manager =
115 printing::PrintViewManager::FromWebContents(web_contents);
116 print_view_manager->PrintNow();
[email protected]5ae5bed2009-08-21 18:52:44117}
118
119ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
120 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]c5eed492012-01-04 17:07:50121 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]ecf59c72013-02-28 21:46:11122 return ExternalTabContainer::GetContainerForTab(tab->GetWebContents());
[email protected]5ae5bed2009-08-21 18:52:44123 }
124
125 return NULL;
126}
127
[email protected]ecf59c72013-02-28 21:46:11128void AutomationProvider::OnTabReposition(int tab_handle,
129 const Reposition_Params& params) {
[email protected]5a9708432009-09-23 22:15:04130 if (!tab_tracker_->ContainsHandle(tab_handle))
131 return;
132
133 if (!IsWindow(params.window))
134 return;
135
136 unsigned long process_id = 0;
137 unsigned long thread_id = 0;
138
139 thread_id = GetWindowThreadProcessId(params.window, &process_id);
140
141 if (thread_id != GetCurrentThreadId()) {
142 DCHECK_EQ(thread_id, GetCurrentThreadId());
143 return;
144 }
145
146 SetWindowPos(params.window, params.window_insert_after, params.left,
147 params.top, params.width, params.height, params.flags);
148
149 if (params.set_parent) {
150 if (IsWindow(params.parent_window)) {
151 if (!SetParent(params.window, params.parent_window))
152 DLOG(WARNING) << "SetParent failed. Error 0x%x" << GetLastError();
153 }
154 }
155}
156
[email protected]5ae5bed2009-08-21 18:52:44157void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle,
158 int command) {
[email protected]c9d9a812012-09-26 19:56:30159 ExternalTabContainer* external_tab = GetExternalTabForHandle(tab_handle);
[email protected]bd5ee092012-10-03 21:28:47160 if (external_tab)
161 external_tab->ExecuteContextMenuCommand(command);
[email protected]5ae5bed2009-08-21 18:52:44162}
[email protected]632fbb12009-09-06 15:27:14163
[email protected]ecf59c72013-02-28 21:46:11164void AutomationProvider::ConnectExternalTab(uint64 cookie,
165 bool allow,
166 HWND parent_window,
167 HWND* tab_container_window,
168 HWND* tab_window,
169 int* tab_handle,
170 int* session_id) {
[email protected]366ae242011-05-10 02:23:58171 TRACE_EVENT_BEGIN_ETW("AutomationProvider::ConnectExternalTab", 0, "");
[email protected]a872ea1f2010-08-11 04:45:33172
[email protected]632fbb12009-09-06 15:27:14173 *tab_handle = 0;
174 *tab_container_window = NULL;
175 *tab_window = NULL;
[email protected]751bf4b2010-11-05 22:06:31176 *session_id = -1;
[email protected]632fbb12009-09-06 15:27:14177
178 scoped_refptr<ExternalTabContainer> external_tab_container =
[email protected]b1c55638612010-03-08 16:26:11179 ExternalTabContainer::RemovePendingTab(static_cast<uintptr_t>(cookie));
[email protected]632fbb12009-09-06 15:27:14180 if (!external_tab_container.get()) {
181 NOTREACHED();
182 return;
183 }
184
[email protected]b1c55638612010-03-08 16:26:11185 if (allow && AddExternalTab(external_tab_container)) {
[email protected]632fbb12009-09-06 15:27:14186 external_tab_container->Reinitialize(this,
[email protected]6e47f2f2010-07-12 17:30:58187 automation_resource_message_filter_,
188 parent_window);
[email protected]50a9a76b2012-09-12 14:19:36189 WebContents* web_contents = external_tab_container->GetWebContents();
190 SessionTabHelper* session_tab_helper =
191 SessionTabHelper::FromWebContents(web_contents);
[email protected]d3708032012-06-21 06:10:33192 *tab_handle = external_tab_container->GetTabHandle();
[email protected]ecf59c72013-02-28 21:46:11193 *tab_container_window = external_tab_container->GetExternalTabHWND();
194 *tab_window = external_tab_container->GetContentHWND();
[email protected]50a9a76b2012-09-12 14:19:36195 *session_id = session_tab_helper->session_id().id();
[email protected]632fbb12009-09-06 15:27:14196 } else {
197 external_tab_container->Uninitialize();
198 }
[email protected]a872ea1f2010-08-11 04:45:33199
[email protected]366ae242011-05-10 02:23:58200 TRACE_EVENT_END_ETW("AutomationProvider::ConnectExternalTab", 0, "");
[email protected]632fbb12009-09-06 15:27:14201}
202
[email protected]2b19e2fe2010-02-16 02:24:18203void AutomationProvider::OnBrowserMoved(int tab_handle) {
204 ExternalTabContainer* external_tab = GetExternalTabForHandle(tab_handle);
[email protected]43cb919a2011-11-30 20:32:33205 if (!external_tab) {
[email protected]2b19e2fe2010-02-16 02:24:18206 DLOG(WARNING) <<
207 "AutomationProvider::OnBrowserMoved called with invalid tab handle.";
208 }
209}
[email protected]0082d7e0d2010-02-27 14:34:12210
[email protected]52415f842010-06-10 21:51:52211void AutomationProvider::OnMessageFromExternalHost(int handle,
212 const std::string& message,
213 const std::string& origin,
214 const std::string& target) {
215 RenderViewHost* view_host = GetViewForTab(handle);
216 if (!view_host)
217 return;
218
[email protected]2ccf45c2011-08-19 23:35:50219 view_host->Send(new ChromeViewMsg_HandleMessageFromExternalHost(
[email protected]9f76c1e2012-03-05 15:15:58220 view_host->GetRoutingID(), message, origin, target));
[email protected]52415f842010-06-10 21:51:52221}
222
[email protected]52415f842010-06-10 21:51:52223void AutomationProvider::NavigateInExternalTab(
224 int handle, const GURL& url, const GURL& referrer,
225 AutomationMsg_NavigationResponseValues* status) {
226 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
227
228 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]c5eed492012-01-04 17:07:50229 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]95dacd02011-12-05 10:35:26230 tab->LoadURL(
231 url,
232 content::Referrer(referrer, WebKit::WebReferrerPolicyDefault),
233 content::PAGE_TRANSITION_TYPED, std::string());
[email protected]52415f842010-06-10 21:51:52234 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
235 }
236}
237
238void AutomationProvider::NavigateExternalTabAtIndex(
239 int handle, int navigation_index,
240 AutomationMsg_NavigationResponseValues* status) {
241 *status = AUTOMATION_MSG_NAVIGATION_ERROR;
242
243 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]c5eed492012-01-04 17:07:50244 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]52415f842010-06-10 21:51:52245 tab->GoToIndex(navigation_index);
246 *status = AUTOMATION_MSG_NAVIGATION_SUCCESS;
247 }
248}
[email protected]1f71d5882010-07-15 20:39:07249
250void AutomationProvider::OnRunUnloadHandlers(
[email protected]d9d8f0c2010-09-17 21:47:16251 int handle, IPC::Message* reply_message) {
[email protected]1f71d5882010-07-15 20:39:07252 ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
253 if (external_tab) {
[email protected]d9d8f0c2010-09-17 21:47:16254 external_tab->RunUnloadHandlers(reply_message);
[email protected]1f71d5882010-07-15 20:39:07255 }
256}
257
[email protected]7f860dd82010-08-09 23:18:05258void AutomationProvider::OnSetZoomLevel(int handle, int zoom_level) {
259 if (tab_tracker_->ContainsHandle(handle)) {
[email protected]c5eed492012-01-04 17:07:50260 NavigationController* tab = tab_tracker_->GetResource(handle);
[email protected]fbc5e5f92012-01-02 06:08:32261 if (tab->GetWebContents() && tab->GetWebContents()->GetRenderViewHost()) {
262 RenderViewHost* host = tab->GetWebContents()->GetRenderViewHost();
[email protected]54087fe2011-10-28 22:02:48263 content::PageZoom zoom = static_cast<content::PageZoom>(zoom_level);
[email protected]6a64e8a2011-09-19 22:59:57264 host->Zoom(zoom);
[email protected]7f860dd82010-08-09 23:18:05265 }
266 }
267}