summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 16:02:26 +0000
committerstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 16:02:26 +0000
commit11b6e60b413fe6b596cbf08f78e689a360faeb61 (patch)
tree04d332597120edd9a87f42efab62f3b1d7f4f8f4 /chrome_frame
parent18004a3331147f8f84ad8a21caa2ce695d75c28a (diff)
downloadchromium_src-11b6e60b413fe6b596cbf08f78e689a360faeb61.zip
chromium_src-11b6e60b413fe6b596cbf08f78e689a360faeb61.tar.gz
chromium_src-11b6e60b413fe6b596cbf08f78e689a360faeb61.tar.bz2
Review URL: http://codereview.chromium.org/3685006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62407 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp1
-rw-r--r--chrome_frame/external_tab.cc175
-rw-r--r--chrome_frame/external_tab.h40
-rw-r--r--chrome_frame/external_tab_test.cc95
-rw-r--r--chrome_frame/task_marshaller.cc70
-rw-r--r--chrome_frame/task_marshaller.h3
6 files changed, 335 insertions, 49 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index dcffb1b..6ac0b37 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -243,6 +243,7 @@
'sources': [
'../base/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',
diff --git a/chrome_frame/external_tab.cc b/chrome_frame/external_tab.cc
index ecf7927..322f74a 100644
--- a/chrome_frame/external_tab.cc
+++ b/chrome_frame/external_tab.cc
@@ -12,6 +12,14 @@
DISABLE_RUNNABLE_METHOD_REFCOUNT(ExternalTabProxy);
DISABLE_RUNNABLE_METHOD_REFCOUNT(UIDelegate);
+namespace {
+ struct UserDataHolder : public SyncMessageContext {
+ explicit UserDataHolder(void* p) : data(p) {}
+ void* data;
+ };
+}
+
+
ExternalTabProxy::ExternalTabProxy() : state_(NONE), tab_(0), proxy_(NULL),
ui_delegate_(NULL) {
}
@@ -20,10 +28,22 @@ ExternalTabProxy::~ExternalTabProxy() {
Destroy();
}
+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());
done_.reset(new base::WaitableEvent(true, false));
- proxy_factory_->ReleaseProxy(this, tab_params_.profile);
+ proxy_factory_->ReleaseProxy(this, tab_params_.proxy_params.profile);
done_->Wait();
done_.reset(NULL);
@@ -35,12 +55,12 @@ 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;
tab_params_ = create_params;
state_ = INIT_IN_PROGRESS;
- // TODO(stoyan): initialize ProxyParams from CreateTabParams.
- ProxyParams p;
- proxy_factory_->GetProxy(this, p);
+ proxy_factory_->GetProxy(this, create_params.proxy_params);
}
void ExternalTabProxy::Connected(ChromeProxy* proxy) {
@@ -48,6 +68,14 @@ void ExternalTabProxy::Connected(ChromeProxy* proxy) {
ui_.PostTask(FROM_HERE, NewRunnableMethod(this,
&ExternalTabProxy::UiConnected, proxy));
}
+
+void ExternalTabProxy::UiConnected(ChromeProxy* proxy) {
+ proxy_ = proxy;
+ IPC::ExternalTabSettings settings;
+ // TODO(stoyan): Initialize settings.
+ proxy->CreateTab(this, settings);
+}
+
void ExternalTabProxy::Disconnected() {
// in ipc thread
DCHECK(done_.get() != NULL);
@@ -59,6 +87,10 @@ void ExternalTabProxy::PeerLost(ChromeProxy* proxy, DisconnectReason reason) {
proxy, reason));
}
+void ExternalTabProxy::UiPeerLost(ChromeProxy* proxy, DisconnectReason reason) {
+ // TODO(stoyan):
+}
+
void ExternalTabProxy::Navigate(const std::string& url,
const std::string& referrer, bool is_privileged) {
// in ui thread
@@ -69,23 +101,74 @@ void ExternalTabProxy::Navigate(const std::string& url,
return;
}
+ GURL parsed_referrer(referrer);
+ // If we are still establishing channel, simply replace the params
if (state_ == INIT_IN_PROGRESS) {
- // TODO(stoyan): replace CreateTabParams with the new ones
+ 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) {
- // ah! too late. wait to get tab handle and then navigate
- pending_navigation_.Set(parsed_url, GURL(referrer));
+ pending_navigation_.Set(parsed_url, parsed_referrer);
}
if (state_ == READY) {
- proxy_->Tab_Navigate(tab_, parsed_url, GURL(referrer));
+ 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(PageZoom::Function 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::SetEnableExtensionAutomation(
+ const std::vector<std::string>& functions_enabled) {
+ proxy_->Tab_SetEnableExtensionAutomation(tab_, functions_enabled);
+}
+
+void ExternalTabProxy::InstallExtension(const FilePath& crx_path,
+ void* user_data) {
+ proxy_->InstallExtension(this, crx_path, new UserDataHolder(user_data));
+}
+
+void ExternalTabProxy::LoadExpandedExtension(const FilePath& path,
+ void* user_data) {
+ proxy_->LoadExtension(this, path, new UserDataHolder(user_data));
+}
+
+void ExternalTabProxy::GetEnabledExtensions(void* user_data) {
+ proxy_->GetEnabledExtensions(this, new UserDataHolder(user_data));
+}
+
+void ExternalTabProxy::ChromeFrameHostMoved() {
+ proxy_->Tab_OnHostMoved(tab_);
+}
+
+//////////////////////////////////////////////////////////////////////////
void ExternalTabProxy::Completed_CreateTab(bool success, HWND chrome_wnd,
HWND tab_window, int tab_handle) {
// in ipc_thread.
+ // ui_.PostTask()
}
void ExternalTabProxy::Completed_ConnectToTab(bool success,
@@ -129,3 +212,79 @@ void ExternalTabProxy::TabLoaded(const GURL& url) {
ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
&UIDelegate::OnLoad, url));
}
+
+void ExternalTabProxy::MessageToHost(const std::string& message,
+ const std::string& origin,
+ const std::string& target) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnMessageFromChromeFrame, message, origin, target));
+}
+
+void ExternalTabProxy::HandleAccelerator(const MSG& accel_message) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnHandleAccelerator, accel_message));
+}
+
+void ExternalTabProxy::HandleContextMenu(HANDLE menu_handle, int align_flags,
+ const IPC::ContextMenuParams& params) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnHandleContextMenu, menu_handle, align_flags, params));
+}
+
+void ExternalTabProxy::TabbedOut(bool reverse) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnTabbedOut, reverse));
+}
+
+void ExternalTabProxy::GoToHistoryOffset(int offset) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnGoToHistoryOffset, offset));
+}
+
+void ExternalTabProxy::OpenURL(const GURL& url_to_open, const GURL& referrer,
+ int open_disposition) {
+ ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
+ &UIDelegate::OnOpenURL, url_to_open, referrer, open_disposition));
+}
+
+void ExternalTabProxy::NavigationFailed(int error_code, const GURL& gurl) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::DidNavigate(const IPC::NavigationInfo& navigation_info) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::Network_Start(
+ int request_id, const IPC::AutomationURLRequest& request_info) {
+ // TODO(stoyan): url_fetcher_.Start();
+}
+
+void ExternalTabProxy::Network_Read(int request_id, int bytes_to_read) {
+ // TODO(stoyan): url_fetcher_.Read();
+}
+
+void ExternalTabProxy::Network_End(int request_id, const URLRequestStatus& s) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::Network_DownloadInHost(int request_id) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::GetCookies(const GURL& url, int cookie_id) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::SetCookie(const GURL& url, const std::string& cookie) {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::TabClosed() {
+ // TODO(stoyan):
+}
+
+void ExternalTabProxy::AttachTab(
+ const IPC::AttachExternalTabParams& attach_params) {
+ // TODO(stoyan):
+}
diff --git a/chrome_frame/external_tab.h b/chrome_frame/external_tab.h
index eba2965..882cbed 100644
--- a/chrome_frame/external_tab.h
+++ b/chrome_frame/external_tab.h
@@ -41,24 +41,26 @@ class UIDelegate {
virtual void OnUpdateTargetUrl(const std::wstring& new_target_url) = 0;
virtual void OnExtensionInstalled(const FilePath& path, void* user_data,
AutomationMsg_ExtensionResponseValues response) = 0;
- virtual void OnAcceleratorPressed(const MSG& accel_message) = 0;
virtual void OnLoad(const GURL& url) = 0;
virtual void OnMessageFromChromeFrame(const std::string& message,
const std::string& origin, const std::string& target) = 0;
virtual void OnHandleContextMenu(HANDLE menu_handle, int align_flags,
const IPC::ContextMenuParams& params) = 0;
+ 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 {
- std::string profile;
- std::string extra_arguments;
+ struct ProxyParams proxy_params;
bool is_incognito;
bool is_widget_mode;
GURL url;
GURL referrer;
- base::TimeDelta launch_timeout;
};
/////////////////////////////////////////////////////////////////////////
@@ -91,12 +93,10 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
UIDelegate* delegate);
virtual void Navigate(const std::string& url, const std::string& referrer,
bool is_privileged);
- virtual bool NavigateToIndex(int index);
+ virtual void NavigateToIndex(int index);
virtual void ForwardMessageFromExternalHost(const std::string& message,
- const std::string& origin, const std::string& target) {
- proxy_->Tab_PostMessage(tab_, message, origin, target);
- }
- virtual void OnChromeFrameHostMoved();
+ const std::string& origin, const std::string& target);
+ virtual void ChromeFrameHostMoved();
virtual void SetEnableExtensionAutomation(
const std::vector<std::string>& functions_enabled);
@@ -105,14 +105,16 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
virtual void GetEnabledExtensions(void* user_data);
// Attaches an existing external tab to this automation client instance.
- virtual void AttachExternalTab(uint64 external_tab_cookie);
+ virtual void ConnectToExternalTab(uint64 external_tab_cookie);
virtual void BlockExternalTab(uint64 cookie);
- void SetZoomLevel(PageZoom::Function zoom_level) {
- proxy_->Tab_Zoom(tab_, zoom_level);
- }
+ void SetZoomLevel(PageZoom::Function zoom_level);
private:
+ BEGIN_MSG_MAP(ExternalTabProxy)
+ CHAIN_MSG_MAP_MEMBER(ui_);
+ END_MSG_MAP()
+
//////////////////////////////////////////////////////////////////////////
// ChromeProxyDelegate implementation
virtual int tab_handle() {
@@ -125,9 +127,9 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
// Sync message responses.
virtual void Completed_CreateTab(bool success, HWND chrome_wnd,
- HWND tab_window, int tab_handle) = 0; // TODO(stoyan): Error_code
+ HWND tab_window, int tab_handle); // TODO(stoyan): Error_code
virtual void Completed_ConnectToTab(bool success, HWND chrome_window,
- HWND tab_window, int tab_handle) = 0;
+ HWND tab_window, int tab_handle);
virtual void Completed_Navigate(bool success,
enum AutomationMsg_NavigationResponseValues res);
virtual void Completed_InstallExtension(bool success,
@@ -162,6 +164,8 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
// Misc. UI.
virtual void HandleAccelerator(const MSG& accel_message);
+ virtual void HandleContextMenu(HANDLE menu_handle, int align_flags,
+ const IPC::ContextMenuParams& params);
virtual void TabbedOut(bool reverse);
// Other
@@ -170,7 +174,7 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
// end of ChromeProxyDelegate methods
//////////////////////////////////////////////////////////////////////////
-
+ void Init();
void Destroy();
// The UiXXXX are the ChromeProxyDelegate methods but on UI thread.
@@ -191,7 +195,11 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
} state_;
int tab_;
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_;
diff --git a/chrome_frame/external_tab_test.cc b/chrome_frame/external_tab_test.cc
new file mode 100644
index 0000000..f34c169
--- /dev/null
+++ b/chrome_frame/external_tab_test.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome_frame/external_tab.h"
+// #include "base/tracked.h"
+// #include "base/task.h"
+// #include "base/waitable_event.h"
+
+#include "chrome/test/automation/automation_messages.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+
+
+// DISABLE_RUNNABLE_METHOD_REFCOUNT(ExternalTabProxy);
+// DISABLE_RUNNABLE_METHOD_REFCOUNT(UIDelegate);
+
+
+struct MockUIDelegate : public UIDelegate {
+ MOCK_METHOD2(OnNavigationStateChanged, void(int flags,
+ const IPC::NavigationInfo& nav_info));
+ MOCK_METHOD1(OnUpdateTargetUrl, void(const std::wstring& new_target_url));
+ MOCK_METHOD3(OnExtensionInstalled, void(const FilePath& path, void* user_data,
+ AutomationMsg_ExtensionResponseValues response));
+ MOCK_METHOD1(OnLoad, void(const GURL& url));
+ MOCK_METHOD3(OnMessageFromChromeFrame, void(const std::string& message,
+ const std::string& origin, const std::string& target));
+ MOCK_METHOD3(OnHandleContextMenu, void(HANDLE menu_handle, int align_flags,
+ const IPC::ContextMenuParams& 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_METHOD3(InstallExtension, void(ChromeProxyDelegate* delegate,
+ const FilePath& crx_path, SyncMessageContext* ctx));
+ MOCK_METHOD3(LoadExtension, void(ChromeProxyDelegate* delegate,
+ const FilePath& path, SyncMessageContext* ctx));
+ MOCK_METHOD2(GetEnabledExtensions, void(ChromeProxyDelegate* delegate,
+ SyncMessageContext* ctx));
+ MOCK_METHOD1(SetProxyConfig, void(const std::string& json_encoded_settings));
+
+ MOCK_METHOD2(CreateTab, void(ChromeProxyDelegate* delegate,
+ const IPC::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, PageZoom::Function 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_METHOD2(Tab_SetEnableExtensionAutomation, void(int tab,
+ const std::vector<std::string>& functions_enabled));
+ MOCK_METHOD3(Tab_Navigate, void(int tab, const GURL& url,
+ const GURL& referrer));
+ MOCK_METHOD2(Tab_OverrideEncoding, void(int tab, const char* encoding));
+
+ private:
+ MOCK_METHOD1(Init, void(const ProxyParams& params));
+ MOCK_METHOD1(AddDelegate, int(ChromeProxyDelegate* delegate));
+ MOCK_METHOD1(RemoveDelegate, int(ChromeProxyDelegate* delegate));
+};
+
+TEST(ExternalTabProxy, Simple1) {
+ MockUIDelegate ui;
+ MockProxy proxy;
+ ExternalTabProxy tab;
+}
diff --git a/chrome_frame/task_marshaller.cc b/chrome_frame/task_marshaller.cc
index ba1df2c..b8a504a5 100644
--- a/chrome_frame/task_marshaller.cc
+++ b/chrome_frame/task_marshaller.cc
@@ -14,34 +14,54 @@ TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() {
}
void TaskMarshallerThroughMessageQueue::PostTask(
- const tracked_objects::Location& from_here, Task* task) {
- task->SetBirthPlace(from_here);
- lock_.Acquire();
- bool has_work = !pending_tasks_.empty();
- pending_tasks_.push(task);
- lock_.Release();
-
- // Don't post message if there is already one.
- if (has_work)
- return;
-
- if (!::PostMessage(wnd_, msg_, 0, 0)) {
- DLOG(INFO) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
- DeleteAll();
- }
+ const tracked_objects::Location& from_here, Task* task) {
+ DCHECK(wnd_ != NULL);
+ task->SetBirthPlace(from_here);
+ lock_.Acquire();
+ bool has_work = !pending_tasks_.empty();
+ pending_tasks_.push(task);
+ lock_.Release();
+
+ // Don't post message if there is already one.
+ if (has_work)
+ return;
+
+ if (!::PostMessage(wnd_, msg_, 0, 0)) {
+ DLOG(INFO) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
+ DeleteAll();
+ }
}
void TaskMarshallerThroughMessageQueue::PostDelayedTask(
- const tracked_objects::Location& source, Task* task,
- base::TimeDelta& delay) {
- AutoLock lock(lock_);
- DelayedTask delayed_task(task, base::Time::Now() + delay);
- delayed_tasks_.push(delayed_task);
- // If we become the 'top' task - reschedule the timer.
- if (delayed_tasks_.top().task == task) {
- ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
- static_cast<DWORD>(delay.InMilliseconds()), NULL);
- }
+ const tracked_objects::Location& source, Task* task,
+ base::TimeDelta& delay) {
+ DCHECK(wnd_ != NULL);
+ AutoLock lock(lock_);
+ DelayedTask delayed_task(task, base::Time::Now() + delay);
+ delayed_tasks_.push(delayed_task);
+ // If we become the 'top' task - reschedule the timer.
+ if (delayed_tasks_.top().task == task) {
+ ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
+ static_cast<DWORD>(delay.InMilliseconds()), NULL);
+ }
+}
+
+BOOL TaskMarshallerThroughMessageQueue::ProcessWindowMessage(HWND hWnd,
+ UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult,
+ DWORD dwMsgMapID) {
+ if (hWnd == wnd_ && uMsg == msg_) {
+ ExecuteQueuedTasks();
+ lResult = 0;
+ return TRUE;
+ }
+
+ if (hWnd == wnd_ && uMsg == WM_TIMER) {
+ ExecuteDelayedTasks();
+ lResult = 0;
+ return TRUE;
+ }
+
+ return FALSE;
}
Task* TaskMarshallerThroughMessageQueue::PopTask() {
diff --git a/chrome_frame/task_marshaller.h b/chrome_frame/task_marshaller.h
index b3f87b8..f0f6890 100644
--- a/chrome_frame/task_marshaller.h
+++ b/chrome_frame/task_marshaller.h
@@ -36,6 +36,9 @@ class TaskMarshallerThroughMessageQueue : public NonThreadSafe {
virtual void PostDelayedTask(const tracked_objects::Location& source,
Task* task,
base::TimeDelta& delay);
+ // Called by the owner of the HWND.
+ BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
+ LRESULT& lResult, DWORD dwMsgMapID = 0);
private:
void DeleteAll();
inline Task* PopTask();