1// Copyright (c) 2012 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.
4
5#ifndef CHROME_FRAME_CHROME_FRAME_ACTIVEX_H_
6#define CHROME_FRAME_CHROME_FRAME_ACTIVEX_H_
7
8#include <atlbase.h>
9#include <atlcom.h>
10#include <atlctl.h>
11
12#include <set>
13#include <string>
14#include <vector>
15
16#include "chrome_frame/chrome_frame_activex_base.h"
17#include "chrome_frame/chrome_tab.h"
18#include "chrome_frame/com_type_info_holder.h"
19#include "grit/chrome_frame_resources.h"
20
21#define WM_HOST_MOVED_NOTIFICATION (WM_APP + 1)
22
23// ChromeFrameActivex: Implementation of the ActiveX control that is
24// responsible for hosting a chrome frame, i.e. an iframe like widget which
25// hosts the the chrome window. This object delegates to Chrome.exe
26// (via the Chrome IPC-based automation mechanism) for the actual rendering.
27class ATL_NO_VTABLE ChromeFrameActivex
28    : public ChromeFrameActivexBase<ChromeFrameActivex, CLSID_ChromeFrame>,
29      public IObjectSafetyImpl<ChromeFrameActivex,
30                                 INTERFACESAFE_FOR_UNTRUSTED_CALLER |
31                                 INTERFACESAFE_FOR_UNTRUSTED_DATA>,
32      public IObjectWithSiteImpl<ChromeFrameActivex>,
33      public IPersistPropertyBag {
34 public:
35  typedef ChromeFrameActivexBase<ChromeFrameActivex, CLSID_ChromeFrame> Base;
36  ChromeFrameActivex();
37  ~ChromeFrameActivex();
38
39DECLARE_REGISTRY_RESOURCEID(IDR_CHROMEFRAME_ACTIVEX)
40
41BEGIN_COM_MAP(ChromeFrameActivex)
42  COM_INTERFACE_ENTRY(IObjectWithSite)
43  COM_INTERFACE_ENTRY(IObjectSafety)
44  COM_INTERFACE_ENTRY(IPersist)
45  COM_INTERFACE_ENTRY(IPersistPropertyBag)
46  COM_INTERFACE_ENTRY_CHAIN(Base)
47END_COM_MAP()
48
49BEGIN_MSG_MAP(ChromeFrameActivex)
50  MESSAGE_HANDLER(WM_CREATE, OnCreate)
51  MESSAGE_HANDLER(WM_HOST_MOVED_NOTIFICATION, OnHostMoved)
52  CHAIN_MSG_MAP(Base)
53END_MSG_MAP()
54
55  HRESULT FinalConstruct();
56
57  virtual HRESULT OnDraw(ATL_DRAWINFO& draw_info);  // NOLINT
58
59  // IPersistPropertyBag implementation
60  STDMETHOD(GetClassID)(CLSID* class_id) {
61    if (class_id != NULL)
62      *class_id = GetObjectCLSID();
63    return S_OK;
64  }
65
66  STDMETHOD(InitNew)() {
67    return S_OK;
68  }
69
70  STDMETHOD(Load)(IPropertyBag* bag, IErrorLog* error_log);
71
72  STDMETHOD(Save)(IPropertyBag* bag, BOOL clear_dirty, BOOL save_all) {
73    return E_NOTIMPL;
74  }
75
76  // Used to setup the document_url_ member needed for completing navigation.
77  // Create external tab (possibly in incognito mode).
78  HRESULT IOleObject_SetClientSite(IOleClientSite* client_site);
79
80  // Overridden to perform security checks.
81  STDMETHOD(put_src)(BSTR src);
82
83  // IChromeFrame
84  // On a fresh install of ChromeFrame the BHO will not be loaded in existing
85  // IE tabs/windows. This function instantiates the BHO and registers it
86  // explicitly.
87  STDMETHOD(registerBhoIfNeeded)();
88
89 protected:
90  // ChromeFrameDelegate overrides
91  virtual void OnLoad(const GURL& url);
92  virtual void OnMessageFromChromeFrame(const std::string& message,
93                                        const std::string& origin,
94                                        const std::string& target);
95  virtual void OnLoadFailed(int error_code, const std::string& url);
96  virtual void OnAutomationServerLaunchFailed(
97      AutomationLaunchResult reason, const std::string& server_version);
98  virtual void OnChannelError();
99
100  // Separated to static function for unit testing this logic more easily.
101  static bool ShouldShowVersionMismatchDialog(bool is_privileged,
102                                              IOleClientSite* client_site);
103
104 private:
105  LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam,
106                   BOOL& handled);  // NO_LINT
107  LRESULT OnHostMoved(UINT message, WPARAM wparam, LPARAM lparam,
108                      BOOL& handled);  // NO_LINT
109
110  HRESULT GetContainingDocument(IHTMLDocument2** doc);
111  HRESULT GetDocumentWindow(IHTMLWindow2** window);
112
113  // Gets the value of the 'id' attribute of the object element.
114  HRESULT GetObjectScriptId(IHTMLObjectElement* object_elem, BSTR* id);
115
116  // Returns the object element in the HTML page.
117  // Note that if we're not being hosted inside an HTML
118  // document, then this call will fail.
119  HRESULT GetObjectElement(IHTMLObjectElement** element);
120
121  HRESULT CreateScriptBlockForEvent(IHTMLElement2* insert_after,
122                                    BSTR instance_id, BSTR script,
123                                    BSTR event_name);
124
125  // Utility function that checks the size of the vector and if > 0 creates
126  // a variant for the string argument and forwards the call to the other
127  // FireEvent method.
128  void FireEvent(const EventHandlers& handlers, const std::string& arg);
129
130  // Invokes all registered handlers in a vector of event handlers.
131  void FireEvent(const EventHandlers& handlers, IDispatch* event);
132
133  // This variant is used for the privatemessage handler only.
134  void FireEvent(const EventHandlers& handlers, IDispatch* event,
135                 BSTR target);
136
137  // Installs a hook on the top-level window hosting the control.
138  HRESULT InstallTopLevelHook(IOleClientSite* client_site);
139
140  // A hook attached to the top-level window containing the ActiveX control.
141  HHOOK chrome_wndproc_hook_;
142
143  // Set to true if the current instance is attaching to an existing Chrome
144  // tab. This occurs when a window.open request is performed by Chrome.
145  bool attaching_to_existing_cf_tab_;
146};
147
148#endif  // CHROME_FRAME_CHROME_FRAME_ACTIVEX_H_
149