diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-25 15:10:30 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-25 15:10:30 +0000 |
commit | 4af3cc758ddb8f642d068d9c10d9563306bf5c50 (patch) | |
tree | 05576b7e2c987fa25e2db1b3eb67563361242bfb /chrome_frame | |
parent | 37bea5c6ed274854888578057d3578bd691ae6bc (diff) | |
download | chromium_src-4af3cc758ddb8f642d068d9c10d9563306bf5c50.zip chromium_src-4af3cc758ddb8f642d068d9c10d9563306bf5c50.tar.gz chromium_src-4af3cc758ddb8f642d068d9c10d9563306bf5c50.tar.bz2 |
Remove ChromeProxy and friends.
This code isn't used in production. Its associated tests flake from time to time, so I'm removing it all. If anyone wants to try completing the implementation and integration, revive it from the archive.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/9838102
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128818 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/cfproxy.h | 163 | ||||
-rw-r--r-- | chrome_frame/cfproxy_factory.cc | 79 | ||||
-rw-r--r-- | chrome_frame/cfproxy_private.h | 180 | ||||
-rw-r--r-- | chrome_frame/cfproxy_proxy.cc | 226 | ||||
-rw-r--r-- | chrome_frame/cfproxy_support.cc | 312 | ||||
-rw-r--r-- | chrome_frame/cfproxy_test.cc | 374 | ||||
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 9 | ||||
-rw-r--r-- | chrome_frame/external_tab.cc | 356 | ||||
-rw-r--r-- | chrome_frame/external_tab.h | 229 | ||||
-rw-r--r-- | chrome_frame/external_tab_test.cc | 186 |
10 files changed, 0 insertions, 2114 deletions
diff --git a/chrome_frame/cfproxy.h b/chrome_frame/cfproxy.h deleted file mode 100644 index 2d305e8..0000000 --- a/chrome_frame/cfproxy.h +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2011 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/synchronization/lock.h" -#include "base/time.h" // for base::TimeDelta -#include "base/file_path.h" -#include "chrome/common/automation_constants.h" -#include "content/public/common/page_zoom.h" -#include "ipc/ipc_channel.h" - -class ChromeProxyDelegate; -class ChromeProxyFactory; -class GURL; -struct ExternalTabSettings; -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() {} -}; - - -/* -[activex] UIDelegate (UI_THREAD) -[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 SetProxyConfig(const std::string& json_encoded_settings) = 0; - - // Tab management. - virtual void CreateTab(ChromeProxyDelegate* delegate, - const 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, content::PageZoom 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_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; - virtual ~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 IPC::Channel::Listener { - 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, int session_id) = 0; - virtual void Completed_ConnectToTab(bool success, HWND chrome_window, - HWND tab_window, int tab_handle, int session_id) = 0; - virtual void Completed_Navigate(bool success, - enum AutomationMsg_NavigationResponseValues res) = 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_; - base::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 35694af..0000000 --- a/chrome_frame/cfproxy_factory.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2011 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) { - return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL); -} - -////////////////////////////////////////////////////////// -// ChromeProxyFactory - -ChromeProxyFactory::ChromeProxyFactory() { -} - -ChromeProxyFactory::~ChromeProxyFactory() { - base::AutoLock lock(lock_); - ProxyMap::iterator it = proxies_.begin(); - for (; it != proxies_.end(); ++it) { - ChromeProxy* proxy = it->second; - delete proxy; - } - proxies_.clear(); -} - -void ChromeProxyFactory::GetProxy(ChromeProxyDelegate* delegate, - const ProxyParams& params) { - base::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) { - base::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 12b4b26..0000000 --- a/chrome_frame/cfproxy_private.h +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2011 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/threading/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_; - base::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, content::PageZoom 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); - 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 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 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 implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - virtual void OnChannelError() OVERRIDE; - - bool CalledOnIpcThread() const { - return base::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_; -}; - -// Support functions. -std::string GenerateChannelId(); -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 c3da4a6..0000000 --- a/chrome_frame/cfproxy_proxy.cc +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2011 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/bind.h" -#include "base/bind_helpers.h" -#include "base/tuple.h" -#include "ipc/ipc_sync_message.h" -#include "chrome/common/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, - base::Bind(&CFProxy::CleanupOnIoThread, base::Unretained(this))); - // 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, - base::Bind(&CFProxy::InitInIoThread, base::Unretained(this), params)); -} - -int CFProxy::AddDelegate(ChromeProxyDelegate* delegate) { - ipc_thread_.message_loop()->PostTask( - FROM_HERE, base::Bind(&CFProxy::AddDelegateOnIoThread, - base::Unretained(this), delegate)); - return ++delegate_count_; -} - -int CFProxy::RemoveDelegate(ChromeProxyDelegate* delegate) { - ipc_thread_.message_loop()->PostTask( - FROM_HERE, base::Bind(&CFProxy::RemoveDelegateOnIoThread, - base::Unretained(this), delegate)); - return --delegate_count_; -} - -void CFProxy::AddDelegateOnIoThread(ChromeProxyDelegate* delegate) { - DCHECK(CalledOnIpcThread()); - DelegateHolder::AddDelegate(delegate); - if (is_connected_) { - delegate->Connected(this); - } -} - -void CFProxy::RemoveDelegateOnIoThread(ChromeProxyDelegate* delegate) { - DCHECK(CalledOnIpcThread()); - // Cancel any calls in progress. - sync_dispatcher_.Cancel(delegate); - DelegateHolder::RemoveDelegate(delegate); - delegate->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 (!cmd_line.empty() && api_->LaunchApp(cmd_line)) { - ipc_thread_.message_loop()->PostDelayedTask( - FROM_HERE, base::Bind(&CFProxy::LaunchTimeOut, base::Unretained(this)), - 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, base::Bind(&CFProxy::SendIpcMessageOnIoThread, - base::Unretained(this), m)); -} - -void CFProxy::SendIpcMessageOnIoThread(IPC::Message* m) { - DCHECK(CalledOnIpcThread()); - if (ipc_sender_) { - ipc_sender_->Send(m); - } else { - delete m; - } -} - -////////////////////////////////////////////////////////////////////////// -// Sync messages. -void CFProxy::Tab_Find(int tab, const string16& search_string, - FindInPageDirection forward, FindInPageCase match_case, - bool find_next) { - AutomationMsg_Find_Params params; - 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(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(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( - 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 ExternalTabSettings& p) { - IPC::SyncMessage* m = new AutomationMsg_CreateExternalTab(p, 0, 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(cookie, true, - hwnd, NULL, NULL, NULL, 0); - sync_dispatcher_.QueueSyncMessage(m, delegate, NULL); - SendIpcMessage(m); -} - -void CFProxy::BlockTab(uint64 cookie) { - IPC::SyncMessage* m = new AutomationMsg_ConnectExternalTab(cookie, false, - NULL, NULL, NULL, NULL, 0); - sync_dispatcher_.QueueSyncMessage(m, NULL, NULL); - SendIpcMessage(m); -} - -void CFProxy::Tab_RunUnloadHandlers(int tab) { - IPC::SyncMessage* m = new AutomationMsg_RunUnloadHandlers(tab, 0); - ChromeProxyDelegate* p = Tab2Delegate(tab); - sync_dispatcher_.QueueSyncMessage(m, p, NULL); - SendIpcMessage(m); -} - -// IPC::Channel::Listener -bool CFProxy::OnMessageReceived(const IPC::Message& message) { - // Handle sync message reply. - bool done = sync_dispatcher_.OnReplyReceived(&message); - if (done) - return true; - - // Handle tab related message. - ChromeProxyDelegate* d = Tab2Delegate(message.routing_id()); - if (d) - return d->OnMessageReceived(message); - - DLOG(WARNING) << "Unknown message received!"; - return false; -} - -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 695fd3b..0000000 --- a/chrome_frame/cfproxy_support.cc +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (c) 2012 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 <vector> -#include "base/atomic_sequence_num.h" -#include "base/command_line.h" -#include "base/memory/scoped_ptr.h" -#include "base/process_util.h" -#include "chrome/common/automation_messages.h" -#include "chrome/common/chrome_switches.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, 0, 0); - break; - case AutomationMsg_ConnectExternalTab::ID: - delegate->Completed_ConnectToTab(false, NULL, NULL, 0, 0); - break; - } -} - -bool DispatchReplyOk(const IPC::Message* reply_msg, uint32 type, - ChromeProxyDelegate* delegate, SyncMessageContext* ctx, - TabsMap* tab2delegate) { - PickleIterator iter = IPC::SyncMessage::GetDataIterator(reply_msg); - switch (type) { - case AutomationMsg_CreateExternalTab::ID: { - // Tuple4<HWND, HWND, int, 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, out.d); - } - return true; - } - - case AutomationMsg_ConnectExternalTab::ID: { - // Tuple4<HWND, HWND, int, 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, out.d); - } - return true; - } - } // switch - - return false; -} -} // namespace - -// Itf2IPCMessage -// Converts and sends trivial messages. -void Interface2IPCMessage::RemoveBrowsingData(int mask) { - sender_->Send(new AutomationMsg_RemoveBrowsingData(mask)); -} - -void Interface2IPCMessage::SetProxyConfig( - const std::string& json_encoded_proxy_cfg) { - sender_->Send(new AutomationMsg_SetProxyConfig(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( - tab, message, origin, target)); -} - -void Interface2IPCMessage::Tab_Reload(int tab) { - sender_->Send(new AutomationMsg_ReloadAsync(tab)); -} - -void Interface2IPCMessage::Tab_Stop(int tab) { - sender_->Send(new AutomationMsg_StopAsync(tab)); -} - -void Interface2IPCMessage::Tab_SaveAs(int tab) { - sender_->Send(new AutomationMsg_SaveAsAsync(tab)); -} - -void Interface2IPCMessage::Tab_Print(int tab) { - sender_->Send(new AutomationMsg_PrintAsync(tab)); -} - -void Interface2IPCMessage::Tab_Cut(int tab) { - sender_->Send(new AutomationMsg_Cut(tab)); -} - -void Interface2IPCMessage::Tab_Copy(int tab) { - sender_->Send(new AutomationMsg_Copy(tab)); -} - -void Interface2IPCMessage::Tab_Paste(int tab) { - sender_->Send(new AutomationMsg_Paste(tab)); -} - -void Interface2IPCMessage::Tab_SelectAll(int tab) { - sender_->Send(new AutomationMsg_SelectAll(tab)); -} - -void Interface2IPCMessage::Tab_MenuCommand(int tab, int selected_command) { - sender_->Send(new AutomationMsg_ForwardContextMenuCommandToChrome( - tab, selected_command)); -} - -void Interface2IPCMessage::Tab_Zoom(int tab, content::PageZoom zoom_level) { - sender_->Send(new AutomationMsg_SetZoomLevel(tab, zoom_level)); -} - -void Interface2IPCMessage::Tab_FontSize(int tab, - enum AutomationPageFontSize font_size) { - sender_->Send(new AutomationMsg_SetPageFontSize(tab, font_size)); -} - -void Interface2IPCMessage::Tab_SetInitialFocus(int tab, bool reverse, - bool restore_focus_to_view) { - sender_->Send(new AutomationMsg_SetInitialFocus(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(tab, msg)); -} - -// Misc. -void Interface2IPCMessage::Tab_OnHostMoved(int tab) { - sender_->Send(new AutomationMsg_BrowserMove(tab)); -} - -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. - base::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); - } -} - -// Cancel all outgoing calls for this delegate. -void SyncMsgSender::Cancel(ChromeProxyDelegate* delegate) { - std::vector<SingleSentMessage*> cancelled; - { - base::AutoLock lock(messages_lock_); - SentMessages::iterator it = messages_.begin(); - for (; it != messages_.end(); ) { - SingleSentMessage* origin = it->second; - if (origin->delegate_ == delegate) { - cancelled.push_back(origin); - it = messages_.erase(it); - } else { - ++it; - } - } - } - - for (std::vector<SingleSentMessage*>::iterator it = cancelled.begin(); - it != cancelled.end(); ++it) { - SingleSentMessage* origin = *it; - DispatchReplyFail(origin->type_, delegate, origin->ctx_); - delete origin; - } -} - -SyncMsgSender::SingleSentMessage* SyncMsgSender::RemoveMessage(int id) { - base::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 - { - base::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::StaticAtomicSequenceNumber g_proxy_channel_id; -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) { - std::wstring command_line_string; - scoped_ptr<CommandLine> command_line; - if (chrome_launcher::CreateLaunchCommandLine(&command_line)) { - 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); - - command_line_string = command_line->GetCommandLineString(); - if (!extra_args.empty()) { - command_line_string.append(L" "); - command_line_string.append(extra_args); - } - } - - return command_line_string; -} diff --git a/chrome_frame/cfproxy_test.cc b/chrome_frame/cfproxy_test.cc deleted file mode 100644 index 338244a..0000000 --- a/chrome_frame/cfproxy_test.cc +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright (c) 2012 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/bind.h" -#include "base/bind_helpers.h" -#include "base/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/synchronization/waitable_event.h" -#include "chrome/common/automation_messages.h" -#include "chrome_frame/cfproxy_private.h" -#include "chrome_frame/test/chrome_frame_test_utils.h" -#include "chrome_frame/test/test_scrubber.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; -using testing::StrEq; -using testing::Eq; - -// 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(OnMessageReceived, bool(const IPC::Message& message)); - MOCK_METHOD1(Connected, void(ChromeProxy* proxy)); - MOCK_METHOD2(PeerLost, void(ChromeProxy*, enum DisconnectReason reason)); - MOCK_METHOD0(Disconnected, void()); - MOCK_METHOD0(tab_handle, int()); - - MOCK_METHOD5(Completed_CreateTab, void(bool success, HWND chrome_wnd, - HWND tab_window, int tab_handle, int session_id)); - MOCK_METHOD5(Completed_ConnectToTab, void(bool success, HWND chrome_window, - HWND tab_window, int tab_handle, int session_id)); - MOCK_METHOD2(Completed_Navigate, void(bool success, - enum AutomationMsg_NavigationResponseValues res)); - - // Network requests from Chrome. - MOCK_METHOD2(Network_Start, void(int request_id, - const AutomationURLRequest& request_info)); - MOCK_METHOD2(Network_Read, void(int request_id, int bytes_to_read)); - MOCK_METHOD2(Network_End, void(int request_id, - const net::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 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 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_METHOD3(HandleContextMenu, void(HANDLE menu_handle, int align_flags, - const MiniContextMenuParams& params)); - MOCK_METHOD1(TabbedOut, void(bool reverse)); - - // - MOCK_METHOD0(TabClosed, void()); - MOCK_METHOD1(AttachTab, void(const 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, base::Bind(&IPC::Channel::Listener::OnChannelConnected, - base::Unretained(listener), 0), - t.InMilliseconds()); - } - - void FireError(base::TimeDelta t) { - ASSERT_TRUE(ipc_loop != NULL); - ipc_loop->PostDelayedTask( - FROM_HERE, base::Bind(&IPC::Channel::Listener::OnChannelError, - base::Unretained(listener)), - t.InMilliseconds()); - } - - void FireMessage(const IPC::Message& m, base::TimeDelta t) { - ASSERT_TRUE(ipc_loop != NULL); - ipc_loop->PostDelayedTask( - FROM_HERE, - base::Bind( - base::IgnoreResult(&IPC::Channel::Listener::OnMessageReceived), - base::Unretained(listener), m), - t.InMilliseconds()); - } - - MockCFProxyTraits() : ipc_loop(NULL) {} - MockSender sender; - private: - MessageLoop* ipc_loop; - IPC::Channel::Listener* listener; -}; - -// Handy macros when we want so simulate 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)) - -class ChromeProxyTest : public ::testing::Test { - protected: - virtual void SetUp() OVERRIDE { - chrome_frame_test::OverrideDataDirectoryForThisTest( - chrome_frame_test::GetProfilePath(L"").value()); - params_.profile = "Adam N. Epilinter"; - params_.timeout = base::TimeDelta::FromSeconds(4); - } - - ProxyParams params_; -}; - -TEST_F(ChromeProxyTest, 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()); - - factory.GetProxy(&delegate, params_); - factory.ReleaseProxy(&delegate, params_.profile); -} - -// Not very useful test. Just for illustration. :) -TEST_F(ChromeProxyTest, 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)); - - 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_F(ChromeProxyTest, LaunchTimeout) { - base::WaitableEvent done(true, false); - StrictMock<MockCFProxyTraits> api; - StrictMock<MockChromeProxyDelegate> delegate; - StrictMock<MockFactory> factory; - 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)); - 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_F(ChromeProxyTest, LaunchChrome) { - base::WaitableEvent connected(false, false); - StrictMock<MockChromeProxyDelegate> delegate; - ChromeProxyFactory factory; - - 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); -} - -// Test that a channel error results in Completed_XYZ(false, ) called if -// the synchronious XYZ message has been sent. -TEST_F(ChromeProxyTest, ChannelError) { - base::WaitableEvent connected(false, false); - StrictMock<MockCFProxyTraits> api; - StrictMock<MockChromeProxyDelegate> delegate; - StrictMock<MockFactory> factory; - CFProxy* proxy = new CFProxy(&api); - - params_.timeout = base::TimeDelta::FromMilliseconds(300); - - testing::InSequence s; - - 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(10)), - Return(true))); - EXPECT_CALL(delegate, Connected(proxy)) - .WillOnce(DoAll( - InvokeWithoutArgs(CreateFunctor(proxy, &ChromeProxy::ConnectTab, - &delegate, HWND(6), 512)), - InvokeWithoutArgs(&connected, &base::WaitableEvent::Signal))); - - EXPECT_CALL(api.sender, Send(_)); - EXPECT_CALL(delegate, Completed_ConnectToTab(false, _, _, _, _)); - EXPECT_CALL(api, CloseChannel(&api.sender)); - EXPECT_CALL(delegate, PeerLost(_, ChromeProxyDelegate::CHANNEL_ERROR)); - - factory.GetProxy(&delegate, params_); - EXPECT_TRUE(connected.TimedWait(base::TimeDelta::FromSeconds(15))); - // Simulate a channel error. - api.FireError(base::TimeDelta::FromMilliseconds(0)); - - // Expectations when the Proxy is destroyed. - EXPECT_CALL(delegate, tab_handle()).WillOnce(Return(0)); - 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; -} - -template <typename M, typename A, typename B, typename C, typename D> -inline IPC::Message* CreateReply(M* m, const A& a, const B& b, const C& c, - const D& d) { - IPC::Message* r = IPC::SyncMessage::GenerateReply(m); - if (r) { - M::WriteReplyParams(r, a, b, c, d); - } - return r; -}} // namespace - -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); - - const int kTabHandle = 6; - const int kSessionId = 8; - - // Create a sync message and its reply. - AutomationMsg_CreateExternalTab m(ExternalTabSettings(), 0, 0, 0, 0); - scoped_ptr<IPC::Message> r(CreateReply(&m, (HWND)1, (HWND)2, kTabHandle, - kSessionId)); - - queue.QueueSyncMessage(&m, &d1, NULL); - - testing::InSequence s; - EXPECT_CALL(d1, Completed_CreateTab(true, (HWND)1, (HWND)2, kTabHandle, - kSessionId)); - - // Execute replies in a worker thread. - ipc.message_loop()->PostTask( - FROM_HERE, - base::Bind(base::IgnoreResult(&SyncMsgSender::OnReplyReceived), - base::Unretained(&queue), r.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 c45eb9f..dc06bec 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -212,8 +212,6 @@ ], 'sources': [ '../base/test/test_suite.h', - 'cfproxy_test.cc', - 'external_tab_test.cc', 'test/automation_client_mock.cc', 'test/automation_client_mock.h', 'test/chrome_frame_test_utils.cc', @@ -810,11 +808,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', @@ -825,8 +818,6 @@ 'chrome_launcher_utils.h', 'custom_sync_call_context.cc', 'custom_sync_call_context.h', - 'external_tab.h', - 'external_tab.cc', 'navigation_constraints.h', 'navigation_constraints.cc', 'plugin_url_request.h', diff --git a/chrome_frame/external_tab.cc b/chrome_frame/external_tab.cc deleted file mode 100644 index 89b3a06..0000000 --- a/chrome_frame/external_tab.cc +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2011 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 "base/bind.h" -#include "base/bind_helpers.h" -#include "base/lazy_instance.h" -#include "base/location.h" -#include "chrome_frame/external_tab.h" -#include "base/synchronization/waitable_event.h" -#include "chrome/common/automation_messages.h" -#include "chrome_frame/chrome_frame_delegate.h" -#include "chrome_frame/utils.h" - -namespace { - static base::LazyInstance<ChromeProxyFactory> g_proxy_factory = - LAZY_INSTANCE_INITIALIZER; - - struct UserDataHolder : public SyncMessageContext { - explicit UserDataHolder(void* p) : data(p) {} - void* data; - }; -} - - -ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), tab_wnd_(NULL), - chrome_wnd_(NULL), proxy_factory_(g_proxy_factory.Pointer()), proxy_(NULL), - ui_delegate_(NULL) { -} - -ExternalTabProxy::~ExternalTabProxy() { - Destroy(); -} - -bool ExternalTabProxy::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ExternalTabProxy, message) - IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged, - OnNavigationStateChanged) - IPC_MESSAGE_HANDLER(AutomationMsg_UpdateTargetUrl, OnUpdateTargetUrl) - IPC_MESSAGE_HANDLER(AutomationMsg_HandleAccelerator, OnHandleAccelerator) - IPC_MESSAGE_HANDLER(AutomationMsg_TabbedOut, OnTabbedOut) - IPC_MESSAGE_HANDLER(AutomationMsg_OpenURL, OnOpenURL) - IPC_MESSAGE_HANDLER(AutomationMsg_NavigationFailed, OnNavigationFailed) - IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate) - IPC_MESSAGE_HANDLER(AutomationMsg_TabLoaded, OnTabLoaded) - IPC_MESSAGE_HANDLER(AutomationMsg_MoveWindow, OnMoveWindow) - IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost, - OnMessageToHost) - IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuToExternalHost, - OnHandleContextMenu) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestStart, OnNetwork_Start) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestRead, OnNetwork_Read) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnNetwork_End) - IPC_MESSAGE_HANDLER(AutomationMsg_DownloadRequestInHost, - OnNetwork_DownloadInHost) - IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost, OnGetCookies) - IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieAsync, OnSetCookie) - IPC_MESSAGE_HANDLER(AutomationMsg_AttachExternalTab, OnAttachTab) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestGoToHistoryEntryOffset, - OnGoToHistoryOffset) - IPC_MESSAGE_HANDLER(AutomationMsg_CloseExternalTab, OnTabClosed) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void ExternalTabProxy::Init() { - if (m_hWnd == NULL) { - // Create a window on the UI thread for marshaling messages back and forth - // from the IPC thread. This window cannot be a message only window as the - // external chrome tab window initially is created as a child of this window - CWindowImpl<ExternalTabProxy>::Create(GetDesktopWindow(), NULL, NULL, - WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOLWINDOW); - DCHECK(m_hWnd != NULL); - ui_.SetWindow(m_hWnd, WM_APP + 6); - } -} - -void ExternalTabProxy::Destroy() { - DCHECK(NULL == done_.get()); - // TODO(stoyan): Should we release proxy first and then destroy the window - // (parent of the chrome window) or the other way around? - if (state_ != NONE) { - done_.reset(new base::WaitableEvent(true, false)); - proxy_factory_->ReleaseProxy(this, tab_params_.proxy_params.profile); - done_->Wait(); - done_.reset(NULL); - - state_ = NONE; - proxy_ = NULL; - tab_ = 0; - CWindowImpl<ExternalTabProxy>::DestroyWindow(); - tab_wnd_ = NULL; - chrome_wnd_ = NULL; - // We shall tell the TaskMarshaller to delete queued tasks. - // ui_.DeleteAll(); - } -} - -void ExternalTabProxy::CreateTab(const CreateTabParams& create_params, - UIDelegate* delegate) { - DCHECK(ui_delegate_ == NULL); - DCHECK_EQ(NONE, state_); - // Create host window if needed. - Init(); - ui_delegate_ = delegate; - // TODO(stoyan): Shall we check the CanNavigate(create_params.url)? - tab_params_ = create_params; - state_ = INIT_IN_PROGRESS; - proxy_factory_->GetProxy(this, create_params.proxy_params); -} - -void ExternalTabProxy::Connected(ChromeProxy* proxy) { - // in ipc thread - ui_.PostTask(FROM_HERE, base::Bind(&ExternalTabProxy::UiConnected, - base::Unretained(this), proxy)); -} - -void ExternalTabProxy::UiConnected(ChromeProxy* proxy) { - proxy_ = proxy; - ExternalTabSettings settings; - settings.parent = m_hWnd; - settings.style = WS_CHILD; - settings.is_incognito = tab_params_.is_incognito; - // TODO(stoyan): FIX this. - settings.load_requests_via_automation = true; - // TODO(stoyan): FIX this. - settings.handle_top_level_requests = true; - settings.initial_url = tab_params_.url; - settings.referrer = tab_params_.referrer; - // Infobars are disabled in widget mode. - settings.infobars_enabled = !tab_params_.is_widget_mode; - // TODO(stoyan): FIX this. - settings.route_all_top_level_navigations = false; - - state_ = CREATE_TAB_IN_PROGRESS; - proxy->CreateTab(this, settings); -} - -void ExternalTabProxy::Disconnected() { - // in ipc thread - DCHECK(done_.get() != NULL); - done_->Signal(); -} - -void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) { - ui_.PostTask(FROM_HERE, base::Bind(&ExternalTabProxy::UiPeerLost, - base::Unretained(this), proxy, reason)); -} - -void ExternalTabProxy::UiPeerLost(ChromeProxy* proxy, DisconnectReason reason) { - // TODO(stoyan): -} - -void ExternalTabProxy::Navigate(const std::string& url, - const std::string& referrer, - NavigationConstraints* navigation_constraints) { - // in ui thread - // Catch invalid URLs early. Can we allow this navigation to happen? - GURL parsed_url(url); - if (!CanNavigate(parsed_url, navigation_constraints)) { - DLOG(ERROR) << __FUNCTION__ << " Not allowing navigation to: " << url; - return; - } - - GURL parsed_referrer(referrer); - // If we are still establishing channel, simply replace the params - if (state_ == INIT_IN_PROGRESS) { - tab_params_.url = parsed_url; - tab_params_.referrer = parsed_referrer; - } - - // Ah! Too late. Wait to get tab handle and then navigate. - if (state_ == CREATE_TAB_IN_PROGRESS) { - pending_navigation_.Set(parsed_url, parsed_referrer); - } - - if (state_ == READY) { - proxy_->Tab_Navigate(tab_, parsed_url, parsed_referrer); - } -} - -void ExternalTabProxy::ConnectToExternalTab(uint64 external_tab_cookie) { - proxy_->ConnectTab(this, m_hWnd, external_tab_cookie); -} - -void ExternalTabProxy::BlockExternalTab(uint64 cookie) { - proxy_->BlockTab(cookie); -} - -void ExternalTabProxy::SetZoomLevel(content::PageZoom zoom_level) { - proxy_->Tab_Zoom(tab_, zoom_level); -} - -void ExternalTabProxy::NavigateToIndex(int index) { - CHECK(0); -} - -void ExternalTabProxy::ForwardMessageFromExternalHost( - const std::string& message, const std::string& origin, - const std::string& target) { - proxy_->Tab_PostMessage(tab_, message, origin, target); -} - -void ExternalTabProxy::ChromeFrameHostMoved() { - proxy_->Tab_OnHostMoved(tab_); -} - -////////////////////////////////////////////////////////////////////////// -void ExternalTabProxy::UiCompleted_CreateTab(bool success, HWND chrome_window, - HWND tab_window, int tab_handle, - int session_id) { - if (success) { - state_ = READY; - tab_ = tab_handle; - tab_wnd_ = tab_window; - chrome_wnd_ = chrome_window; - - // If a navigation request came while tab creation was in progress - - // go ahead and navigate. - if (pending_navigation_.url.is_valid()) - proxy_->Tab_Navigate(tab_, pending_navigation_.url, - pending_navigation_.referrer); - } -} - -void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd, - HWND tab_window, int tab_handle, - int session_id) { - // in ipc_thread. - ui_.PostTask( - FROM_HERE, base::Bind(&ExternalTabProxy::UiCompleted_CreateTab, - base::Unretained(this), success, chrome_wnd, - tab_window, tab_handle, session_id)); -} - -void ExternalTabProxy::Completed_ConnectToTab( - bool success, HWND chrome_window, HWND tab_window, int tab_handle, - int session_id) { - CHECK(0); -} - -void ExternalTabProxy::Completed_Navigate( - bool success, enum AutomationMsg_NavigationResponseValues res) { - // ipc_thread; - CHECK(0); -} - -void ExternalTabProxy::OnNavigationStateChanged( - int flags, const NavigationInfo& nav_info) { - ui_.PostTask(FROM_HERE, - base::Bind(&UIDelegate::OnNavigationStateChanged, - base::Unretained(ui_delegate_), flags, nav_info)); -} - -void ExternalTabProxy::OnUpdateTargetUrl(const std::wstring& url) { - ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnUpdateTargetUrl, - base::Unretained(ui_delegate_), url)); -} - -void ExternalTabProxy::OnTabLoaded(const GURL& url) { - ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnLoad, - base::Unretained(ui_delegate_), url)); -} - -void ExternalTabProxy::OnMoveWindow(const gfx::Rect& pos) { - ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnMoveWindow, - base::Unretained(ui_delegate_), pos)); -} - -void ExternalTabProxy::OnMessageToHost(const std::string& message, - const std::string& origin, - const std::string& target) { - ui_.PostTask( - FROM_HERE, - base::Bind(&UIDelegate::OnMessageFromChromeFrame, - base::Unretained(ui_delegate_), message, origin, target)); -} - -void ExternalTabProxy::OnHandleAccelerator(const MSG& accel_message) { - ui_.PostTask(FROM_HERE, - base::Bind(&UIDelegate::OnHandleAccelerator, - base::Unretained(ui_delegate_), accel_message)); -} - -void ExternalTabProxy::OnHandleContextMenu( - const ContextMenuModel& context_menu_model, - int align_flags, - const MiniContextMenuParams& params) { - ui_.PostTask(FROM_HERE, - base::Bind(&UIDelegate::OnHandleContextMenu, - base::Unretained(ui_delegate_), context_menu_model, - align_flags, params)); -} - -void ExternalTabProxy::OnTabbedOut(bool reverse) { - ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnTabbedOut, - base::Unretained(ui_delegate_), reverse)); -} - -void ExternalTabProxy::OnGoToHistoryOffset(int offset) { - ui_.PostTask(FROM_HERE, base::Bind(&UIDelegate::OnGoToHistoryOffset, - base::Unretained(ui_delegate_), offset)); -} - -void ExternalTabProxy::OnOpenURL(const GURL& url_to_open, const GURL& referrer, - int open_disposition) { - ui_.PostTask( - FROM_HERE, - base::Bind(&UIDelegate::OnOpenURL, base::Unretained(ui_delegate_), - url_to_open, referrer, open_disposition)); -} - -void ExternalTabProxy::OnNavigationFailed(int error_code, const GURL& gurl) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnDidNavigate(const NavigationInfo& navigation_info) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnNetwork_Start( - int request_id, const AutomationURLRequest& request_info) { - // TODO(stoyan): url_fetcher_.Start(); -} - -void ExternalTabProxy::OnNetwork_Read(int request_id, int bytes_to_read) { - // TODO(stoyan): url_fetcher_.Read(); -} - -void ExternalTabProxy::OnNetwork_End(int request_id, - const net::URLRequestStatus& s) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnNetwork_DownloadInHost(int request_id) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnGetCookies(const GURL& url, int cookie_id) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnSetCookie(const GURL& url, const std::string& cookie) { - // TODO(stoyan): -} - -void ExternalTabProxy::OnTabClosed() { - // TODO(stoyan): -} - -void ExternalTabProxy::OnAttachTab( - const AttachExternalTabParams& attach_params) { - // TODO(stoyan): -} diff --git a/chrome_frame/external_tab.h b/chrome_frame/external_tab.h deleted file mode 100644 index 2932581..0000000 --- a/chrome_frame/external_tab.h +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2011 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 <string> -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "base/time.h" -#include "base/win/scoped_comptr.h" -#include "chrome/common/automation_constants.h" -#include "chrome_frame/cfproxy.h" -#include "chrome_frame/task_marshaller.h" -#include "content/public/common/page_zoom.h" -#include "googleurl/src/gurl.h" - -struct AttachExternalTabParams; -struct AutomationURLRequest; -struct ContextMenuModel; -struct MiniContextMenuParams; -struct NavigationInfo; -class Task; - -namespace base { -class WaitableEvent; -} - -namespace gfx { -class Rect; -} - -namespace net { -class URLRequestStatus; -} - -// 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 NavigationInfo& nav_info) = 0; - virtual void OnUpdateTargetUrl(const std::wstring& new_target_url) = 0; - virtual void OnLoad(const GURL& url) = 0; - virtual void OnMoveWindow(const gfx::Rect& pos) = 0; - - virtual void OnMessageFromChromeFrame( - const std::string& message, const std::string& origin, - const std::string& target) = 0; - virtual void OnHandleContextMenu( - const ContextMenuModel& context_menu_model, int align_flags, - const MiniContextMenuParams& params) = 0; - virtual void OnHandleAccelerator(const MSG& accel_message) = 0; - virtual void OnTabbedOut(bool reverse) = 0; - virtual void OnGoToHistoryOffset(int offset) = 0; - virtual void OnOpenURL( - const GURL& url_to_open, const GURL& referrer, int open_disposition) = 0; - protected: - ~UIDelegate() {} -}; - -struct CreateTabParams { - struct ProxyParams proxy_params; - bool is_incognito; - bool is_widget_mode; - GURL url; - GURL referrer; -}; - -class NavigationConstraints; - -///////////////////////////////////////////////////////////////////////// -// ExternalTabProxy is a mediator between ChromeProxy (which runs mostly in the -// background IPC-channel thread) and the UI object (ActiveX, 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 - - // IPC::Channel::Listener implementation. - bool OnMessageReceived(const IPC::Message& message); - - // - virtual void CreateTab(const CreateTabParams& create_params, - UIDelegate* delegate); - virtual void Navigate(const std::string& url, const std::string& referrer, - NavigationConstraints* navigation_constraints); - virtual void NavigateToIndex(int index); - virtual void ForwardMessageFromExternalHost(const std::string& message, - const std::string& origin, const std::string& target); - virtual void ChromeFrameHostMoved(); - - // Attaches an existing external tab to this automation client instance. - virtual void ConnectToExternalTab(uint64 external_tab_cookie); - virtual void BlockExternalTab(uint64 cookie); - - void SetZoomLevel(content::PageZoom zoom_level); - - private: - BEGIN_MSG_MAP(ExternalTabProxy) - CHAIN_MSG_MAP_MEMBER(ui_); - END_MSG_MAP() - - ////////////////////////////////////////////////////////////////////////// - // 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, int session_id); - virtual void Completed_ConnectToTab(bool success, HWND chrome_window, - HWND tab_window, int tab_handle, int session_id); - virtual void Completed_Navigate(bool success, - enum AutomationMsg_NavigationResponseValues res); - - // Network requests from Chrome. - virtual void OnNetwork_Start( - int request_id, const AutomationURLRequest& request_info); - virtual void OnNetwork_Read(int request_id, int bytes_to_read); - virtual void OnNetwork_End(int request_id, const net::URLRequestStatus& s); - virtual void OnNetwork_DownloadInHost(int request_id); - virtual void OnGetCookies(const GURL& url, int cookie_id); - virtual void OnSetCookie(const GURL& url, const std::string& cookie); - - // Navigation progress notifications. - virtual void OnNavigationStateChanged( - int flags, const NavigationInfo& nav_info); - virtual void OnUpdateTargetUrl(const std::wstring& url); - virtual void OnNavigationFailed(int error_code, const GURL& gurl); - virtual void OnDidNavigate(const NavigationInfo& navigation_info); - virtual void OnTabLoaded(const GURL& url); - virtual void OnMoveWindow(const gfx::Rect& pos); - - virtual void OnOpenURL(const GURL& url_to_open, const GURL& referrer, - int open_disposition); - virtual void OnGoToHistoryOffset(int offset); - virtual void OnMessageToHost( - const std::string& message, const std::string& origin, - const std::string& target); - - // Misc. UI. - virtual void OnHandleAccelerator(const MSG& accel_message); - virtual void OnHandleContextMenu(const ContextMenuModel& context_menu_model, - int align_flags, - const MiniContextMenuParams& params); - virtual void OnTabbedOut(bool reverse); - - // Other - virtual void OnTabClosed(); - virtual void OnAttachTab(const AttachExternalTabParams& attach_params); - - // end of ChromeProxyDelegate methods - ////////////////////////////////////////////////////////////////////////// - void Init(); - void Destroy(); - - // The UiXXXX are the ChromeProxyDelegate methods but on UI thread. - void UiConnected(ChromeProxy* proxy); - void UiPeerLost(ChromeProxy* proxy, DisconnectReason reason); - void UiCompleted_CreateTab(bool success, HWND chrome_window, - HWND tab_window, int tab_handle, int session_id); - - // 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_; - HWND tab_wnd_; - HWND chrome_wnd_; - ChromeProxyFactory* proxy_factory_; - // Accessed only in the UI thread for simplicity. - ChromeProxy* proxy_; - // Accessed from ipc thread as well. It's safe if the object goes away - // because this should be preceded by destruction of the window and - // therefore all queued tasks should be destroyed. - 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_; -}; - -#endif // CHROME_FRAME_EXTERNAL_TAB_H_ diff --git a/chrome_frame/external_tab_test.cc b/chrome_frame/external_tab_test.cc deleted file mode 100644 index 5017eb2..0000000 --- a/chrome_frame/external_tab_test.cc +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2011 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/synchronization/waitable_event.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/threading/thread.h" -#include "chrome/common/automation_messages.h" -#include "chrome_frame/navigation_constraints.h" -#include "chrome_frame/test/chrome_frame_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" - -using testing::StrictMock; -using testing::_; -using testing::Invoke; -using testing::InvokeWithoutArgs; -using testing::CreateFunctor; -using testing::Return; -using testing::DoAll; -using testing::Field; -using chrome_frame_test::TimedMsgLoop; - -struct MockUIDelegate : public UIDelegate { - MOCK_METHOD2(OnNavigationStateChanged, void(int flags, - const NavigationInfo& nav_info)); - MOCK_METHOD1(OnUpdateTargetUrl, void(const std::wstring& new_target_url)); - MOCK_METHOD1(OnLoad, void(const GURL& url)); - MOCK_METHOD1(OnMoveWindow, void(const gfx::Rect& pos)); - MOCK_METHOD3(OnMessageFromChromeFrame, void(const std::string& message, - const std::string& origin, const std::string& target)); - MOCK_METHOD3(OnHandleContextMenu, void(const ContextMenuModel& menu_model, - int align_flags, const MiniContextMenuParams& params)); - MOCK_METHOD1(OnHandleAccelerator, void(const MSG& accel_message)); - MOCK_METHOD1(OnTabbedOut, void(bool reverse)); - MOCK_METHOD1(OnGoToHistoryOffset, void(int offset)); - MOCK_METHOD3(OnOpenURL, void(const GURL& url_to_open, const GURL& referrer, - int open_disposition)); -}; - -struct MockProxy : public ChromeProxy { - MOCK_METHOD1(RemoveBrowsingData, void(int remove_mask)); - MOCK_METHOD1(SetProxyConfig, void(const std::string& json_encoded_settings)); - - MOCK_METHOD2(CreateTab, void(ChromeProxyDelegate* delegate, - const ExternalTabSettings& settings)); - MOCK_METHOD3(ConnectTab, void(ChromeProxyDelegate* delegate, HWND hwnd, - uint64 cookie)); - MOCK_METHOD1(BlockTab, void(uint64 cookie)); - - MOCK_METHOD4(Tab_PostMessage, void(int tab, const std::string& message, - const std::string& origin, const std::string& target)); - MOCK_METHOD1(Tab_Reload, void(int tab)); - MOCK_METHOD1(Tab_Stop, void(int tab)); - MOCK_METHOD1(Tab_SaveAs, void(int tab)); - MOCK_METHOD1(Tab_Print, void(int tab)); - MOCK_METHOD1(Tab_Cut, void(int tab)); - MOCK_METHOD1(Tab_Copy, void(int tab)); - MOCK_METHOD1(Tab_Paste, void(int tab)); - MOCK_METHOD1(Tab_SelectAll, void(int tab)); - MOCK_METHOD5(Tab_Find, void(int tab, const string16& search_string, - FindInPageDirection forward, FindInPageCase match_case, bool find_next)); - MOCK_METHOD2(Tab_MenuCommand, void(int tab, int selected_command)); - - MOCK_METHOD2(Tab_Zoom, void(int tab, content::PageZoom zoom_level)); - MOCK_METHOD2(Tab_FontSize, void(int tab, AutomationPageFontSize font_size)); - MOCK_METHOD3(Tab_SetInitialFocus, void(int tab, bool reverse, - bool restore_focus_to_view)); - MOCK_METHOD1(Tab_SetParentWindow, void(int tab)); - MOCK_METHOD1(Tab_Resize, void(int tab)); - MOCK_METHOD2(Tab_ProcessAccelerator, void(int tab, const MSG& msg)); - - // Misc. - MOCK_METHOD1(Tab_OnHostMoved, void(int tab)); - MOCK_METHOD1(Tab_RunUnloadHandlers, void(int tab)); - MOCK_METHOD3(Tab_Navigate, void(int tab, const GURL& url, - const GURL& referrer)); - MOCK_METHOD2(Tab_OverrideEncoding, void(int tab, const char* encoding)); - - MOCK_METHOD1(Init, void(const ProxyParams& params)); - MOCK_METHOD1(AddDelegate, int(ChromeProxyDelegate* delegate)); - MOCK_METHOD1(RemoveDelegate, int(ChromeProxyDelegate* delegate)); -}; - -struct MockFactory : public ChromeProxyFactory { - MOCK_METHOD0(CreateProxy, ChromeProxy*()); -}; - - -// This class just calls methods of ChromeProxyDelegate but in background thread -struct AsyncEventCreator { - public: - explicit AsyncEventCreator(ChromeProxyDelegate* delegate) - : delegate_(delegate), ipc_thread_("ipc") { - base::Thread::Options options(MessageLoop::TYPE_IO, 0); - ipc_thread_.StartWithOptions(options); - ipc_loop_ = ipc_thread_.message_loop(); - } - - void Fire_Connected(ChromeProxy* proxy, base::TimeDelta delay) { - ipc_loop_->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeProxyDelegate::Connected, base::Unretained(delegate_), - proxy), - delay.InMilliseconds()); - } - - void Fire_PeerLost(ChromeProxy* proxy, - ChromeProxyDelegate::DisconnectReason reason, base::TimeDelta delay) { - ipc_loop_->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeProxyDelegate::PeerLost, base::Unretained(delegate_), - proxy, reason), - delay.InMilliseconds()); - } - - void Fire_Disconnected(base::TimeDelta delay) { - ipc_loop_->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeProxyDelegate::Disconnected, - base::Unretained(delegate_)), - delay.InMilliseconds()); - } - - void Fire_CompletedCreateTab(bool success, HWND chrome_wnd, HWND tab_window, - int tab_handle, int session_id, - base::TimeDelta delay) { - ipc_loop_->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeProxyDelegate::Completed_CreateTab, - base::Unretained(delegate_), success, chrome_wnd, tab_window, - tab_handle, session_id), - delay.InMilliseconds()); - } - - private: - ChromeProxyDelegate* delegate_; - base::Thread ipc_thread_; - MessageLoop* ipc_loop_; -}; - -// We may want the same test with 'real' proxy and mock 'proxy traits'. -TEST(ExternalTabProxy, CancelledCreateTab) { - MockUIDelegate ui_delegate; - StrictMock<MockFactory> factory; - scoped_ptr<ExternalTabProxy> tab(new ExternalTabProxy()); - AsyncEventCreator async_events(tab.get()); - StrictMock<MockProxy>* proxy = new StrictMock<MockProxy>(); - TimedMsgLoop loop; - tab->set_proxy_factory(&factory); - - EXPECT_CALL(factory, CreateProxy()).WillOnce(Return(proxy)); - EXPECT_CALL(*proxy, Init(_)); - EXPECT_CALL(*proxy, AddDelegate(tab.get())).WillOnce(DoAll(InvokeWithoutArgs( - CreateFunctor(&async_events, &AsyncEventCreator::Fire_Connected, - proxy, base::TimeDelta::FromMilliseconds(30))), - Return(1))); - - EXPECT_CALL(*proxy, CreateTab(tab.get(), _)) - .WillOnce(QUIT_LOOP(loop)); - - EXPECT_CALL(*proxy, RemoveDelegate(_)).WillOnce(DoAll( - InvokeWithoutArgs(CreateFunctor(&async_events, - &AsyncEventCreator::Fire_CompletedCreateTab, false, HWND(0), HWND(0), - 0, 0, base::TimeDelta::FromMilliseconds(0))), - InvokeWithoutArgs(CreateFunctor(&async_events, - &AsyncEventCreator::Fire_Disconnected, - base::TimeDelta::FromMilliseconds(0))), - Return(0))); - - CreateTabParams tab_params; - tab_params.is_incognito = true; - tab_params.is_widget_mode = false; - tab_params.url = GURL("http://Xanadu.org"); - - tab->CreateTab(tab_params, &ui_delegate); - loop.RunFor(5); - EXPECT_FALSE(loop.WasTimedOut()); - tab.reset(); -} |