blob: 785f6afbb7b133ab1ac41fbdc1d94009c06bc764 [file] [log] [blame]
[email protected]5a8db802010-10-06 17:34:431// Copyright (c) 2010 The Chromium Authors. All rights reserved.
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_frame/external_tab.h"
[email protected]314a06962010-10-20 21:32:326#include "base/singleton.h"
[email protected]5a8db802010-10-06 17:34:437#include "base/tracked.h"
8#include "base/task.h"
9#include "base/waitable_event.h"
[email protected]ea1c18e2010-11-01 19:24:3310#include "chrome/test/automation/automation_messages.h"
[email protected]5a8db802010-10-06 17:34:4311#include "chrome_frame/utils.h"
12
13DISABLE_RUNNABLE_METHOD_REFCOUNT(ExternalTabProxy);
14DISABLE_RUNNABLE_METHOD_REFCOUNT(UIDelegate);
15
[email protected]11b6e602010-10-13 16:02:2616namespace {
[email protected]314a06962010-10-20 21:32:3217 Singleton<ChromeProxyFactory> g_proxy_factory;
18
[email protected]11b6e602010-10-13 16:02:2619 struct UserDataHolder : public SyncMessageContext {
20 explicit UserDataHolder(void* p) : data(p) {}
21 void* data;
22 };
23}
24
25
[email protected]314a06962010-10-20 21:32:3226ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), tab_wnd_(NULL),
27 chrome_wnd_(NULL), proxy_factory_(g_proxy_factory.get()), proxy_(NULL),
[email protected]5a8db802010-10-06 17:34:4328 ui_delegate_(NULL) {
29}
30
31ExternalTabProxy::~ExternalTabProxy() {
32 Destroy();
33}
34
[email protected]11b6e602010-10-13 16:02:2635void ExternalTabProxy::Init() {
36 if (m_hWnd == NULL) {
37 // Create a window on the UI thread for marshaling messages back and forth
38 // from the IPC thread. This window cannot be a message only window as the
39 // external chrome tab window initially is created as a child of this window
40 CWindowImpl<ExternalTabProxy>::Create(GetDesktopWindow(), NULL, NULL,
41 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOLWINDOW);
42 DCHECK(m_hWnd != NULL);
43 ui_.SetWindow(m_hWnd, WM_APP + 6);
44 }
45}
46
[email protected]5a8db802010-10-06 17:34:4347void ExternalTabProxy::Destroy() {
48 DCHECK(NULL == done_.get());
[email protected]314a06962010-10-20 21:32:3249 // TODO(stoyan): Should we release proxy first and then destroy the window
50 // (parent of the chrome window) or the other way around?
51 if (state_ != NONE) {
52 done_.reset(new base::WaitableEvent(true, false));
53 proxy_factory_->ReleaseProxy(this, tab_params_.proxy_params.profile);
54 done_->Wait();
55 done_.reset(NULL);
[email protected]5a8db802010-10-06 17:34:4356
[email protected]314a06962010-10-20 21:32:3257 state_ = NONE;
58 proxy_ = NULL;
59 tab_ = 0;
60 CWindowImpl<ExternalTabProxy>::DestroyWindow();
61 tab_wnd_ = NULL;
62 chrome_wnd_ = NULL;
63 // We shall tell the TaskMarshaller to delete queued tasks.
64 // ui_.DeleteAll();
65 }
[email protected]5a8db802010-10-06 17:34:4366}
67
68void ExternalTabProxy::CreateTab(const CreateTabParams& create_params,
69 UIDelegate* delegate) {
[email protected]314a06962010-10-20 21:32:3270 DCHECK(ui_delegate_ == NULL);
[email protected]5a8db802010-10-06 17:34:4371 DCHECK_EQ(NONE, state_);
[email protected]11b6e602010-10-13 16:02:2672 // Create host window if needed.
73 Init();
[email protected]5a8db802010-10-06 17:34:4374 ui_delegate_ = delegate;
[email protected]314a06962010-10-20 21:32:3275 // TODO(stoyan): Shall we check the CanNavigate(create_params.url)?
[email protected]5a8db802010-10-06 17:34:4376 tab_params_ = create_params;
77 state_ = INIT_IN_PROGRESS;
[email protected]11b6e602010-10-13 16:02:2678 proxy_factory_->GetProxy(this, create_params.proxy_params);
[email protected]5a8db802010-10-06 17:34:4379}
80
81void ExternalTabProxy::Connected(ChromeProxy* proxy) {
82 // in ipc thread
83 ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
84 &ExternalTabProxy::UiConnected, proxy));
85}
[email protected]11b6e602010-10-13 16:02:2686
87void ExternalTabProxy::UiConnected(ChromeProxy* proxy) {
88 proxy_ = proxy;
89 IPC::ExternalTabSettings settings;
[email protected]314a06962010-10-20 21:32:3290 settings.parent = m_hWnd;
91 settings.style = WS_CHILD;
92 settings.is_off_the_record = tab_params_.is_incognito;
93 // TODO(stoyan): FIX this.
94 settings.load_requests_via_automation = true;
95 // TODO(stoyan): FIX this.
96 settings.handle_top_level_requests = true;
97 settings.initial_url = tab_params_.url;
98 settings.referrer = tab_params_.referrer;
99 // Infobars are disabled in widget mode.
100 settings.infobars_enabled = !tab_params_.is_widget_mode;
101 // TODO(stoyan): FIX this.
102 settings.route_all_top_level_navigations = false;
103
104 state_ = CREATE_TAB_IN_PROGRESS;
[email protected]11b6e602010-10-13 16:02:26105 proxy->CreateTab(this, settings);
106}
107
[email protected]5a8db802010-10-06 17:34:43108void ExternalTabProxy::Disconnected() {
109 // in ipc thread
110 DCHECK(done_.get() != NULL);
111 done_->Signal();
112}
113
114void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) {
115 ui_.PostTask(FROM_HERE, NewRunnableMethod(this, &ExternalTabProxy::UiPeerLost,
116 proxy, reason));
117}
118
[email protected]11b6e602010-10-13 16:02:26119void ExternalTabProxy::UiPeerLost(ChromeProxy* proxy, DisconnectReason reason) {
120 // TODO(stoyan):
121}
122
[email protected]5a8db802010-10-06 17:34:43123void ExternalTabProxy::Navigate(const std::string& url,
124 const std::string& referrer, bool is_privileged) {
125 // in ui thread
126 // Catch invalid URLs early. Can we allow this navigation to happen?
127 GURL parsed_url(url);
128 if (!CanNavigate(parsed_url, security_manager_, is_privileged)) {
129 DLOG(ERROR) << __FUNCTION__ << " Not allowing navigation to: " << url;
130 return;
131 }
132
[email protected]11b6e602010-10-13 16:02:26133 GURL parsed_referrer(referrer);
134 // If we are still establishing channel, simply replace the params
[email protected]5a8db802010-10-06 17:34:43135 if (state_ == INIT_IN_PROGRESS) {
[email protected]11b6e602010-10-13 16:02:26136 tab_params_.url = parsed_url;
137 tab_params_.referrer = parsed_referrer;
[email protected]5a8db802010-10-06 17:34:43138 }
139
[email protected]11b6e602010-10-13 16:02:26140 // Ah! Too late. Wait to get tab handle and then navigate.
[email protected]5a8db802010-10-06 17:34:43141 if (state_ == CREATE_TAB_IN_PROGRESS) {
[email protected]11b6e602010-10-13 16:02:26142 pending_navigation_.Set(parsed_url, parsed_referrer);
[email protected]5a8db802010-10-06 17:34:43143 }
144
145 if (state_ == READY) {
[email protected]11b6e602010-10-13 16:02:26146 proxy_->Tab_Navigate(tab_, parsed_url, parsed_referrer);
[email protected]5a8db802010-10-06 17:34:43147 }
148}
149
[email protected]11b6e602010-10-13 16:02:26150void ExternalTabProxy::ConnectToExternalTab(uint64 external_tab_cookie) {
151 proxy_->ConnectTab(this, m_hWnd, external_tab_cookie);
152}
153
[email protected]11b6e602010-10-13 16:02:26154void ExternalTabProxy::BlockExternalTab(uint64 cookie) {
155 proxy_->BlockTab(cookie);
156}
157
158void ExternalTabProxy::SetZoomLevel(PageZoom::Function zoom_level) {
159 proxy_->Tab_Zoom(tab_, zoom_level);
160}
161
162void ExternalTabProxy::NavigateToIndex(int index) {
163 CHECK(0);
164}
165
166void ExternalTabProxy::ForwardMessageFromExternalHost(
167 const std::string& message, const std::string& origin,
168 const std::string& target) {
169 proxy_->Tab_PostMessage(tab_, message, origin, target);
170}
171
172void ExternalTabProxy::SetEnableExtensionAutomation(
173 const std::vector<std::string>& functions_enabled) {
174 proxy_->Tab_SetEnableExtensionAutomation(tab_, functions_enabled);
175}
176
177void ExternalTabProxy::InstallExtension(const FilePath& crx_path,
178 void* user_data) {
179 proxy_->InstallExtension(this, crx_path, new UserDataHolder(user_data));
180}
181
182void ExternalTabProxy::LoadExpandedExtension(const FilePath& path,
183 void* user_data) {
184 proxy_->LoadExtension(this, path, new UserDataHolder(user_data));
185}
186
187void ExternalTabProxy::GetEnabledExtensions(void* user_data) {
188 proxy_->GetEnabledExtensions(this, new UserDataHolder(user_data));
189}
190
191void ExternalTabProxy::ChromeFrameHostMoved() {
192 proxy_->Tab_OnHostMoved(tab_);
193}
194
195//////////////////////////////////////////////////////////////////////////
[email protected]314a06962010-10-20 21:32:32196void ExternalTabProxy::UiCompleted_CreateTab(bool success, HWND chrome_window,
[email protected]751bf4b2010-11-05 22:06:31197 HWND tab_window, int tab_handle,
198 int session_id) {
[email protected]314a06962010-10-20 21:32:32199 if (success) {
200 state_ = READY;
201 tab_ = tab_handle;
202 tab_wnd_ = tab_window;
203 chrome_wnd_ = chrome_window;
204
205 // If a navigation request came while tab creation was in progress -
206 // go ahead and navigate.
207 if (pending_navigation_.url.is_valid())
208 proxy_->Tab_Navigate(tab_, pending_navigation_.url,
209 pending_navigation_.referrer);
210 }
211}
212
[email protected]5a8db802010-10-06 17:34:43213void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd,
[email protected]751bf4b2010-11-05 22:06:31214 HWND tab_window, int tab_handle,
215 int session_id) {
[email protected]5a8db802010-10-06 17:34:43216 // in ipc_thread.
[email protected]314a06962010-10-20 21:32:32217 ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
218 &ExternalTabProxy::UiCompleted_CreateTab,
[email protected]751bf4b2010-11-05 22:06:31219 success, chrome_wnd, tab_window, tab_handle, session_id));
[email protected]5a8db802010-10-06 17:34:43220}
221
222void ExternalTabProxy::Completed_ConnectToTab(bool success,
[email protected]751bf4b2010-11-05 22:06:31223 HWND chrome_window, HWND tab_window, int tab_handle, int session_id) {
[email protected]5a8db802010-10-06 17:34:43224 CHECK(0);
225}
226
227void ExternalTabProxy::Completed_Navigate(bool success,
228 enum AutomationMsg_NavigationResponseValues res) {
229 // ipc_thread;
230 CHECK(0);
231}
232
233void ExternalTabProxy::Completed_InstallExtension(bool success,
234 enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) {
235 CHECK(0);
236}
237
238void ExternalTabProxy::Completed_LoadExpandedExtension(bool success,
239 enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) {
240 CHECK(0);
241}
242
243void ExternalTabProxy::Completed_GetEnabledExtensions(bool success,
244 const std::vector<FilePath>* extensions) {
245 CHECK(0);
246}
247
248void ExternalTabProxy::NavigationStateChanged(int flags,
249 const IPC::NavigationInfo& nav_info) {
250 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
251 &UIDelegate::OnNavigationStateChanged, flags, nav_info));
252}
253
254void ExternalTabProxy::UpdateTargetUrl(const std::wstring& url) {
255 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
256 &UIDelegate::OnUpdateTargetUrl, url));
257}
258
259void ExternalTabProxy::TabLoaded(const GURL& url) {
260 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
261 &UIDelegate::OnLoad, url));
262}
[email protected]11b6e602010-10-13 16:02:26263
264void ExternalTabProxy::MessageToHost(const std::string& message,
265 const std::string& origin,
266 const std::string& target) {
267 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
268 &UIDelegate::OnMessageFromChromeFrame, message, origin, target));
269}
270
271void ExternalTabProxy::HandleAccelerator(const MSG& accel_message) {
272 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
273 &UIDelegate::OnHandleAccelerator, accel_message));
274}
275
[email protected]47af65f02010-11-08 21:43:55276void ExternalTabProxy::HandleContextMenu(
277 HANDLE menu_handle,
278 int align_flags,
279 const IPC::MiniContextMenuParams& params) {
[email protected]11b6e602010-10-13 16:02:26280 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
281 &UIDelegate::OnHandleContextMenu, menu_handle, align_flags, params));
282}
283
284void ExternalTabProxy::TabbedOut(bool reverse) {
285 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
286 &UIDelegate::OnTabbedOut, reverse));
287}
288
289void ExternalTabProxy::GoToHistoryOffset(int offset) {
290 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
291 &UIDelegate::OnGoToHistoryOffset, offset));
292}
293
294void ExternalTabProxy::OpenURL(const GURL& url_to_open, const GURL& referrer,
295 int open_disposition) {
296 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
297 &UIDelegate::OnOpenURL, url_to_open, referrer, open_disposition));
298}
299
300void ExternalTabProxy::NavigationFailed(int error_code, const GURL& gurl) {
301 // TODO(stoyan):
302}
303
304void ExternalTabProxy::DidNavigate(const IPC::NavigationInfo& navigation_info) {
305 // TODO(stoyan):
306}
307
308void ExternalTabProxy::Network_Start(
309 int request_id, const IPC::AutomationURLRequest& request_info) {
310 // TODO(stoyan): url_fetcher_.Start();
311}
312
313void ExternalTabProxy::Network_Read(int request_id, int bytes_to_read) {
314 // TODO(stoyan): url_fetcher_.Read();
315}
316
317void ExternalTabProxy::Network_End(int request_id, const URLRequestStatus& s) {
318 // TODO(stoyan):
319}
320
321void ExternalTabProxy::Network_DownloadInHost(int request_id) {
322 // TODO(stoyan):
323}
324
325void ExternalTabProxy::GetCookies(const GURL& url, int cookie_id) {
326 // TODO(stoyan):
327}
328
329void ExternalTabProxy::SetCookie(const GURL& url, const std::string& cookie) {
330 // TODO(stoyan):
331}
332
333void ExternalTabProxy::TabClosed() {
334 // TODO(stoyan):
335}
336
337void ExternalTabProxy::AttachTab(
338 const IPC::AttachExternalTabParams& attach_params) {
339 // TODO(stoyan):
340}