blob: 856fcb84510acd120440dd819bc6f0fa3ce5f094 [file] [log] [blame]
[email protected]27a112c2011-01-06 04:19:301// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]f7817822009-09-24 05:11:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
6#define CHROME_FRAME_CHROME_FRAME_DELEGATE_H_
[email protected]27a112c2011-01-06 04:19:307#pragma once
[email protected]f7817822009-09-24 05:11:588
[email protected]5778de6e2009-10-24 01:29:209#include <atlbase.h>
10#include <atlwin.h>
[email protected]4c3fe4ae2010-03-01 20:01:2411#include <queue>
[email protected]efd4dfc22010-03-26 20:14:4012#include <string>
13#include <vector>
[email protected]5778de6e2009-10-24 01:29:2014
[email protected]bb04c4e2011-11-18 20:44:2215#include "base/callback.h"
[email protected]a1e62d12010-03-16 02:18:4316#include "base/file_path.h"
[email protected]c62dd9d2011-09-21 18:05:4117#include "base/location.h"
[email protected]bb04c4e2011-11-18 20:44:2218#include "base/pending_task.h"
[email protected]20305ec2011-01-21 04:55:5219#include "base/synchronization/lock.h"
[email protected]a22f7e02011-02-09 07:15:3520#include "chrome/common/automation_constants.h"
[email protected]f7817822009-09-24 05:11:5821#include "ipc/ipc_message.h"
22
[email protected]a22f7e02011-02-09 07:15:3523class GURL;
24struct AttachExternalTabParams;
25struct AutomationURLRequest;
[email protected]b516e2d2011-07-12 16:54:1226struct ContextMenuModel;
[email protected]a22f7e02011-02-09 07:15:3527struct MiniContextMenuParams;
28struct NavigationInfo;
29
30namespace net {
31class URLRequestStatus;
32}
33
[email protected]326d3b72011-03-29 20:38:2434namespace gfx {
35class Rect;
36}
37
[email protected]f7817822009-09-24 05:11:5838// A common interface supported by all the browser specific ChromeFrame
39// implementations.
40class ChromeFrameDelegate {
41 public:
[email protected]f7817822009-09-24 05:11:5842 typedef HWND WindowType;
43
44 virtual WindowType GetWindow() const = 0;
45 virtual void GetBounds(RECT* bounds) = 0;
46 virtual std::string GetDocumentUrl() = 0;
47 virtual void OnAutomationServerReady() = 0;
48 virtual void OnAutomationServerLaunchFailed(
49 AutomationLaunchResult reason, const std::string& server_version) = 0;
[email protected]a95986a82010-12-24 06:19:2850 virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
[email protected]efd4dfc22010-03-26 20:14:4051 virtual void OnChannelError() = 0;
[email protected]f7817822009-09-24 05:11:5852
53 // This remains in interface since we call it if Navigate()
54 // returns immediate error.
55 virtual void OnLoadFailed(int error_code, const std::string& url) = 0;
56
57 // Returns true if this instance is alive and well for processing automation
58 // messages.
59 virtual bool IsValid() const = 0;
60
[email protected]2b19e2fe2010-02-16 02:24:1861 // To be called when the top-most window of an application hosting
62 // ChromeFrame is moved.
63 virtual void OnHostMoved() = 0;
64
[email protected]f7817822009-09-24 05:11:5865 protected:
[email protected]efd4dfc22010-03-26 20:14:4066 virtual ~ChromeFrameDelegate() {}
[email protected]f7817822009-09-24 05:11:5867};
68
[email protected]f7817822009-09-24 05:11:5869extern UINT kAutomationServerReady;
70extern UINT kMessageFromChromeFrame;
71
72class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
73 public:
74 virtual WindowType GetWindow() { return NULL; }
75 virtual void GetBounds(RECT* bounds) {}
76 virtual std::string GetDocumentUrl() { return std::string(); }
77 virtual void OnAutomationServerReady() {}
78 virtual void OnAutomationServerLaunchFailed(
79 AutomationLaunchResult reason, const std::string& server_version) {}
80 virtual void OnLoadFailed(int error_code, const std::string& url) {}
[email protected]a95986a82010-12-24 06:19:2881 virtual bool OnMessageReceived(const IPC::Message& msg);
[email protected]efd4dfc22010-03-26 20:14:4082 virtual void OnChannelError() {}
[email protected]00f6b772009-10-23 17:03:4183
[email protected]f5494d42010-12-23 22:15:3484 static bool IsTabMessage(const IPC::Message& message);
[email protected]f7817822009-09-24 05:11:5885
86 virtual bool IsValid() const {
87 return true;
88 }
89
[email protected]2b19e2fe2010-02-16 02:24:1890 virtual void OnHostMoved() {}
91
[email protected]f7817822009-09-24 05:11:5892 protected:
[email protected]bb04c4e2011-11-18 20:44:2293 // Protected methods to be overridden.
[email protected]f5494d42010-12-23 22:15:3494 virtual void OnNavigationStateChanged(
95 int flags, const NavigationInfo& nav_info) {}
96 virtual void OnUpdateTargetUrl(const std::wstring& new_target_url) {}
97 virtual void OnAcceleratorPressed(const MSG& accel_message) {}
98 virtual void OnTabbedOut(bool reverse) {}
99 virtual void OnOpenURL(
100 const GURL& url, const GURL& referrer, int open_disposition) {}
101 virtual void OnDidNavigate(const NavigationInfo& navigation_info) {}
102 virtual void OnNavigationFailed(int error_code, const GURL& gurl) {}
103 virtual void OnLoad(const GURL& url) {}
[email protected]326d3b72011-03-29 20:38:24104 virtual void OnMoveWindow(const gfx::Rect& pos) {}
[email protected]f5494d42010-12-23 22:15:34105 virtual void OnMessageFromChromeFrame(const std::string& message,
[email protected]f7817822009-09-24 05:11:58106 const std::string& origin,
107 const std::string& target) {}
[email protected]b516e2d2011-07-12 16:54:12108 virtual void OnHandleContextMenu(const ContextMenuModel& context_menu_model,
109 int align_flags,
[email protected]f5494d42010-12-23 22:15:34110 const MiniContextMenuParams& params) {}
111 virtual void OnRequestStart(
112 int request_id, const AutomationURLRequest& request) {}
113 virtual void OnRequestRead(int request_id, int bytes_to_read) {}
[email protected]27a112c2011-01-06 04:19:30114 virtual void OnRequestEnd(int request_id,
115 const net::URLRequestStatus& status) {}
[email protected]f5494d42010-12-23 22:15:34116 virtual void OnDownloadRequestInHost(int request_id) {}
117 virtual void OnSetCookieAsync(const GURL& url, const std::string& cookie) {}
118 virtual void OnAttachExternalTab(
119 const AttachExternalTabParams& attach_params) {}
120 virtual void OnGoToHistoryEntryOffset(int offset) {}
[email protected]70daf0b2010-03-02 19:13:00121
[email protected]f5494d42010-12-23 22:15:34122 virtual void OnGetCookiesFromHost(const GURL& url, int cookie_id) {}
123 virtual void OnCloseTab() {}
[email protected]f7817822009-09-24 05:11:58124};
125
[email protected]efd4dfc22010-03-26 20:14:40126// This interface enables tasks to be marshaled to desired threads.
127class TaskMarshaller { // NOLINT
[email protected]5778de6e2009-10-24 01:29:20128 public:
129 virtual void PostTask(const tracked_objects::Location& from_here,
[email protected]bb04c4e2011-11-18 20:44:22130 const base::Closure& task) = 0;
[email protected]5778de6e2009-10-24 01:29:20131};
132
133// T is expected to be something CWindowImpl derived, or at least to have
134// PostMessage(UINT, WPARAM) method. Do not forget to CHAIN_MSG_MAP
135template <class T> class TaskMarshallerThroughWindowsMessages
136 : public TaskMarshaller {
137 public:
[email protected]4c3fe4ae2010-03-01 20:01:24138 TaskMarshallerThroughWindowsMessages() {}
[email protected]bb04c4e2011-11-18 20:44:22139 virtual void PostTask(const tracked_objects::Location& posted_from,
140 const base::Closure& task) OVERRIDE {
[email protected]5778de6e2009-10-24 01:29:20141 T* this_ptr = static_cast<T*>(this);
142 if (this_ptr->IsWindow()) {
143 this_ptr->AddRef();
[email protected]bb04c4e2011-11-18 20:44:22144 base::PendingTask* pending_task =
145 new base::PendingTask(posted_from, task);
146 PushTask(pending_task);
147 this_ptr->PostMessage(MSG_EXECUTE_TASK,
148 reinterpret_cast<WPARAM>(pending_task));
[email protected]5778de6e2009-10-24 01:29:20149 } else {
[email protected]2b9a9f162010-10-19 20:30:45150 DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
[email protected]4c3fe4ae2010-03-01 20:01:24151 }
152 }
153
[email protected]4c3fe4ae2010-03-01 20:01:24154 protected:
155 ~TaskMarshallerThroughWindowsMessages() {
156 DeleteAllPendingTasks();
157 }
158
159 void DeleteAllPendingTasks() {
[email protected]20305ec2011-01-21 04:55:52160 base::AutoLock lock(lock_);
[email protected]5044da82010-10-27 01:09:16161 DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying "
162 << pending_tasks_.size()
163 << " pending tasks";
[email protected]4c3fe4ae2010-03-01 20:01:24164 while (!pending_tasks_.empty()) {
[email protected]bb04c4e2011-11-18 20:44:22165 base::PendingTask* task = pending_tasks_.front();
[email protected]4c3fe4ae2010-03-01 20:01:24166 pending_tasks_.pop();
167 delete task;
[email protected]5778de6e2009-10-24 01:29:20168 }
169 }
170
171 BEGIN_MSG_MAP(PostMessageMarshaller)
172 MESSAGE_HANDLER(MSG_EXECUTE_TASK, ExecuteTask)
173 END_MSG_MAP()
174
175 private:
176 enum { MSG_EXECUTE_TASK = WM_APP + 6 };
177 inline LRESULT ExecuteTask(UINT, WPARAM wparam, LPARAM,
178 BOOL& handled) { // NOLINT
[email protected]bb04c4e2011-11-18 20:44:22179 base::PendingTask* pending_task =
180 reinterpret_cast<base::PendingTask*>(wparam);
181 if (pending_task && PopTask(pending_task)) {
182 pending_task->task.Run();
183 delete pending_task;
[email protected]3148c0ae2010-03-11 18:06:00184 }
185
[email protected]5778de6e2009-10-24 01:29:20186 T* this_ptr = static_cast<T*>(this);
187 this_ptr->Release();
188 return 0;
189 }
[email protected]4c3fe4ae2010-03-01 20:01:24190
[email protected]bb04c4e2011-11-18 20:44:22191 inline void PushTask(base::PendingTask* pending_task) {
[email protected]20305ec2011-01-21 04:55:52192 base::AutoLock lock(lock_);
[email protected]bb04c4e2011-11-18 20:44:22193 pending_tasks_.push(pending_task);
[email protected]4c3fe4ae2010-03-01 20:01:24194 }
195
[email protected]bb04c4e2011-11-18 20:44:22196 // If |pending_task| is front of the queue, removes the task and returns true,
[email protected]3148c0ae2010-03-11 18:06:00197 // otherwise we assume this is an already destroyed task (but Window message
198 // had remained in the thread queue).
[email protected]bb04c4e2011-11-18 20:44:22199 inline bool PopTask(base::PendingTask* pending_task) {
[email protected]20305ec2011-01-21 04:55:52200 base::AutoLock lock(lock_);
[email protected]bb04c4e2011-11-18 20:44:22201 if (!pending_tasks_.empty() && pending_task == pending_tasks_.front()) {
[email protected]3148c0ae2010-03-11 18:06:00202 pending_tasks_.pop();
203 return true;
204 }
205
206 return false;
[email protected]4c3fe4ae2010-03-01 20:01:24207 }
208
[email protected]20305ec2011-01-21 04:55:52209 base::Lock lock_;
[email protected]bb04c4e2011-11-18 20:44:22210 std::queue<base::PendingTask*> pending_tasks_;
[email protected]5778de6e2009-10-24 01:29:20211};
212
[email protected]f7817822009-09-24 05:11:58213#endif // CHROME_FRAME_CHROME_FRAME_DELEGATE_H_