diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-06 00:17:40 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-06 00:17:40 +0000 |
commit | fcbd65c23cccdb2e0bea7aa7accb47592388845d (patch) | |
tree | e1550fd98bcc4c35e40e470d077fd65354125426 | |
parent | 7f0199682d1d591a2a0024a7cacf7205b739ad5d (diff) | |
download | chromium_src-fcbd65c23cccdb2e0bea7aa7accb47592388845d.zip chromium_src-fcbd65c23cccdb2e0bea7aa7accb47592388845d.tar.gz chromium_src-fcbd65c23cccdb2e0bea7aa7accb47592388845d.tar.bz2 |
Revert 61583 - Initial skeleton for refactored ChromeFrameAutomationClient and AutomationProxy for the needs of ChromeFrame.
CFProxy is ready to some extent, while CFAC is mostly structure-only.
Review URL: http://codereview.chromium.org/3528004
TBR=stoyan@chromium.org
Review URL: http://codereview.chromium.org/3547013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61590 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/cfproxy.h | 227 | ||||
-rw-r--r-- | chrome_frame/cfproxy_factory.cc | 79 | ||||
-rw-r--r-- | chrome_frame/cfproxy_private.h | 192 | ||||
-rw-r--r-- | chrome_frame/cfproxy_proxy.cc | 246 | ||||
-rw-r--r-- | chrome_frame/cfproxy_support.cc | 450 | ||||
-rw-r--r-- | chrome_frame/cfproxy_test.cc | 316 | ||||
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 10 | ||||
-rw-r--r-- | chrome_frame/external_tab.cc | 131 | ||||
-rw-r--r-- | chrome_frame/external_tab.h | 213 | ||||
-rw-r--r-- | chrome_frame/task_marshaller.cc | 133 | ||||
-rw-r--r-- | chrome_frame/task_marshaller.h | 63 |
11 files changed, 0 insertions, 2060 deletions
diff --git a/chrome_frame/cfproxy.h b/chrome_frame/cfproxy.h deleted file mode 100644 index b45e30f..0000000 --- a/chrome_frame/cfproxy.h +++ /dev/null @@ -1,227 +0,0 @@ -// 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_CFPROXY_H_ -#define CHROME_FRAME_CFPROXY_H_ -#pragma once - -#include <windows.h> -#include <map> // for proxy factory -#include <vector> -#include <string> -#include "base/lock.h" -#include "base/time.h" // for base::TimeDelta -#include "base/file_path.h" -#include "chrome/common/page_zoom.h" -#include "chrome/test/automation/automation_constants.h" - -enum FindInPageDirection { BACK = 0, FWD = 1 }; -enum FindInPageCase { IGNORE_CASE = 0, CASE_SENSITIVE = 1 }; -// Specifies the font size on a page which is requested by an automation -// client. -enum AutomationPageFontSize { - SMALLEST_FONT = 8, - SMALL_FONT = 12, - MEDIUM_FONT = 16, - LARGE_FONT = 24, - LARGEST_FONT = 36 -}; - -class URLRequestStatus; -namespace IPC { - struct ExternalTabSettings; - struct NavigationInfo; - struct AutomationURLRequest; - struct AttachExternalTabParams; -}; - -class GURL; -class ChromeProxyFactory; -class ChromeProxyDelegate; -struct ProxyParams; - -// Some callers of synchronous messages wants a context to be passed back -// in order to identify the call they made. Presumably one can make -// multiple sync calls of same type (as async) and want to identify what -// is what. -struct SyncMessageContext { - virtual ~SyncMessageContext() {} -}; - - -/* -[npapi] UIDelegate (UI_THREAD) -[activex] <---------------+ -[activedoc] | - | - | ChromeProxy (UI_THREAD) - +----------------+ --------------> +-------+ - URL_FETCHER <---------|ExternalTabProxy| |CFProxy| - +----------------+ +-------+ - | - ^ | - | | - +-----------------------------+ - - ChromeProxyDelegate (IPC_THREAD) - -*/ - -// ChromeProxy is an abstract class. Is forwards the commands to an -// instance of the running Chromium browser. -// A pointer to ChromeProxy instance is obtained through a -// ChromeProxyFactory object. -class ChromeProxy { - public: - // General - virtual void RemoveBrowsingData(int remove_mask) = 0; // async - virtual void InstallExtension(ChromeProxyDelegate* delegate, - const FilePath& crx_path, - SyncMessageContext* ctx) = 0; - virtual void LoadExtension(ChromeProxyDelegate* delegate, - const FilePath& path, - SyncMessageContext* ctx) = 0; - virtual void GetEnabledExtensions(ChromeProxyDelegate* delegate, - SyncMessageContext* ctx) = 0; - virtual void SetProxyConfig(const std::string& json_encoded_settings) = 0; - - // Tab management. - virtual void CreateTab(ChromeProxyDelegate* delegate, - const IPC::ExternalTabSettings& settings) = 0; - virtual void ConnectTab(ChromeProxyDelegate* delegate, HWND hwnd, - uint64 cookie) = 0; - virtual void BlockTab(uint64 cookie) = 0; - - // Tab related. - virtual void Tab_PostMessage(int tab, const std::string& message, - const std::string& origin, - const std::string& target) = 0; - virtual void Tab_Reload(int tab) = 0; - virtual void Tab_Stop(int tab) = 0; - virtual void Tab_SaveAs(int tab) = 0; - virtual void Tab_Print(int tab) = 0; - virtual void Tab_Cut(int tab) = 0; - virtual void Tab_Copy(int tab) = 0; - virtual void Tab_Paste(int tab) = 0; - virtual void Tab_SelectAll(int tab) = 0; - virtual void Tab_Find(int tab, const string16& search_string, - FindInPageDirection forward, FindInPageCase match_case, - bool find_next) = 0; - virtual void Tab_MenuCommand(int tab, int selected_command) = 0; - - // UI - virtual void Tab_Zoom(int tab, PageZoom::Function zoom_level) = 0; - virtual void Tab_FontSize(int tab, enum AutomationPageFontSize font_size) = 0; - virtual void Tab_SetInitialFocus(int tab, - bool reverse, bool restore_focus_to_view) = 0; - virtual void Tab_SetParentWindow(int tab) = 0; - virtual void Tab_Resize(int tab) = 0; - virtual void Tab_ProcessAccelerator(int tab, const MSG& msg) = 0; - - // Misc. - virtual void Tab_OnHostMoved(int tab) = 0; - virtual void Tab_RunUnloadHandlers(int tab) = 0; - virtual void Tab_SetEnableExtensionAutomation(int tab, - const std::vector<std::string>& functions_enabled) = 0; - virtual void Tab_Navigate(int tab, const GURL& url, const GURL& referrer) = 0; - virtual void Tab_OverrideEncoding(int tab, const char* encoding) = 0; - - protected: - // Accessible by ChromeProxyFactory - friend class ChromeProxyFactory; - ~ChromeProxy() {} - virtual void Init(const ProxyParams& params) = 0; - virtual int AddDelegate(ChromeProxyDelegate* delegate) = 0; - virtual int RemoveDelegate(ChromeProxyDelegate* delegate) = 0; -}; - -// The object that uses ChromeProxy should implement ChromeProxyDelegate in -// order to get notified about important events/requests coming from the -// instance of Chromium. -// Allow only one delegate per tab, i.e. delegate can handle only a single tab. -// Note: all of the methods are invoked always in a background IPC thread. -class ChromeProxyDelegate { - public: - enum DisconnectReason { - CHROME_EXE_LAUNCH_FAILED, - CHROME_EXE_LAUNCH_TIMEOUT, - CHANNEL_ERROR - }; - - virtual void Connected(ChromeProxy* proxy) = 0; - virtual void Disconnected() = 0; - virtual void PeerLost(ChromeProxy* proxy, DisconnectReason reason) = 0; - virtual int tab_handle() = 0; // to avoid reverse lookup :) - - // Sync message responses. - virtual void Completed_CreateTab(bool success, HWND chrome_wnd, - HWND tab_window, int tab_handle) = 0; - 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) = 0; - virtual void Completed_InstallExtension(bool success, - AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) = 0; - virtual void Completed_LoadExpandedExtension(bool success, - AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) = 0; - virtual void Completed_GetEnabledExtensions(bool success, - const std::vector<FilePath>* extensions) = 0; - - // Network requests from Chrome. - virtual void Network_Start(int request_id, - const IPC::AutomationURLRequest& request_info) = 0; - virtual void Network_Read(int request_id, int bytes_to_read) = 0; - virtual void Network_End(int request_id, const URLRequestStatus& status) = 0; - virtual void Network_DownloadInHost(int request_id) = 0; - virtual void GetCookies(const GURL& url, int cookie_id) = 0; - virtual void SetCookie(const GURL& url, const std::string& cookie) = 0; - - // Navigation progress notifications. - virtual void NavigationStateChanged(int flags, - const IPC::NavigationInfo& nav_info) = 0; - virtual void UpdateTargetUrl(const std::wstring& url) = 0; - virtual void NavigationFailed(int error_code, const GURL& gurl) = 0; - virtual void DidNavigate(const IPC::NavigationInfo& navigation_info) = 0; - virtual void TabLoaded(const GURL& url) = 0; - - // Navigation and messaging. - virtual void OpenURL(const GURL& url_to_open, const GURL& referrer, - int open_disposition) = 0; - virtual void GoToHistoryOffset(int offset) = 0; - virtual void MessageToHost(const std::string& message, - const std::string& origin, - const std::string& target) = 0; - // Misc. UI. - virtual void HandleAccelerator(const MSG& accel_message) = 0; - virtual void TabbedOut(bool reverse) = 0; - - // Tab related. - virtual void TabClosed() = 0; - virtual void AttachTab(const IPC::AttachExternalTabParams& attach_params) = 0; - protected: - ~ChromeProxyDelegate() {} -}; - -// a way to obtain a ChromeProxy implementation -struct ProxyParams { - std::string profile; - std::wstring extra_params; - FilePath profile_path; - base::TimeDelta timeout; -}; - -class ChromeProxyFactory { - public: - ChromeProxyFactory(); - ~ChromeProxyFactory(); - void GetProxy(ChromeProxyDelegate* delegate, const ProxyParams& params); - bool ReleaseProxy(ChromeProxyDelegate* delegate, const std::string& profile); - protected: - virtual ChromeProxy* CreateProxy(); - typedef std::map<std::string, ChromeProxy*> ProxyMap; - ProxyMap proxies_; - Lock lock_; -}; - -#endif // CHROME_FRAME_CFPROXY_H_ diff --git a/chrome_frame/cfproxy_factory.cc b/chrome_frame/cfproxy_factory.cc deleted file mode 100644 index c936873..0000000 --- a/chrome_frame/cfproxy_factory.cc +++ /dev/null @@ -1,79 +0,0 @@ -// 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. - -#include "chrome_frame/cfproxy_private.h" -#include "base/process_util.h" - -IPC::Message::Sender* CFProxyTraits::CreateChannel(const std::string& id, - IPC::Channel::Listener* listener) { - IPC::Channel* c = new IPC::Channel(id, IPC::Channel::MODE_SERVER, listener); - if (c) - c->Connect(); // must be called on the IPC thread. - return c; -} - -void CFProxyTraits::CloseChannel(IPC::Message::Sender* s) { - IPC::Channel *c = static_cast<IPC::Channel*>(s); - delete c; -} - -bool CFProxyTraits::LaunchApp(const std::wstring& cmd_line) { - bool ok = base::LaunchApp(cmd_line, false, false, NULL); - return ok; -} - -////////////////////////////////////////////////////////// -// ChromeProxyFactory - -ChromeProxyFactory::ChromeProxyFactory() { -} - -ChromeProxyFactory::~ChromeProxyFactory() { - AutoLock lock(lock_); - ProxyMap::iterator it = proxies_.begin(); - for (; it != proxies_.end(); ++it) { - delete it->second; - } - proxies_.clear(); -} - -void ChromeProxyFactory::GetProxy(ChromeProxyDelegate* delegate, - const ProxyParams& params) { - AutoLock lock(lock_); - ChromeProxy* proxy = NULL; - // TODO(stoyan): consider extra_params/timeout - ProxyMap::iterator it = proxies_.find(params.profile); - if (it == proxies_.end()) { - proxy = CreateProxy(); - proxy->Init(params); - proxies_.insert(make_pair(params.profile, proxy)); - } else { - proxy = it->second; - } - - proxy->AddDelegate(delegate); - // TODO(stoyan): ::DeleteTimerQueueTimer (if any). -} - -bool ChromeProxyFactory::ReleaseProxy(ChromeProxyDelegate* delegate, - const std::string& profile) { - AutoLock lock(lock_); - ProxyMap::iterator it = proxies_.find(profile); - if (it == proxies_.end()) - return false; - - if (0 == it->second->RemoveDelegate(delegate)) { - // This was the last delegate for this proxy. - // TODO(stoyan): Use ::CreateTimerQueueTimer to schedule destroy of - // the proxy in a reasonable timeout. - } - - return true; -} - -static CFProxyTraits g_default_traits; -ChromeProxy* ChromeProxyFactory::CreateProxy() { - ChromeProxy* p = new CFProxy(&g_default_traits); - return p; -} diff --git a/chrome_frame/cfproxy_private.h b/chrome_frame/cfproxy_private.h deleted file mode 100644 index a9cc6dc..0000000 --- a/chrome_frame/cfproxy_private.h +++ /dev/null @@ -1,192 +0,0 @@ -// 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_CFPROXY_PRIVATE_H_ -#define CHROME_FRAME_CFPROXY_PRIVATE_H_ -#pragma once - -#include <map> -#include <set> -#include <string> -#include <vector> -#include "chrome_frame/cfproxy.h" -#include "base/thread.h" -// Since we can't forward declare IPC::Message::Sender or IPC::Channel::Listener -#include "ipc/ipc_message.h" -#include "ipc/ipc_channel.h" - -typedef std::map<int, ChromeProxyDelegate*> TabsMap; - -// This is the functions needed by CFProxy implementation. -// Extracted in separate class so we can mock it. -class CFProxyTraits { - public: - virtual IPC::Message::Sender* CreateChannel(const std::string& id, - IPC::Channel::Listener* l); - virtual void CloseChannel(IPC::Message::Sender* s); - virtual bool LaunchApp(const std::wstring& cmd_line); -}; - -// Holds a queue of sent synchronous IPC messages. Knows how to dispatch -// the replies. -class SyncMsgSender { - public: - explicit SyncMsgSender(TabsMap* tab2delegate); - void QueueSyncMessage(const IPC::SyncMessage* msg, - ChromeProxyDelegate* delegate, SyncMessageContext* ctx); - bool OnReplyReceived(const IPC::Message* reply_msg); - void OnChannelClosed(); - void Cancel(ChromeProxyDelegate* delegate); - private: - // sync_message_id -> (message_type, delegate, context) - struct SingleSentMessage { - SingleSentMessage() : type_(0), ctx_(NULL), delegate_(NULL) {} - SingleSentMessage(uint32 type, - ChromeProxyDelegate* delegate, - SyncMessageContext* ctx) - : type_(type), ctx_(ctx), delegate_(delegate) {} - ~SingleSentMessage() { delete ctx_; } - uint32 type_; - SyncMessageContext* ctx_; - ChromeProxyDelegate* delegate_; - }; - - SingleSentMessage* RemoveMessage(int id); - typedef std::map<int, SingleSentMessage*> SentMessages; - SentMessages messages_; - Lock messages_lock_; - TabsMap* tab2delegate_; -}; - -// Converts method call to an IPC message and then send it over Message::Sender -class Interface2IPCMessage : public ChromeProxy { - public: - Interface2IPCMessage() {} - - // General - virtual void RemoveBrowsingData(int mask); - virtual void SetProxyConfig(const std::string& json_encoded_proxy_cfg); - // Tab related. - virtual void Tab_PostMessage(int tab, const std::string& message, - const std::string& origin, const std::string& target); - virtual void Tab_Reload(int tab); - virtual void Tab_Stop(int tab); - virtual void Tab_SaveAs(int tab); - virtual void Tab_Print(int tab); - virtual void Tab_Cut(int tab); - virtual void Tab_Copy(int tab); - virtual void Tab_Paste(int tab); - virtual void Tab_SelectAll(int tab); - virtual void Tab_MenuCommand(int tab, int selected_command); - virtual void Tab_Zoom(int tab, PageZoom::Function zoom_level); - virtual void Tab_FontSize(int tab, enum AutomationPageFontSize font_size); - virtual void Tab_SetInitialFocus(int tab, bool reverse, - bool restore_focus_to_view); - virtual void Tab_SetParentWindow(int tab); - virtual void Tab_Resize(int tab); - virtual void Tab_ProcessAccelerator(int tab, const MSG& msg); - - // Misc. - virtual void Tab_OnHostMoved(int tab); - virtual void Tab_SetEnableExtensionAutomation(int tab, - const std::vector<std::string>& functions_enabled); - protected: - ~Interface2IPCMessage() {} - private: - IPC::Message::Sender* sender_; -}; - -// Simple class to keep a list of pointers to ChromeProxyDelegate for a -// specific proxy as well as mapping between tab_id -> ChromeProxyDelegate. -class DelegateHolder { - protected: - DelegateHolder() { - } - - void AddDelegate(ChromeProxyDelegate* p); - void RemoveDelegate(ChromeProxyDelegate* p); - // Helper - ChromeProxyDelegate* Tab2Delegate(int tab_handle); - TabsMap tab2delegate_; - typedef std::set<ChromeProxyDelegate*> DelegateList; - DelegateList delegate_list_; -}; - -// ChromeFrame Automation Proxy implementation. -class CFProxy : public Interface2IPCMessage, - public IPC::Channel::Listener, - public DelegateHolder { - public: - explicit CFProxy(CFProxyTraits* api); - ~CFProxy(); - - private: - virtual void Init(const ProxyParams& params); - virtual int AddDelegate(ChromeProxyDelegate* p); - virtual int RemoveDelegate(ChromeProxyDelegate* p); - - // Executed in IPC thread. - void AddDelegateOnIoThread(ChromeProxyDelegate* p); - void RemoveDelegateOnIoThread(ChromeProxyDelegate* p); - // Initialization that has to be mede in IPC thread. - void InitInIoThread(const ProxyParams& params); - // Cleanup that has to be made in IPC thread. - void CleanupOnIoThread(); - // IPC connection was not established in timely manner - void LaunchTimeOut(); - // Close channel, inform delegates. - void OnPeerLost(ChromeProxyDelegate::DisconnectReason reason); - // Queues message to be send in IPC thread. - void SendIpcMessage(IPC::Message* m); - // Same but in IPC thread. - void SendIpcMessageOnIoThread(IPC::Message* m); - - ////////////////////////////////////////////////////////////////////////// - // Sync messages. - virtual void InstallExtension(ChromeProxyDelegate* delegate, - const FilePath& crx_path, SyncMessageContext* ctx); - virtual void LoadExtension(ChromeProxyDelegate* delegate, - const FilePath& path, SyncMessageContext* ctx); - virtual void GetEnabledExtensions(ChromeProxyDelegate* delegate, - SyncMessageContext* ctx); - virtual void Tab_Find(int tab, const string16& search_string, - FindInPageDirection forward, FindInPageCase match_case, bool find_next); - virtual void Tab_OverrideEncoding(int tab, const char* encoding); - virtual void Tab_Navigate(int tab, const GURL& url, const GURL& referrer); - virtual void CreateTab(ChromeProxyDelegate* delegate, - const IPC::ExternalTabSettings& p); - virtual void ConnectTab(ChromeProxyDelegate* delegate, HWND hwnd, - uint64 cookie); - virtual void BlockTab(uint64 cookie); - virtual void Tab_RunUnloadHandlers(int tab); - - ////////////////////////////////////////////////////////////////////////// - // IPC::Channel::Listener - virtual void OnMessageReceived(const IPC::Message& message); - virtual void OnChannelConnected(int32 peer_pid); - virtual void OnChannelError(); - - bool CalledOnIpcThread() const { - return PlatformThread::CurrentId() == ipc_thread_.thread_id(); - } - - base::Thread ipc_thread_; - SyncMsgSender sync_dispatcher_; - IPC::Message::Sender* ipc_sender_; - CFProxyTraits* api_; - int delegate_count_; - bool is_connected_; -}; - -DISABLE_RUNNABLE_METHOD_REFCOUNT(CFProxy); - -// Support functions. -std::string GenerateChannelId(); -int IsTabMessage(const IPC::Message& message); -bool DispatchTabMessageToDelegate(ChromeProxyDelegate* delegate, - const IPC::Message& m); -std::wstring BuildCmdLine(const std::string& channel_id, - const FilePath& profile_path, - const std::wstring& extra_args); -#endif // CHROME_FRAME_CFPROXY_PRIVATE_H_ diff --git a/chrome_frame/cfproxy_proxy.cc b/chrome_frame/cfproxy_proxy.cc deleted file mode 100644 index 5a826c7..0000000 --- a/chrome_frame/cfproxy_proxy.cc +++ /dev/null @@ -1,246 +0,0 @@ -// 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. - -#include "chrome_frame/cfproxy_private.h" - -#include "base/tuple.h" -#include "ipc/ipc_sync_message.h" -#include "chrome/test/automation/automation_messages.h" - -CFProxy::CFProxy(CFProxyTraits* api) : ipc_thread_("ipc"), - sync_dispatcher_(&tab2delegate_), - ipc_sender_(NULL), - api_(api), - delegate_count_(0), - is_connected_(false) { -} - -CFProxy::~CFProxy() { - ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, - &CFProxy::CleanupOnIoThread)); - // ipc_thread destructor will do the Stop anyway. this is for debug :) - ipc_thread_.Stop(); -} - - -void CFProxy::Init(const ProxyParams& params) { - ipc_thread_.StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0)); - ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, - &CFProxy::InitInIoThread, params)); -} - -int CFProxy::AddDelegate(ChromeProxyDelegate* proxy) { - ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, - &CFProxy::AddDelegateOnIoThread, proxy)); - return ++delegate_count_; -} - -int CFProxy::RemoveDelegate(ChromeProxyDelegate* proxy) { - ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, - &CFProxy::RemoveDelegateOnIoThread, proxy)); - return --delegate_count_; -} - -void CFProxy::AddDelegateOnIoThread(ChromeProxyDelegate* proxy) { - DCHECK(CalledOnIpcThread()); - DelegateHolder::AddDelegate(proxy); - if (is_connected_) { - proxy->Connected(this); - } -} - -void CFProxy::RemoveDelegateOnIoThread(ChromeProxyDelegate* proxy) { - DCHECK(CalledOnIpcThread()); - DelegateHolder::RemoveDelegate(proxy); - proxy->Disconnected(); -} - -void CFProxy::InitInIoThread(const ProxyParams& params) { - DCHECK(CalledOnIpcThread()); - std::string channel_id = GenerateChannelId(); - ipc_sender_ = api_->CreateChannel(channel_id, this); - std::wstring cmd_line = BuildCmdLine(channel_id, params.profile_path, - params.extra_params); - if (api_->LaunchApp(cmd_line)) { - CancelableTask* launch_timeout = NewRunnableMethod(this, - &CFProxy::LaunchTimeOut); - ipc_thread_.message_loop()->PostDelayedTask(FROM_HERE, launch_timeout, - params.timeout.InMilliseconds()); - } else { - OnPeerLost(ChromeProxyDelegate::CHROME_EXE_LAUNCH_FAILED); - } -} - -void CFProxy::CleanupOnIoThread() { - DCHECK(CalledOnIpcThread()); - if (ipc_sender_) { - api_->CloseChannel(ipc_sender_); - ipc_sender_ = NULL; - } - // TODO(stoyan): shall we notify delegates? - // The object is dying, so under normal circumstances there should be - // no delegates. - DCHECK_EQ(0, delegate_count_); - DCHECK_EQ(0u, delegate_list_.size()); - DCHECK_EQ(0u, tab2delegate_.size()); -} - -void CFProxy::LaunchTimeOut() { - DCHECK(CalledOnIpcThread()); - if (!is_connected_) { - OnPeerLost(ChromeProxyDelegate::CHROME_EXE_LAUNCH_TIMEOUT); - } -} - -void CFProxy::OnPeerLost(ChromeProxyDelegate::DisconnectReason reason) { - // Kill the channel. Inform delegates - DCHECK(CalledOnIpcThread()); - if (ipc_sender_) { - api_->CloseChannel(ipc_sender_); - ipc_sender_ = NULL; - } - - for (DelegateList::iterator it = delegate_list_.begin(); - it != delegate_list_.end(); ++it) { - (*it)->PeerLost(this, reason); - } -} - -void CFProxy::SendIpcMessage(IPC::Message* m) { - ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, - &CFProxy::SendIpcMessageOnIoThread, m)); -} - -void CFProxy::SendIpcMessageOnIoThread(IPC::Message* m) { - DCHECK(CalledOnIpcThread()); - if (ipc_sender_) { - ipc_sender_->Send(m); - } else { - delete m; - } -} - -////////////////////////////////////////////////////////////////////////// -// Sync messages. -void CFProxy::InstallExtension(ChromeProxyDelegate* delegate, - const FilePath& crx_path, - SyncMessageContext* ctx) { - IPC::SyncMessage* m = new AutomationMsg_InstallExtension(0, crx_path, NULL); - sync_dispatcher_.QueueSyncMessage(m, delegate, ctx); - SendIpcMessage(m); -} - -void CFProxy::LoadExtension(ChromeProxyDelegate* delegate, - const FilePath& path, SyncMessageContext* ctx) { - IPC::SyncMessage* m = new AutomationMsg_LoadExpandedExtension(0, path, 0); - sync_dispatcher_.QueueSyncMessage(m, delegate, ctx); - SendIpcMessage(m); -} - -void CFProxy::GetEnabledExtensions(ChromeProxyDelegate* delegate, - SyncMessageContext* ctx) { - IPC::SyncMessage* m = new AutomationMsg_GetEnabledExtensions(0, NULL); - sync_dispatcher_.QueueSyncMessage(m, delegate, ctx); - SendIpcMessage(m); -} - -void CFProxy::Tab_Find(int tab, const string16& search_string, - FindInPageDirection forward, FindInPageCase match_case, - bool find_next) { - AutomationMsg_Find_Params params; - params.unused = 0; - params.search_string = search_string; - params.find_next = find_next; - params.match_case = (match_case == CASE_SENSITIVE); - params.forward = (forward == FWD); - IPC::SyncMessage* m = new AutomationMsg_Find(0, tab, params, NULL, NULL); - // Not interested in result. - sync_dispatcher_.QueueSyncMessage(m, NULL, NULL); - SendIpcMessage(m); -} - -void CFProxy::Tab_OverrideEncoding(int tab, const char* encoding) { - IPC::SyncMessage* m = new AutomationMsg_OverrideEncoding(0, tab, encoding, - NULL); - // Not interested in result. - sync_dispatcher_.QueueSyncMessage(m, NULL, NULL); - SendIpcMessage(m); -} - -void CFProxy::Tab_Navigate(int tab, const GURL& url, const GURL& referrer) { - IPC::SyncMessage* m = new AutomationMsg_NavigateInExternalTab(0, - tab, url, referrer, NULL); - // We probably are not interested in result since provider just checks - // whether tab handle is valid. - sync_dispatcher_.QueueSyncMessage(m, NULL, NULL); - SendIpcMessage(m); -} - -void CFProxy::CreateTab(ChromeProxyDelegate* delegate, - const IPC::ExternalTabSettings& p) { - IPC::SyncMessage* m = new AutomationMsg_CreateExternalTab(0, p, 0, 0, 0); - sync_dispatcher_.QueueSyncMessage(m, delegate, NULL); - SendIpcMessage(m); -} - -void CFProxy::ConnectTab(ChromeProxyDelegate* delegate, HWND hwnd, - uint64 cookie) { - IPC::SyncMessage* m = new AutomationMsg_ConnectExternalTab(0, cookie, true, - hwnd, NULL, NULL, NULL); - sync_dispatcher_.QueueSyncMessage(m, delegate, NULL); - SendIpcMessage(m); -} - -void CFProxy::BlockTab(uint64 cookie) { - IPC::SyncMessage* m = new AutomationMsg_ConnectExternalTab(0, cookie, false, - NULL, NULL, NULL, NULL); - sync_dispatcher_.QueueSyncMessage(m, NULL, NULL); - SendIpcMessage(m); -} - -void CFProxy::Tab_RunUnloadHandlers(int tab) { - IPC::SyncMessage* m = new AutomationMsg_RunUnloadHandlers(0, tab, 0); - ChromeProxyDelegate* p = Tab2Delegate(tab); - sync_dispatcher_.QueueSyncMessage(m, p, NULL); - SendIpcMessage(m); -} - -// IPC::Channel::Listener -void CFProxy::OnMessageReceived(const IPC::Message& message) { - // Handle sync message reply. - bool done = sync_dispatcher_.OnReplyReceived(&message); - if (done) - return; - - // Handle tab related message. - int tab_handle = IsTabMessage(message); - if (tab_handle != 0) { - ChromeProxyDelegate* d = Tab2Delegate(tab_handle); - if (d) - DispatchTabMessageToDelegate(d, message); - return; - } - - DLOG(WARNING) << "Unknown message received!"; -} - -void CFProxy::OnChannelConnected(int32 peer_pid) { - is_connected_ = true; - // TODO(stoyan): May be we should wait for Hello message. - for (DelegateList::iterator it = delegate_list_.begin(); - it != delegate_list_.end(); ++it) { - (*it)->Connected(this); - } -} - -void CFProxy::OnChannelError() { - is_connected_ = false; - - // Inform the sync message callbacks that there are not going to see - // any reply. - sync_dispatcher_.OnChannelClosed(); - OnPeerLost(ChromeProxyDelegate::CHANNEL_ERROR); - - // TODO(stoyan): Relaunch? -} diff --git a/chrome_frame/cfproxy_support.cc b/chrome_frame/cfproxy_support.cc deleted file mode 100644 index 72454c0..0000000 --- a/chrome_frame/cfproxy_support.cc +++ /dev/null @@ -1,450 +0,0 @@ -// 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. - -#include "chrome_frame/cfproxy_private.h" - -#include "base/atomic_sequence_num.h" -#include "base/command_line.h" -#include "base/process_util.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/test/automation/automation_messages.h" -#include "chrome_frame/chrome_launcher_utils.h" -#include "chrome_frame/utils.h" // for IsHeadlessMode(); - - -namespace { -void DispatchReplyFail(uint32 type, - ChromeProxyDelegate* delegate, - SyncMessageContext* ctx) { - switch (type) { - case AutomationMsg_CreateExternalTab::ID: - delegate->Completed_CreateTab(false, NULL, NULL, NULL); - break; - case AutomationMsg_ConnectExternalTab::ID: - delegate->Completed_ConnectToTab(false, NULL, NULL, NULL); - break; - case AutomationMsg_InstallExtension::ID: - delegate->Completed_InstallExtension(false, - AUTOMATION_MSG_EXTENSION_INSTALL_FAILED, ctx); - break; - } -} - -bool DispatchReplyOk(const IPC::Message* reply_msg, uint32 type, - ChromeProxyDelegate* delegate, SyncMessageContext* ctx, - TabsMap* tab2delegate) { - void* iter = IPC::SyncMessage::GetDataIterator(reply_msg); - switch (type) { - case AutomationMsg_CreateExternalTab::ID: { - // Tuple3<HWND, HWND, int> out; - TupleTypes<AutomationMsg_CreateExternalTab::ReplyParam>::ValueTuple out; - if (ReadParam(reply_msg, &iter, &out)) { - DCHECK(tab2delegate->find(out.c) == tab2delegate->end()); - (*tab2delegate)[out.c] = delegate; - delegate->Completed_CreateTab(true, out.a, out.b, out.c); - } - return true; - } - - case AutomationMsg_ConnectExternalTab::ID: { - // Tuple3<HWND, HWND, int> out; - TupleTypes<AutomationMsg_ConnectExternalTab::ReplyParam>::ValueTuple out; - if (ReadParam(reply_msg, &iter, &out)) { - DCHECK(tab2delegate->find(out.c) == tab2delegate->end()); - (*tab2delegate)[out.c] = delegate; - delegate->Completed_ConnectToTab(true, out.a, out.b, out.c); - } - return true; - } - - case AutomationMsg_InstallExtension::ID: { - // Tuple1<AutomationMsg_ExtensionResponseValues> out; - TupleTypes<AutomationMsg_InstallExtension::ReplyParam>::ValueTuple out; - if (ReadParam(reply_msg, &iter, &out)) - delegate->Completed_InstallExtension(true, out.a, ctx); - return true; - } - - case AutomationMsg_LoadExpandedExtension::ID: { - // Tuple1<AutomationMsg_ExtensionResponseValues> out; - TupleTypes<AutomationMsg_LoadExpandedExtension::ReplyParam>::ValueTuple - out; - if (ReadParam(reply_msg, &iter, &out)) - delegate->Completed_LoadExpandedExtension(true, out.a, ctx); - break; - } - - case AutomationMsg_GetEnabledExtensions::ID: { - // Tuple1<std::vector<FilePath> > - TupleTypes<AutomationMsg_GetEnabledExtensions::ReplyParam>::ValueTuple - out; - if (ReadParam(reply_msg, &iter, &out)) - delegate->Completed_GetEnabledExtensions(true, &out.a); - break; - } - } // switch - - return false; -} -} // namespace - -// Itf2IPCMessage -// Converts and sends trivial messages. -void Interface2IPCMessage::RemoveBrowsingData(int mask) { - sender_->Send(new AutomationMsg_RemoveBrowsingData(0, mask)); -} - -void Interface2IPCMessage::SetProxyConfig( - const std::string& json_encoded_proxy_cfg) { - sender_->Send(new AutomationMsg_SetProxyConfig(0, json_encoded_proxy_cfg)); -} - -// Tab related. -void Interface2IPCMessage::Tab_PostMessage(int tab, const std::string& message, - const std::string& origin, const std::string& target) { - sender_->Send(new AutomationMsg_HandleMessageFromExternalHost( - 0, tab, message, origin, target)); -} - -void Interface2IPCMessage::Tab_Reload(int tab) { - sender_->Send(new AutomationMsg_ReloadAsync(0, tab)); -} - -void Interface2IPCMessage::Tab_Stop(int tab) { - sender_->Send(new AutomationMsg_StopAsync(0, tab)); -} - -void Interface2IPCMessage::Tab_SaveAs(int tab) { - sender_->Send(new AutomationMsg_SaveAsAsync(0, tab)); -} - -void Interface2IPCMessage::Tab_Print(int tab) { - sender_->Send(new AutomationMsg_PrintAsync(0, tab)); -} - -void Interface2IPCMessage::Tab_Cut(int tab) { - sender_->Send(new AutomationMsg_Cut(0, tab)); -} - -void Interface2IPCMessage::Tab_Copy(int tab) { - sender_->Send(new AutomationMsg_Copy(0, tab)); -} - -void Interface2IPCMessage::Tab_Paste(int tab) { - sender_->Send(new AutomationMsg_Paste(0, tab)); -} - -void Interface2IPCMessage::Tab_SelectAll(int tab) { - sender_->Send(new AutomationMsg_SelectAll(0, tab)); -} - -void Interface2IPCMessage::Tab_MenuCommand(int tab, int selected_command) { - sender_->Send(new AutomationMsg_ForwardContextMenuCommandToChrome( - 0, tab, selected_command)); -} - -void Interface2IPCMessage::Tab_Zoom(int tab, PageZoom::Function zoom_level) { - sender_->Send(new AutomationMsg_SetZoomLevel(0, tab, zoom_level)); -} - -void Interface2IPCMessage::Tab_FontSize(int tab, - enum AutomationPageFontSize font_size) { - sender_->Send(new AutomationMsg_SetPageFontSize(0, tab, font_size)); -} - -void Interface2IPCMessage::Tab_SetInitialFocus(int tab, bool reverse, - bool restore_focus_to_view) { - sender_->Send(new AutomationMsg_SetInitialFocus(0, tab, reverse, - restore_focus_to_view)); -} - -void Interface2IPCMessage::Tab_SetParentWindow(int tab) { - CHECK(0) << "Implement me"; - // AutomationMsg_TabReposition -} - -void Interface2IPCMessage::Tab_Resize(int tab) { - CHECK(0) << "Implement me"; - // AutomationMsg_TabReposition -} - -void Interface2IPCMessage::Tab_ProcessAccelerator(int tab, const MSG& msg) { - sender_->Send(new AutomationMsg_ProcessUnhandledAccelerator(0, tab, msg)); -} - -// Misc. -void Interface2IPCMessage::Tab_OnHostMoved(int tab) { - sender_->Send(new AutomationMsg_BrowserMove(0, tab)); -} - -void Interface2IPCMessage::Tab_SetEnableExtensionAutomation(int tab, - const std::vector<std::string>& functions_enabled) { - sender_->Send(new AutomationMsg_SetEnableExtensionAutomation(0, tab, - functions_enabled)); -} - -void DelegateHolder::AddDelegate(ChromeProxyDelegate* p) { - delegate_list_.insert(p); -} - -void DelegateHolder::RemoveDelegate(ChromeProxyDelegate* p) { - // DCHECK(CalledOnValidThread()); - int tab_handle = p->tab_handle(); // Could be 0. - delegate_list_.erase(p); - tab2delegate_.erase(tab_handle); -} - -ChromeProxyDelegate* DelegateHolder::Tab2Delegate(int tab_handle) { - TabsMap::const_iterator iter = tab2delegate_.find(tab_handle); - if (iter != tab2delegate_.end()) - return iter->second; - return NULL; -} - -SyncMsgSender::SyncMsgSender(TabsMap* tab2delegate) - : tab2delegate_(tab2delegate) { -} - -// The outgoing queue of sync messages must be locked. -// Case: ui thread is sending message and waits for event, that is going to be -// signaled by completion handler in ipc_thread. -// We must append the message to the outgoing queue in UI thread, -// otherwise if channel is disconnected before having a chance to -// send the message, the ChromeProxyDelegate::_Disconnect implementation -// shall know how to unblock arbitrary sync call. Instead -// ChromeProxyDelgate::Completed_XXXX knows how to unblock a specific one. -void SyncMsgSender::QueueSyncMessage(const IPC::SyncMessage* msg, - ChromeProxyDelegate* delegate, - SyncMessageContext* ctx) { - if (delegate) { - // We are interested of the result. - AutoLock lock(messages_lock_); - int id = IPC::SyncMessage::GetMessageId(*msg); - // A message can be sent only once. - DCHECK(messages_.end() == messages_.find(id)); - messages_[id] = new SingleSentMessage(msg->type(), delegate, ctx); - } -} - -void SyncMsgSender::Cancel(ChromeProxyDelegate* delegate) { - // TODO(stoyan): Cancel all outgoing calls for this delegate - // We may not need this. :) -} - -SyncMsgSender::SingleSentMessage* SyncMsgSender::RemoveMessage(int id) { - AutoLock lock(messages_lock_); - SentMessages::iterator it = messages_.find(id); - if (it == messages_.end()) { - // Delegate is not interested in this sync message response. - return NULL; - } - - // See what message is this. - SingleSentMessage* origin = it->second; - messages_.erase(it); - return origin; -} - -bool SyncMsgSender::OnReplyReceived(const IPC::Message* reply_msg) { - if (!reply_msg->is_reply()) - return false; // Not a reply to sync message. - - // Find message by id. - int id = IPC::SyncMessage::GetMessageId(*reply_msg); - SingleSentMessage* origin = RemoveMessage(id); - if (origin) { - DispatchReplyOk(reply_msg, origin->type_, origin->delegate_, origin->ctx_, - tab2delegate_); - delete origin; - } - - return true; -} - -void SyncMsgSender::OnChannelClosed() { - SentMessages messages_sent; - // Make a copy of the messages queue - { - AutoLock lock(messages_lock_); - messages_.swap(messages_sent); - } - - - SentMessages::reverse_iterator it = messages_sent.rbegin(); - for (; it != messages_sent.rend(); ++it) { - SingleSentMessage* origin = it->second; - DispatchReplyFail(origin->type_, origin->delegate_, origin->ctx_); - delete origin; - } - messages_sent.clear(); -} - -static base::AtomicSequenceNumber g_proxy_channel_id(base::LINKER_INITIALIZED); -std::string GenerateChannelId() { - return StringPrintf("ChromeTestingInterface:%u.%d", - base::GetCurrentProcId(), g_proxy_channel_id.GetNext() + 0xC000); -} - -std::wstring BuildCmdLine(const std::string& channel_id, - const FilePath& profile_path, - const std::wstring& extra_args) { - scoped_ptr<CommandLine> command_line( - chrome_launcher::CreateLaunchCommandLine()); - command_line->AppendSwitchASCII(switches::kAutomationClientChannelID, - channel_id); - // Run Chrome in Chrome Frame mode. In practice, this modifies the paths - // and registry keys that Chrome looks in via the BrowserDistribution - // mechanism. - command_line->AppendSwitch(switches::kChromeFrame); - // Chrome Frame never wants Chrome to start up with a First Run UI. - command_line->AppendSwitch(switches::kNoFirstRun); - command_line->AppendSwitch(switches::kDisablePopupBlocking); - -#ifndef NDEBUG - // Disable the "Whoa! Chrome has crashed." dialog, because that isn't very - // useful for Chrome Frame users. - command_line->AppendSwitch(switches::kNoErrorDialogs); -#endif - - // In headless mode runs like reliability test runs we want full crash dumps - // from chrome. - if (IsHeadlessMode()) - command_line->AppendSwitch(switches::kFullMemoryCrashReport); - - command_line->AppendSwitchPath(switches::kUserDataDir, profile_path); - - std::wstring command_line_string(command_line->command_line_string()); - if (!extra_args.empty()) { - command_line_string.append(L" "); - command_line_string.append(extra_args); - } - return command_line_string; -} - -int IsTabMessage(const IPC::Message& message) { - switch (message.type()) { - case AutomationMsg_NavigationStateChanged__ID: - case AutomationMsg_UpdateTargetUrl__ID: - case AutomationMsg_HandleAccelerator__ID: - case AutomationMsg_TabbedOut__ID: - case AutomationMsg_OpenURL__ID: - case AutomationMsg_NavigationFailed__ID: - case AutomationMsg_DidNavigate__ID: - case AutomationMsg_TabLoaded__ID: - case AutomationMsg_ForwardMessageToExternalHost__ID: - case AutomationMsg_ForwardContextMenuToExternalHost__ID: - case AutomationMsg_RequestStart__ID: - case AutomationMsg_RequestRead__ID: - case AutomationMsg_RequestEnd__ID: - case AutomationMsg_DownloadRequestInHost__ID: - case AutomationMsg_SetCookieAsync__ID: - case AutomationMsg_AttachExternalTab__ID: - case AutomationMsg_RequestGoToHistoryEntryOffset__ID: - case AutomationMsg_GetCookiesFromHost__ID: - case AutomationMsg_CloseExternalTab__ID: { - // Read tab handle from the message. - void* iter = NULL; - int tab_handle = 0; - message.ReadInt(&iter, &tab_handle); - return tab_handle; - } - } - - return 0; -} - -bool DispatchTabMessageToDelegate(ChromeProxyDelegate* delegate, - const IPC::Message& m) { - void* iter = 0; - switch (m.type()) { - case AutomationMsg_NavigationStateChanged__ID: { - // Tuple3<int, int, IPC::NavigationInfo> - AutomationMsg_NavigationStateChanged::Param params; - if (ReadParam(&m, &iter, ¶ms)) - delegate->NavigationStateChanged(params.b, params.c); - return true; - } - - case AutomationMsg_UpdateTargetUrl__ID: { - // Tuple2<int, std::wstring> - AutomationMsg_UpdateTargetUrl::Param params; - if (ReadParam(&m, &iter, ¶ms)) - delegate->UpdateTargetUrl(params.b); - return true; - } - - case AutomationMsg_HandleAccelerator__ID: { - AutomationMsg_HandleAccelerator::Param params; - return true; - } - - case AutomationMsg_TabbedOut__ID: { - AutomationMsg_TabbedOut::Param params; - return true; - } - - case AutomationMsg_OpenURL__ID: { - AutomationMsg_OpenURL::Param params; - return true; - } - - case AutomationMsg_NavigationFailed__ID: { - AutomationMsg_NavigationFailed::Param params; - return true; - } - - case AutomationMsg_DidNavigate__ID: { - AutomationMsg_DidNavigate::Param params; - return true; - } - - case AutomationMsg_TabLoaded__ID: { - return true; - } - case AutomationMsg_ForwardMessageToExternalHost__ID: { - return true; - } - - case AutomationMsg_ForwardContextMenuToExternalHost__ID: { - return true; - } - - case AutomationMsg_RequestStart__ID: { - return true; - } - - case AutomationMsg_RequestRead__ID: { - return true; - } - - case AutomationMsg_RequestEnd__ID: { - return true; - } - - case AutomationMsg_DownloadRequestInHost__ID: { - return true; - } - - case AutomationMsg_SetCookieAsync__ID: { - return true; - } - - case AutomationMsg_AttachExternalTab__ID: { - return true; - } - - case AutomationMsg_RequestGoToHistoryEntryOffset__ID: { - return true; - } - - case AutomationMsg_GetCookiesFromHost__ID: { - return true; - } - - case AutomationMsg_CloseExternalTab__ID: { - return true; - } - } - return true; -} diff --git a/chrome_frame/cfproxy_test.cc b/chrome_frame/cfproxy_test.cc deleted file mode 100644 index a291103..0000000 --- a/chrome_frame/cfproxy_test.cc +++ /dev/null @@ -1,316 +0,0 @@ -// 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. - -#include <string> -#include "base/file_path.h" -#include "base/waitable_event.h" -#include "chrome_frame/cfproxy_private.h" -#include "chrome/test/automation/automation_messages.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" - -using testing::_; -using testing::DoAll; -using testing::NotNull; -using testing::Return; -using testing::StrictMock; -using testing::InvokeWithoutArgs; -using testing::WithoutArgs; -using testing::CreateFunctor; - -// There is not much to test here since CFProxy is pretty dumb. -struct MockFactory : public ChromeProxyFactory { - MOCK_METHOD0(CreateProxy, ChromeProxy*()); -}; - -struct MockChromeProxyDelegate : public ChromeProxyDelegate { - MOCK_METHOD1(Connected, void(ChromeProxy* proxy)); - MOCK_METHOD2(PeerLost, void(ChromeProxy*, enum DisconnectReason reason)); - MOCK_METHOD0(Disconnected, void()); - MOCK_METHOD0(tab_handle, int()); - - MOCK_METHOD4(Completed_CreateTab, void(bool success, HWND chrome_wnd, - HWND tab_window, int tab_handle)); - MOCK_METHOD4(Completed_ConnectToTab, void(bool success, HWND chrome_window, - HWND tab_window, int tab_handle)); - MOCK_METHOD2(Completed_Navigate, void(bool success, - enum AutomationMsg_NavigationResponseValues res)); - MOCK_METHOD3(Completed_InstallExtension, void(bool success, - enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx)); - MOCK_METHOD3(Completed_LoadExpandedExtension, void(bool success, - enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx)); - MOCK_METHOD2(Completed_GetEnabledExtensions, void(bool success, - const std::vector<FilePath>* v)); - - // Network requests from Chrome. - MOCK_METHOD2(Network_Start, void(int request_id, - const IPC::AutomationURLRequest& request_info)); - MOCK_METHOD2(Network_Read, void(int request_id, int bytes_to_read)); - MOCK_METHOD2(Network_End, void(int request_id, const URLRequestStatus& s)); - MOCK_METHOD1(Network_DownloadInHost, void(int request_id)); - MOCK_METHOD2(GetCookies, void(const GURL& url, int cookie_id)); - MOCK_METHOD2(SetCookie, void(const GURL& url, const std::string& cookie)); - - // Navigation progress notifications. - MOCK_METHOD2(NavigationStateChanged, void(int flags, - const IPC::NavigationInfo& nav_info)); - MOCK_METHOD1(UpdateTargetUrl, void(const std::wstring& url)); - MOCK_METHOD2(NavigationFailed, void(int error_code, const GURL& gurl)); - MOCK_METHOD1(DidNavigate, void(const IPC::NavigationInfo& navigation_info)); - MOCK_METHOD1(TabLoaded, void(const GURL& url)); - - // - MOCK_METHOD3(OpenURL, void(const GURL& url_to_open, const GURL& referrer, - int open_disposition)); - MOCK_METHOD1(GoToHistoryOffset, void(int offset)); - MOCK_METHOD3(MessageToHost, void(const std::string& message, - const std::string& origin, const std::string& target)); - - // Misc. UI. - MOCK_METHOD1(HandleAccelerator, void(const MSG& accel_message)); - MOCK_METHOD1(TabbedOut, void(bool reverse)); - - // - MOCK_METHOD0(TabClosed, void()); - MOCK_METHOD1(AttachTab, - void(const IPC::AttachExternalTabParams& attach_params)); -}; - -struct MockSender : public IPC::Message::Sender { - MOCK_METHOD1(Send, bool(IPC::Message* m)); -}; - -struct MockCFProxyTraits : public CFProxyTraits { - MOCK_METHOD2(DoCreateChannel, IPC::Message::Sender*(const std::string& id, - IPC::Channel::Listener* l)); - MOCK_METHOD1(CloseChannel, void(IPC::Message::Sender* s)); - MOCK_METHOD1(LaunchApp, bool(const std::wstring& cmd_line)); - - // Forward the CreateChannel to DoCreateChannel, but save the ipc_thread - // and the listener (i.e. proxy implementation of Channel::Listener) - virtual IPC::Message::Sender* CreateChannel(const std::string& id, - IPC::Channel::Listener* l) { - ipc_loop = MessageLoop::current(); - listener = l; - return this->DoCreateChannel(id, l); - } - - // Simulate some activity in the IPC thread. - // You may find API_FIRE_XXXX macros (see below) handy instead. - void FireConnect(base::TimeDelta t) { - ASSERT_TRUE(ipc_loop != NULL); - ipc_loop->PostDelayedTask(FROM_HERE, NewRunnableMethod(listener, - &IPC::Channel::Listener::OnChannelConnected, 0), t.InMilliseconds()); - } - - void FireError(base::TimeDelta t) { - ASSERT_TRUE(ipc_loop != NULL); - ipc_loop->PostDelayedTask(FROM_HERE, NewRunnableMethod(listener, - &IPC::Channel::Listener::OnChannelError), t.InMilliseconds()); - } - - void FireMessage(const IPC::Message& m, base::TimeDelta t) { - ASSERT_TRUE(ipc_loop != NULL); - ipc_loop->PostDelayedTask(FROM_HERE, NewRunnableMethod(listener, - &IPC::Channel::Listener::OnMessageReceived, m), t.InMilliseconds()); - } - - MockCFProxyTraits() : ipc_loop(NULL) {} - MockSender sender; - private: - MessageLoop* ipc_loop; - IPC::Channel::Listener* listener; -}; - -// Handy macros when we want so similate something on the IPC thread. -#define API_FIRE_CONNECT(api, t) InvokeWithoutArgs(CreateFunctor(&api, \ - &MockCFProxyTraits::FireConnect, t)) -#define API_FIRE_ERROR(api, t) InvokeWithoutArgs(CreateFunctor(&api, \ - &MockCFProxyTraits::FireError, t)) -#define API_FIRE_MESSAGE(api, t) InvokeWithoutArgs(CreateFunctor(&api, \ - &MockCFProxyTraits::FireMessage, t)) -DISABLE_RUNNABLE_METHOD_REFCOUNT(IPC::Channel::Listener); - -TEST(ChromeProxy, DelegateAddRemove) { - StrictMock<MockCFProxyTraits> api; - StrictMock<MockChromeProxyDelegate> delegate; - StrictMock<MockFactory> factory; // to be destroyed before other mocks - CFProxy* proxy = new CFProxy(&api); - - - EXPECT_CALL(factory, CreateProxy()).WillOnce(Return(proxy)); - EXPECT_CALL(api, DoCreateChannel(_, proxy)).WillOnce(Return(&api.sender)); - EXPECT_CALL(api, LaunchApp(_)).WillOnce(Return(true)); - EXPECT_CALL(api, CloseChannel(&api.sender)); - - EXPECT_CALL(delegate, tab_handle()).WillRepeatedly(Return(0)); - EXPECT_CALL(delegate, Disconnected()); - - ProxyParams params; - params.profile = "Adam N. Epilinter"; - params.timeout = base::TimeDelta::FromSeconds(4); - factory.GetProxy(&delegate, params); - factory.ReleaseProxy(&delegate, params.profile); -} - -// Not very useful test. Just for illustration. :) -TEST(ChromeProxy, SharedProxy) { - base::WaitableEvent done1(false, false); - base::WaitableEvent done2(false, false); - StrictMock<MockCFProxyTraits> api; - StrictMock<MockChromeProxyDelegate> delegate1; - StrictMock<MockChromeProxyDelegate> delegate2; - StrictMock<MockFactory> factory; - CFProxy* proxy = new CFProxy(&api); - - EXPECT_CALL(factory, CreateProxy()).WillOnce(Return(proxy)); - EXPECT_CALL(api, DoCreateChannel(_, proxy)).WillOnce(Return(&api.sender)); - EXPECT_CALL(api, LaunchApp(_)).WillOnce(DoAll( - API_FIRE_CONNECT(api, base::TimeDelta::FromMilliseconds(150)), - Return(true))); - EXPECT_CALL(api, CloseChannel(&api.sender)); - - EXPECT_CALL(delegate1, tab_handle()).WillRepeatedly(Return(0)); - EXPECT_CALL(delegate2, tab_handle()).WillRepeatedly(Return(0)); - - EXPECT_CALL(delegate1, Connected(proxy)) - .WillOnce(InvokeWithoutArgs(&done1, &base::WaitableEvent::Signal)); - EXPECT_CALL(delegate2, Connected(proxy)) - .WillOnce(InvokeWithoutArgs(&done2, &base::WaitableEvent::Signal)); - - ProxyParams params; - params.profile = "Adam N. Epilinter"; - params.timeout = base::TimeDelta::FromSeconds(4); - - factory.GetProxy(&delegate1, params); - params.timeout = base::TimeDelta::FromSeconds(2); - factory.GetProxy(&delegate2, params); - - EXPECT_TRUE(done1.TimedWait(base::TimeDelta::FromSeconds(1))); - EXPECT_TRUE(done2.TimedWait(base::TimeDelta::FromSeconds(1))); - - EXPECT_CALL(delegate2, Disconnected()); - EXPECT_CALL(delegate1, Disconnected()); - - factory.ReleaseProxy(&delegate2, params.profile); - factory.ReleaseProxy(&delegate1, params.profile); -} - -TEST(ChromeProxy, LaunchTimeout) { - base::WaitableEvent done(true, false); - StrictMock<MockFactory> factory; - StrictMock<MockCFProxyTraits> api; - StrictMock<MockChromeProxyDelegate> delegate; - CFProxy* proxy = new CFProxy(&api); - - EXPECT_CALL(delegate, tab_handle()).WillRepeatedly(Return(0)); - EXPECT_CALL(factory, CreateProxy()).WillOnce(Return(proxy)); - EXPECT_CALL(api, DoCreateChannel(_, proxy)).WillOnce(Return(&api.sender)); - EXPECT_CALL(api, LaunchApp(_)).WillOnce(Return(true)); - EXPECT_CALL(api, CloseChannel(&api.sender)); - - EXPECT_CALL(delegate, PeerLost(_, - ChromeProxyDelegate::CHROME_EXE_LAUNCH_TIMEOUT)) - .WillOnce(InvokeWithoutArgs(&done, &base::WaitableEvent::Signal)); - ProxyParams params; - params.profile = "Adam N. Epilinter"; - params.timeout = base::TimeDelta::FromMilliseconds(300); - factory.GetProxy(&delegate, params); - EXPECT_TRUE(done.TimedWait(base::TimeDelta::FromSeconds(1))); - - EXPECT_CALL(delegate, Disconnected()); - factory.ReleaseProxy(&delegate, params.profile); -} - -TEST(ChromeProxy, LaunchChrome) { - base::WaitableEvent connected(false, false); - StrictMock<MockChromeProxyDelegate> delegate; - ChromeProxyFactory factory; - - ProxyParams params; - params.profile = "Adam N. Epilinter"; - params.timeout = base::TimeDelta::FromSeconds(10); - - EXPECT_CALL(delegate, tab_handle()).WillRepeatedly(Return(0)); - EXPECT_CALL(delegate, Connected(NotNull())) - .WillOnce(InvokeWithoutArgs(&connected, &base::WaitableEvent::Signal)); - - factory.GetProxy(&delegate, params); - EXPECT_TRUE(connected.TimedWait(base::TimeDelta::FromSeconds(15))); - - EXPECT_CALL(delegate, Disconnected()); - factory.ReleaseProxy(&delegate, params.profile); -} - -/////////////////////////////////////////////////////////////////////////////// -namespace { -template <typename M, typename A> -inline IPC::Message* CreateReply(M* m, const A& a) { - IPC::Message* r = IPC::SyncMessage::GenerateReply(m); - if (r) { - M::WriteReplyParams(r, a); - } - return r; -} - -template <typename M, typename A, typename B> -inline IPC::Message* CreateReply(M* m, const A& a, const B& b) { - IPC::Message* r = IPC::SyncMessage::GenerateReply(m); - if (r) { - M::WriteReplyParams(r, a, b); - } - return r; -} - -template <typename M, typename A, typename B, typename C> -inline IPC::Message* CreateReply(M* m, const A& a, const B& b, const C& c) { - IPC::Message* r = IPC::SyncMessage::GenerateReply(m); - if (r) { - M::WriteReplyParams(r, a, b, c); - } - return r; -} -} // namespace - -DISABLE_RUNNABLE_METHOD_REFCOUNT(SyncMsgSender); -TEST(SyncMsgSender, Deserialize) { - // Note the ipc thread is not actually needed, but we try to be close - // to real-world conditions - that SyncMsgSender works from multiple threads. - base::Thread ipc("ipc"); - ipc.StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0)); - - StrictMock<MockChromeProxyDelegate> d1; - TabsMap tab2delegate; - SyncMsgSender queue(&tab2delegate); - - // Create some sync messages and their replies. - AutomationMsg_InstallExtension m1(0, FilePath(L"c:\\awesome.x"), 0); - AutomationMsg_CreateExternalTab m2(0, IPC::ExternalTabSettings(), 0, 0, 0); - scoped_ptr<IPC::Message> r1(CreateReply(&m1, - AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED)); - scoped_ptr<IPC::Message> r2(CreateReply(&m2, (HWND)1, (HWND)2, 6)); - - queue.QueueSyncMessage(&m1, &d1, NULL); - queue.QueueSyncMessage(&m2, &d1, NULL); - - testing::InSequence s; - EXPECT_CALL(d1, Completed_InstallExtension(true, - AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED, NULL)); - EXPECT_CALL(d1, Completed_CreateTab(true, (HWND)1, (HWND)2, 6)); - - // Execute replies in a worker thread. - ipc.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(&queue, - &SyncMsgSender::OnReplyReceived, r1.get())); - ipc.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(&queue, - &SyncMsgSender::OnReplyReceived, r2.get())); - ipc.Stop(); - - // Expect that tab 6 has been associated with the delegate. - EXPECT_EQ(&d1, tab2delegate[6]); -} - -TEST(SyncMsgSender, OnChannelClosed) { - // TODO(stoyan): implement. -} diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index dcffb1b..5d3893e 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -242,7 +242,6 @@ ], 'sources': [ '../base/test_suite.h', - 'cfproxy_test.cc', 'test/automation_client_mock.cc', 'test/automation_client_mock.h', 'test/chrome_frame_test_utils.cc', @@ -796,11 +795,6 @@ 'target_name': 'chrome_frame_common', 'type': 'static_library', 'sources': [ - 'cfproxy.h', - 'cfproxy_private.h', - 'cfproxy_factory.cc', - 'cfproxy_proxy.cc', - 'cfproxy_support.cc', 'chrome_frame_automation.h', 'chrome_frame_automation.cc', 'chrome_frame_delegate.h', @@ -809,14 +803,10 @@ 'chrome_launcher_utils.cc', 'chrome_launcher_utils.h', 'custom_sync_call_context.h', - 'external_tab.h', - 'external_tab.cc', 'plugin_url_request.h', 'plugin_url_request.cc', 'sync_msg_reply_dispatcher.h', 'sync_msg_reply_dispatcher.cc', - 'task_marshaller.h', - 'task_marshaller.cc', ] }, { diff --git a/chrome_frame/external_tab.cc b/chrome_frame/external_tab.cc deleted file mode 100644 index ecf7927..0000000 --- a/chrome_frame/external_tab.cc +++ /dev/null @@ -1,131 +0,0 @@ -// 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. - -#include "chrome_frame/external_tab.h" -#include "base/tracked.h" -#include "base/task.h" -#include "base/waitable_event.h" -#include "chrome/test/automation/automation_messages.h" -#include "chrome_frame/utils.h" - -DISABLE_RUNNABLE_METHOD_REFCOUNT(ExternalTabProxy); -DISABLE_RUNNABLE_METHOD_REFCOUNT(UIDelegate); - -ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), proxy_(NULL), - ui_delegate_(NULL) { -} - -ExternalTabProxy::~ExternalTabProxy() { - Destroy(); -} - -void ExternalTabProxy::Destroy() { - DCHECK(NULL == done_.get()); - done_.reset(new base::WaitableEvent(true, false)); - proxy_factory_->ReleaseProxy(this, tab_params_.profile); - done_->Wait(); - done_.reset(NULL); - - proxy_ = NULL; - tab_ = 0; -} - -void ExternalTabProxy::CreateTab(const CreateTabParams& create_params, - UIDelegate* delegate) { - DCHECK(ui_delegate_ != NULL); - DCHECK_EQ(NONE, state_); - ui_delegate_ = delegate; - tab_params_ = create_params; - state_ = INIT_IN_PROGRESS; - // TODO(stoyan): initialize ProxyParams from CreateTabParams. - ProxyParams p; - proxy_factory_->GetProxy(this, p); -} - -void ExternalTabProxy::Connected(ChromeProxy* proxy) { - // in ipc thread - ui_.PostTask(FROM_HERE, NewRunnableMethod(this, - &ExternalTabProxy::UiConnected, proxy)); -} -void ExternalTabProxy::Disconnected() { - // in ipc thread - DCHECK(done_.get() != NULL); - done_->Signal(); -} - -void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) { - ui_.PostTask(FROM_HERE, NewRunnableMethod(this, &ExternalTabProxy::UiPeerLost, - proxy, reason)); -} - -void ExternalTabProxy::Navigate(const std::string& url, - const std::string& referrer, bool is_privileged) { - // in ui thread - // Catch invalid URLs early. Can we allow this navigation to happen? - GURL parsed_url(url); - if (!CanNavigate(parsed_url, security_manager_, is_privileged)) { - DLOG(ERROR) << __FUNCTION__ << " Not allowing navigation to: " << url; - return; - } - - if (state_ == INIT_IN_PROGRESS) { - // TODO(stoyan): replace CreateTabParams with the new ones - } - - if (state_ == CREATE_TAB_IN_PROGRESS) { - // ah! too late. wait to get tab handle and then navigate - pending_navigation_.Set(parsed_url, GURL(referrer)); - } - - if (state_ == READY) { - proxy_->Tab_Navigate(tab_, parsed_url, GURL(referrer)); - } -} - -void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd, - HWND tab_window, int tab_handle) { - // in ipc_thread. -} - -void ExternalTabProxy::Completed_ConnectToTab(bool success, - HWND chrome_window, HWND tab_window, int tab_handle) { - CHECK(0); -} - -void ExternalTabProxy::Completed_Navigate(bool success, - enum AutomationMsg_NavigationResponseValues res) { - // ipc_thread; - CHECK(0); -} - -void ExternalTabProxy::Completed_InstallExtension(bool success, - enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) { - CHECK(0); -} - -void ExternalTabProxy::Completed_LoadExpandedExtension(bool success, - enum AutomationMsg_ExtensionResponseValues res, SyncMessageContext* ctx) { - CHECK(0); -} - -void ExternalTabProxy::Completed_GetEnabledExtensions(bool success, - const std::vector<FilePath>* extensions) { - CHECK(0); -} - -void ExternalTabProxy::NavigationStateChanged(int flags, - const IPC::NavigationInfo& nav_info) { - ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_, - &UIDelegate::OnNavigationStateChanged, flags, nav_info)); -} - -void ExternalTabProxy::UpdateTargetUrl(const std::wstring& url) { - ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_, - &UIDelegate::OnUpdateTargetUrl, url)); -} - -void ExternalTabProxy::TabLoaded(const GURL& url) { - ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_, - &UIDelegate::OnLoad, url)); -} diff --git a/chrome_frame/external_tab.h b/chrome_frame/external_tab.h deleted file mode 100644 index eba2965..0000000 --- a/chrome_frame/external_tab.h +++ /dev/null @@ -1,213 +0,0 @@ -// 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_ diff --git a/chrome_frame/task_marshaller.cc b/chrome_frame/task_marshaller.cc deleted file mode 100644 index 4e89d06e..0000000 --- a/chrome_frame/task_marshaller.cc +++ /dev/null @@ -1,133 +0,0 @@ -// 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. -#include "chrome_frame/task_marshaller.h" -#include "base/task.h" - -TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue() { - wnd_ = NULL; - msg_ = 0xFFFF; -} - -TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() { - DeleteAll(); -} - -void TaskMarshallerThroughMessageQueue::PostTask( - const tracked_objects::Location& from_here, Task* task) { - task->SetBirthPlace(from_here); - lock_.Acquire(); - bool has_work = !pending_tasks_.empty(); - pending_tasks_.push(task); - lock_.Release(); - - // Don't post message if there is already one. - if (has_work) - return; - - if (!::PostMessage(wnd_, msg_, 0, 0)) { - DLOG(INFO) << "Dropping MSG_EXECUTE_TASK message for destroyed window."; - DeleteAll(); - } -} - -void TaskMarshallerThroughMessageQueue::PostDelayedTask( - const tracked_objects::Location& source, - Task* task, - base::TimeDelta& delay) { - AutoLock lock(lock_); - DelayedTask delayed_task(task, base::Time::Now() + delay); - delayed_tasks_.push(delayed_task); - // If we become the 'top' task - reschedule the timer. - if (delayed_tasks_.top().task == task) { - ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this), - static_cast<DWORD>(delay.InMilliseconds()), NULL); - } -} - -Task* TaskMarshallerThroughMessageQueue::PopTask() { - AutoLock lock(lock_); - Task* task = NULL; - if (!pending_tasks_.empty()) { - task = pending_tasks_.front(); - pending_tasks_.pop(); - } - return task; -} - -void TaskMarshallerThroughMessageQueue::ExecuteQueuedTasks() { - DCHECK(CalledOnValidThread()); - Task* task; - while ((task = PopTask()) != NULL) { - RunTask(task); - } -} - -void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() { - DCHECK(CalledOnValidThread()); - ::KillTimer(wnd_, reinterpret_cast<UINT_PTR>(this)); - while (1) { - lock_.Acquire(); - - if (delayed_tasks_.empty()) { - lock_.Release(); - return; - } - - base::Time now = base::Time::Now(); - DelayedTask next_task = delayed_tasks_.top(); - base::Time next_run = next_task.run_at; - if (next_run > now) { - int64 delay = (next_run - now).InMillisecondsRoundedUp(); - ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this), - static_cast<DWORD>(delay), NULL); - lock_.Release(); - return; - } - - delayed_tasks_.pop(); - lock_.Release(); - - // Run the task outside the lock. - RunTask(next_task.task); - } -} - -void TaskMarshallerThroughMessageQueue::DeleteAll() { - AutoLock lock(lock_); - DLOG_IF(INFO, !pending_tasks_.empty()) << - "Destroying " << pending_tasks_.size() << " pending tasks."; - while (!pending_tasks_.empty()) { - Task* task = pending_tasks_.front(); - pending_tasks_.pop(); - delete task; - } - - while (!delayed_tasks_.empty()) { - delete delayed_tasks_.top().task; - delayed_tasks_.pop(); - } -} - -void TaskMarshallerThroughMessageQueue::RunTask(Task* task) { - ++invoke_task_; - task->Run(); - --invoke_task_; - delete task; -} - -bool TaskMarshallerThroughMessageQueue::DelayedTask::operator<( - const DelayedTask& other) const { - // Since the top of a priority queue is defined as the "greatest" element, we - // need to invert the comparison here. We want the smaller time to be at the - // top of the heap. - if (run_at < other.run_at) - return false; - - if (run_at > other.run_at) - return true; - - // If the times happen to match, then we use the sequence number to decide. - // Compare the difference to support integer roll-over. - return (seq - other.seq) > 0; -} diff --git a/chrome_frame/task_marshaller.h b/chrome_frame/task_marshaller.h deleted file mode 100644 index b3f87b8..0000000 --- a/chrome_frame/task_marshaller.h +++ /dev/null @@ -1,63 +0,0 @@ -// 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_TASK_MARSHALLER_H_ -#define CHROME_FRAME_TASK_MARSHALLER_H_ -#pragma once - -#include <windows.h> -#include <deque> -#include <queue> -#include "base/lock.h" -#include "base/non_thread_safe.h" -#include "base/time.h" -class Task; -namespace tracked_objects { - class Location; -} - -// TaskMarshallerThroughMessageQueue is similar to base::MessageLoopForUI -// in cases where we do not control the thread lifetime and message retrieval -// and dispatching. It uses a HWND to ::PostMessage to it as a signal that -// the task queue is not empty. -class TaskMarshallerThroughMessageQueue : public NonThreadSafe { - public: - TaskMarshallerThroughMessageQueue(); - ~TaskMarshallerThroughMessageQueue(); - - void SetWindow(HWND wnd, UINT msg) { - wnd_ = wnd; - msg_ = msg; - } - - virtual void PostTask(const tracked_objects::Location& from_here, - Task* task); - virtual void PostDelayedTask(const tracked_objects::Location& source, - Task* task, - base::TimeDelta& delay); - private: - void DeleteAll(); - inline Task* PopTask(); - inline void ExecuteQueuedTasks(); - void ExecuteDelayedTasks(); - void RunTask(Task* task); - - struct DelayedTask { - DelayedTask(Task* task, base::Time at) : run_at(at), task(task), seq(0) {} - base::Time run_at; - Task* task; - int seq; - // To support sorting based on time in priority_queue. - bool operator<(const DelayedTask& other) const; - }; - - std::priority_queue<DelayedTask> delayed_tasks_; - std::queue<Task*> pending_tasks_; - Lock lock_; - HWND wnd_; - UINT msg_; - int invoke_task_; -}; - -#endif // CHROME_FRAME_TASK_MARSHALLER_H_ |