[email protected] | b5717a4 | 2012-02-14 19:33:52 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 2 | // 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] | 0b8caad | 2011-11-28 23:33:27 | [diff] [blame] | 7 | #include "base/bind.h" |
[email protected] | 8c6517e5 | 2011-10-17 01:20:36 | [diff] [blame] | 8 | #include "base/callback.h" |
[email protected] | 5858035 | 2010-10-26 04:07:50 | [diff] [blame] | 9 | #include "base/debug/trace_event.h" |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 10 | #include "base/json/json_reader.h" |
[email protected] | 8e937c1e | 2012-06-28 22:57:30 | [diff] [blame] | 11 | #include "base/run_loop.h" |
[email protected] | 252cad6 | 2010-08-18 18:33:57 | [diff] [blame] | 12 | #include "base/utf_string_conversions.h" |
[email protected] | 67908205 | 2010-07-21 21:30:13 | [diff] [blame] | 13 | #include "chrome/browser/automation/automation_browser_tracker.h" |
[email protected] | 67908205 | 2010-07-21 21:30:13 | [diff] [blame] | 14 | #include "chrome/browser/automation/automation_tab_tracker.h" |
| 15 | #include "chrome/browser/automation/automation_window_tracker.h" |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 16 | #include "chrome/browser/external_tab/external_tab_container.h" |
[email protected] | 6876147 | 2011-08-31 18:55:14 | [diff] [blame] | 17 | #include "chrome/browser/printing/print_view_manager.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 18 | #include "chrome/browser/profiles/profile.h" |
[email protected] | bde40b82 | 2012-08-30 17:28:56 | [diff] [blame] | 19 | #include "chrome/browser/sessions/session_tab_helper.h" |
[email protected] | d2912a2 | 2011-03-15 15:20:50 | [diff] [blame] | 20 | #include "chrome/browser/ui/browser.h" |
[email protected] | 00070c73 | 2011-04-09 15:31:33 | [diff] [blame] | 21 | #include "chrome/browser/ui/browser_window.h" |
[email protected] | a8ba636 | 2010-11-10 20:02:25 | [diff] [blame] | 22 | #include "chrome/common/automation_messages.h" |
[email protected] | 53a0afa | 2011-04-28 02:09:33 | [diff] [blame] | 23 | #include "chrome/common/render_messages.h" |
[email protected] | cdcb1dee | 2012-01-04 00:46:20 | [diff] [blame] | 24 | #include "content/public/browser/navigation_controller.h" |
[email protected] | 9c1662b | 2012-03-06 15:44:33 | [diff] [blame] | 25 | #include "content/public/browser/render_view_host.h" |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 26 | #include "content/public/browser/web_contents.h" |
[email protected] | 54087fe | 2011-10-28 22:02:48 | [diff] [blame] | 27 | #include "content/public/common/page_zoom.h" |
[email protected] | b6d8126 | 2011-01-13 17:36:09 | [diff] [blame] | 28 | #include "ui/base/keycodes/keyboard_codes.h" |
[email protected] | 477ae05 | 2011-11-18 23:53:57 | [diff] [blame] | 29 | #include "ui/views/focus/accelerator_handler.h" |
[email protected] | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 30 | #include "ui/views/widget/root_view.h" |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 31 | |
[email protected] | c5eed49 | 2012-01-04 17:07:50 | [diff] [blame] | 32 | using content::NavigationController; |
[email protected] | eaabba2 | 2012-03-07 15:02:11 | [diff] [blame] | 33 | using content::RenderViewHost; |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 34 | using content::WebContents; |
| 35 | |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 36 | void AutomationProvider::CreateExternalTab( |
[email protected] | f5494d4 | 2010-12-23 22:15:34 | [diff] [blame] | 37 | const ExternalTabSettings& settings, |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 38 | HWND* tab_container_window, |
| 39 | HWND* tab_window, |
| 40 | int* tab_handle, |
| 41 | int* session_id) { |
[email protected] | 366ae24 | 2011-05-10 02:23:58 | [diff] [blame] | 42 | TRACE_EVENT_BEGIN_ETW("AutomationProvider::CreateExternalTab", 0, ""); |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 43 | |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 44 | *tab_handle = 0; |
| 45 | *tab_container_window = NULL; |
| 46 | *tab_window = NULL; |
[email protected] | 751bf4b | 2010-11-05 22:06:31 | [diff] [blame] | 47 | *session_id = -1; |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 48 | scoped_refptr<ExternalTabContainer> external_tab_container = |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 49 | ExternalTabContainer::Create(this, automation_resource_message_filter_); |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 50 | |
[email protected] | 6acaea6 | 2011-03-17 01:18:32 | [diff] [blame] | 51 | Profile* profile = settings.is_incognito ? |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 52 | profile_->GetOffTheRecordProfile() : profile_; |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 53 | |
| 54 | // When the ExternalTabContainer window is created we grab a reference on it |
| 55 | // which is released when the window is destroyed. |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 56 | external_tab_container->Init(profile, settings.parent, settings.dimensions, |
| 57 | settings.style, settings.load_requests_via_automation, |
[email protected] | 7de487c | 2009-12-18 21:07:53 | [diff] [blame] | 58 | settings.handle_top_level_requests, NULL, settings.initial_url, |
[email protected] | 9eeb35e | 2010-09-30 21:38:50 | [diff] [blame] | 59 | settings.referrer, settings.infobars_enabled, |
| 60 | settings.route_all_top_level_navigations); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 61 | |
| 62 | if (AddExternalTab(external_tab_container)) { |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 63 | WebContents* web_contents = external_tab_container->GetWebContents(); |
[email protected] | 50a9a76b | 2012-09-12 14:19:36 | [diff] [blame] | 64 | SessionTabHelper* session_tab_helper = |
| 65 | SessionTabHelper::FromWebContents(web_contents); |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 66 | *tab_handle = external_tab_container->GetTabHandle(); |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 67 | *tab_container_window = external_tab_container->GetExternalTabHWND(); |
| 68 | *tab_window = external_tab_container->GetContentHWND(); |
[email protected] | 50a9a76b | 2012-09-12 14:19:36 | [diff] [blame] | 69 | *session_id = session_tab_helper->session_id().id(); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 70 | } else { |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 71 | external_tab_container->Uninitialize(); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 72 | } |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 73 | |
[email protected] | 366ae24 | 2011-05-10 02:23:58 | [diff] [blame] | 74 | TRACE_EVENT_END_ETW("AutomationProvider::CreateExternalTab", 0, ""); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | bool AutomationProvider::AddExternalTab(ExternalTabContainer* external_tab) { |
| 78 | DCHECK(external_tab != NULL); |
| 79 | |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 80 | WebContents* web_contents = external_tab->GetWebContents(); |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 81 | if (web_contents) { |
| 82 | int tab_handle = tab_tracker_->Add(&web_contents->GetController()); |
[email protected] | 1a98a93 | 2009-11-17 00:12:52 | [diff] [blame] | 83 | external_tab->SetTabHandle(tab_handle); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 84 | return true; |
| 85 | } |
| 86 | |
| 87 | return false; |
| 88 | } |
| 89 | |
| 90 | void 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 | |
| 99 | void AutomationProvider::SetInitialFocus(const IPC::Message& message, |
[email protected] | 1fd4569 | 2010-04-19 21:01:18 | [diff] [blame] | 100 | int handle, bool reverse, |
| 101 | bool restore_focus_to_view) { |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 102 | ExternalTabContainer* external_tab = GetExternalTabForHandle(handle); |
| 103 | if (external_tab) { |
[email protected] | 1fd4569 | 2010-04-19 21:01:18 | [diff] [blame] | 104 | external_tab->FocusThroughTabTraversal(reverse, restore_focus_to_view); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 105 | } |
| 106 | // This message expects no response. |
| 107 | } |
| 108 | |
| 109 | void AutomationProvider::PrintAsync(int tab_handle) { |
[email protected] | ea049a0 | 2011-12-25 21:37:09 | [diff] [blame] | 110 | WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL); |
| 111 | if (!web_contents) |
[email protected] | 49fe226 | 2011-04-15 20:56:15 | [diff] [blame] | 112 | return; |
| 113 | |
[email protected] | e3a7e6f | 2012-09-18 22:44:31 | [diff] [blame] | 114 | printing::PrintViewManager* print_view_manager = |
| 115 | printing::PrintViewManager::FromWebContents(web_contents); |
| 116 | print_view_manager->PrintNow(); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) { |
| 120 | if (tab_tracker_->ContainsHandle(handle)) { |
[email protected] | c5eed49 | 2012-01-04 17:07:50 | [diff] [blame] | 121 | NavigationController* tab = tab_tracker_->GetResource(handle); |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 122 | return ExternalTabContainer::GetContainerForTab(tab->GetWebContents()); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | return NULL; |
| 126 | } |
| 127 | |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 128 | void AutomationProvider::OnTabReposition(int tab_handle, |
| 129 | const Reposition_Params& params) { |
[email protected] | 5a970843 | 2009-09-23 22:15:04 | [diff] [blame] | 130 | 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] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 157 | void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle, |
| 158 | int command) { |
[email protected] | c9d9a81 | 2012-09-26 19:56:30 | [diff] [blame] | 159 | ExternalTabContainer* external_tab = GetExternalTabForHandle(tab_handle); |
[email protected] | bd5ee09 | 2012-10-03 21:28:47 | [diff] [blame] | 160 | if (external_tab) |
| 161 | external_tab->ExecuteContextMenuCommand(command); |
[email protected] | 5ae5bed | 2009-08-21 18:52:44 | [diff] [blame] | 162 | } |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 163 | |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 164 | void 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] | 366ae24 | 2011-05-10 02:23:58 | [diff] [blame] | 171 | TRACE_EVENT_BEGIN_ETW("AutomationProvider::ConnectExternalTab", 0, ""); |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 172 | |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 173 | *tab_handle = 0; |
| 174 | *tab_container_window = NULL; |
| 175 | *tab_window = NULL; |
[email protected] | 751bf4b | 2010-11-05 22:06:31 | [diff] [blame] | 176 | *session_id = -1; |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 177 | |
| 178 | scoped_refptr<ExternalTabContainer> external_tab_container = |
[email protected] | b1c5563861 | 2010-03-08 16:26:11 | [diff] [blame] | 179 | ExternalTabContainer::RemovePendingTab(static_cast<uintptr_t>(cookie)); |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 180 | if (!external_tab_container.get()) { |
| 181 | NOTREACHED(); |
| 182 | return; |
| 183 | } |
| 184 | |
[email protected] | b1c5563861 | 2010-03-08 16:26:11 | [diff] [blame] | 185 | if (allow && AddExternalTab(external_tab_container)) { |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 186 | external_tab_container->Reinitialize(this, |
[email protected] | 6e47f2f | 2010-07-12 17:30:58 | [diff] [blame] | 187 | automation_resource_message_filter_, |
| 188 | parent_window); |
[email protected] | 50a9a76b | 2012-09-12 14:19:36 | [diff] [blame] | 189 | WebContents* web_contents = external_tab_container->GetWebContents(); |
| 190 | SessionTabHelper* session_tab_helper = |
| 191 | SessionTabHelper::FromWebContents(web_contents); |
[email protected] | d370803 | 2012-06-21 06:10:33 | [diff] [blame] | 192 | *tab_handle = external_tab_container->GetTabHandle(); |
[email protected] | ecf59c7 | 2013-02-28 21:46:11 | [diff] [blame] | 193 | *tab_container_window = external_tab_container->GetExternalTabHWND(); |
| 194 | *tab_window = external_tab_container->GetContentHWND(); |
[email protected] | 50a9a76b | 2012-09-12 14:19:36 | [diff] [blame] | 195 | *session_id = session_tab_helper->session_id().id(); |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 196 | } else { |
| 197 | external_tab_container->Uninitialize(); |
| 198 | } |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 199 | |
[email protected] | 366ae24 | 2011-05-10 02:23:58 | [diff] [blame] | 200 | TRACE_EVENT_END_ETW("AutomationProvider::ConnectExternalTab", 0, ""); |
[email protected] | 632fbb1 | 2009-09-06 15:27:14 | [diff] [blame] | 201 | } |
| 202 | |
[email protected] | 2b19e2fe | 2010-02-16 02:24:18 | [diff] [blame] | 203 | void AutomationProvider::OnBrowserMoved(int tab_handle) { |
| 204 | ExternalTabContainer* external_tab = GetExternalTabForHandle(tab_handle); |
[email protected] | 43cb919a | 2011-11-30 20:32:33 | [diff] [blame] | 205 | if (!external_tab) { |
[email protected] | 2b19e2fe | 2010-02-16 02:24:18 | [diff] [blame] | 206 | DLOG(WARNING) << |
| 207 | "AutomationProvider::OnBrowserMoved called with invalid tab handle."; |
| 208 | } |
| 209 | } |
[email protected] | 0082d7e0d | 2010-02-27 14:34:12 | [diff] [blame] | 210 | |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 211 | void 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] | 2ccf45c | 2011-08-19 23:35:50 | [diff] [blame] | 219 | view_host->Send(new ChromeViewMsg_HandleMessageFromExternalHost( |
[email protected] | 9f76c1e | 2012-03-05 15:15:58 | [diff] [blame] | 220 | view_host->GetRoutingID(), message, origin, target)); |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 221 | } |
| 222 | |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 223 | void 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] | c5eed49 | 2012-01-04 17:07:50 | [diff] [blame] | 229 | NavigationController* tab = tab_tracker_->GetResource(handle); |
[email protected] | 95dacd0 | 2011-12-05 10:35:26 | [diff] [blame] | 230 | tab->LoadURL( |
| 231 | url, |
| 232 | content::Referrer(referrer, WebKit::WebReferrerPolicyDefault), |
| 233 | content::PAGE_TRANSITION_TYPED, std::string()); |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 234 | *status = AUTOMATION_MSG_NAVIGATION_SUCCESS; |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | void 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] | c5eed49 | 2012-01-04 17:07:50 | [diff] [blame] | 244 | NavigationController* tab = tab_tracker_->GetResource(handle); |
[email protected] | 52415f84 | 2010-06-10 21:51:52 | [diff] [blame] | 245 | tab->GoToIndex(navigation_index); |
| 246 | *status = AUTOMATION_MSG_NAVIGATION_SUCCESS; |
| 247 | } |
| 248 | } |
[email protected] | 1f71d588 | 2010-07-15 20:39:07 | [diff] [blame] | 249 | |
| 250 | void AutomationProvider::OnRunUnloadHandlers( |
[email protected] | d9d8f0c | 2010-09-17 21:47:16 | [diff] [blame] | 251 | int handle, IPC::Message* reply_message) { |
[email protected] | 1f71d588 | 2010-07-15 20:39:07 | [diff] [blame] | 252 | ExternalTabContainer* external_tab = GetExternalTabForHandle(handle); |
| 253 | if (external_tab) { |
[email protected] | d9d8f0c | 2010-09-17 21:47:16 | [diff] [blame] | 254 | external_tab->RunUnloadHandlers(reply_message); |
[email protected] | 1f71d588 | 2010-07-15 20:39:07 | [diff] [blame] | 255 | } |
| 256 | } |
| 257 | |
[email protected] | 7f860dd8 | 2010-08-09 23:18:05 | [diff] [blame] | 258 | void AutomationProvider::OnSetZoomLevel(int handle, int zoom_level) { |
| 259 | if (tab_tracker_->ContainsHandle(handle)) { |
[email protected] | c5eed49 | 2012-01-04 17:07:50 | [diff] [blame] | 260 | NavigationController* tab = tab_tracker_->GetResource(handle); |
[email protected] | fbc5e5f9 | 2012-01-02 06:08:32 | [diff] [blame] | 261 | if (tab->GetWebContents() && tab->GetWebContents()->GetRenderViewHost()) { |
| 262 | RenderViewHost* host = tab->GetWebContents()->GetRenderViewHost(); |
[email protected] | 54087fe | 2011-10-28 22:02:48 | [diff] [blame] | 263 | content::PageZoom zoom = static_cast<content::PageZoom>(zoom_level); |
[email protected] | 6a64e8a | 2011-09-19 22:59:57 | [diff] [blame] | 264 | host->Zoom(zoom); |
[email protected] | 7f860dd8 | 2010-08-09 23:18:05 | [diff] [blame] | 265 | } |
| 266 | } |
| 267 | } |