dom/plugins/ipc/PluginScriptableObjectUtils.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:9b3855c311c8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef dom_plugins_PluginScriptableObjectUtils_h
8 #define dom_plugins_PluginScriptableObjectUtils_h
9
10 #include "PluginModuleParent.h"
11 #include "PluginModuleChild.h"
12 #include "PluginInstanceParent.h"
13 #include "PluginInstanceChild.h"
14 #include "PluginScriptableObjectParent.h"
15 #include "PluginScriptableObjectChild.h"
16
17 #include "npapi.h"
18 #include "npfunctions.h"
19 #include "npruntime.h"
20
21 #include "nsDebug.h"
22
23 namespace mozilla {
24 namespace plugins {
25
26 inline PluginInstanceParent*
27 GetInstance(NPObject* aObject)
28 {
29 NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
30 "Bad class!");
31
32 ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
33 if (object->invalidated) {
34 NS_WARNING("Calling method on an invalidated object!");
35 return nullptr;
36 }
37 if (!object->parent) {
38 return nullptr;
39 }
40 return object->parent->GetInstance();
41 }
42
43 inline NPObject*
44 NPObjectFromVariant(const Variant& aRemoteVariant)
45 {
46 switch (aRemoteVariant.type()) {
47 case Variant::TPPluginScriptableObjectParent: {
48 PluginScriptableObjectParent* actor =
49 const_cast<PluginScriptableObjectParent*>(
50 reinterpret_cast<const PluginScriptableObjectParent*>(
51 aRemoteVariant.get_PPluginScriptableObjectParent()));
52 return actor->GetObject(true);
53 }
54
55 case Variant::TPPluginScriptableObjectChild: {
56 PluginScriptableObjectChild* actor =
57 const_cast<PluginScriptableObjectChild*>(
58 reinterpret_cast<const PluginScriptableObjectChild*>(
59 aRemoteVariant.get_PPluginScriptableObjectChild()));
60 return actor->GetObject(true);
61 }
62
63 default:
64 NS_NOTREACHED("Shouldn't get here!");
65 return nullptr;
66 }
67 }
68
69 inline NPObject*
70 NPObjectFromVariant(const NPVariant& aVariant)
71 {
72 NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
73 return NPVARIANT_TO_OBJECT(aVariant);
74 }
75
76 inline const NPNetscapeFuncs*
77 GetNetscapeFuncs(PluginInstanceParent* aInstance)
78 {
79 PluginModuleParent* module = aInstance->Module();
80 if (!module) {
81 NS_WARNING("Null module?!");
82 return nullptr;
83 }
84 return module->GetNetscapeFuncs();
85 }
86
87 inline const NPNetscapeFuncs*
88 GetNetscapeFuncs(NPObject* aObject)
89 {
90 NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
91 "Bad class!");
92
93 PluginInstanceParent* instance = GetInstance(aObject);
94 if (!instance) {
95 return nullptr;
96 }
97
98 return GetNetscapeFuncs(instance);
99 }
100
101 inline void
102 ReleaseRemoteVariant(Variant& aVariant)
103 {
104 switch (aVariant.type()) {
105 case Variant::TPPluginScriptableObjectParent: {
106 PluginScriptableObjectParent* actor =
107 const_cast<PluginScriptableObjectParent*>(
108 reinterpret_cast<const PluginScriptableObjectParent*>(
109 aVariant.get_PPluginScriptableObjectParent()));
110 actor->Unprotect();
111 break;
112 }
113
114 case Variant::TPPluginScriptableObjectChild: {
115 NS_ASSERTION(PluginModuleChild::current(),
116 "Should only be running in the child!");
117 PluginScriptableObjectChild* actor =
118 const_cast<PluginScriptableObjectChild*>(
119 reinterpret_cast<const PluginScriptableObjectChild*>(
120 aVariant.get_PPluginScriptableObjectChild()));
121 actor->Unprotect();
122 break;
123 }
124
125 default:
126 break; // Intentional fall-through for other variant types.
127 }
128
129 aVariant = mozilla::void_t();
130 }
131
132 bool
133 ConvertToVariant(const Variant& aRemoteVariant,
134 NPVariant& aVariant,
135 PluginInstanceParent* aInstance = nullptr);
136
137 template <class InstanceType>
138 bool
139 ConvertToRemoteVariant(const NPVariant& aVariant,
140 Variant& aRemoteVariant,
141 InstanceType* aInstance,
142 bool aProtectActors = false);
143
144 class ProtectedVariant
145 {
146 public:
147 ProtectedVariant(const NPVariant& aVariant,
148 PluginInstanceParent* aInstance)
149 {
150 mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
151 }
152
153 ProtectedVariant(const NPVariant& aVariant,
154 PluginInstanceChild* aInstance)
155 {
156 mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
157 }
158
159 ~ProtectedVariant() {
160 ReleaseRemoteVariant(mVariant);
161 }
162
163 bool IsOk() {
164 return mOk;
165 }
166
167 operator const Variant&() {
168 return mVariant;
169 }
170
171 private:
172 Variant mVariant;
173 bool mOk;
174 };
175
176 class ProtectedVariantArray
177 {
178 public:
179 ProtectedVariantArray(const NPVariant* aArgs,
180 uint32_t aCount,
181 PluginInstanceParent* aInstance)
182 : mUsingShadowArray(false)
183 {
184 for (uint32_t index = 0; index < aCount; index++) {
185 Variant* remoteVariant = mArray.AppendElement();
186 if (!(remoteVariant &&
187 ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
188 true))) {
189 mOk = false;
190 return;
191 }
192 }
193 mOk = true;
194 }
195
196 ProtectedVariantArray(const NPVariant* aArgs,
197 uint32_t aCount,
198 PluginInstanceChild* aInstance)
199 : mUsingShadowArray(false)
200 {
201 for (uint32_t index = 0; index < aCount; index++) {
202 Variant* remoteVariant = mArray.AppendElement();
203 if (!(remoteVariant &&
204 ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
205 true))) {
206 mOk = false;
207 return;
208 }
209 }
210 mOk = true;
211 }
212
213 ~ProtectedVariantArray()
214 {
215 InfallibleTArray<Variant>& vars = EnsureAndGetShadowArray();
216 uint32_t count = vars.Length();
217 for (uint32_t index = 0; index < count; index++) {
218 ReleaseRemoteVariant(vars[index]);
219 }
220 }
221
222 operator const InfallibleTArray<Variant>&()
223 {
224 return EnsureAndGetShadowArray();
225 }
226
227 bool IsOk()
228 {
229 return mOk;
230 }
231
232 private:
233 InfallibleTArray<Variant>&
234 EnsureAndGetShadowArray()
235 {
236 if (!mUsingShadowArray) {
237 mShadowArray.SwapElements(mArray);
238 mUsingShadowArray = true;
239 }
240 return mShadowArray;
241 }
242
243 // We convert the variants fallibly, but pass them to Call*()
244 // methods as an infallible array
245 nsTArray<Variant> mArray;
246 InfallibleTArray<Variant> mShadowArray;
247 bool mOk;
248 bool mUsingShadowArray;
249 };
250
251 template<class ActorType>
252 struct ProtectedActorTraits
253 {
254 static bool Nullable();
255 };
256
257 template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
258 class ProtectedActor
259 {
260 public:
261 ProtectedActor(ActorType* aActor) : mActor(aActor)
262 {
263 if (!Traits::Nullable()) {
264 NS_ASSERTION(mActor, "This should never be null!");
265 }
266 }
267
268 ~ProtectedActor()
269 {
270 if (Traits::Nullable() && !mActor)
271 return;
272 mActor->Unprotect();
273 }
274
275 ActorType* operator->()
276 {
277 return mActor;
278 }
279
280 operator bool()
281 {
282 return !!mActor;
283 }
284
285 private:
286 ActorType* mActor;
287 };
288
289 template<>
290 struct ProtectedActorTraits<PluginScriptableObjectParent>
291 {
292 static bool Nullable() { return true; }
293 };
294
295 template<>
296 struct ProtectedActorTraits<PluginScriptableObjectChild>
297 {
298 static bool Nullable() { return false; }
299 };
300
301 } /* namespace plugins */
302 } /* namespace mozilla */
303
304 #include "PluginScriptableObjectUtils-inl.h"
305
306 #endif /* dom_plugins_PluginScriptableObjectUtils_h */

mercurial