blob: 38e74aabdafbcf0dbda12141a69353f3783d16d1 [file] [log] [blame]
[email protected]f90bf0d92011-01-13 02:12:441// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]5a8db802010-10-06 17:34:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]625332e02010-12-14 07:48:495#include "base/lazy_instance.h"
[email protected]c62dd9d2011-09-21 18:05:416#include "base/location.h"
7#include "chrome_frame/external_tab.h"
[email protected]5a8db802010-10-06 17:34:438#include "base/task.h"
[email protected]44f9c952011-01-02 06:05:399#include "base/synchronization/waitable_event.h"
[email protected]a8ba6362010-11-10 20:02:2510#include "chrome/common/automation_messages.h"
[email protected]354bcba2010-12-14 04:34:4311#include "chrome_frame/chrome_frame_delegate.h"
[email protected]5a8db802010-10-06 17:34:4312#include "chrome_frame/utils.h"
13
14DISABLE_RUNNABLE_METHOD_REFCOUNT(ExternalTabProxy);
15DISABLE_RUNNABLE_METHOD_REFCOUNT(UIDelegate);
16
[email protected]11b6e602010-10-13 16:02:2617namespace {
[email protected]625332e02010-12-14 07:48:4918 static base::LazyInstance<ChromeProxyFactory> g_proxy_factory(
19 base::LINKER_INITIALIZED);
[email protected]314a06962010-10-20 21:32:3220
[email protected]11b6e602010-10-13 16:02:2621 struct UserDataHolder : public SyncMessageContext {
22 explicit UserDataHolder(void* p) : data(p) {}
23 void* data;
24 };
25}
26
27
[email protected]314a06962010-10-20 21:32:3228ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), tab_wnd_(NULL),
[email protected]625332e02010-12-14 07:48:4929 chrome_wnd_(NULL), proxy_factory_(g_proxy_factory.Pointer()), proxy_(NULL),
[email protected]5a8db802010-10-06 17:34:4330 ui_delegate_(NULL) {
31}
32
33ExternalTabProxy::~ExternalTabProxy() {
34 Destroy();
35}
36
[email protected]a95986a82010-12-24 06:19:2837bool ExternalTabProxy::OnMessageReceived(const IPC::Message& message) {
38 bool handled = true;
[email protected]f5494d42010-12-23 22:15:3439 IPC_BEGIN_MESSAGE_MAP(ExternalTabProxy, message)
40 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged,
41 OnNavigationStateChanged)
42 IPC_MESSAGE_HANDLER(AutomationMsg_UpdateTargetUrl, OnUpdateTargetUrl)
43 IPC_MESSAGE_HANDLER(AutomationMsg_HandleAccelerator, OnHandleAccelerator)
44 IPC_MESSAGE_HANDLER(AutomationMsg_TabbedOut, OnTabbedOut)
45 IPC_MESSAGE_HANDLER(AutomationMsg_OpenURL, OnOpenURL)
46 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationFailed, OnNavigationFailed)
47 IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate)
48 IPC_MESSAGE_HANDLER(AutomationMsg_TabLoaded, OnTabLoaded)
[email protected]326d3b72011-03-29 20:38:2449 IPC_MESSAGE_HANDLER(AutomationMsg_MoveWindow, OnMoveWindow)
[email protected]f5494d42010-12-23 22:15:3450 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost,
51 OnMessageToHost)
52 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuToExternalHost,
53 OnHandleContextMenu)
54 IPC_MESSAGE_HANDLER(AutomationMsg_RequestStart, OnNetwork_Start)
55 IPC_MESSAGE_HANDLER(AutomationMsg_RequestRead, OnNetwork_Read)
56 IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnNetwork_End)
57 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadRequestInHost,
58 OnNetwork_DownloadInHost)
59 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost, OnGetCookies)
60 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieAsync, OnSetCookie)
61 IPC_MESSAGE_HANDLER(AutomationMsg_AttachExternalTab, OnAttachTab)
62 IPC_MESSAGE_HANDLER(AutomationMsg_RequestGoToHistoryEntryOffset,
63 OnGoToHistoryOffset)
64 IPC_MESSAGE_HANDLER(AutomationMsg_CloseExternalTab, OnTabClosed)
[email protected]a95986a82010-12-24 06:19:2865 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]f5494d42010-12-23 22:15:3466 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:2867 return handled;
[email protected]f5494d42010-12-23 22:15:3468}
69
[email protected]11b6e602010-10-13 16:02:2670void ExternalTabProxy::Init() {
71 if (m_hWnd == NULL) {
72 // Create a window on the UI thread for marshaling messages back and forth
73 // from the IPC thread. This window cannot be a message only window as the
74 // external chrome tab window initially is created as a child of this window
75 CWindowImpl<ExternalTabProxy>::Create(GetDesktopWindow(), NULL, NULL,
76 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOLWINDOW);
77 DCHECK(m_hWnd != NULL);
78 ui_.SetWindow(m_hWnd, WM_APP + 6);
79 }
80}
81
[email protected]5a8db802010-10-06 17:34:4382void ExternalTabProxy::Destroy() {
83 DCHECK(NULL == done_.get());
[email protected]314a06962010-10-20 21:32:3284 // TODO(stoyan): Should we release proxy first and then destroy the window
85 // (parent of the chrome window) or the other way around?
86 if (state_ != NONE) {
87 done_.reset(new base::WaitableEvent(true, false));
88 proxy_factory_->ReleaseProxy(this, tab_params_.proxy_params.profile);
89 done_->Wait();
90 done_.reset(NULL);
[email protected]5a8db802010-10-06 17:34:4391
[email protected]314a06962010-10-20 21:32:3292 state_ = NONE;
93 proxy_ = NULL;
94 tab_ = 0;
95 CWindowImpl<ExternalTabProxy>::DestroyWindow();
96 tab_wnd_ = NULL;
97 chrome_wnd_ = NULL;
98 // We shall tell the TaskMarshaller to delete queued tasks.
99 // ui_.DeleteAll();
100 }
[email protected]5a8db802010-10-06 17:34:43101}
102
103void ExternalTabProxy::CreateTab(const CreateTabParams& create_params,
104 UIDelegate* delegate) {
[email protected]314a06962010-10-20 21:32:32105 DCHECK(ui_delegate_ == NULL);
[email protected]5a8db802010-10-06 17:34:43106 DCHECK_EQ(NONE, state_);
[email protected]11b6e602010-10-13 16:02:26107 // Create host window if needed.
108 Init();
[email protected]5a8db802010-10-06 17:34:43109 ui_delegate_ = delegate;
[email protected]314a06962010-10-20 21:32:32110 // TODO(stoyan): Shall we check the CanNavigate(create_params.url)?
[email protected]5a8db802010-10-06 17:34:43111 tab_params_ = create_params;
112 state_ = INIT_IN_PROGRESS;
[email protected]11b6e602010-10-13 16:02:26113 proxy_factory_->GetProxy(this, create_params.proxy_params);
[email protected]5a8db802010-10-06 17:34:43114}
115
116void ExternalTabProxy::Connected(ChromeProxy* proxy) {
117 // in ipc thread
118 ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
119 &ExternalTabProxy::UiConnected, proxy));
120}
[email protected]11b6e602010-10-13 16:02:26121
122void ExternalTabProxy::UiConnected(ChromeProxy* proxy) {
123 proxy_ = proxy;
[email protected]f5494d42010-12-23 22:15:34124 ExternalTabSettings settings;
[email protected]314a06962010-10-20 21:32:32125 settings.parent = m_hWnd;
126 settings.style = WS_CHILD;
[email protected]6acaea62011-03-17 01:18:32127 settings.is_incognito = tab_params_.is_incognito;
[email protected]314a06962010-10-20 21:32:32128 // TODO(stoyan): FIX this.
129 settings.load_requests_via_automation = true;
130 // TODO(stoyan): FIX this.
131 settings.handle_top_level_requests = true;
132 settings.initial_url = tab_params_.url;
133 settings.referrer = tab_params_.referrer;
134 // Infobars are disabled in widget mode.
135 settings.infobars_enabled = !tab_params_.is_widget_mode;
136 // TODO(stoyan): FIX this.
137 settings.route_all_top_level_navigations = false;
138
139 state_ = CREATE_TAB_IN_PROGRESS;
[email protected]11b6e602010-10-13 16:02:26140 proxy->CreateTab(this, settings);
141}
142
[email protected]5a8db802010-10-06 17:34:43143void ExternalTabProxy::Disconnected() {
144 // in ipc thread
145 DCHECK(done_.get() != NULL);
146 done_->Signal();
147}
148
149void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) {
150 ui_.PostTask(FROM_HERE, NewRunnableMethod(this, &ExternalTabProxy::UiPeerLost,
151 proxy, reason));
152}
153
[email protected]11b6e602010-10-13 16:02:26154void ExternalTabProxy::UiPeerLost(ChromeProxy* proxy, DisconnectReason reason) {
155 // TODO(stoyan):
156}
157
[email protected]5a8db802010-10-06 17:34:43158void ExternalTabProxy::Navigate(const std::string& url,
[email protected]354bcba2010-12-14 04:34:43159 const std::string& referrer,
160 NavigationConstraints* navigation_constraints) {
[email protected]5a8db802010-10-06 17:34:43161 // in ui thread
162 // Catch invalid URLs early. Can we allow this navigation to happen?
163 GURL parsed_url(url);
[email protected]354bcba2010-12-14 04:34:43164 if (!CanNavigate(parsed_url, navigation_constraints)) {
[email protected]5a8db802010-10-06 17:34:43165 DLOG(ERROR) << __FUNCTION__ << " Not allowing navigation to: " << url;
166 return;
167 }
168
[email protected]11b6e602010-10-13 16:02:26169 GURL parsed_referrer(referrer);
170 // If we are still establishing channel, simply replace the params
[email protected]5a8db802010-10-06 17:34:43171 if (state_ == INIT_IN_PROGRESS) {
[email protected]11b6e602010-10-13 16:02:26172 tab_params_.url = parsed_url;
173 tab_params_.referrer = parsed_referrer;
[email protected]5a8db802010-10-06 17:34:43174 }
175
[email protected]11b6e602010-10-13 16:02:26176 // Ah! Too late. Wait to get tab handle and then navigate.
[email protected]5a8db802010-10-06 17:34:43177 if (state_ == CREATE_TAB_IN_PROGRESS) {
[email protected]11b6e602010-10-13 16:02:26178 pending_navigation_.Set(parsed_url, parsed_referrer);
[email protected]5a8db802010-10-06 17:34:43179 }
180
181 if (state_ == READY) {
[email protected]11b6e602010-10-13 16:02:26182 proxy_->Tab_Navigate(tab_, parsed_url, parsed_referrer);
[email protected]5a8db802010-10-06 17:34:43183 }
184}
185
[email protected]11b6e602010-10-13 16:02:26186void ExternalTabProxy::ConnectToExternalTab(uint64 external_tab_cookie) {
187 proxy_->ConnectTab(this, m_hWnd, external_tab_cookie);
188}
189
[email protected]11b6e602010-10-13 16:02:26190void ExternalTabProxy::BlockExternalTab(uint64 cookie) {
191 proxy_->BlockTab(cookie);
192}
193
194void ExternalTabProxy::SetZoomLevel(PageZoom::Function zoom_level) {
195 proxy_->Tab_Zoom(tab_, zoom_level);
196}
197
198void ExternalTabProxy::NavigateToIndex(int index) {
199 CHECK(0);
200}
201
202void ExternalTabProxy::ForwardMessageFromExternalHost(
203 const std::string& message, const std::string& origin,
204 const std::string& target) {
205 proxy_->Tab_PostMessage(tab_, message, origin, target);
206}
207
[email protected]11b6e602010-10-13 16:02:26208void ExternalTabProxy::ChromeFrameHostMoved() {
209 proxy_->Tab_OnHostMoved(tab_);
210}
211
212//////////////////////////////////////////////////////////////////////////
[email protected]314a06962010-10-20 21:32:32213void ExternalTabProxy::UiCompleted_CreateTab(bool success, HWND chrome_window,
[email protected]751bf4b2010-11-05 22:06:31214 HWND tab_window, int tab_handle,
215 int session_id) {
[email protected]314a06962010-10-20 21:32:32216 if (success) {
217 state_ = READY;
218 tab_ = tab_handle;
219 tab_wnd_ = tab_window;
220 chrome_wnd_ = chrome_window;
221
222 // If a navigation request came while tab creation was in progress -
223 // go ahead and navigate.
224 if (pending_navigation_.url.is_valid())
225 proxy_->Tab_Navigate(tab_, pending_navigation_.url,
226 pending_navigation_.referrer);
227 }
228}
229
[email protected]5a8db802010-10-06 17:34:43230void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd,
[email protected]751bf4b2010-11-05 22:06:31231 HWND tab_window, int tab_handle,
232 int session_id) {
[email protected]5a8db802010-10-06 17:34:43233 // in ipc_thread.
[email protected]314a06962010-10-20 21:32:32234 ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
235 &ExternalTabProxy::UiCompleted_CreateTab,
[email protected]751bf4b2010-11-05 22:06:31236 success, chrome_wnd, tab_window, tab_handle, session_id));
[email protected]5a8db802010-10-06 17:34:43237}
238
[email protected]f5494d42010-12-23 22:15:34239void ExternalTabProxy::Completed_ConnectToTab(
240 bool success, HWND chrome_window, HWND tab_window, int tab_handle,
241 int session_id) {
[email protected]5a8db802010-10-06 17:34:43242 CHECK(0);
243}
244
[email protected]f5494d42010-12-23 22:15:34245void ExternalTabProxy::Completed_Navigate(
246 bool success, enum AutomationMsg_NavigationResponseValues res) {
[email protected]5a8db802010-10-06 17:34:43247 // ipc_thread;
248 CHECK(0);
249}
250
[email protected]f5494d42010-12-23 22:15:34251void ExternalTabProxy::OnNavigationStateChanged(
252 int flags, const NavigationInfo& nav_info) {
[email protected]5a8db802010-10-06 17:34:43253 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
254 &UIDelegate::OnNavigationStateChanged, flags, nav_info));
255}
256
[email protected]f5494d42010-12-23 22:15:34257void ExternalTabProxy::OnUpdateTargetUrl(const std::wstring& url) {
[email protected]5a8db802010-10-06 17:34:43258 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
259 &UIDelegate::OnUpdateTargetUrl, url));
260}
261
[email protected]f5494d42010-12-23 22:15:34262void ExternalTabProxy::OnTabLoaded(const GURL& url) {
[email protected]5a8db802010-10-06 17:34:43263 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
264 &UIDelegate::OnLoad, url));
265}
[email protected]11b6e602010-10-13 16:02:26266
[email protected]326d3b72011-03-29 20:38:24267void ExternalTabProxy::OnMoveWindow(const gfx::Rect& pos) {
268 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
269 &UIDelegate::OnMoveWindow, pos));
270}
271
[email protected]f5494d42010-12-23 22:15:34272void ExternalTabProxy::OnMessageToHost(const std::string& message,
273 const std::string& origin,
274 const std::string& target) {
[email protected]11b6e602010-10-13 16:02:26275 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
276 &UIDelegate::OnMessageFromChromeFrame, message, origin, target));
277}
278
[email protected]f5494d42010-12-23 22:15:34279void ExternalTabProxy::OnHandleAccelerator(const MSG& accel_message) {
[email protected]11b6e602010-10-13 16:02:26280 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
281 &UIDelegate::OnHandleAccelerator, accel_message));
282}
283
[email protected]f5494d42010-12-23 22:15:34284void ExternalTabProxy::OnHandleContextMenu(
[email protected]b516e2d2011-07-12 16:54:12285 const ContextMenuModel& context_menu_model,
[email protected]47af65f02010-11-08 21:43:55286 int align_flags,
[email protected]f5494d42010-12-23 22:15:34287 const MiniContextMenuParams& params) {
[email protected]11b6e602010-10-13 16:02:26288 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
[email protected]b516e2d2011-07-12 16:54:12289 &UIDelegate::OnHandleContextMenu, context_menu_model, align_flags,
290 params));
[email protected]11b6e602010-10-13 16:02:26291}
292
[email protected]f5494d42010-12-23 22:15:34293void ExternalTabProxy::OnTabbedOut(bool reverse) {
[email protected]11b6e602010-10-13 16:02:26294 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
295 &UIDelegate::OnTabbedOut, reverse));
296}
297
[email protected]f5494d42010-12-23 22:15:34298void ExternalTabProxy::OnGoToHistoryOffset(int offset) {
[email protected]11b6e602010-10-13 16:02:26299 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
300 &UIDelegate::OnGoToHistoryOffset, offset));
301}
302
[email protected]f5494d42010-12-23 22:15:34303void ExternalTabProxy::OnOpenURL(const GURL& url_to_open, const GURL& referrer,
304 int open_disposition) {
[email protected]11b6e602010-10-13 16:02:26305 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
306 &UIDelegate::OnOpenURL, url_to_open, referrer, open_disposition));
307}
308
[email protected]f5494d42010-12-23 22:15:34309void ExternalTabProxy::OnNavigationFailed(int error_code, const GURL& gurl) {
[email protected]11b6e602010-10-13 16:02:26310 // TODO(stoyan):
311}
312
[email protected]f5494d42010-12-23 22:15:34313void ExternalTabProxy::OnDidNavigate(const NavigationInfo& navigation_info) {
[email protected]11b6e602010-10-13 16:02:26314 // TODO(stoyan):
315}
316
[email protected]f5494d42010-12-23 22:15:34317void ExternalTabProxy::OnNetwork_Start(
318 int request_id, const AutomationURLRequest& request_info) {
[email protected]11b6e602010-10-13 16:02:26319 // TODO(stoyan): url_fetcher_.Start();
320}
321
[email protected]f5494d42010-12-23 22:15:34322void ExternalTabProxy::OnNetwork_Read(int request_id, int bytes_to_read) {
[email protected]11b6e602010-10-13 16:02:26323 // TODO(stoyan): url_fetcher_.Read();
324}
325
[email protected]f5494d42010-12-23 22:15:34326void ExternalTabProxy::OnNetwork_End(int request_id,
[email protected]f90bf0d92011-01-13 02:12:44327 const net::URLRequestStatus& s) {
[email protected]11b6e602010-10-13 16:02:26328 // TODO(stoyan):
329}
330
[email protected]f5494d42010-12-23 22:15:34331void ExternalTabProxy::OnNetwork_DownloadInHost(int request_id) {
[email protected]11b6e602010-10-13 16:02:26332 // TODO(stoyan):
333}
334
[email protected]f5494d42010-12-23 22:15:34335void ExternalTabProxy::OnGetCookies(const GURL& url, int cookie_id) {
[email protected]11b6e602010-10-13 16:02:26336 // TODO(stoyan):
337}
338
[email protected]f5494d42010-12-23 22:15:34339void ExternalTabProxy::OnSetCookie(const GURL& url, const std::string& cookie) {
[email protected]11b6e602010-10-13 16:02:26340 // TODO(stoyan):
341}
342
[email protected]f5494d42010-12-23 22:15:34343void ExternalTabProxy::OnTabClosed() {
[email protected]11b6e602010-10-13 16:02:26344 // TODO(stoyan):
345}
346
[email protected]f5494d42010-12-23 22:15:34347void ExternalTabProxy::OnAttachTab(
348 const AttachExternalTabParams& attach_params) {
[email protected]11b6e602010-10-13 16:02:26349 // TODO(stoyan):
350}