OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #ifndef CHROME_FRAME_CHROME_FRAME_NPAPI_H_ |
| 6 #define CHROME_FRAME_CHROME_FRAME_NPAPI_H_ |
| 7 |
| 8 #include <atlbase.h> |
| 9 #include <atlwin.h> |
| 10 #include <string> |
| 11 |
| 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" |
| 18 |
| 19 class MessageLoop; |
| 20 |
| 21 // ChromeFrameNPAPI: Implementation of the NPAPI plugin, which is responsible |
| 22 // for hosting a chrome frame, i.e. an iframe like widget which hosts the the |
| 23 // chrome window. This object delegates to Chrome.exe (via the Chrome |
| 24 // IPC-based automation mechanism) for the actual rendering. |
| 25 class ChromeFrameNPAPI |
| 26 : public CWindowImpl<ChromeFrameNPAPI>, |
| 27 public ChromeFramePlugin<ChromeFrameNPAPI>, |
| 28 public NpEventDelegate { |
| 29 public: |
| 30 typedef ChromeFramePlugin<ChromeFrameNPAPI> Base; |
| 31 |
| 32 // NPObject structure which is exposed by us. |
| 33 struct ChromeFrameNPObject : public NPObject { |
| 34 NPP npp; |
| 35 ChromeFrameNPAPI* chrome_frame_plugin_instance; |
| 36 }; |
| 37 |
| 38 typedef enum { |
| 39 PLUGIN_PROPERTY_VERSION, |
| 40 PLUGIN_PROPERTY_SRC, |
| 41 PLUGIN_PROPERTY_ONLOAD, |
| 42 PLUGIN_PROPERTY_ONERROR, |
| 43 PLUGIN_PROPERTY_ONMESSAGE, |
| 44 PLUGIN_PROPERTY_READYSTATE, |
| 45 PLUGIN_PROPERTY_ONPRIVATEMESSAGE, |
| 46 PLUGIN_PROPERTY_USECHROMENETWORK, |
| 47 PLUGIN_PROPERTY_COUNT // must be last |
| 48 } PluginPropertyId; |
| 49 |
| 50 static const int kWmSwitchFocusToChromeFrame = WM_APP + 0x100; |
| 51 |
| 52 static NPClass plugin_class_; |
| 53 static NPClass* PluginClass() { |
| 54 return &plugin_class_; |
| 55 } |
| 56 |
| 57 ChromeFrameNPAPI(); |
| 58 ~ChromeFrameNPAPI(); |
| 59 |
| 60 bool Initialize(NPMIMEType mime_type, NPP instance, uint16 mode, |
| 61 int16 argc, char* argn[], char* argv[]); |
| 62 void Uninitialize(); |
| 63 |
| 64 bool SetWindow(NPWindow* window_info); |
| 65 void UrlNotify(const char* url, NPReason reason, void* notify_data); |
| 66 bool NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, |
| 67 uint16* stream_type); |
| 68 |
| 69 void Print(NPPrint* print_info); |
| 70 |
| 71 // NPObject functions, which ensure that the plugin object is scriptable. |
| 72 static bool HasMethod(NPObject* obj, NPIdentifier name); |
| 73 static bool Invoke(NPObject* header, NPIdentifier name, |
| 74 const NPVariant* args, uint32_t arg_count, |
| 75 NPVariant* result); |
| 76 static NPObject* AllocateObject(NPP instance, NPClass* class_name); |
| 77 static void DeallocateObject(NPObject* header); |
| 78 |
| 79 // Called by the scripting environment when the native code is shutdown. |
| 80 // Any attempt to message a NPObject instance after the invalidate callback |
| 81 // has been called will result in undefined behavior, even if the native code |
| 82 // is still retaining those NPObject instances. |
| 83 static void Invalidate(NPObject* header); |
| 84 |
| 85 // The following functions need to be implemented to ensure that FF3 |
| 86 // invokes methods on the plugin. If these methods are not implemented |
| 87 // then invokes on the plugin NPObject from the script fail with a |
| 88 // bad NPObject error. |
| 89 static bool HasProperty(NPObject* obj, NPIdentifier name); |
| 90 static bool GetProperty(NPObject* obj, NPIdentifier name, NPVariant *variant); |
| 91 static bool SetProperty(NPObject* obj, NPIdentifier name, |
| 92 const NPVariant *variant); |
| 93 |
| 94 // Returns the ChromeFrameNPAPI object pointer from the NPP instance structure |
| 95 // passed in by the browser. |
| 96 static ChromeFrameNPAPI* ChromeFrameInstanceFromPluginInstance(NPP instance); |
| 97 |
| 98 // Returns the ChromeFrameNPAPI object pointer from the NPObject structure |
| 99 // which represents our plugin class. |
| 100 static ChromeFrameNPAPI* ChromeFrameInstanceFromNPObject(void* object); |
| 101 |
| 102 // Return a UrlRequest instance associated with the given instance and |
| 103 // stream combination. |
| 104 static NPAPIUrlRequest* ValidateRequest(NPP instance, void* notify_data); |
| 105 |
| 106 BEGIN_MSG_MAP(ChromeFrameNPAPI) |
| 107 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) |
| 108 CHAIN_MSG_MAP(Base) |
| 109 END_MSG_MAP() |
| 110 |
| 111 LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam, |
| 112 BOOL& handled); // NO_LINT |
| 113 |
| 114 // Implementation of NpEventDelegate |
| 115 virtual void OnEvent(const char* event_name); |
| 116 |
| 117 void OnFocus(); |
| 118 void OnBlur(); |
| 119 |
| 120 // Implementation of SetProperty, public to allow unittesting. |
| 121 bool SetProperty(NPIdentifier name, const NPVariant *variant); |
| 122 // Implementation of GetProperty, public to allow unittesting. |
| 123 bool GetProperty(NPIdentifier name, NPVariant *variant); |
| 124 |
| 125 // Initialize string->identifier mapping, public to allow unittesting. |
| 126 static void InitializeIdentifiers(); |
| 127 |
| 128 bool HandleContextMenuCommand(UINT cmd); |
| 129 protected: |
| 130 // Handler for accelerator messages passed on from the hosted chrome |
| 131 // instance. |
| 132 virtual void OnAcceleratorPressed(int tab_handle, const MSG& accel_message); |
| 133 virtual void OnTabbedOut(int tab_handle, bool reverse); |
| 134 virtual void OnOpenURL(int tab_handle, const GURL& url, int open_disposition); |
| 135 virtual void OnLoad(int tab_handle, const GURL& url); |
| 136 virtual void OnMessageFromChromeFrame(int tab_handle, |
| 137 const std::string& message, |
| 138 const std::string& origin, |
| 139 const std::string& target); |
| 140 virtual void OnRequestStart(int tab_handle, int request_id, |
| 141 const IPC::AutomationURLRequest& request); |
| 142 virtual void OnRequestRead(int tab_handle, int request_id, |
| 143 int bytes_to_read); |
| 144 virtual void OnRequestEnd(int tab_handle, int request_id, |
| 145 const URLRequestStatus& status); |
| 146 virtual void OnSetCookieAsync(int tab_handle, const GURL& url, |
| 147 const std::string& cookie); |
| 148 |
| 149 // ChromeFrameDelegate overrides |
| 150 virtual void OnLoadFailed(int error_code, const std::string& url); |
| 151 virtual void OnAutomationServerReady(); |
| 152 virtual void OnAutomationServerLaunchFailed( |
| 153 AutomationLaunchResult reason, const std::string& server_version); |
| 154 |
| 155 private: |
| 156 void SubscribeToFocusEvents(); |
| 157 void UnsubscribeFromFocusEvents(); |
| 158 |
| 159 // Equivalent of: |
| 160 // event = window.document.createEvent("Event"); |
| 161 // event.initEvent(type, bubbles, cancelable); |
| 162 // and then returns the event object. |
| 163 bool CreateEvent(const std::string& type, bool bubbles, bool cancelable, |
| 164 NPObject** basic_event); |
| 165 |
| 166 // Creates and initializes an event object of type "message". |
| 167 // Used for postMessage. |
| 168 bool CreateMessageEvent(bool bubbles, bool cancelable, |
| 169 const std::string& data, const std::string& origin, |
| 170 NPObject** message_event); |
| 171 |
| 172 // Calls chrome_frame.dispatchEvent to fire events to event listeners. |
| 173 void DispatchEvent(NPObject* event); |
| 174 |
| 175 // Returns a pointer to the <object> element in the page that |
| 176 // hosts the plugin. Note that this is the parent element of the <embed> |
| 177 // element. The <embed> element doesn't support some of the events that |
| 178 // we require, so we use the object element for receiving events. |
| 179 bool GetObjectElement(nsIDOMElement** element); |
| 180 |
| 181 // Prototype for all methods that can be invoked from script. |
| 182 typedef bool (ChromeFrameNPAPI::*PluginMethod)(NPObject* npobject, |
| 183 const NPVariant* args, |
| 184 uint32_t arg_count, |
| 185 NPVariant* result); |
| 186 |
| 187 // Implementations of scriptable methods. |
| 188 |
| 189 bool NavigateToURL(const NPVariant* args, uint32_t arg_count, |
| 190 NPVariant* result); |
| 191 |
| 192 bool postMessage(NPObject* npobject, const NPVariant* args, |
| 193 uint32_t arg_count, NPVariant* result); |
| 194 |
| 195 // This method is only available when the control is in privileged mode. |
| 196 bool postPrivateMessage(NPObject* npobject, const NPVariant* args, |
| 197 uint32_t arg_count, NPVariant* result); |
| 198 |
| 199 // Pointers to method implementations. |
| 200 static PluginMethod plugin_methods_[]; |
| 201 |
| 202 // NPObject method ids exposed by the plugin. |
| 203 static NPIdentifier plugin_method_identifiers_[]; |
| 204 |
| 205 // NPObject method names exposed by the plugin. |
| 206 static const NPUTF8* plugin_method_identifier_names_[]; |
| 207 |
| 208 // NPObject property ids exposed by the plugin. |
| 209 static NPIdentifier plugin_property_identifiers_[]; |
| 210 |
| 211 // NPObject property names exposed by the plugin. |
| 212 static const NPUTF8* |
| 213 plugin_property_identifier_names_[]; |
| 214 |
| 215 virtual void OnFinalMessage(HWND window); |
| 216 |
| 217 // Helper function to invoke a function on a NPObject. |
| 218 bool InvokeDefault(NPObject* object, const std::string& param, |
| 219 NPVariant* result); |
| 220 |
| 221 bool InvokeDefault(NPObject* object, const NPVariant& param, |
| 222 NPVariant* result); |
| 223 |
| 224 bool InvokeDefault(NPObject* object, unsigned param_count, |
| 225 const NPVariant* params, NPVariant* result); |
| 226 |
| 227 // Helper function to convert javascript code to a NPObject we can |
| 228 // invoke on. |
| 229 virtual NPObject* JavascriptToNPObject(const std::string& function_name); |
| 230 |
| 231 // Helper function to execute a script. |
| 232 // Returns S_OK on success. |
| 233 bool ExecuteScript(const std::string& script, NPVariant* result); |
| 234 |
| 235 // Returns true if the script passed in is a valid function in the DOM. |
| 236 bool IsValidJavascriptFunction(const std::string& script); |
| 237 |
| 238 // Converts the data parameter to an NPVariant and forwards the call to the |
| 239 // other FireEvent method. |
| 240 void FireEvent(const std::string& event_type, const std::string& data); |
| 241 |
| 242 // Creates an event object, assigns the data parameter to a |data| property |
| 243 // on the event object and then calls DispatchEvent to fire the event to |
| 244 // listeners. event_type is the name of the event being fired. |
| 245 void FireEvent(const std::string& event_type, const NPVariant& data); |
| 246 |
| 247 // Returns a new prefs service. Virtual to allow overriding in unittests. |
| 248 virtual NpProxyService* CreatePrefService(); |
| 249 |
| 250 // Returns our associated windows' location. |
| 251 virtual std::string GetLocation(); |
| 252 |
| 253 // Returns true iff we're successfully able to query for the browser's |
| 254 // incognito mode, and the browser returns true. |
| 255 virtual bool GetBrowserIncognitoMode(); |
| 256 |
| 257 // Returns the window script object for the page. |
| 258 // This function will cache the window object to avoid calling |
| 259 // npapi::GetValue which can cause problems in Opera. |
| 260 NPObject* GetWindowObject() const; |
| 261 |
| 262 virtual void SetReadyState(READYSTATE new_state) { |
| 263 ready_state_ = new_state; |
| 264 NPVariant var; |
| 265 INT32_TO_NPVARIANT(ready_state_, var); |
| 266 FireEvent("readystatechanged", var); |
| 267 } |
| 268 |
| 269 // Host function to compile-time asserts over members of this class. |
| 270 static void CompileAsserts(); |
| 271 |
| 272 // Get request from the stream notify data |
| 273 NPAPIUrlRequest* RequestFromNotifyData(void* notify_data) const; |
| 274 |
| 275 static LRESULT CALLBACK DropKillFocusHook(int code, WPARAM wparam, |
| 276 LPARAM lparam); // NO_LINT |
| 277 |
| 278 // The plugins opaque instance handle |
| 279 NPP instance_; |
| 280 |
| 281 // The plugin instantiation mode (NP_FULL or NP_EMBED) |
| 282 int16 mode_; |
| 283 // The plugins mime type. |
| 284 std::string mime_type_; |
| 285 |
| 286 // Set to true if we need a full page plugin. |
| 287 bool force_full_page_plugin_; |
| 288 |
| 289 scoped_refptr<NpProxyService> pref_service_; |
| 290 |
| 291 // Used to receive focus and blur events from the object element |
| 292 // that hosts the plugin. |
| 293 scoped_refptr<NpEventListener> focus_listener_; |
| 294 |
| 295 // In some cases the IPC channel proxy object is instantiated on the UI |
| 296 // thread in FF. It then tries to use the IPC logger, which relies on |
| 297 // the message loop being around. Declaring a dummy message loop |
| 298 // is a hack to get around this. Eventually the automation code needs to |
| 299 // be fixed to ensure that the channel proxy always gets created on a thread |
| 300 // with a message loop. |
| 301 static MessageLoop* message_loop_; |
| 302 static int instance_count_; |
| 303 |
| 304 // The following members contain the NPObject pointers representing the |
| 305 // onload/onerror/onmessage handlers on the page. |
| 306 ScopedNpObject<NPObject> onerror_handler_; |
| 307 ScopedNpObject<NPObject> onmessage_handler_; |
| 308 ScopedNpObject<NPObject> onprivatemessage_handler_; |
| 309 |
| 310 // As a workaround for a problem in Opera we cache the window object. |
| 311 // The problem stems from two things: window messages aren't always removed |
| 312 // from the message queue and messages can be pumped inside GetValue. |
| 313 // This can cause an infinite recursion of processing the same message |
| 314 // repeatedly. |
| 315 mutable ScopedNpObject<NPObject> window_object_; |
| 316 |
| 317 // Note since 'onload' is a registered event name, the browser will |
| 318 // automagically create a code block for the handling code and hook it |
| 319 // up to the CF object via addEventListener. |
| 320 // See this list of known event types: |
| 321 // http://www.w3.org/TR/DOM-Level-3-Events/events.html#Event-types |
| 322 |
| 323 READYSTATE ready_state_; |
| 324 |
| 325 |
| 326 // Popups are enabled |
| 327 bool enabled_popups_; |
| 328 |
| 329 // The value of src property keeping the current URL. |
| 330 std::string src_; |
| 331 }; |
| 332 |
| 333 #endif // CHROME_FRAME_CHROME_FRAME_NPAPI_H_ |
OLD | NEW |