WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
       
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
       
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
       
    24  */
       
    25 
       
    26 #if USE(PLUGIN_HOST_PROCESS)
       
    27 
       
    28 #ifndef NetscapePluginInstanceProxy_h
       
    29 #define NetscapePluginInstanceProxy_h
       
    30 
       
    31 #include <JavaScriptCore/Protect.h>
       
    32 #include <WebCore/Timer.h>
       
    33 #include <WebKit/npapi.h>
       
    34 #include <wtf/Deque.h>
       
    35 #include <wtf/HashMap.h>
       
    36 #include <wtf/PassRefPtr.h>
       
    37 #include <wtf/RefCounted.h>
       
    38 #include <wtf/RetainPtr.h>
       
    39 #include "WebKitPluginHostTypes.h"
       
    40 
       
    41 namespace WebCore {
       
    42     class String;
       
    43 }
       
    44 
       
    45 namespace JSC {
       
    46     namespace Bindings {
       
    47         class Instance;
       
    48         class RootObject;
       
    49     }
       
    50     class ArgList;
       
    51 }
       
    52 @class WebHostedNetscapePluginView;
       
    53 @class WebFrame;
       
    54 
       
    55 namespace WebKit {
       
    56 
       
    57 class HostedNetscapePluginStream;
       
    58 class NetscapePluginHostProxy;
       
    59 class PluginRequest;
       
    60 class ProxyInstance;
       
    61     
       
    62 class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
       
    63 public:
       
    64     static PassRefPtr<NetscapePluginInstanceProxy> create(NetscapePluginHostProxy*, WebHostedNetscapePluginView *, bool fullFramePlugin);
       
    65     ~NetscapePluginInstanceProxy();
       
    66     
       
    67     uint32_t pluginID() const 
       
    68     {
       
    69         ASSERT(m_pluginID);
       
    70         
       
    71         return m_pluginID;
       
    72     }
       
    73     uint32_t renderContextID() const { ASSERT(fastMallocSize(this)); return m_renderContextID; }
       
    74     void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
       
    75     
       
    76     RendererType rendererType() const { return m_rendererType; }
       
    77     void setRendererType(RendererType rendererType) { m_rendererType = rendererType; }
       
    78     
       
    79     WebHostedNetscapePluginView *pluginView() const { ASSERT(fastMallocSize(this)); return m_pluginView; }
       
    80     NetscapePluginHostProxy* hostProxy() const { ASSERT(fastMallocSize(this)); return m_pluginHostProxy; }
       
    81     
       
    82     bool cancelStreamLoad(uint32_t streamID, NPReason);
       
    83     void disconnectStream(HostedNetscapePluginStream*);
       
    84     
       
    85     void setManualStream(PassRefPtr<HostedNetscapePluginStream>);
       
    86     HostedNetscapePluginStream* manualStream() const { return m_manualStream.get(); }
       
    87     
       
    88     void pluginHostDied();
       
    89     
       
    90     void resize(NSRect size, NSRect clipRect);
       
    91     void destroy();
       
    92     void focusChanged(bool hasFocus);
       
    93     void windowFocusChanged(bool hasFocus);
       
    94     void windowFrameChanged(NSRect frame);
       
    95     
       
    96     void mouseEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
       
    97     void keyEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
       
    98     void insertText(NSString *);
       
    99     bool wheelEvent(NSView *pluginView, NSEvent *);
       
   100     void syntheticKeyDownWithCommandModifier(int keyCode, char character);
       
   101     void flagsChanged(NSEvent *);
       
   102     void print(CGContextRef, unsigned width, unsigned height);
       
   103     void snapshot(CGContextRef, unsigned width, unsigned height);
       
   104     
       
   105     void startTimers(bool throttleTimers);
       
   106     void stopTimers();
       
   107     
       
   108     void invalidateRect(double x, double y, double width, double height);
       
   109     
       
   110     // NPRuntime
       
   111     bool getWindowNPObject(uint32_t& objectID);
       
   112     bool getPluginElementNPObject(uint32_t& objectID);
       
   113     bool forgetBrowserObjectID(uint32_t objectID); // Will fail if the ID is being sent to plug-in right now (i.e., retain/release calls aren't balanced).
       
   114 
       
   115     bool evaluate(uint32_t objectID, const WebCore::String& script, data_t& resultData, mach_msg_type_number_t& resultLength, bool allowPopups);
       
   116     bool invoke(uint32_t objectID, const JSC::Identifier& methodName, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
       
   117     bool invokeDefault(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
       
   118     bool construct(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
       
   119     bool enumerate(uint32_t objectID, data_t& resultData, mach_msg_type_number_t& resultLength);
       
   120     
       
   121     bool getProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);
       
   122     bool getProperty(uint32_t objectID, unsigned propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);    
       
   123     bool setProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t valueData, mach_msg_type_number_t valueLength);
       
   124     bool setProperty(uint32_t objectID, unsigned propertyName, data_t valueData, mach_msg_type_number_t valueLength);
       
   125     bool removeProperty(uint32_t objectID, const JSC::Identifier& propertyName);
       
   126     bool removeProperty(uint32_t objectID, unsigned propertyName);
       
   127     bool hasProperty(uint32_t objectID, const JSC::Identifier& propertyName);
       
   128     bool hasProperty(uint32_t objectID, unsigned propertyName);
       
   129     bool hasMethod(uint32_t objectID, const JSC::Identifier& methodName);
       
   130     
       
   131     void status(const char* message);
       
   132     NPError loadURL(const char* url, const char* target, const char* postData, uint32_t postDataLength, LoadURLFlags, uint32_t& requestID);
       
   133 
       
   134     bool getCookies(data_t urlData, mach_msg_type_number_t urlLength, data_t& cookiesData, mach_msg_type_number_t& cookiesLength);
       
   135     bool setCookies(data_t urlData, mach_msg_type_number_t urlLength, data_t cookiesData, mach_msg_type_number_t cookiesLength);
       
   136              
       
   137     bool getProxy(data_t urlData, mach_msg_type_number_t urlLength, data_t& proxyData, mach_msg_type_number_t& proxyLength);
       
   138     bool getAuthenticationInfo(data_t protocolData, data_t hostData, uint32_t port, data_t schemeData, data_t realmData, 
       
   139                                data_t& usernameData, mach_msg_type_number_t& usernameLength, data_t& passwordData, mach_msg_type_number_t& passwordLength);
       
   140     bool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 
       
   141                       double& destX, double& destY, NPCoordinateSpace destSpace);
       
   142 
       
   143     PassRefPtr<JSC::Bindings::Instance> createBindingsInstance(PassRefPtr<JSC::Bindings::RootObject>);
       
   144     RetainPtr<NSData *> marshalValues(JSC::ExecState*, const JSC::ArgList& args);
       
   145     void marshalValue(JSC::ExecState*, JSC::JSValue, data_t& resultData, mach_msg_type_number_t& resultLength);
       
   146     JSC::JSValue demarshalValue(JSC::ExecState*, const char* valueData, mach_msg_type_number_t valueLength);
       
   147 
       
   148     // No-op if the value does not contain a local object.
       
   149     void retainLocalObject(JSC::JSValue);
       
   150     void releaseLocalObject(JSC::JSValue);
       
   151 
       
   152     void addInstance(ProxyInstance*);
       
   153     void removeInstance(ProxyInstance*);
       
   154     
       
   155     void cleanup();
       
   156     void invalidate();
       
   157     
       
   158     void willCallPluginFunction();
       
   159     void didCallPluginFunction();
       
   160     bool shouldStop();
       
   161     
       
   162     uint32_t nextRequestID();
       
   163     
       
   164     uint32_t checkIfAllowedToLoadURL(const char* url, const char* target);
       
   165     void cancelCheckIfAllowedToLoadURL(uint32_t checkID);
       
   166     void checkIfAllowedToLoadURLResult(uint32_t checkID, bool allowed);
       
   167 
       
   168     void resolveURL(const char* url, const char* target, data_t& resolvedURLData, mach_msg_type_number_t& resolvedURLLength);
       
   169     
       
   170     void didDraw();
       
   171     void privateBrowsingModeDidChange(bool isPrivateBrowsingEnabled);
       
   172     
       
   173     static void setGlobalException(const WebCore::String&);
       
   174     static void moveGlobalExceptionToExecState(JSC::ExecState*);
       
   175 
       
   176     // Reply structs
       
   177     struct Reply {
       
   178         enum Type {
       
   179             InstantiatePlugin,
       
   180             GetScriptableNPObject,
       
   181             BooleanAndData,
       
   182             Boolean
       
   183         };
       
   184         
       
   185         Reply(Type type) 
       
   186             : m_type(type)
       
   187         {
       
   188         }
       
   189         
       
   190         virtual ~Reply() { }
       
   191     
       
   192         Type m_type;
       
   193     };
       
   194 
       
   195     struct InstantiatePluginReply : public Reply {
       
   196         static const int ReplyType = InstantiatePlugin;
       
   197         
       
   198         InstantiatePluginReply(kern_return_t resultCode, uint32_t renderContextID, RendererType rendererType)
       
   199             : Reply(InstantiatePlugin)
       
   200             , m_resultCode(resultCode)
       
   201             , m_renderContextID(renderContextID)
       
   202             , m_rendererType(rendererType)
       
   203         {
       
   204         }
       
   205                  
       
   206         kern_return_t m_resultCode;
       
   207         uint32_t m_renderContextID;
       
   208         RendererType m_rendererType;
       
   209     };
       
   210 
       
   211     struct GetScriptableNPObjectReply : public Reply {
       
   212         static const Reply::Type ReplyType = GetScriptableNPObject;
       
   213         
       
   214         GetScriptableNPObjectReply(uint32_t objectID)
       
   215             : Reply(ReplyType)
       
   216             , m_objectID(objectID)
       
   217         {
       
   218         }
       
   219             
       
   220         uint32_t m_objectID;
       
   221     };
       
   222     
       
   223     struct BooleanReply : public Reply {
       
   224         static const Reply::Type ReplyType = Boolean;
       
   225         
       
   226         BooleanReply(boolean_t result)
       
   227             : Reply(ReplyType)
       
   228             , m_result(result)
       
   229         {
       
   230         }
       
   231         
       
   232         boolean_t m_result;
       
   233     };
       
   234 
       
   235     struct BooleanAndDataReply : public Reply {
       
   236         static const Reply::Type ReplyType = BooleanAndData;
       
   237         
       
   238         BooleanAndDataReply(boolean_t returnValue, RetainPtr<CFDataRef> result)
       
   239             : Reply(ReplyType)
       
   240             , m_returnValue(returnValue)
       
   241             , m_result(result)
       
   242         {
       
   243         }
       
   244         
       
   245         boolean_t m_returnValue;
       
   246         RetainPtr<CFDataRef> m_result;
       
   247     };
       
   248     
       
   249     void setCurrentReply(uint32_t requestID, Reply* reply)
       
   250     {
       
   251         ASSERT(!m_replies.contains(requestID));
       
   252         m_replies.set(requestID, reply);
       
   253     }
       
   254     
       
   255     template <typename T>
       
   256     std::auto_ptr<T> waitForReply(uint32_t requestID)
       
   257     {
       
   258         RefPtr<NetscapePluginInstanceProxy> protect(this); // Plug-in host may crash while we are waiting for reply, releasing all instances to the instance proxy.
       
   259 
       
   260         willCallPluginFunction();
       
   261         m_waitingForReply = true;
       
   262 
       
   263         Reply* reply = processRequestsAndWaitForReply(requestID);
       
   264         if (reply)
       
   265             ASSERT(reply->m_type == T::ReplyType);
       
   266         
       
   267         m_waitingForReply = false;
       
   268         
       
   269         didCallPluginFunction();
       
   270 
       
   271         return std::auto_ptr<T>(static_cast<T*>(reply));
       
   272     }
       
   273     
       
   274     void webFrameDidFinishLoadWithReason(WebFrame*, NPReason);
       
   275 
       
   276 private:
       
   277     NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView*, bool fullFramePlugin);
       
   278 
       
   279     NPError loadRequest(NSURLRequest*, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
       
   280     
       
   281     class PluginRequest;
       
   282     void performRequest(PluginRequest*);
       
   283     void evaluateJavaScript(PluginRequest*);
       
   284     
       
   285     void stopAllStreams();
       
   286     Reply* processRequestsAndWaitForReply(uint32_t requestID);
       
   287     
       
   288     NetscapePluginHostProxy* m_pluginHostProxy;
       
   289     WebHostedNetscapePluginView *m_pluginView;
       
   290 
       
   291     void requestTimerFired(WebCore::Timer<NetscapePluginInstanceProxy>*);
       
   292     WebCore::Timer<NetscapePluginInstanceProxy> m_requestTimer;
       
   293     Deque<RefPtr<PluginRequest> > m_pluginRequests;
       
   294     
       
   295     HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
       
   296 
       
   297     uint32_t m_currentURLRequestID;
       
   298     
       
   299     uint32_t m_pluginID;
       
   300     uint32_t m_renderContextID;
       
   301     RendererType m_rendererType;
       
   302     
       
   303     bool m_waitingForReply;
       
   304     HashMap<uint32_t, Reply*> m_replies;
       
   305     
       
   306     // NPRuntime
       
   307 
       
   308     void addValueToArray(NSMutableArray *, JSC::ExecState* exec, JSC::JSValue value);
       
   309     
       
   310     bool demarshalValueFromArray(JSC::ExecState*, NSArray *array, NSUInteger& index, JSC::JSValue& result);
       
   311     void demarshalValues(JSC::ExecState*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::MarkedArgumentBuffer& result);
       
   312 
       
   313     class LocalObjectMap : Noncopyable {
       
   314     public:
       
   315         LocalObjectMap();
       
   316         ~LocalObjectMap();
       
   317         uint32_t idForObject(JSC::JSObject*);
       
   318         void retain(JSC::JSObject*);
       
   319         void release(JSC::JSObject*);
       
   320         void clear();
       
   321         bool forget(uint32_t);
       
   322         bool contains(uint32_t) const;
       
   323         JSC::JSObject* get(uint32_t) const;
       
   324 
       
   325     private:
       
   326         HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> > m_idToJSObjectMap;
       
   327         // The pair consists of object ID and a reference count. One reference belongs to remote plug-in,
       
   328         // and the proxy will add transient references for arguments that are being sent out.
       
   329         HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> > m_jsObjectToIDMap;
       
   330         uint32_t m_objectIDCounter;
       
   331     };
       
   332 
       
   333     LocalObjectMap m_localObjects;
       
   334 
       
   335     typedef HashSet<ProxyInstance*> ProxyInstanceSet;
       
   336     ProxyInstanceSet m_instances;
       
   337 
       
   338     uint32_t m_urlCheckCounter;
       
   339     typedef HashMap<uint32_t, RetainPtr<id> > URLCheckMap;
       
   340     URLCheckMap m_urlChecks;
       
   341     
       
   342     unsigned m_pluginFunctionCallDepth;
       
   343     bool m_shouldStopSoon;
       
   344     uint32_t m_currentRequestID;
       
   345 
       
   346     // All NPRuntime functions will return false when destroying a plug-in. This is necessary because there may be unhandled messages waiting,
       
   347     // and spinning in processRequests() will unexpectedly execute them from inside destroy(). That's not a good time to execute arbitrary JavaScript,
       
   348     // since both loading and rendering data structures may be in inconsistent state.
       
   349     // This suppresses calls from all plug-ins, even those in different pages, since JS might affect the frame with plug-in that's being stopped.
       
   350     //
       
   351     // FIXME: Plug-ins can execute arbitrary JS from destroy() in same process case, and other browsers also support that.
       
   352     // A better fix may be to make sure that unrelated messages are postponed until after destroy() returns.
       
   353     // Another possible fix may be to send destroy message at a time when internal structures are consistent.
       
   354     //
       
   355     // FIXME: We lack similar message suppression in other cases - resize() is also triggered by layout, so executing arbitrary JS is also problematic.
       
   356     static bool m_inDestroy;
       
   357 
       
   358     bool m_pluginIsWaitingForDraw;
       
   359     
       
   360     RefPtr<HostedNetscapePluginStream> m_manualStream;
       
   361 
       
   362     typedef HashMap<WebFrame*, RefPtr<PluginRequest> > FrameLoadMap;
       
   363     FrameLoadMap m_pendingFrameLoads;
       
   364 };
       
   365     
       
   366 } // namespace WebKit
       
   367 
       
   368 #endif // NetscapePluginInstanceProxy_h
       
   369 #endif // USE(PLUGIN_HOST_PROCESS)