chromeos: dbus: add Bluetooth properties support
[chromium-blink-merge.git] / chrome_frame / chrome_frame_plugin.h
bloba6066f9c3b71a1a46dfadceceb8406057ab7a234
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_PLUGIN_H_
6 #define CHROME_FRAME_CHROME_FRAME_PLUGIN_H_
8 #include <string>
9 #include <vector>
11 #include "base/memory/ref_counted.h"
12 #include "base/win/win_util.h"
13 #include "chrome_frame/chrome_frame_automation.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/chrome_paths_internal.h"
16 #include "chrome_frame/simple_resource_loader.h"
17 #include "chrome_frame/navigation_constraints.h"
18 #include "chrome_frame/utils.h"
19 #include "grit/chromium_strings.h"
21 #define IDC_ABOUT_CHROME_FRAME 40018
23 // Helper so that this file doesn't include the messages header.
24 void ChromeFramePluginGetParamsCoordinates(
25 const MiniContextMenuParams& params,
26 int* x,
27 int* y);
29 // A class to implement common functionality for all types of
30 // plugins: ActiveX and ActiveDoc
31 template <typename T>
32 class ChromeFramePlugin
33 : public ChromeFrameDelegateImpl,
34 public NavigationConstraintsImpl {
35 public:
36 ChromeFramePlugin() : ignore_setfocus_(false){
38 ~ChromeFramePlugin() {
39 Uninitialize();
42 BEGIN_MSG_MAP(T)
43 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
44 MESSAGE_HANDLER(WM_SIZE, OnSize)
45 MESSAGE_HANDLER(WM_PARENTNOTIFY, OnParentNotify)
46 END_MSG_MAP()
48 bool Initialize() {
49 DVLOG(1) << __FUNCTION__;
50 DCHECK(!automation_client_.get());
51 automation_client_ = CreateAutomationClient();
52 if (!automation_client_.get()) {
53 NOTREACHED() << "new ChromeFrameAutomationClient";
54 return false;
57 return true;
60 void Uninitialize() {
61 DVLOG(1) << __FUNCTION__;
62 if (IsValid()) {
63 automation_client_->Uninitialize();
64 automation_client_ = NULL;
68 bool InitializeAutomation(const std::wstring& profile_name,
69 bool incognito, bool is_widget_mode,
70 const GURL& url, const GURL& referrer,
71 bool route_all_top_level_navigations) {
72 DCHECK(IsValid());
73 DCHECK(launch_params_ == NULL);
74 // We don't want to do incognito when privileged, since we're
75 // running in browser chrome or some other privileged context.
76 bool incognito_mode = !is_privileged() && incognito;
77 FilePath profile_path;
78 GetProfilePath(profile_name, &profile_path);
79 // The profile name could change based on the browser version. For e.g. for
80 // IE6/7 the profile is created in a different folder whose last component
81 // is Google Chrome Frame.
82 FilePath actual_profile_name = profile_path.BaseName();
83 launch_params_ = new ChromeFrameLaunchParams(url, referrer, profile_path,
84 actual_profile_name.value(), SimpleResourceLoader::GetLanguage(),
85 incognito_mode, is_widget_mode, route_all_top_level_navigations);
86 return automation_client_->Initialize(this, launch_params_);
89 // ChromeFrameDelegate implementation
90 virtual WindowType GetWindow() const {
91 return (static_cast<const T*>(this))->m_hWnd;
94 virtual void GetBounds(RECT* bounds) {
95 if (bounds) {
96 if (::IsWindow(GetWindow())) {
97 (static_cast<T*>(this))->GetClientRect(bounds);
101 virtual std::string GetDocumentUrl() {
102 return document_url_;
104 virtual void OnAutomationServerReady() {
107 virtual bool IsValid() const {
108 return automation_client_.get() != NULL;
111 virtual void OnHostMoved() {
112 if (IsValid())
113 automation_client_->OnChromeFrameHostMoved();
116 protected:
117 virtual void OnNavigationFailed(int error_code, const GURL& gurl) {
118 OnLoadFailed(error_code, gurl.spec());
121 virtual void OnHandleContextMenu(const ContextMenuModel& menu_model,
122 int align_flags,
123 const MiniContextMenuParams& params) {
124 if (!automation_client_.get()) {
125 NOTREACHED();
126 return;
129 HMENU menu = BuildContextMenu(menu_model);
130 if (!menu)
131 return;
133 T* self = static_cast<T*>(this);
134 if (self->PreProcessContextMenu(menu)) {
135 // In order for the context menu to handle keyboard input, give the
136 // ActiveX window focus.
137 ignore_setfocus_ = true;
138 SetFocus(GetWindow());
139 ignore_setfocus_ = false;
140 UINT flags = align_flags | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE;
141 int x, y;
142 ChromeFramePluginGetParamsCoordinates(params, &x, &y);
143 UINT selected = TrackPopupMenuEx(menu, flags, x, y, GetWindow(), NULL);
144 // Menu is over now give focus back to chrome
145 GiveFocusToChrome(false);
146 if (IsValid() && selected != 0 &&
147 !self->HandleContextMenuCommand(selected, params)) {
148 automation_client_->SendContextMenuCommandToChromeFrame(selected);
152 DestroyMenu(menu);
155 LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam,
156 BOOL& handled) { // NO_LINT
157 if (!ignore_setfocus_ && IsValid()) {
158 // Pass false to |restore_focus_view|, because we do not want Chrome
159 // to focus the first focusable element in the current view, only the
160 // view itself.
161 GiveFocusToChrome(false);
163 return 0;
166 LRESULT OnSize(UINT message, WPARAM wparam, LPARAM lparam,
167 BOOL& handled) { // NO_LINT
168 handled = FALSE;
169 // When we get resized, we need to resize the external tab window too.
170 if (IsValid())
171 automation_client_->Resize(LOWORD(lparam), HIWORD(lparam),
172 SWP_NOACTIVATE | SWP_NOZORDER);
173 return 0;
176 LRESULT OnParentNotify(UINT message, WPARAM wparam, LPARAM lparam,
177 BOOL& handled) { // NO_LINT
178 switch (LOWORD(wparam)) {
179 case WM_LBUTTONDOWN:
180 case WM_MBUTTONDOWN:
181 case WM_RBUTTONDOWN:
182 case WM_XBUTTONDOWN: {
183 // If we got activated via mouse click on the external tab,
184 // we need to update the state of this thread and tell the
185 // browser that we now have the focus.
186 HWND focus = ::GetFocus();
187 HWND plugin_window = GetWindow();
189 // The Chrome-Frame instance may have launched a popup which currently
190 // has focus. Because experimental extension popups are top-level
191 // windows, we have to check that the focus has shifted to a window
192 // that does not share the same GA_ROOTOWNER as the plugin.
193 if (focus != plugin_window &&
194 ::GetAncestor(plugin_window, GA_ROOTOWNER) !=
195 ::GetAncestor(focus, GA_ROOTOWNER)) {
196 ignore_setfocus_ = true;
197 SetFocus(plugin_window);
198 ignore_setfocus_ = false;
200 break;
204 return 0;
207 // Return true if context menu should be displayed. The menu could be
208 // modified as well (enable/disable commands, add/remove items).
209 // Override in most-derived class if needed.
210 bool PreProcessContextMenu(HMENU menu) {
211 // Add an "About" item.
212 AppendMenu(menu, MF_STRING, IDC_ABOUT_CHROME_FRAME,
213 SimpleResourceLoader::Get(IDS_CHROME_FRAME_MENU_ABOUT).c_str());
214 return true;
217 // Return true if menu command is processed, otherwise the command will be
218 // passed to Chrome for execution. Override in most-derived class if needed.
219 bool HandleContextMenuCommand(UINT cmd,
220 const MiniContextMenuParams& params) {
221 return false;
224 // Allow overriding the type of automation client used, for unit tests.
225 virtual ChromeFrameAutomationClient* CreateAutomationClient() {
226 return new ChromeFrameAutomationClient;
229 void GiveFocusToChrome(bool restore_focus_to_view) {
230 if (IsValid()) {
231 TabProxy* tab = automation_client_->tab();
232 HWND chrome_window = automation_client_->tab_window();
233 if (tab && ::IsWindow(chrome_window)) {
234 DVLOG(1) << "Setting initial focus";
235 tab->SetInitialFocus(base::win::IsShiftPressed(), restore_focus_to_view);
240 virtual void GetProfilePath(const std::wstring& profile_name,
241 FilePath* profile_path) {
242 chrome::GetChromeFrameUserDataDirectory(profile_path);
243 *profile_path = profile_path->Append(profile_name);
244 DVLOG(1) << __FUNCTION__ << ": " << profile_path->value();
247 protected:
248 // Our gateway to chrome land
249 scoped_refptr<ChromeFrameAutomationClient> automation_client_;
251 // How we launched Chrome.
252 scoped_refptr<ChromeFrameLaunchParams> launch_params_;
254 // Url of the containing document.
255 std::string document_url_;
257 // We set this flag when we're taking the focus ourselves
258 // and notifying the host browser that we're doing so.
259 // When the flag is not set, we transfer the focus to chrome.
260 bool ignore_setfocus_;
263 #endif // CHROME_FRAME_CHROME_FRAME_PLUGIN_H_