1 // Copyright (c) 2009 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_NPAPI_H_
6 #define CHROME_FRAME_CHROME_FRAME_NPAPI_H_
12 #include "chrome_frame/chrome_frame_automation.h"
13 #include "chrome_frame/chrome_frame_plugin.h"
14 #include "chrome_frame/np_browser_functions.h"
15 #include "chrome_frame/np_event_listener.h"
16 #include "chrome_frame/np_proxy_service.h"
17 #include "chrome_frame/npapi_url_request.h"
20 class nsICookieService
;
23 // ChromeFrameNPAPI: Implementation of the NPAPI plugin, which is responsible
24 // for hosting a chrome frame, i.e. an iframe like widget which hosts the the
25 // chrome window. This object delegates to Chrome.exe (via the Chrome
26 // IPC-based automation mechanism) for the actual rendering.
27 class ChromeFrameNPAPI
28 : public CWindowImpl
<ChromeFrameNPAPI
>,
29 public ChromeFramePlugin
<ChromeFrameNPAPI
>,
30 public NpEventDelegate
{
32 typedef ChromeFramePlugin
<ChromeFrameNPAPI
> Base
;
34 // NPObject structure which is exposed by us.
35 struct ChromeFrameNPObject
: public NPObject
{
37 ChromeFrameNPAPI
* chrome_frame_plugin_instance
;
41 PLUGIN_PROPERTY_VERSION
,
43 PLUGIN_PROPERTY_ONLOAD
,
44 PLUGIN_PROPERTY_ONERROR
,
45 PLUGIN_PROPERTY_ONMESSAGE
,
46 PLUGIN_PROPERTY_READYSTATE
,
47 PLUGIN_PROPERTY_ONPRIVATEMESSAGE
,
48 PLUGIN_PROPERTY_USECHROMENETWORK
,
49 PLUGIN_PROPERTY_COUNT
// must be last
52 static const int kWmSwitchFocusToChromeFrame
= WM_APP
+ 0x100;
54 static NPClass plugin_class_
;
55 static NPClass
* PluginClass() {
56 return &plugin_class_
;
62 bool Initialize(NPMIMEType mime_type
, NPP instance
, uint16 mode
,
63 int16 argc
, char* argn
[], char* argv
[]);
66 bool SetWindow(NPWindow
* window_info
);
67 void UrlNotify(const char* url
, NPReason reason
, void* notify_data
);
68 NPError
NewStream(NPMIMEType type
, NPStream
* stream
, NPBool seekable
,
70 int32
WriteReady(NPStream
* stream
);
71 int32
Write(NPStream
* stream
, int32 offset
, int32 len
, void* buffer
);
72 NPError
DestroyStream(NPStream
* stream
, NPReason reason
);
74 void Print(NPPrint
* print_info
);
76 // NPObject functions, which ensure that the plugin object is scriptable.
77 static bool HasMethod(NPObject
* obj
, NPIdentifier name
);
78 static bool Invoke(NPObject
* header
, NPIdentifier name
,
79 const NPVariant
* args
, uint32_t arg_count
,
81 static NPObject
* AllocateObject(NPP instance
, NPClass
* class_name
);
82 static void DeallocateObject(NPObject
* header
);
84 // Called by the scripting environment when the native code is shutdown.
85 // Any attempt to message a NPObject instance after the invalidate callback
86 // has been called will result in undefined behavior, even if the native code
87 // is still retaining those NPObject instances.
88 static void Invalidate(NPObject
* header
);
90 // The following functions need to be implemented to ensure that FF3
91 // invokes methods on the plugin. If these methods are not implemented
92 // then invokes on the plugin NPObject from the script fail with a
93 // bad NPObject error.
94 static bool HasProperty(NPObject
* obj
, NPIdentifier name
);
95 static bool GetProperty(NPObject
* obj
, NPIdentifier name
, NPVariant
*variant
);
96 static bool SetProperty(NPObject
* obj
, NPIdentifier name
,
97 const NPVariant
*variant
);
99 // Returns the ChromeFrameNPAPI object pointer from the NPP instance structure
100 // passed in by the browser.
101 static ChromeFrameNPAPI
* ChromeFrameInstanceFromPluginInstance(NPP instance
);
103 // Returns the ChromeFrameNPAPI object pointer from the NPObject structure
104 // which represents our plugin class.
105 static ChromeFrameNPAPI
* ChromeFrameInstanceFromNPObject(void* object
);
107 BEGIN_MSG_MAP(ChromeFrameNPAPI
)
108 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
112 LRESULT
OnSetFocus(UINT message
, WPARAM wparam
, LPARAM lparam
,
113 BOOL
& handled
); // NO_LINT
115 // Implementation of NpEventDelegate
116 virtual void OnEvent(const char* event_name
);
121 // Implementation of SetProperty, public to allow unittesting.
122 bool SetProperty(NPIdentifier name
, const NPVariant
*variant
);
123 // Implementation of GetProperty, public to allow unittesting.
124 bool GetProperty(NPIdentifier name
, NPVariant
*variant
);
126 // Initialize string->identifier mapping, public to allow unittesting.
127 static void InitializeIdentifiers();
129 bool HandleContextMenuCommand(UINT cmd
, const IPC::ContextMenuParams
& params
);
131 // Handler for accelerator messages passed on from the hosted chrome
133 virtual void OnAcceleratorPressed(int tab_handle
, const MSG
& accel_message
);
134 virtual void OnTabbedOut(int tab_handle
, bool reverse
);
135 virtual void OnOpenURL(int tab_handle
, const GURL
& url
, int open_disposition
);
136 virtual void OnLoad(int tab_handle
, const GURL
& url
);
137 virtual void OnMessageFromChromeFrame(int tab_handle
,
138 const std::string
& message
,
139 const std::string
& origin
,
140 const std::string
& target
);
141 // ChromeFrameDelegate overrides
142 virtual void OnLoadFailed(int error_code
, const std::string
& url
);
143 virtual void OnAutomationServerReady();
144 virtual void OnAutomationServerLaunchFailed(
145 AutomationLaunchResult reason
, const std::string
& server_version
);
146 virtual void OnExtensionInstalled(const FilePath
& path
,
147 void* user_data
, AutomationMsg_ExtensionResponseValues response
);
148 virtual void OnGetEnabledExtensionsComplete(
150 const std::vector
<FilePath
>& extension_directories
);
153 void SubscribeToFocusEvents();
154 void UnsubscribeFromFocusEvents();
157 // event = window.document.createEvent("Event");
158 // event.initEvent(type, bubbles, cancelable);
159 // and then returns the event object.
160 bool CreateEvent(const std::string
& type
, bool bubbles
, bool cancelable
,
161 NPObject
** basic_event
);
163 // Creates and initializes an event object of type "message".
164 // Used for postMessage.
165 bool CreateMessageEvent(bool bubbles
, bool cancelable
,
166 const std::string
& data
, const std::string
& origin
,
167 NPObject
** message_event
);
169 // Calls chrome_frame.dispatchEvent to fire events to event listeners.
170 void DispatchEvent(NPObject
* event
);
172 // Returns a pointer to the <object> element in the page that
173 // hosts the plugin. Note that this is the parent element of the <embed>
174 // element. The <embed> element doesn't support some of the events that
175 // we require, so we use the object element for receiving events.
176 bool GetObjectElement(nsIDOMElement
** element
);
178 // Prototype for all methods that can be invoked from script.
179 typedef bool (ChromeFrameNPAPI::*PluginMethod
)(NPObject
* npobject
,
180 const NPVariant
* args
,
184 // Implementations of scriptable methods.
186 bool NavigateToURL(const NPVariant
* args
, uint32_t arg_count
,
189 bool postMessage(NPObject
* npobject
, const NPVariant
* args
,
190 uint32_t arg_count
, NPVariant
* result
);
192 // This method is only available when the control is in privileged mode.
193 bool postPrivateMessage(NPObject
* npobject
, const NPVariant
* args
,
194 uint32_t arg_count
, NPVariant
* result
);
196 // This method is only available when the control is in privileged mode.
197 bool installExtension(NPObject
* npobject
, const NPVariant
* args
,
198 uint32_t arg_count
, NPVariant
* result
);
200 // This method is only available when the control is in privileged mode.
201 bool loadExtension(NPObject
* npobject
, const NPVariant
* args
,
202 uint32_t arg_count
, NPVariant
* result
);
204 // This method is only available when the control is in privileged mode.
205 bool enableExtensionAutomation(NPObject
* npobject
, const NPVariant
* args
,
206 uint32_t arg_count
, NPVariant
* result
);
208 // This method is only available when the control is in privileged mode.
209 bool getEnabledExtensions(NPObject
* npobject
, const NPVariant
* args
,
210 uint32_t arg_count
, NPVariant
* result
);
212 // Pointers to method implementations.
213 static PluginMethod plugin_methods_
[];
215 // NPObject method ids exposed by the plugin.
216 static NPIdentifier plugin_method_identifiers_
[];
218 // NPObject method names exposed by the plugin.
219 static const NPUTF8
* plugin_method_identifier_names_
[];
221 // NPObject property ids exposed by the plugin.
222 static NPIdentifier plugin_property_identifiers_
[];
224 // NPObject property names exposed by the plugin.
226 plugin_property_identifier_names_
[];
228 virtual void OnFinalMessage(HWND window
);
230 // Helper function to invoke a function on a NPObject.
231 bool InvokeDefault(NPObject
* object
, const std::string
& param
,
234 bool InvokeDefault(NPObject
* object
, const NPVariant
& param
,
237 bool InvokeDefault(NPObject
* object
, unsigned param_count
,
238 const NPVariant
* params
, NPVariant
* result
);
240 // Helper function to convert javascript code to a NPObject we can
242 virtual NPObject
* JavascriptToNPObject(const std::string
& function_name
);
244 // Helper function to execute a script.
245 // Returns S_OK on success.
246 bool ExecuteScript(const std::string
& script
, NPVariant
* result
);
248 // Returns true if the script passed in is a valid function in the DOM.
249 bool IsValidJavascriptFunction(const std::string
& script
);
251 // Converts the data parameter to an NPVariant and forwards the call to the
252 // other FireEvent method.
253 void FireEvent(const std::string
& event_type
, const std::string
& data
);
255 // Creates an event object, assigns the data parameter to a |data| property
256 // on the event object and then calls DispatchEvent to fire the event to
257 // listeners. event_type is the name of the event being fired.
258 void FireEvent(const std::string
& event_type
, const NPVariant
& data
);
260 // Returns a new prefs service. Virtual to allow overriding in unittests.
261 virtual NpProxyService
* CreatePrefService();
263 // Returns our associated windows' location.
264 virtual std::string
GetLocation();
266 // Returns true iff we're successfully able to query for the browser's
267 // incognito mode, and the browser returns true.
268 virtual bool GetBrowserIncognitoMode();
270 // Returns the window script object for the page.
271 // This function will cache the window object to avoid calling
272 // npapi::GetValue which can cause problems in Opera.
273 NPObject
* GetWindowObject() const;
275 virtual void SetReadyState(READYSTATE new_state
) {
276 ready_state_
= new_state
;
278 INT32_TO_NPVARIANT(ready_state_
, var
);
279 FireEvent("readystatechanged", var
);
282 // Host function to compile-time asserts over members of this class.
283 static void CompileAsserts();
285 static LRESULT CALLBACK
DropKillFocusHook(int code
, WPARAM wparam
,
286 LPARAM lparam
); // NO_LINT
288 // The plugins opaque instance handle
291 // The plugin instantiation mode (NP_FULL or NP_EMBED)
293 // The plugins mime type.
294 std::string mime_type_
;
296 // Set to true if we need a full page plugin.
297 bool force_full_page_plugin_
;
299 scoped_refptr
<NpProxyService
> pref_service_
;
301 // Used to receive focus and blur events from the object element
302 // that hosts the plugin.
303 scoped_refptr
<NpEventListener
> focus_listener_
;
305 // In some cases the IPC channel proxy object is instantiated on the UI
306 // thread in FF. It then tries to use the IPC logger, which relies on
307 // the message loop being around. Declaring a dummy message loop
308 // is a hack to get around this. Eventually the automation code needs to
309 // be fixed to ensure that the channel proxy always gets created on a thread
310 // with a message loop.
311 static MessageLoop
* message_loop_
;
312 static int instance_count_
;
314 // The following members contain the NPObject pointers representing the
315 // onload/onerror/onmessage handlers on the page.
316 ScopedNpObject
<NPObject
> onerror_handler_
;
317 ScopedNpObject
<NPObject
> onmessage_handler_
;
318 ScopedNpObject
<NPObject
> onprivatemessage_handler_
;
320 // As a workaround for a problem in Opera we cache the window object.
321 // The problem stems from two things: window messages aren't always removed
322 // from the message queue and messages can be pumped inside GetValue.
323 // This can cause an infinite recursion of processing the same message
325 mutable ScopedNpObject
<NPObject
> window_object_
;
327 // Note since 'onload' is a registered event name, the browser will
328 // automagically create a code block for the handling code and hook it
329 // up to the CF object via addEventListener.
330 // See this list of known event types:
331 // http://www.w3.org/TR/DOM-Level-3-Events/events.html#Event-types
333 READYSTATE ready_state_
;
336 // Popups are enabled
337 bool enabled_popups_
;
339 // The value of src property keeping the current URL.
341 // Used to fetch network resources when host network stack is in use.
342 NPAPIUrlRequestManager url_fetcher_
;
345 #endif // CHROME_FRAME_CHROME_FRAME_NPAPI_H_