blob: eba29652add9438be96327b0d155c5e09aab52db [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_FRAME_EXTERNAL_TAB_H_
#define CHROME_FRAME_EXTERNAL_TAB_H_
#pragma once
#include <windows.h>
#include <atlbase.h>
#include <atlwin.h>
#include <vector>
#include <string>
#include "base/scoped_comptr_win.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/common//page_zoom.h"
#include "chrome/test/automation/automation_constants.h"
#include "chrome_frame/cfproxy.h"
#include "chrome_frame/task_marshaller.h"
#include "googleurl/src/gurl.h"
class Task;
class CancelableTask;
namespace base {
class TimeDelta;
class WaitableEvent;
}
namespace IPC {
struct NavigationInfo;
struct ContextMenuParams;
}
// This is the delegate/callback interface that has to be implemented
// by the customers of ExternalTabProxy class.
class UIDelegate {
public:
virtual void OnNavigationStateChanged(int flags,
const IPC::NavigationInfo& nav_info) = 0;
virtual void OnUpdateTargetUrl(const std::wstring& new_target_url) = 0;
virtual void OnExtensionInstalled(const FilePath& path, void* user_data,
AutomationMsg_ExtensionResponseValues response) = 0;
virtual void OnAcceleratorPressed(const MSG& accel_message) = 0;
virtual void OnLoad(const GURL& url) = 0;
virtual void OnMessageFromChromeFrame(const std::string& message,
const std::string& origin, const std::string& target) = 0;
virtual void OnHandleContextMenu(HANDLE menu_handle, int align_flags,
const IPC::ContextMenuParams& params) = 0;
protected:
~UIDelegate() {}
};
struct CreateTabParams {
std::string profile;
std::string extra_arguments;
bool is_incognito;
bool is_widget_mode;
GURL url;
GURL referrer;
base::TimeDelta launch_timeout;
};
/////////////////////////////////////////////////////////////////////////
// ExternalTabProxy is a mediator between ChromeProxy (which runs mostly in
// background IPC-channel thread and the UI object (ActiveX, NPAPI,
// ActiveDocument).
// The lifetime of ExternalTabProxy is determined by the UI object.
//
// When ExternalTabProxy dies:
// 1. Remove itself as a ChromeProxyDelegate. This blocks until _Disconnected()
// is received.
// 2. Kills all posted tasks to the UI thread.
// 3. Stop all network requests
// => It does not have to (and should not) be a refcount-ed object.
// Non-public inheritance is not allowed by the style-guide.
class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
public ChromeProxyDelegate {
public:
ExternalTabProxy();
~ExternalTabProxy();
#ifdef UNIT_TEST
void set_proxy_factory(ChromeProxyFactory* factory) {
proxy_factory_ = factory;
}
#endif
//
virtual void CreateTab(const CreateTabParams& create_params,
UIDelegate* delegate);
virtual void Navigate(const std::string& url, const std::string& referrer,
bool is_privileged);
virtual bool NavigateToIndex(int index);
virtual void ForwardMessageFromExternalHost(const std::string& message,
const std::string& origin, const std::string& target) {
proxy_->Tab_PostMessage(tab_, message, origin, target);
}
virtual void OnChromeFrameHostMoved();
virtual void SetEnableExtensionAutomation(
const std::vector<std::string>& functions_enabled);
virtual void InstallExtension(const FilePath& crx_path, void* user_data);
virtual void LoadExpandedExtension(const FilePath& path, void* user_data);
virtual void GetEnabledExtensions(void* user_data);
// Attaches an existing external tab to this automation client instance.
virtual void AttachExternalTab(uint64 external_tab_cookie);
virtual void BlockExternalTab(uint64 cookie);
void SetZoomLevel(PageZoom::Function zoom_level) {
proxy_->Tab_Zoom(tab_, zoom_level);
}
private:
//////////////////////////////////////////////////////////////////////////
// ChromeProxyDelegate implementation
virtual int tab_handle() {
return tab_;
}
virtual void Connected(ChromeProxy* proxy);
virtual void PeerLost(ChromeProxy* proxy, DisconnectReason reason);
virtual void Disconnected();
// Sync message responses.
virtual void Completed_CreateTab(bool success, HWND chrome_wnd,
HWND tab_window, int tab_handle) = 0; // TODO(stoyan): Error_code
virtual void Completed_ConnectToTab(bool success, HWND chrome_window,
HWND tab_window, int tab_handle) = 0;
virtual void Completed_Navigate(bool success,
enum AutomationMsg_NavigationResponseValues res);
virtual void Completed_InstallExtension(bool success,
enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx);
virtual void Completed_LoadExpandedExtension(bool success,
enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx);
virtual void Completed_GetEnabledExtensions(bool success,
const std::vector<FilePath>* extensions);
// Network requests from Chrome.
virtual void Network_Start(int request_id,
const IPC::AutomationURLRequest& request_info);
virtual void Network_Read(int request_id, int bytes_to_read);
virtual void Network_End(int request_id, const URLRequestStatus& s);
virtual void Network_DownloadInHost(int request_id);
virtual void GetCookies(const GURL& url, int cookie_id);
virtual void SetCookie(const GURL& url, const std::string& cookie);
// Navigation progress notifications.
virtual void NavigationStateChanged(int flags,
const IPC::NavigationInfo& nav_info);
virtual void UpdateTargetUrl(const std::wstring& url);
virtual void NavigationFailed(int error_code, const GURL& gurl);
virtual void DidNavigate(const IPC::NavigationInfo& navigation_info);
virtual void TabLoaded(const GURL& url);
virtual void OpenURL(const GURL& url_to_open, const GURL& referrer,
int open_disposition);
virtual void GoToHistoryOffset(int offset);
virtual void MessageToHost(const std::string& message,
const std::string& origin, const std::string& target);
// Misc. UI.
virtual void HandleAccelerator(const MSG& accel_message);
virtual void TabbedOut(bool reverse);
// Other
virtual void TabClosed();
virtual void AttachTab(const IPC::AttachExternalTabParams& attach_params);
// end of ChromeProxyDelegate methods
//////////////////////////////////////////////////////////////////////////
void Destroy();
// The UiXXXX are the ChromeProxyDelegate methods but on UI thread.
void UiConnected(ChromeProxy* proxy);
void UiPeerLost(ChromeProxy* proxy, DisconnectReason reason);
// With the present state of affairs the only response we can possibly handle
// in the background IPC thread is Completed_CreateTab() where we can
// initiate a navigation (if there is a pending one).
// To simplify - will handle Completed_CreateTab in UI thread and avoid
// the need of lock when accessing members.
enum {
NONE,
INIT_IN_PROGRESS,
CREATE_TAB_IN_PROGRESS,
READY,
RELEASE_CF_PROXY_IN_PROGRESS
} state_;
int tab_;
ChromeProxyFactory* proxy_factory_;
ChromeProxy* proxy_;
UIDelegate* ui_delegate_;
TaskMarshallerThroughMessageQueue ui_;
scoped_ptr<base::WaitableEvent> done_;
CreateTabParams tab_params_;
struct PendingNavigation {
GURL url;
GURL referrer;
void Set(const GURL& gurl, const GURL& ref) {
url = gurl;
referrer = ref;
}
} pending_navigation_;
ScopedComPtr<IInternetSecurityManager> security_manager_;
};
#endif // CHROME_FRAME_EXTERNAL_TAB_H_