1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
6 #define CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
14 #include "base/callback.h"
15 #include "base/file_path.h"
16 #include "base/location.h"
17 #include "base/pending_task.h"
18 #include "base/synchronization/lock.h"
19 #include "chrome/common/automation_constants.h"
20 #include "ipc/ipc_message.h"
23 struct AttachExternalTabParams
;
24 struct AutomationURLRequest
;
25 struct ContextMenuModel
;
26 struct MiniContextMenuParams
;
27 struct NavigationInfo
;
30 class URLRequestStatus
;
37 // A common interface supported by all the browser specific ChromeFrame
39 class ChromeFrameDelegate
{
41 typedef HWND WindowType
;
43 virtual WindowType
GetWindow() const = 0;
44 virtual void GetBounds(RECT
* bounds
) = 0;
45 virtual std::string
GetDocumentUrl() = 0;
46 virtual void OnAutomationServerReady() = 0;
47 virtual void OnAutomationServerLaunchFailed(
48 AutomationLaunchResult reason
, const std::string
& server_version
) = 0;
49 virtual bool OnMessageReceived(const IPC::Message
& msg
) = 0;
50 virtual void OnChannelError() = 0;
52 // This remains in interface since we call it if Navigate()
53 // returns immediate error.
54 virtual void OnLoadFailed(int error_code
, const std::string
& url
) = 0;
56 // Returns true if this instance is alive and well for processing automation
58 virtual bool IsValid() const = 0;
60 // To be called when the top-most window of an application hosting
61 // ChromeFrame is moved.
62 virtual void OnHostMoved() = 0;
65 virtual ~ChromeFrameDelegate() {}
68 extern UINT kAutomationServerReady
;
69 extern UINT kMessageFromChromeFrame
;
71 class ChromeFrameDelegateImpl
: public ChromeFrameDelegate
{
73 virtual WindowType
GetWindow() { return NULL
; }
74 virtual void GetBounds(RECT
* bounds
) {}
75 virtual std::string
GetDocumentUrl() { return std::string(); }
76 virtual void OnAutomationServerReady() {}
77 virtual void OnAutomationServerLaunchFailed(
78 AutomationLaunchResult reason
, const std::string
& server_version
) {}
79 virtual void OnLoadFailed(int error_code
, const std::string
& url
) {}
80 virtual bool OnMessageReceived(const IPC::Message
& msg
);
81 virtual void OnChannelError() {}
83 static bool IsTabMessage(const IPC::Message
& message
);
85 virtual bool IsValid() const {
89 virtual void OnHostMoved() {}
92 // Protected methods to be overridden.
93 virtual void OnNavigationStateChanged(
94 int flags
, const NavigationInfo
& nav_info
) {}
95 virtual void OnUpdateTargetUrl(const std::wstring
& new_target_url
) {}
96 virtual void OnAcceleratorPressed(const MSG
& accel_message
) {}
97 virtual void OnTabbedOut(bool reverse
) {}
98 virtual void OnOpenURL(
99 const GURL
& url
, const GURL
& referrer
, int open_disposition
) {}
100 virtual void OnDidNavigate(const NavigationInfo
& navigation_info
) {}
101 virtual void OnNavigationFailed(int error_code
, const GURL
& gurl
) {}
102 virtual void OnLoad(const GURL
& url
) {}
103 virtual void OnMoveWindow(const gfx::Rect
& pos
) {}
104 virtual void OnMessageFromChromeFrame(const std::string
& message
,
105 const std::string
& origin
,
106 const std::string
& target
) {}
107 virtual void OnHandleContextMenu(const ContextMenuModel
& context_menu_model
,
109 const MiniContextMenuParams
& params
) {}
110 virtual void OnRequestStart(
111 int request_id
, const AutomationURLRequest
& request
) {}
112 virtual void OnRequestRead(int request_id
, int bytes_to_read
) {}
113 virtual void OnRequestEnd(int request_id
,
114 const net::URLRequestStatus
& status
) {}
115 virtual void OnDownloadRequestInHost(int request_id
) {}
116 virtual void OnSetCookieAsync(const GURL
& url
, const std::string
& cookie
) {}
117 virtual void OnAttachExternalTab(
118 const AttachExternalTabParams
& attach_params
) {}
119 virtual void OnGoToHistoryEntryOffset(int offset
) {}
121 virtual void OnGetCookiesFromHost(const GURL
& url
, int cookie_id
) {}
122 virtual void OnCloseTab() {}
125 // This interface enables tasks to be marshaled to desired threads.
126 class TaskMarshaller
{ // NOLINT
128 virtual void PostTask(const tracked_objects::Location
& from_here
,
129 const base::Closure
& task
) = 0;
132 // T is expected to be something CWindowImpl derived, or at least to have
133 // PostMessage(UINT, WPARAM) method. Do not forget to CHAIN_MSG_MAP
134 template <class T
> class TaskMarshallerThroughWindowsMessages
135 : public TaskMarshaller
{
137 TaskMarshallerThroughWindowsMessages() {}
138 virtual void PostTask(const tracked_objects::Location
& posted_from
,
139 const base::Closure
& task
) OVERRIDE
{
140 T
* this_ptr
= static_cast<T
*>(this);
141 if (this_ptr
->IsWindow()) {
143 base::PendingTask
* pending_task
=
144 new base::PendingTask(posted_from
, task
);
145 PushTask(pending_task
);
146 this_ptr
->PostMessage(MSG_EXECUTE_TASK
,
147 reinterpret_cast<WPARAM
>(pending_task
));
149 DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
154 ~TaskMarshallerThroughWindowsMessages() {
155 DeleteAllPendingTasks();
158 void DeleteAllPendingTasks() {
159 base::AutoLock
lock(lock_
);
160 DVLOG_IF(1, !pending_tasks_
.empty()) << "Destroying "
161 << pending_tasks_
.size()
163 while (!pending_tasks_
.empty()) {
164 base::PendingTask
* task
= pending_tasks_
.front();
165 pending_tasks_
.pop();
170 BEGIN_MSG_MAP(PostMessageMarshaller
)
171 MESSAGE_HANDLER(MSG_EXECUTE_TASK
, ExecuteTask
)
175 enum { MSG_EXECUTE_TASK
= WM_APP
+ 6 };
176 inline LRESULT
ExecuteTask(UINT
, WPARAM wparam
, LPARAM
,
177 BOOL
& handled
) { // NOLINT
178 base::PendingTask
* pending_task
=
179 reinterpret_cast<base::PendingTask
*>(wparam
);
180 if (pending_task
&& PopTask(pending_task
)) {
181 pending_task
->task
.Run();
185 T
* this_ptr
= static_cast<T
*>(this);
190 inline void PushTask(base::PendingTask
* pending_task
) {
191 base::AutoLock
lock(lock_
);
192 pending_tasks_
.push(pending_task
);
195 // If |pending_task| is front of the queue, removes the task and returns true,
196 // otherwise we assume this is an already destroyed task (but Window message
197 // had remained in the thread queue).
198 inline bool PopTask(base::PendingTask
* pending_task
) {
199 base::AutoLock
lock(lock_
);
200 if (!pending_tasks_
.empty() && pending_task
== pending_tasks_
.front()) {
201 pending_tasks_
.pop();
209 std::queue
<base::PendingTask
*> pending_tasks_
;
212 #endif // CHROME_FRAME_CHROME_FRAME_DELEGATE_H_