blob: 4bfeff2fd3ecef47757431f35e43f637de298eaf [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]785993e2010-10-28 18:56:35197 HWND tab_window, int tab_handle) {
[email protected]314a06962010-10-20 21:32:32198 if (success) {
199 state_ = READY;
200 tab_ = tab_handle;
201 tab_wnd_ = tab_window;
202 chrome_wnd_ = chrome_window;
203
204 // If a navigation request came while tab creation was in progress -
205 // go ahead and navigate.
206 if (pending_navigation_.url.is_valid())
207 proxy_->Tab_Navigate(tab_, pending_navigation_.url,
208 pending_navigation_.referrer);
209 }
210}
211
[email protected]5a8db802010-10-06 17:34:43212void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd,
[email protected]785993e2010-10-28 18:56:35213 HWND tab_window, int tab_handle) {
[email protected]5a8db802010-10-06 17:34:43214 // in ipc_thread.
[email protected]314a06962010-10-20 21:32:32215 ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
216 &ExternalTabProxy::UiCompleted_CreateTab,
[email protected]785993e2010-10-28 18:56:35217 success, chrome_wnd, tab_window, tab_handle));
[email protected]5a8db802010-10-06 17:34:43218}
219
220void ExternalTabProxy::Completed_ConnectToTab(bool success,
221 HWND chrome_window, HWND tab_window, int tab_handle) {
222 CHECK(0);
223}
224
225void ExternalTabProxy::Completed_Navigate(bool success,
226 enum AutomationMsg_NavigationResponseValues res) {
227 // ipc_thread;
228 CHECK(0);
229}
230
231void ExternalTabProxy::Completed_InstallExtension(bool success,
232 enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) {
233 CHECK(0);
234}
235
236void ExternalTabProxy::Completed_LoadExpandedExtension(bool success,
237 enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) {
238 CHECK(0);
239}
240
241void ExternalTabProxy::Completed_GetEnabledExtensions(bool success,
242 const std::vector<FilePath>* extensions) {
243 CHECK(0);
244}
245
246void ExternalTabProxy::NavigationStateChanged(int flags,
247 const IPC::NavigationInfo& nav_info) {
248 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
249 &UIDelegate::OnNavigationStateChanged, flags, nav_info));
250}
251
252void ExternalTabProxy::UpdateTargetUrl(const std::wstring& url) {
253 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
254 &UIDelegate::OnUpdateTargetUrl, url));
255}
256
257void ExternalTabProxy::TabLoaded(const GURL& url) {
258 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
259 &UIDelegate::OnLoad, url));
260}
[email protected]11b6e602010-10-13 16:02:26261
262void ExternalTabProxy::MessageToHost(const std::string& message,
263 const std::string& origin,
264 const std::string& target) {
265 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
266 &UIDelegate::OnMessageFromChromeFrame, message, origin, target));
267}
268
269void ExternalTabProxy::HandleAccelerator(const MSG& accel_message) {
270 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
271 &UIDelegate::OnHandleAccelerator, accel_message));
272}
273
[email protected]ea1c18e2010-11-01 19:24:33274void ExternalTabProxy::HandleContextMenu(HANDLE menu_handle, int align_flags,
275 const IPC::ContextMenuParams& params) {
[email protected]11b6e602010-10-13 16:02:26276 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
277 &UIDelegate::OnHandleContextMenu, menu_handle, align_flags, params));
278}
279
280void ExternalTabProxy::TabbedOut(bool reverse) {
281 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
282 &UIDelegate::OnTabbedOut, reverse));
283}
284
285void ExternalTabProxy::GoToHistoryOffset(int offset) {
286 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
287 &UIDelegate::OnGoToHistoryOffset, offset));
288}
289
290void ExternalTabProxy::OpenURL(const GURL& url_to_open, const GURL& referrer,
291 int open_disposition) {
292 ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
293 &UIDelegate::OnOpenURL, url_to_open, referrer, open_disposition));
294}
295
296void ExternalTabProxy::NavigationFailed(int error_code, const GURL& gurl) {
297 // TODO(stoyan):
298}
299
300void ExternalTabProxy::DidNavigate(const IPC::NavigationInfo& navigation_info) {
301 // TODO(stoyan):
302}
303
304void ExternalTabProxy::Network_Start(
305 int request_id, const IPC::AutomationURLRequest& request_info) {
306 // TODO(stoyan): url_fetcher_.Start();
307}
308
309void ExternalTabProxy::Network_Read(int request_id, int bytes_to_read) {
310 // TODO(stoyan): url_fetcher_.Read();
311}
312
313void ExternalTabProxy::Network_End(int request_id, const URLRequestStatus& s) {
314 // TODO(stoyan):
315}
316
317void ExternalTabProxy::Network_DownloadInHost(int request_id) {
318 // TODO(stoyan):
319}
320
321void ExternalTabProxy::GetCookies(const GURL& url, int cookie_id) {
322 // TODO(stoyan):
323}
324
325void ExternalTabProxy::SetCookie(const GURL& url, const std::string& cookie) {
326 // TODO(stoyan):
327}
328
329void ExternalTabProxy::TabClosed() {
330 // TODO(stoyan):
331}
332
333void ExternalTabProxy::AttachTab(
334 const IPC::AttachExternalTabParams& attach_params) {
335 // TODO(stoyan):
336}