| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 "base/bind.h" | |
| 6 #include "base/bind_helpers.h" | |
| 7 #include "base/lazy_instance.h" | |
| 8 #include "base/location.h" | |
| 9 #include "chrome_frame/external_tab.h" | |
| 10 #include "base/synchronization/waitable_event.h" | |
| 11 #include "chrome/common/automation_messages.h" | |
| 12 #include "chrome_frame/chrome_frame_delegate.h" | |
| 13 #include "chrome_frame/utils.h" | |
| 14 | |
| 15 namespace { | |
| 16 static base::LazyInstance<ChromeProxyFactory> g_proxy_factory = | |
| 17 LAZY_INSTANCE_INITIALIZER; | |
| 18 | |
| 19 struct UserDataHolder : public SyncMessageContext { | |
| 20 explicit UserDataHolder(void* p) : data(p) {} | |
| 21 void* data; | |
| 22 }; | |
| 23 } | |
| 24 | |
| 25 | |
| 26 ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), tab_wnd_(NULL), | |
| 27 chrome_wnd_(NULL), proxy_factory_(g_proxy_factory.Pointer()), proxy_(NULL), | |
| 28 ui_delegate_(NULL) { | |
| 29 } | |
| 30 | |
| 31 ExternalTabProxy::~ExternalTabProxy() { | |
| 32 Destroy(); | |
| 33 } | |
| 34 | |
| 35 bool ExternalTabProxy::OnMessageReceived(const IPC::Message& message) { | |
| 36 bool handled = true; | |
| 37 IPC_BEGIN_MESSAGE_MAP(ExternalTabProxy, message) | |
| 38 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged, | |
| 39 OnNavigationStateChanged) | |
| 40 IPC_MESSAGE_HANDLER(AutomationMsg_UpdateTargetUrl, OnUpdateTargetUrl) | |
| 41 IPC_MESSAGE_HANDLER(AutomationMsg_HandleAccelerator, OnHandleAccelerator) | |
| 42 IPC_MESSAGE_HANDLER(AutomationMsg_TabbedOut, OnTabbedOut) | |
| 43 IPC_MESSAGE_HANDLER(AutomationMsg_OpenURL, OnOpenURL) | |
| 44 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationFailed, OnNavigationFailed) | |
| 45 IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate) | |
| 46 IPC_MESSAGE_HANDLER(AutomationMsg_TabLoaded, OnTabLoaded) | |
| 47 IPC_MESSAGE_HANDLER(AutomationMsg_MoveWindow, OnMoveWindow) | |
| 48 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost, | |
| 49 OnMessageToHost) | |
| 50 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuToExternalHost, | |
| 51 OnHandleContextMenu) | |
| 52 IPC_MESSAGE_HANDLER(AutomationMsg_RequestStart, OnNetwork_Start) | |
| 53 IPC_MESSAGE_HANDLER(AutomationMsg_RequestRead, OnNetwork_Read) | |
| 54 IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnNetwork_End) | |
| 55 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadRequestInHost, | |
| 56 OnNetwork_DownloadInHost) | |
| 57 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost, OnGetCookies) | |
| 58 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieAsync, OnSetCookie) | |
| 59 IPC_MESSAGE_HANDLER(AutomationMsg_AttachExternalTab, OnAttachTab) | |
| 60 IPC_MESSAGE_HANDLER(AutomationMsg_RequestGoToHistoryEntryOffset, | |
| 61 OnGoToHistoryOffset) | |
| 62 IPC_MESSAGE_HANDLER(AutomationMsg_CloseExternalTab, OnTabClosed) | |
| 63 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 64 IPC_END_MESSAGE_MAP() | |
| 65 return handled; | |
| 66 } | |
| 67 | |
| 68 void ExternalTabProxy::Init() { | |
| 69 if (m_hWnd == NULL) { | |
| 70 // Create a window on the UI thread for marshaling messages back and forth | |
| 71 // from the IPC thread. This window cannot be a message only window as the | |
| 72 // external chrome tab window initially is created as a child of this window | |
| 73 CWindowImpl<ExternalTabProxy>::Create(GetDesktopWindow(), NULL, NULL, | |
| 74 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOLWINDOW); | |
| 75 DCHECK(m_hWnd != NULL); | |
| 76 ui_.SetWindow(m_hWnd, WM_APP + 6); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 void ExternalTabProxy::Destroy() { | |
| 81 DCHECK(NULL == done_.get()); | |
| 82 // TODO(stoyan): Should we release proxy first and then destroy the window | |
| 83 // (parent of the chrome window) or the other way around? | |
| 84 if (state_ != NONE) { | |
| 85 done_.reset(new base::WaitableEvent(true, false)); | |
| 86 proxy_factory_->ReleaseProxy(this, tab_params_.proxy_params.profile); | |
| 87 done_->Wait(); | |
| 88 done_.reset(NULL); | |
| 89 | |
| 90 state_ = NONE; | |
| 91 proxy_ = NULL; | |
| 92 tab_ = 0; | |
| 93 CWindowImpl<ExternalTabProxy>::DestroyWindow(); | |
| 94 tab_wnd_ = NULL; | |
| 95 chrome_wnd_ = NULL; | |
| 96 // We shall tell the TaskMarshaller to delete queued tasks. | |
| 97 // ui_.DeleteAll(); | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 void ExternalTabProxy::CreateTab(const CreateTabParams& create_params, | |
| 102 UIDelegate* delegate) { | |
| 103 DCHECK(ui_delegate_ == NULL); | |
| 104 DCHECK_EQ(NONE, state_); | |
| 105 // Create host window if needed. | |
| 106 Init(); | |
| 107 ui_delegate_ = delegate; | |
| 108 // TODO(stoyan): Shall we check the CanNavigate(create_params.url)? | |
| 109 tab_params_ = create_params; | |
| 110 state_ = INIT_IN_PROGRESS; | |
| 111 proxy_factory_->GetProxy(this, create_params.proxy_params); | |
| 112 } | |
| 113 | |
| 114 void ExternalTabProxy::Connected(ChromeProxy* proxy) { | |
| 115 // in ipc thread | |
| 116 ui_.PostTask(FROM_HERE, base::Bind(&ExternalTabProxy::UiConnected, | |
| 117 base::Unretained(this), proxy)); | |
| 118 } | |
| 119 | |
| 120 void ExternalTabProxy::UiConnected(ChromeProxy* proxy) { | |
| 121 proxy_ = proxy; | |
| 122 ExternalTabSettings settings; | |
| 123 settings.parent = m_hWnd; | |
| 124 settings.style = WS_CHILD; | |
| 125 settings.is_incognito = tab_params_.is_incognito; | |
| 126 // TODO(stoyan): FIX this. | |
| 127 settings.load_requests_via_automation = true; | |
| 128 // TODO(stoyan): FIX this. | |
| 129 settings.handle_top_level_requests = true; | |
| 130 settings.initial_url = tab_params_.url; | |
| 131 settings.referrer = tab_params_.referrer; | |
| 132 // Infobars are disabled in widget mode. | |
| 133 settings.infobars_enabled = !tab_params_.is_widget_mode; | |
| 134 // TODO(stoyan): FIX this. | |
| 135 settings.route_all_top_level_navigations = false; | |
| 136 | |
| 137 state_ = CREATE_TAB_IN_PROGRESS; | |
| 138 proxy->CreateTab(this, settings); | |
| 139 } | |
| 140 | |
| 141 void ExternalTabProxy::Disconnected() { | |
| 142 // in ipc thread | |
| 143 DCHECK(done_.get() != NULL); | |
| 144 done_->Signal(); | |
| 145 } | |
| 146 | |
| 147 void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) { | |
| 148 ui_.PostTask(FROM_HERE, base::Bind(&ExternalTabProxy::UiPeerLost, | |
| 149 base::Unretained(this), proxy, reason)); | |
| 150 } | |
| 151 | |
| 152 void ExternalTabProxy::UiPeerLost(ChromeProxy* proxy, DisconnectReason reason) { | |
| 153 // TODO(stoyan): | |
| 154 } | |
| 155 | |
| 156 void ExternalTabProxy::Navigate(const std::string& url, | |
| 157 const std::string& referrer, | |
| 158 NavigationConstraints* navigation_constraints) { | |
| 159 // in ui thread | |
| 160 // Catch invalid URLs early. Can we allow this navigation to happen? | |
| 161 GURL parsed_url(url); | |
| 162 if (!CanNavigate(parsed_url, navigation_constraints)) { | |
| 163 DLOG(ERROR) << __FUNCTION__ << " Not allowing navigation to: " << url; | |
| 164 return; | |
| 165 } | |
| 166 | |
| 167 GURL parsed_referrer(referrer); | |
| 168 // If we are still establishing channel, simply replace the params | |
| 169 if (state_ == INIT_IN_PROGRESS) { | |
| 170 tab_params_.url = parsed_url; | |
| 171 tab_params_.referrer = parsed_referrer; | |
| 172 } | |
| 173 | |
| 174 // Ah! Too late. Wait to get tab handle and then navigate. | |
| 175 if (state_ == CREATE_TAB_IN_PROGRESS) { | |
| 176 pending_navigation_.Set(parsed_url, parsed_referrer); | |
| 177 } | |
| 178 | |
| 179 if (state_ == READY) { | |
| 180 proxy_->Tab_Navigate(tab_, parsed_url, parsed_referrer); | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 void ExternalTabProxy::ConnectToExternalTab(uint64 external_tab_cookie) { | |
| 185 proxy_->ConnectTab(this, m_hWnd, external_tab_cookie); | |
| 186 } | |
| 187 | |
| 188 void ExternalTabProxy::BlockExternalTab(uint64 cookie) { | |
| 189 proxy_->BlockTab(cookie); | |
| 190 } | |
| 191 | |
| 192 void ExternalTabProxy::SetZoomLevel(content::PageZoom zoom_level) { | |
| 193 proxy_->Tab_Zoom(tab_, zoom_level); | |
| 194 } | |
| 195 | |
| 196 void ExternalTabProxy::NavigateToIndex(int index) { | |
| 197 CHECK(0); | |
| 198 } | |
| 199 | |
| 200 void ExternalTabProxy::ForwardMessageFromExternalHost( | |
| 201 const std::string& message, const std::string& origin, | |
| 202 const std::string& target) { | |
| 203 proxy_->Tab_PostMessage(tab_, message, origin, target); | |
| 204 } | |
| 205 | |
| 206 void ExternalTabProxy::ChromeFrameHostMoved() { | |
| 207 proxy_->Tab_OnHostMoved(tab_); | |
| 208 } | |
| 209 | |
| 210 ////////////////////////////////////////////////////////////////////////// | |
| 211 void ExternalTabProxy::UiCompleted_CreateTab(bool success, HWND chrome_window, | |
| 212 HWND tab_window, int tab_handle, | |
| 213 int session_id) { | |
| 214 if (success) { | |
| 215 state_ = READY; | |
| 216 tab_ = tab_handle; | |
| 217 tab_wnd_ = tab_window; | |
| 218 chrome_wnd_ = chrome_window; | |
| 219 | |
| 220 // If a navigation request came while tab creation was in progress - | |
| 221 // go ahead and navigate. | |
| 222 if (pending_navigation_.url.is_valid()) | |
| 223 proxy_->Tab_Navigate(tab_, pending_navigation_.url, | |
| 224 pending_navigation_.referrer); | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd, | |
| 229 HWND tab_window, int tab_handle, | |
| 230 int session_id) { | |
| 231 // in ipc_thread. | |
| 232 ui_.PostTask( | |
| 233 FROM_HERE, base::Bind(&ExternalTabProxy::UiCompleted_CreateTab, | |
| 234 base::Unretained(this), success, chrome_wnd, | |
| 235 tab_window, tab_handle, session_id)); | |
| 236 } | |
| 237 | |
| 238 void ExternalTabProxy::Completed_ConnectToTab( | |
| 239 bool success, HWND chrome_window, HWND tab_window, int tab_handle, | |
| 240 int session_id) { | |
| 241 CHECK(0); | |
| 242 } | |
| 243 | |
| 244 void ExternalTabProxy::Completed_Navigate( | |
| 245 bool success, enum AutomationMsg_NavigationResponseValues res) { | |
| 246 // ipc_thread; | |
| 247 CHECK(0); | |
| 248 } | |
| 249 | |
| 250 void ExternalTabProxy::OnNavigationStateChanged( | |
| 251 int flags, const NavigationInfo& nav_info) { | |
| 252 ui_.PostTask(FROM_HERE, | |
| 253 base::Bind(&UIDelegate::OnNavigationStateChanged, | |
| 254 base::Unretained(ui_delegate_), flags, nav_info)); | |
| 255 } | |
| 256 | |
| 257 void ExternalTabProxy::OnUpdateTargetUrl(const std::wstring& url) { | |
| 258 ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnUpdateTargetUrl, | |
| 259 base::Unretained(ui_delegate_), url)); | |
| 260 } | |
| 261 | |
| 262 void ExternalTabProxy::OnTabLoaded(const GURL& url) { | |
| 263 ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnLoad, | |
| 264 base::Unretained(ui_delegate_), url)); | |
| 265 } | |
| 266 | |
| 267 void ExternalTabProxy::OnMoveWindow(const gfx::Rect& pos) { | |
| 268 ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnMoveWindow, | |
| 269 base::Unretained(ui_delegate_), pos)); | |
| 270 } | |
| 271 | |
| 272 void ExternalTabProxy::OnMessageToHost(const std::string& message, | |
| 273 const std::string& origin, | |
| 274 const std::string& target) { | |
| 275 ui_.PostTask( | |
| 276 FROM_HERE, | |
| 277 base::Bind(&UIDelegate::OnMessageFromChromeFrame, | |
| 278 base::Unretained(ui_delegate_), message, origin, target)); | |
| 279 } | |
| 280 | |
| 281 void ExternalTabProxy::OnHandleAccelerator(const MSG& accel_message) { | |
| 282 ui_.PostTask(FROM_HERE, | |
| 283 base::Bind(&UIDelegate::OnHandleAccelerator, | |
| 284 base::Unretained(ui_delegate_), accel_message)); | |
| 285 } | |
| 286 | |
| 287 void ExternalTabProxy::OnHandleContextMenu( | |
| 288 const ContextMenuModel& context_menu_model, | |
| 289 int align_flags, | |
| 290 const MiniContextMenuParams& params) { | |
| 291 ui_.PostTask(FROM_HERE, | |
| 292 base::Bind(&UIDelegate::OnHandleContextMenu, | |
| 293 base::Unretained(ui_delegate_), context_menu_model, | |
| 294 align_flags, params)); | |
| 295 } | |
| 296 | |
| 297 void ExternalTabProxy::OnTabbedOut(bool reverse) { | |
| 298 ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnTabbedOut, | |
| 299 base::Unretained(ui_delegate_), reverse)); | |
| 300 } | |
| 301 | |
| 302 void ExternalTabProxy::OnGoToHistoryOffset(int offset) { | |
| 303 ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnGoToHistoryOffset, | |
| 304 base::Unretained(ui_delegate_), offset)); | |
| 305 } | |
| 306 | |
| 307 void ExternalTabProxy::OnOpenURL(const GURL& url_to_open, const GURL& referrer, | |
| 308 int open_disposition) { | |
| 309 ui_.PostTask( | |
| 310 FROM_HERE, | |
| 311 base::Bind(&UIDelegate::OnOpenURL, base::Unretained(ui_delegate_), | |
| 312 url_to_open, referrer, open_disposition)); | |
| 313 } | |
| 314 | |
| 315 void ExternalTabProxy::OnNavigationFailed(int error_code, const GURL& gurl) { | |
| 316 // TODO(stoyan): | |
| 317 } | |
| 318 | |
| 319 void ExternalTabProxy::OnDidNavigate(const NavigationInfo& navigation_info) { | |
| 320 // TODO(stoyan): | |
| 321 } | |
| 322 | |
| 323 void ExternalTabProxy::OnNetwork_Start( | |
| 324 int request_id, const AutomationURLRequest& request_info) { | |
| 325 // TODO(stoyan): url_fetcher_.Start(); | |
| 326 } | |
| 327 | |
| 328 void ExternalTabProxy::OnNetwork_Read(int request_id, int bytes_to_read) { | |
| 329 // TODO(stoyan): url_fetcher_.Read(); | |
| 330 } | |
| 331 | |
| 332 void ExternalTabProxy::OnNetwork_End(int request_id, | |
| 333 const net::URLRequestStatus& s) { | |
| 334 // TODO(stoyan): | |
| 335 } | |
| 336 | |
| 337 void ExternalTabProxy::OnNetwork_DownloadInHost(int request_id) { | |
| 338 // TODO(stoyan): | |
| 339 } | |
| 340 | |
| 341 void ExternalTabProxy::OnGetCookies(const GURL& url, int cookie_id) { | |
| 342 // TODO(stoyan): | |
| 343 } | |
| 344 | |
| 345 void ExternalTabProxy::OnSetCookie(const GURL& url, const std::string& cookie) { | |
| 346 // TODO(stoyan): | |
| 347 } | |
| 348 | |
| 349 void ExternalTabProxy::OnTabClosed() { | |
| 350 // TODO(stoyan): | |
| 351 } | |
| 352 | |
| 353 void ExternalTabProxy::OnAttachTab( | |
| 354 const AttachExternalTabParams& attach_params) { | |
| 355 // TODO(stoyan): | |
| 356 } | |
| OLD | NEW |