forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathchrome_frame_delegate.h
169 lines (142 loc) · 5.09 KB
/
chrome_frame_delegate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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_CHROME_FRAME_DELEGATE_H_
#define CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
#include <atlbase.h>
#include <atlwin.h>
#include <queue>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/pending_task.h"
#include "base/synchronization/lock.h"
#include "chrome/common/automation_constants.h"
#include "ipc/ipc_message.h"
class GURL;
struct ContextMenuModel;
namespace net {
class URLRequestStatus;
}
namespace gfx {
class Rect;
}
// A common interface supported by all the browser specific ChromeFrame
// implementations.
class ChromeFrameDelegate {
public:
typedef HWND WindowType;
virtual WindowType GetWindow() const = 0;
virtual void GetBounds(RECT* bounds) = 0;
virtual std::string GetDocumentUrl() = 0;
virtual void OnAutomationServerReady() = 0;
virtual void OnAutomationServerLaunchFailed(
AutomationLaunchResult reason, const std::string& server_version) = 0;
virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
virtual void OnChannelError() = 0;
// This remains in interface since we call it if Navigate()
// returns immediate error.
virtual void OnLoadFailed(int error_code, const std::string& url) = 0;
// Returns true if this instance is alive and well for processing automation
// messages.
virtual bool IsValid() const = 0;
protected:
virtual ~ChromeFrameDelegate() {}
};
extern UINT kAutomationServerReady;
extern UINT kMessageFromChromeFrame;
class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
public:
virtual WindowType GetWindow() { return NULL; }
virtual void GetBounds(RECT* bounds) {}
virtual std::string GetDocumentUrl() { return std::string(); }
virtual void OnAutomationServerReady() {}
virtual void OnAutomationServerLaunchFailed(
AutomationLaunchResult reason, const std::string& server_version) {}
virtual void OnLoadFailed(int error_code, const std::string& url) {}
virtual bool OnMessageReceived(const IPC::Message& msg);
virtual void OnChannelError() {}
static bool IsTabMessage(const IPC::Message& message);
virtual bool IsValid() const {
return true;
}
};
// This interface enables tasks to be marshaled to desired threads.
class TaskMarshaller { // NOLINT
public:
virtual void PostTask(const tracked_objects::Location& from_here,
const base::Closure& task) = 0;
};
// T is expected to be something CWindowImpl derived, or at least to have
// PostMessage(UINT, WPARAM) method. Do not forget to CHAIN_MSG_MAP
template <class T> class TaskMarshallerThroughWindowsMessages
: public TaskMarshaller {
public:
TaskMarshallerThroughWindowsMessages() {}
virtual void PostTask(const tracked_objects::Location& posted_from,
const base::Closure& task) OVERRIDE {
T* this_ptr = static_cast<T*>(this);
if (this_ptr->IsWindow()) {
this_ptr->AddRef();
base::PendingTask* pending_task =
new base::PendingTask(posted_from, task);
PushTask(pending_task);
this_ptr->PostMessage(MSG_EXECUTE_TASK,
reinterpret_cast<WPARAM>(pending_task));
} else {
DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
}
}
protected:
~TaskMarshallerThroughWindowsMessages() {
DeleteAllPendingTasks();
}
void DeleteAllPendingTasks() {
base::AutoLock lock(lock_);
DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying "
<< pending_tasks_.size()
<< " pending tasks";
while (!pending_tasks_.empty()) {
base::PendingTask* task = pending_tasks_.front();
pending_tasks_.pop();
delete task;
}
}
BEGIN_MSG_MAP(PostMessageMarshaller)
MESSAGE_HANDLER(MSG_EXECUTE_TASK, ExecuteTask)
END_MSG_MAP()
private:
enum { MSG_EXECUTE_TASK = WM_APP + 6 };
inline LRESULT ExecuteTask(UINT, WPARAM wparam, LPARAM,
BOOL& handled) { // NOLINT
base::PendingTask* pending_task =
reinterpret_cast<base::PendingTask*>(wparam);
if (pending_task && PopTask(pending_task)) {
pending_task->task.Run();
delete pending_task;
}
T* this_ptr = static_cast<T*>(this);
this_ptr->Release();
return 0;
}
inline void PushTask(base::PendingTask* pending_task) {
base::AutoLock lock(lock_);
pending_tasks_.push(pending_task);
}
// If |pending_task| is front of the queue, removes the task and returns true,
// otherwise we assume this is an already destroyed task (but Window message
// had remained in the thread queue).
inline bool PopTask(base::PendingTask* pending_task) {
base::AutoLock lock(lock_);
if (!pending_tasks_.empty() && pending_task == pending_tasks_.front()) {
pending_tasks_.pop();
return true;
}
return false;
}
base::Lock lock_;
std::queue<base::PendingTask*> pending_tasks_;
};
#endif // CHROME_FRAME_CHROME_FRAME_DELEGATE_H_