summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/automation/tab_proxy.cc14
-rw-r--r--chrome/test/automation/tab_proxy.h6
-rw-r--r--chrome_frame/chrome_frame_activex.cc18
-rw-r--r--chrome_frame/chrome_frame_activex.h4
-rw-r--r--chrome_frame/chrome_frame_activex_base.h28
-rw-r--r--chrome_frame/chrome_frame_automation.cc58
-rw-r--r--chrome_frame/chrome_frame_automation.h18
-rw-r--r--chrome_frame/chrome_frame_delegate.cc3
-rw-r--r--chrome_frame/chrome_frame_delegate.h10
-rw-r--r--chrome_frame/chrome_tab.idl8
-rw-r--r--chrome_frame/test/automation_client_mock.cc5
-rw-r--r--chrome_frame/test/automation_client_mock.h9
12 files changed, 137 insertions, 44 deletions
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index 0f28409..6f2f9a6 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -79,10 +79,10 @@ AutomationMsg_NavigationResponseValues
const GURL& url, int number_of_navigations) {
if (!is_valid())
return AUTOMATION_MSG_NAVIGATION_ERROR;
-
+
AutomationMsg_NavigationResponseValues navigate_response =
AUTOMATION_MSG_NAVIGATION_ERROR;
-
+
if (number_of_navigations == 1) {
// TODO(phajdan.jr): Remove when the reference build gets updated.
// This is only for backwards compatibility.
@@ -92,7 +92,7 @@ AutomationMsg_NavigationResponseValues
sender_->Send(new AutomationMsg_NavigateToURLBlockUntilNavigationsComplete(
0, handle_, url, number_of_navigations, &navigate_response));
}
-
+
return navigate_response;
}
@@ -469,7 +469,7 @@ bool TabProxy::ShowInterstitialPage(const std::string& html_text) {
0, handle_, html_text, &result))) {
return false;
}
-
+
return result == AUTOMATION_MSG_NAVIGATION_SUCCESS;
}
@@ -681,7 +681,6 @@ bool TabProxy::OverrideEncoding(const std::string& encoding) {
void TabProxy::Reposition(HWND window, HWND window_insert_after, int left,
int top, int width, int height, int flags,
HWND parent_window) {
-
IPC::Reposition_Params params = {0};
params.window = window;
params.window_insert_after = window_insert_after;
@@ -749,3 +748,8 @@ void TabProxy::OnMessageReceived(const IPC::Message& message) {
FOR_EACH_OBSERVER(TabProxyDelegate, observers_list_,
OnMessageReceived(this, message));
}
+
+void TabProxy::OnChannelError() {
+ AutoLock lock(list_lock_);
+ FOR_EACH_OBSERVER(TabProxyDelegate, observers_list_, OnChannelError(this));
+}
diff --git a/chrome/test/automation/tab_proxy.h b/chrome/test/automation/tab_proxy.h
index 15b5ab9..e7a7951 100644
--- a/chrome/test/automation/tab_proxy.h
+++ b/chrome/test/automation/tab_proxy.h
@@ -5,10 +5,10 @@
#ifndef CHROME_TEST_AUTOMATION_TAB_PROXY_H_
#define CHROME_TEST_AUTOMATION_TAB_PROXY_H_
-#include "build/build_config.h"
+#include "build/build_config.h" // NOLINT
#if defined(OS_WIN)
-#include <wtypes.h>
+#include <wtypes.h> // NOLINT
#endif
#include <string>
@@ -45,6 +45,7 @@ class TabProxy : public AutomationResourceProxy {
class TabProxyDelegate {
public:
virtual void OnMessageReceived(TabProxy* tab, const IPC::Message& msg) {}
+ virtual void OnChannelError(TabProxy* tab) {}
protected:
virtual ~TabProxyDelegate() {}
@@ -381,6 +382,7 @@ class TabProxy : public AutomationResourceProxy {
void AddObserver(TabProxyDelegate* observer);
void RemoveObserver(TabProxyDelegate* observer);
void OnMessageReceived(const IPC::Message& message);
+ void OnChannelError();
protected:
virtual ~TabProxy() {}
private:
diff --git a/chrome_frame/chrome_frame_activex.cc b/chrome_frame/chrome_frame_activex.cc
index f982072..a46d294 100644
--- a/chrome_frame/chrome_frame_activex.cc
+++ b/chrome_frame/chrome_frame_activex.cc
@@ -126,11 +126,11 @@ HRESULT ChromeFrameActivex::FinalConstruct() {
ChromeFrameActivex::~ChromeFrameActivex() {
// We expect these to be released during a call to SetClientSite(NULL).
- DCHECK(onmessage_.size() == 0);
- DCHECK(onloaderror_.size() == 0);
- DCHECK(onload_.size() == 0);
- DCHECK(onreadystatechanged_.size() == 0);
- DCHECK(onextensionready_.size() == 0);
+ DCHECK_EQ(0, onmessage_.size());
+ DCHECK_EQ(0, onloaderror_.size());
+ DCHECK_EQ(0, onload_.size());
+ DCHECK_EQ(0, onreadystatechanged_.size());
+ DCHECK_EQ(0, onextensionready_.size());
if (chrome_wndproc_hook_) {
BOOL unhook_success = ::UnhookWindowsHookEx(chrome_wndproc_hook_);
@@ -274,7 +274,11 @@ void ChromeFrameActivex::OnGetEnabledExtensionsComplete(
::SafeArrayDestroy(sa);
}
-HRESULT ChromeFrameActivex::OnDraw(ATL_DRAWINFO& draw_info) { // NO_LINT
+void ChromeFrameActivex::OnChannelError() {
+ Fire_onchannelerror();
+}
+
+HRESULT ChromeFrameActivex::OnDraw(ATL_DRAWINFO& draw_info) { // NOLINT
HRESULT hr = S_OK;
int dc_type = ::GetObjectType(draw_info.hicTargetDev);
if (dc_type == OBJ_ENHMETADC) {
@@ -496,7 +500,7 @@ HRESULT ChromeFrameActivex::CreateScriptBlockForEvent(
IHTMLElement2* insert_after, BSTR instance_id, BSTR script,
BSTR event_name) {
DCHECK(insert_after);
- DCHECK(::SysStringLen(event_name) > 0); // should always have this
+ DCHECK_GT(::SysStringLen(event_name), 0UL); // should always have this
// This might be 0 if not specified in the HTML document.
if (!::SysStringLen(instance_id)) {
diff --git a/chrome_frame/chrome_frame_activex.h b/chrome_frame/chrome_frame_activex.h
index 8ebab2b..dec399e 100644
--- a/chrome_frame/chrome_frame_activex.h
+++ b/chrome_frame/chrome_frame_activex.h
@@ -11,6 +11,7 @@
#include <set>
#include <string>
+#include <vector>
#include "base/scoped_bstr_win.h"
#include "base/scoped_comptr_win.h"
@@ -56,7 +57,7 @@ END_MSG_MAP()
HRESULT FinalConstruct();
- virtual HRESULT OnDraw(ATL_DRAWINFO& draw_info);
+ virtual HRESULT OnDraw(ATL_DRAWINFO& draw_info); // NOLINT
// IPersistPropertyBag implementation
STDMETHOD(GetClassID)(CLSID* class_id) {
@@ -97,6 +98,7 @@ END_MSG_MAP()
virtual void OnGetEnabledExtensionsComplete(
void* user_data,
const std::vector<FilePath>& extension_directories);
+ virtual void OnChannelError();
private:
LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam,
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h
index 2b9d60d..ebb57b0 100644
--- a/chrome_frame/chrome_frame_activex_base.h
+++ b/chrome_frame/chrome_frame_activex_base.h
@@ -14,6 +14,7 @@
#include <set>
#include <string>
+#include <vector>
#include "base/histogram.h"
#include "base/scoped_bstr_win.h"
@@ -46,14 +47,19 @@ class ATL_NO_VTABLE ProxyDIChromeFrameEvents
void FireMethodWithParams(ChromeFrameEventDispId dispid,
const VARIANT* params, size_t num_params) {
T* me = static_cast<T*>(this);
- int connections = m_vec.GetSize();
-
- for (int connection = 0; connection < connections; ++connection) {
- me->Lock();
- CComPtr<IUnknown> sink(m_vec.GetAt(connection));
- me->Unlock();
-
- DIChromeFrameEvents* events = static_cast<DIChromeFrameEvents*>(sink.p);
+ // We need to copy the whole vector and AddRef the sinks in case
+ // some would get disconnected as we fire methods. Note that this is not
+ // a threading issue, but a re-entrance issue, because the connection
+ // can be affected by the implementation of the sinks receiving the event.
+ me->Lock();
+ std::vector< ScopedComPtr<IUnknown> > sink_array(m_vec.GetSize());
+ for (int connection = 0; connection < m_vec.GetSize(); ++connection)
+ sink_array[connection] = m_vec.GetAt(connection);
+ me->Unlock();
+
+ for (size_t sink = 0; sink < sink_array.size(); ++sink) {
+ DIChromeFrameEvents* events =
+ static_cast<DIChromeFrameEvents*>(sink_array[sink].get());
if (events) {
DISPPARAMS disp_params = {
const_cast<VARIANT*>(params),
@@ -123,13 +129,17 @@ class ATL_NO_VTABLE ProxyDIChromeFrameEvents
arraysize(args));
}
- void Fire_ongetenabledextensionscomplete(SAFEARRAY* extension_dirs) { // NOLINT
+ void Fire_ongetenabledextensionscomplete(SAFEARRAY* extension_dirs) {
VARIANT args[1] = { { VT_ARRAY | VT_BSTR } };
args[0].parray = extension_dirs;
FireMethodWithParams(CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE,
args, arraysize(args));
}
+
+ void Fire_onchannelerror() { // NOLINT
+ FireMethodWithParams(CF_EVENT_DISPID_ONCHANNELERROR, NULL, 0);
+ }
};
extern bool g_first_launch_by_process_;
diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc
index 3c30d00..bf11755 100644
--- a/chrome_frame/chrome_frame_automation.cc
+++ b/chrome_frame/chrome_frame_automation.cc
@@ -40,13 +40,21 @@ static const wchar_t kUmaSendIntervalValue[] = L"UmaSendInterval";
// threads.
Lock g_ChromeFrameHistogramLock;
-class TabProxyNotificationMessageFilter
+class ChromeFrameAutomationProxyImpl::TabProxyNotificationMessageFilter
: public IPC::ChannelProxy::MessageFilter {
public:
explicit TabProxyNotificationMessageFilter(AutomationHandleTracker* tracker)
: tracker_(tracker) {
}
+ void AddTabProxy(AutomationHandle tab_proxy) {
+ tabs_list_.push_back(tab_proxy);
+ }
+
+ void RemoveTabProxy(AutomationHandle tab_proxy) {
+ tabs_list_.remove(tab_proxy);
+ }
+
virtual bool OnMessageReceived(const IPC::Message& message) {
if (message.is_reply())
return false;
@@ -64,9 +72,21 @@ class TabProxyNotificationMessageFilter
return true;
}
+ virtual void OnChannelError() {
+ std::list<AutomationHandle>::const_iterator iter = tabs_list_.begin();
+ for (; iter != tabs_list_.end(); ++iter) {
+ // Get AddRef-ed pointer to corresponding TabProxy object
+ TabProxy* tab = static_cast<TabProxy*>(tracker_->GetResource(*iter));
+ if (tab) {
+ tab->OnChannelError();
+ tab->Release();
+ }
+ }
+ }
private:
AutomationHandleTracker* tracker_;
+ std::list<AutomationHandle> tabs_list_;
};
class ChromeFrameAutomationProxyImpl::CFMsgDispatcher
@@ -108,8 +128,9 @@ ChromeFrameAutomationProxyImpl::ChromeFrameAutomationProxyImpl(
int launch_timeout)
: AutomationProxy(launch_timeout) {
sync_ = new CFMsgDispatcher();
+ message_filter_ = new TabProxyNotificationMessageFilter(tracker_.get());
// Order of filters is not important.
- channel_->AddFilter(new TabProxyNotificationMessageFilter(tracker_.get()));
+ channel_->AddFilter(message_filter_.get());
channel_->AddFilter(sync_.get());
}
@@ -129,7 +150,14 @@ void ChromeFrameAutomationProxyImpl::CancelAsync(void* key) {
scoped_refptr<TabProxy> ChromeFrameAutomationProxyImpl::CreateTabProxy(
int handle) {
DCHECK(tracker_->GetResource(handle) == NULL);
- return new TabProxy(this, tracker_.get(), handle);
+ TabProxy* tab_proxy = new TabProxy(this, tracker_.get(), handle);
+ if (tab_proxy != NULL)
+ message_filter_->AddTabProxy(handle);
+ return tab_proxy;
+}
+
+void ChromeFrameAutomationProxyImpl::ReleaseTabProxy(AutomationHandle handle) {
+ message_filter_->RemoveTabProxy(handle);
}
struct LaunchTimeStats {
@@ -513,6 +541,8 @@ void ChromeFrameAutomationClient::Uninitialize() {
if (tab_.get()) {
tab_->RemoveObserver(this);
+ if (automation_server_)
+ automation_server_->ReleaseTabProxy(tab_->handle());
tab_ = NULL; // scoped_refptr::Release
}
@@ -522,7 +552,7 @@ void ChromeFrameAutomationClient::Uninitialize() {
// We must destroy the window, since if there are pending tasks
// window procedure may be invoked after DLL is unloaded.
// Unfortunately pending tasks are leaked.
- if (m_hWnd)
+ if (::IsWindow(m_hWnd))
DestroyWindow();
chrome_frame_delegate_ = NULL;
@@ -993,7 +1023,7 @@ bool ChromeFrameAutomationClient::ProcessUrlRequestMessage(TabProxy* tab,
return true;
}
-// This is invoked in channel's background thread.
+// These are invoked in channel's background thread.
// Cannot call any method of the activex/npapi here since they are STA
// kind of beings.
// By default we marshal the IPC message to the main/GUI thread and from there
@@ -1013,13 +1043,31 @@ void ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab,
&ChromeFrameAutomationClient::OnMessageReceivedUIThread, msg));
}
+void ChromeFrameAutomationClient::OnChannelError(TabProxy* tab) {
+ DCHECK(tab == tab_.get());
+ // Early check to avoid needless marshaling
+ if (chrome_frame_delegate_ == NULL)
+ return;
+
+ PostTask(FROM_HERE, NewRunnableMethod(this,
+ &ChromeFrameAutomationClient::OnChannelErrorUIThread));
+}
+
void ChromeFrameAutomationClient::OnMessageReceivedUIThread(
const IPC::Message& msg) {
+ DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_);
// Forward to the delegate.
if (chrome_frame_delegate_)
chrome_frame_delegate_->OnMessageReceived(msg);
}
+void ChromeFrameAutomationClient::OnChannelErrorUIThread() {
+ DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_);
+ // Forward to the delegate.
+ if (chrome_frame_delegate_)
+ chrome_frame_delegate_->OnChannelError();
+}
+
void ChromeFrameAutomationClient::ReportNavigationError(
AutomationMsg_NavigationResponseValues error_code,
const std::string& url) {
diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h
index 6c0d895..1a1948e 100644
--- a/chrome_frame/chrome_frame_automation.h
+++ b/chrome_frame/chrome_frame_automation.h
@@ -9,6 +9,7 @@
#include <atlwin.h>
#include <string>
#include <map>
+#include <vector>
#include "base/lock.h"
#include "base/ref_counted.h"
@@ -31,18 +32,19 @@ const unsigned long kCommandExecutionTimeout = 60000; // NOLINT, 60 seconds
class ProxyFactory;
enum AutomationPageFontSize;
-struct DECLSPEC_NOVTABLE ChromeFrameAutomationProxy {
+struct DECLSPEC_NOVTABLE ChromeFrameAutomationProxy { // NOLINT
virtual bool Send(IPC::Message* msg) = 0;
virtual void SendAsAsync(IPC::SyncMessage* msg, void* callback,
void* key) = 0;
virtual void CancelAsync(void* key) = 0;
virtual scoped_refptr<TabProxy> CreateTabProxy(int handle) = 0;
+ virtual void ReleaseTabProxy(AutomationHandle handle) = 0;
virtual std::string server_version() = 0;
virtual void SendProxyConfig(const std::string&) = 0;
protected:
- ~ChromeFrameAutomationProxy() {}
+ virtual ~ChromeFrameAutomationProxy() {}
};
// We extend the AutomationProxy class to handle our custom
@@ -58,11 +60,11 @@ class ChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxy,
virtual void CancelAsync(void* key);
virtual scoped_refptr<TabProxy> CreateTabProxy(int handle);
+ virtual void ReleaseTabProxy(AutomationHandle handle);
virtual std::string server_version() {
return AutomationProxy::server_version();
}
-
virtual bool Send(IPC::Message* msg) {
return AutomationProxy::Send(msg);
}
@@ -76,6 +78,8 @@ class ChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxy,
~ChromeFrameAutomationProxyImpl();
class CFMsgDispatcher;
scoped_refptr<CFMsgDispatcher> sync_;
+ class TabProxyNotificationMessageFilter;
+ scoped_refptr<TabProxyNotificationMessageFilter> message_filter_;
friend class ProxyFactory;
};
@@ -98,13 +102,13 @@ class ProxyFactory {
public:
// Callback when chrome process launch is complete and automation handshake
// (Hello message) is established.
- struct DECLSPEC_NOVTABLE LaunchDelegate {
+ struct DECLSPEC_NOVTABLE LaunchDelegate { // NOLINT
virtual void LaunchComplete(ChromeFrameAutomationProxy* proxy,
AutomationLaunchResult result) = 0;
- };
+ }; // NOLINT
ProxyFactory();
- ~ProxyFactory();
+ virtual ~ProxyFactory();
virtual void GetAutomationServer(LaunchDelegate* delegate,
const ChromeFrameLaunchParams& params,
@@ -273,6 +277,7 @@ class ChromeFrameAutomationClient
AutomationLaunchResult result);
// TabProxyDelegate implementation
virtual void OnMessageReceived(TabProxy* tab, const IPC::Message& msg);
+ virtual void OnChannelError(TabProxy* tab);
void CreateExternalTab();
void CreateExternalTabComplete(HWND chrome_window, HWND tab_window,
@@ -287,6 +292,7 @@ class ChromeFrameAutomationClient
private:
void OnMessageReceivedUIThread(const IPC::Message& msg);
+ void OnChannelErrorUIThread();
HWND chrome_window() const { return chrome_window_; }
void BeginNavigate(const GURL& url, const GURL& referrer);
diff --git a/chrome_frame/chrome_frame_delegate.cc b/chrome_frame/chrome_frame_delegate.cc
index f286b08..3e69bd9 100644
--- a/chrome_frame/chrome_frame_delegate.cc
+++ b/chrome_frame/chrome_frame_delegate.cc
@@ -70,7 +70,6 @@ void ChromeFrameDelegateImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(AutomationMsg_AttachExternalTab, OnAttachExternalTab)
IPC_MESSAGE_HANDLER(AutomationMsg_RequestGoToHistoryEntryOffset,
OnGoToHistoryEntryOffset)
- IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost,
- OnGetCookiesFromHost)
+ IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost, OnGetCookiesFromHost)
IPC_END_MESSAGE_MAP()
}
diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h
index d4bdae0..cc2aa95 100644
--- a/chrome_frame/chrome_frame_delegate.h
+++ b/chrome_frame/chrome_frame_delegate.h
@@ -8,6 +8,8 @@
#include <atlbase.h>
#include <atlwin.h>
#include <queue>
+#include <string>
+#include <vector>
#include "base/file_path.h"
#include "base/lock.h"
@@ -34,6 +36,7 @@ class ChromeFrameDelegate {
void* user_data,
const std::vector<FilePath>& extension_directories) = 0;
virtual void OnMessageReceived(const IPC::Message& msg) = 0;
+ virtual void OnChannelError() = 0;
// This remains in interface since we call it if Navigate()
// returns immediate error.
@@ -48,7 +51,7 @@ class ChromeFrameDelegate {
virtual void OnHostMoved() = 0;
protected:
- ~ChromeFrameDelegate() {}
+ virtual ~ChromeFrameDelegate() {}
};
// Template specialization
@@ -77,6 +80,7 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
const std::vector<FilePath>& extension_directories) {}
virtual void OnLoadFailed(int error_code, const std::string& url) {}
virtual void OnMessageReceived(const IPC::Message& msg);
+ virtual void OnChannelError() {}
static bool IsTabMessage(const IPC::Message& message, int* tab_handle);
@@ -125,8 +129,8 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
int cookie_id) {}
};
-// This interface enables tasks to be marshalled to desired threads.
-class TaskMarshaller {
+// This interface enables tasks to be marshaled to desired threads.
+class TaskMarshaller { // NOLINT
public:
virtual void PostTask(const tracked_objects::Location& from_here,
Task* task) = 0;
diff --git a/chrome_frame/chrome_tab.idl b/chrome_frame/chrome_tab.idl
index 7a8d03a..3ce87d0 100644
--- a/chrome_frame/chrome_tab.idl
+++ b/chrome_frame/chrome_tab.idl
@@ -113,6 +113,7 @@ typedef enum {
CF_EVENT_DISPID_ONPRIVATEMESSAGE,
CF_EVENT_DISPID_ONEXTENSIONREADY,
CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE,
+ CF_EVENT_DISPID_ONCHANNELERROR,
CF_EVENT_DISPID_ONREADYSTATECHANGED = DISPID_READYSTATECHANGE,
} ChromeFrameEventDispId;
@@ -150,12 +151,17 @@ library ChromeTabLib {
// This event is only fired when the control is in privileged mode.
// response is one of AutomationMsg_ExtensionResponseValues.
void onextensionready([in] BSTR path, [in] long response);
-
+
[id(CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE)]
// This event is only fired when the control is in privileged mode.
// extension_paths is an array of BSTRs of the base directories of
// enabled extensions.
void ongetenabledextensionscomplete([in] SAFEARRAY(BSTR) extension_paths);
+
+ [id(CF_EVENT_DISPID_ONCHANNELERROR)]
+ // This event is fired when there is an error in communication channel with
+ // Chrome and Automation must be reconnected to continue.
+ void onchannelerror();
};
[uuid(BB1176EE-20DD-41DC-9D1E-AC1335C7BBB0)]
diff --git a/chrome_frame/test/automation_client_mock.cc b/chrome_frame/test/automation_client_mock.cc
index de1736c..486f782 100644
--- a/chrome_frame/test/automation_client_mock.cc
+++ b/chrome_frame/test/automation_client_mock.cc
@@ -298,6 +298,8 @@ TEST_F(CFACMockTest, MockedCreateTabOk) {
};
EXPECT_TRUE(client_->Initialize(&cfd_, clp));
loop_.RunFor(10);
+
+ EXPECT_CALL(proxy_, ReleaseTabProxy(testing::Eq(tab_handle_))).Times(1);
client_->Uninitialize();
}
@@ -337,3 +339,6 @@ TEST_F(CFACMockTest, MockedCreateTabFailed) {
client_->Uninitialize();
}
+TEST_F(CFACMockTest, OnChannelError) {
+
+}
diff --git a/chrome_frame/test/automation_client_mock.h b/chrome_frame/test/automation_client_mock.h
index 4f65bbb..1d187f3 100644
--- a/chrome_frame/test/automation_client_mock.h
+++ b/chrome_frame/test/automation_client_mock.h
@@ -12,6 +12,8 @@
#include "chrome_frame/test/proxy_factory_mock.h"
#include "gmock/gmock.h"
+using testing::StrictMock;
+
// ChromeFrameAutomationClient [CFAC] tests.
struct MockCFDelegate : public ChromeFrameDelegateImpl {
MOCK_CONST_METHOD0(GetWindow, WindowType());
@@ -91,6 +93,7 @@ class MockAutomationProxy : public ChromeFrameAutomationProxy {
void* key));
MOCK_METHOD1(CancelAsync, void(void* key));
MOCK_METHOD1(CreateTabProxy, scoped_refptr<TabProxy>(int handle));
+ MOCK_METHOD1(ReleaseTabProxy, void(AutomationHandle handle));
MOCK_METHOD0(server_version, std::string(void));
MOCK_METHOD1(SendProxyConfig, void(const std::string&));
MOCK_METHOD1(SetEnableExtensionAutomation, void(bool enable));
@@ -102,13 +105,13 @@ struct MockAutomationMessageSender : public AutomationMessageSender {
MOCK_METHOD1(Send, bool(IPC::Message*));
MOCK_METHOD3(SendWithTimeout, bool(IPC::Message* , int , bool*));
- void ForwardTo(MockAutomationProxy *p) {
+ void ForwardTo(StrictMock<MockAutomationProxy> *p) {
proxy_ = p;
ON_CALL(*this, Send(testing::_))
.WillByDefault(testing::Invoke(proxy_, &MockAutomationProxy::Send));
}
- MockAutomationProxy* proxy_;
+ StrictMock<MockAutomationProxy>* proxy_;
};
// [CFAC] -- uses a ProxyFactory for creation of ChromeFrameAutomationProxy
@@ -130,7 +133,7 @@ class CFACMockTest : public testing::Test {
MockProxyFactory factory_;
MockCFDelegate cfd_;
chrome_frame_test::TimedMsgLoop loop_;
- MockAutomationProxy proxy_;
+ StrictMock<MockAutomationProxy> proxy_;
scoped_ptr<AutomationHandleTracker> tracker_;
MockAutomationMessageSender dummy_sender_;
scoped_refptr<TabProxy> tab_;