summaryrefslogtreecommitdiff
path: root/dom/plugins/ipc/PluginAsyncSurrogate.h
blob: f413cdf11237c52fc88f8984a8bd1c2b507bb398 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef dom_plugins_ipc_PluginAsyncSurrogate_h
#define dom_plugins_ipc_PluginAsyncSurrogate_h

#include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h"
#include "npapi.h"
#include "npfunctions.h"
#include "npruntime.h"
#include "nsISupportsImpl.h"
#include "nsPluginHost.h"
#include "nsString.h"
#include "nsTArray.h"
#include "PluginDataResolver.h"

namespace mozilla {
namespace plugins {

struct ParentNPObject;
class PluginInstanceParent;
class PluginModuleParent;

class PluginAsyncSurrogate : public PluginDataResolver
{
public:
  NS_INLINE_DECL_REFCOUNTING(PluginAsyncSurrogate)

  bool Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode,
            int16_t aArgc, char* aArgn[], char* aArgv[]);
  nsresult NPP_New(NPError* aError);
  NPError NPP_Destroy(NPSavedData** aSave);
  NPError NPP_GetValue(NPPVariable aVariable, void* aRetval);
  NPError NPP_SetValue(NPNVariable aVariable, void* aValue);
  NPError NPP_NewStream(NPMIMEType aType, NPStream* aStream, NPBool aSeekable,
                        uint16_t* aStype);
  NPError NPP_SetWindow(NPWindow* aWindow);
  nsresult AsyncSetWindow(NPWindow* aWindow);
  void NPP_Print(NPPrint* aPrintInfo);
  int16_t NPP_HandleEvent(void* aEvent);
  int32_t NPP_WriteReady(NPStream* aStream);
  NPError NPP_DestroyStream(NPStream* aStream, NPReason aReason);
  void OnInstanceCreated(PluginInstanceParent* aInstance);
  static bool Create(PluginModuleParent* aParent, NPMIMEType aPluginType,
                     NPP aInstance, uint16_t aMode, int16_t aArgc,
                     char* aArgn[], char* aArgv[]);
  static const NPClass* GetClass() { return &sNPClass; }
  static void NP_GetEntryPoints(NPPluginFuncs* aFuncs);
  static PluginAsyncSurrogate* Cast(NPP aInstance);
  static void NotifyDestroyPending(NPP aInstance);
  void NotifyDestroyPending();

  virtual PluginAsyncSurrogate*
  GetAsyncSurrogate() { return this; }

  virtual PluginInstanceParent*
  GetInstance() { return nullptr; }

  NPP GetNPP();

  bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
                         bool* aHasProperty, bool* aHasMethod,
                         NPVariant* aResult);

  PluginModuleParent* GetParent() { return mParent; }

  bool IsDestroyPending() const { return mDestroyPending; }

  bool SetAcceptingCalls(bool aAccept)
  {
    bool prevState = mAcceptCalls;
    if (mInstantiated) {
      aAccept = true;
    }
    mAcceptCalls = aAccept;
    return prevState;
  }

  void AsyncCallDeparting();
  void AsyncCallArriving();

  void NotifyAsyncInitFailed();
  void DestroyAsyncStream(NPStream* aStream);

private:
  explicit PluginAsyncSurrogate(PluginModuleParent* aParent);
  virtual ~PluginAsyncSurrogate();

  bool WaitForInit();

  static bool SetStreamType(NPStream* aStream, uint16_t aStreamType);

  static NPError NPP_Destroy(NPP aInstance, NPSavedData** aSave);
  static NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void* aRetval);
  static NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void* aValue);
  static NPError NPP_NewStream(NPP aInstance, NPMIMEType aType, NPStream* aStream,
                               NPBool aSeekable, uint16_t* aStype);
  static NPError NPP_SetWindow(NPP aInstance, NPWindow* aWindow);
  static void NPP_Print(NPP aInstance, NPPrint* aPrintInfo);
  static int16_t NPP_HandleEvent(NPP aInstance, void* aEvent);
  static int32_t NPP_WriteReady(NPP aInstance, NPStream* aStream);
  static NPError NPP_DestroyStream(NPP aInstance, NPStream* aStream,
                                   NPReason aReason);

  static NPObject* ScriptableAllocate(NPP aInstance, NPClass* aClass);
  static void ScriptableInvalidate(NPObject* aObject);
  static void ScriptableDeallocate(NPObject* aObject);
  static bool ScriptableHasMethod(NPObject* aObject, NPIdentifier aName);
  static bool ScriptableInvoke(NPObject* aObject, NPIdentifier aName,
                               const NPVariant* aArgs, uint32_t aArgCount,
                               NPVariant* aResult);
  static bool ScriptableInvokeDefault(NPObject* aObject, const NPVariant* aArgs,
                                      uint32_t aArgCount, NPVariant* aResult);
  static bool ScriptableHasProperty(NPObject* aObject, NPIdentifier aName);
  static bool ScriptableGetProperty(NPObject* aObject, NPIdentifier aName,
                                    NPVariant* aResult);
  static bool ScriptableSetProperty(NPObject* aObject, NPIdentifier aName,
                                    const NPVariant* aValue);
  static bool ScriptableRemoveProperty(NPObject* aObject, NPIdentifier aName);
  static bool ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers,
                                  uint32_t* aCount);
  static bool ScriptableConstruct(NPObject* aObject, const NPVariant* aArgs,
                                  uint32_t aArgCount, NPVariant* aResult);
  static nsNPAPIPluginStreamListener* GetStreamListener(NPStream* aStream);

private:
  struct PendingNewStreamCall
  {
    PendingNewStreamCall(NPMIMEType aType, NPStream* aStream, NPBool aSeekable);
    ~PendingNewStreamCall() {}
    nsCString   mType;
    NPStream*   mStream;
    NPBool      mSeekable;
  };

private:
  PluginModuleParent*             mParent;
  // These values are used to construct the plugin instance
  nsCString                       mMimeType;
  mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance;
  uint16_t                        mMode;
  InfallibleTArray<nsCString>     mNames;
  InfallibleTArray<nsCString>     mValues;
  // This is safe to store as a pointer because the spec says it will remain
  // valid until destruction or a subsequent NPP_SetWindow call.
  NPWindow*                       mWindow;
  nsTArray<PendingNewStreamCall>  mPendingNewStreamCalls;
  UniquePtr<PluginDestructionGuard> mPluginDestructionGuard;

  bool      mAcceptCalls;
  bool      mInstantiated;
  bool      mAsyncSetWindow;
  bool      mInitCancelled;
  bool      mDestroyPending;
  int32_t   mAsyncCallsInFlight;

  static const NPClass sNPClass;
};

struct AsyncNPObject : NPObject
{
  explicit AsyncNPObject(PluginAsyncSurrogate* aSurrogate);
  ~AsyncNPObject();

  NPObject* GetRealObject();

  RefPtr<PluginAsyncSurrogate>  mSurrogate;
  ParentNPObject*                 mRealObject;
};

class MOZ_STACK_CLASS PushSurrogateAcceptCalls
{
public:
  explicit PushSurrogateAcceptCalls(PluginInstanceParent* aInstance);
  ~PushSurrogateAcceptCalls();

private:
  PluginAsyncSurrogate* mSurrogate;
  bool                  mPrevAcceptCallsState;
};

} // namespace plugins
} // namespace mozilla

#endif // dom_plugins_ipc_PluginAsyncSurrogate_h