Line data Source code
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_PluginScriptableObjectChild_h
8 : #define dom_plugins_PluginScriptableObjectChild_h 1
9 :
10 : #include "mozilla/plugins/PPluginScriptableObjectChild.h"
11 : #include "mozilla/plugins/PluginMessageUtils.h"
12 : #include "mozilla/plugins/PluginTypes.h"
13 :
14 : #include "npruntime.h"
15 : #include "nsDataHashtable.h"
16 :
17 : namespace mozilla {
18 : namespace plugins {
19 :
20 : class PluginInstanceChild;
21 : class PluginScriptableObjectChild;
22 :
23 : struct ChildNPObject : NPObject
24 : {
25 0 : ChildNPObject()
26 0 : : NPObject(), parent(nullptr), invalidated(false)
27 : {
28 0 : MOZ_COUNT_CTOR(ChildNPObject);
29 0 : }
30 :
31 0 : ~ChildNPObject()
32 0 : {
33 0 : MOZ_COUNT_DTOR(ChildNPObject);
34 0 : }
35 :
36 : // |parent| is always valid as long as the actor is alive. Once the actor is
37 : // destroyed this will be set to null.
38 : PluginScriptableObjectChild* parent;
39 : bool invalidated;
40 : };
41 :
42 : class PluginScriptableObjectChild : public PPluginScriptableObjectChild
43 : {
44 : friend class PluginInstanceChild;
45 :
46 : public:
47 : explicit PluginScriptableObjectChild(ScriptableObjectType aType);
48 : virtual ~PluginScriptableObjectChild();
49 :
50 : bool
51 : InitializeProxy();
52 :
53 : void
54 : InitializeLocal(NPObject* aObject);
55 :
56 :
57 : virtual mozilla::ipc::IPCResult
58 : AnswerInvalidate() override;
59 :
60 : virtual mozilla::ipc::IPCResult
61 : AnswerHasMethod(const PluginIdentifier& aId,
62 : bool* aHasMethod) override;
63 :
64 : virtual mozilla::ipc::IPCResult
65 : AnswerInvoke(const PluginIdentifier& aId,
66 : InfallibleTArray<Variant>&& aArgs,
67 : Variant* aResult,
68 : bool* aSuccess) override;
69 :
70 : virtual mozilla::ipc::IPCResult
71 : AnswerInvokeDefault(InfallibleTArray<Variant>&& aArgs,
72 : Variant* aResult,
73 : bool* aSuccess) override;
74 :
75 : virtual mozilla::ipc::IPCResult
76 : AnswerHasProperty(const PluginIdentifier& aId,
77 : bool* aHasProperty) override;
78 :
79 : virtual mozilla::ipc::IPCResult
80 : AnswerGetChildProperty(const PluginIdentifier& aId,
81 : bool* aHasProperty,
82 : bool* aHasMethod,
83 : Variant* aResult,
84 : bool* aSuccess) override;
85 :
86 : virtual mozilla::ipc::IPCResult
87 : AnswerSetProperty(const PluginIdentifier& aId,
88 : const Variant& aValue,
89 : bool* aSuccess) override;
90 :
91 : virtual mozilla::ipc::IPCResult
92 : AnswerRemoveProperty(const PluginIdentifier& aId,
93 : bool* aSuccess) override;
94 :
95 : virtual mozilla::ipc::IPCResult
96 : AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
97 : bool* aSuccess) override;
98 :
99 : virtual mozilla::ipc::IPCResult
100 : AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
101 : Variant* aResult,
102 : bool* aSuccess) override;
103 :
104 : virtual mozilla::ipc::IPCResult
105 : RecvProtect() override;
106 :
107 : virtual mozilla::ipc::IPCResult
108 : RecvUnprotect() override;
109 :
110 : NPObject*
111 : GetObject(bool aCanResurrect);
112 :
113 : static const NPClass*
114 0 : GetClass()
115 : {
116 0 : return &sNPClass;
117 : }
118 :
119 : PluginInstanceChild*
120 0 : GetInstance() const
121 : {
122 0 : return mInstance;
123 : }
124 :
125 : // Protect only affects LocalObject actors. It is called by the
126 : // ProtectedVariant/Actor helper classes before the actor is used as an
127 : // argument to an IPC call and when the parent process resurrects a
128 : // proxy object to the NPObject associated with this actor.
129 : void Protect();
130 :
131 : // Unprotect only affects LocalObject actors. It is called by the
132 : // ProtectedVariant/Actor helper classes after the actor is used as an
133 : // argument to an IPC call and when the parent process is no longer using
134 : // this actor.
135 : void Unprotect();
136 :
137 : // DropNPObject is only used for Proxy actors and is called when the child
138 : // process is no longer using the NPObject associated with this actor. The
139 : // parent process may subsequently use this actor again in which case a new
140 : // NPObject will be created and associated with this actor (see
141 : // ResurrectProxyObject).
142 : void DropNPObject();
143 :
144 : /**
145 : * After NPP_Destroy, all NPObjects associated with an instance are
146 : * destroyed. We are informed of this destruction. This should only be called
147 : * on Local actors.
148 : */
149 : void NPObjectDestroyed();
150 :
151 : bool
152 : Evaluate(NPString* aScript,
153 : NPVariant* aResult);
154 :
155 : ScriptableObjectType
156 0 : Type() const {
157 0 : return mType;
158 : }
159 :
160 : private:
161 : struct StoredIdentifier
162 : {
163 : nsCString mIdentifier;
164 : nsAutoRefCnt mRefCnt;
165 : bool mPermanent;
166 :
167 0 : nsrefcnt AddRef() {
168 0 : ++mRefCnt;
169 0 : return mRefCnt;
170 : }
171 :
172 0 : nsrefcnt Release() {
173 0 : --mRefCnt;
174 0 : if (mRefCnt == 0) {
175 0 : delete this;
176 0 : return 0;
177 : }
178 0 : return mRefCnt;
179 : }
180 :
181 0 : explicit StoredIdentifier(const nsCString& aIdentifier)
182 0 : : mIdentifier(aIdentifier), mRefCnt(), mPermanent(false)
183 0 : { MOZ_COUNT_CTOR(StoredIdentifier); }
184 :
185 0 : ~StoredIdentifier() { MOZ_COUNT_DTOR(StoredIdentifier); }
186 : };
187 :
188 : public:
189 : class MOZ_STACK_CLASS StackIdentifier
190 : {
191 : public:
192 : explicit StackIdentifier(const PluginIdentifier& aIdentifier);
193 : explicit StackIdentifier(NPIdentifier aIdentifier);
194 : ~StackIdentifier();
195 :
196 0 : void MakePermanent()
197 : {
198 0 : if (mStored) {
199 0 : mStored->mPermanent = true;
200 : }
201 0 : }
202 : NPIdentifier ToNPIdentifier() const;
203 :
204 0 : bool IsString() const { return mIdentifier.type() == PluginIdentifier::TnsCString; }
205 0 : const nsCString& GetString() const { return mIdentifier.get_nsCString(); }
206 :
207 0 : int32_t GetInt() const { return mIdentifier.get_int32_t(); }
208 :
209 0 : PluginIdentifier GetIdentifier() const { return mIdentifier; }
210 :
211 : private:
212 : DISALLOW_COPY_AND_ASSIGN(StackIdentifier);
213 :
214 : PluginIdentifier mIdentifier;
215 : RefPtr<StoredIdentifier> mStored;
216 : };
217 :
218 : static void ClearIdentifiers();
219 :
220 : bool RegisterActor(NPObject* aObject);
221 : void UnregisterActor(NPObject* aObject);
222 :
223 : static PluginScriptableObjectChild* GetActorForNPObject(NPObject* aObject);
224 :
225 : static void RegisterObject(NPObject* aObject, PluginInstanceChild* aInstance);
226 : static void UnregisterObject(NPObject* aObject);
227 :
228 : static PluginInstanceChild* GetInstanceForNPObject(NPObject* aObject);
229 :
230 : /**
231 : * Fill PluginInstanceChild.mDeletingHash with all the remaining NPObjects
232 : * associated with that instance.
233 : */
234 : static void NotifyOfInstanceShutdown(PluginInstanceChild* aInstance);
235 :
236 : private:
237 : static NPObject*
238 : ScriptableAllocate(NPP aInstance,
239 : NPClass* aClass);
240 :
241 : static void
242 : ScriptableInvalidate(NPObject* aObject);
243 :
244 : static void
245 : ScriptableDeallocate(NPObject* aObject);
246 :
247 : static bool
248 : ScriptableHasMethod(NPObject* aObject,
249 : NPIdentifier aName);
250 :
251 : static bool
252 : ScriptableInvoke(NPObject* aObject,
253 : NPIdentifier aName,
254 : const NPVariant* aArgs,
255 : uint32_t aArgCount,
256 : NPVariant* aResult);
257 :
258 : static bool
259 : ScriptableInvokeDefault(NPObject* aObject,
260 : const NPVariant* aArgs,
261 : uint32_t aArgCount,
262 : NPVariant* aResult);
263 :
264 : static bool
265 : ScriptableHasProperty(NPObject* aObject,
266 : NPIdentifier aName);
267 :
268 : static bool
269 : ScriptableGetProperty(NPObject* aObject,
270 : NPIdentifier aName,
271 : NPVariant* aResult);
272 :
273 : static bool
274 : ScriptableSetProperty(NPObject* aObject,
275 : NPIdentifier aName,
276 : const NPVariant* aValue);
277 :
278 : static bool
279 : ScriptableRemoveProperty(NPObject* aObject,
280 : NPIdentifier aName);
281 :
282 : static bool
283 : ScriptableEnumerate(NPObject* aObject,
284 : NPIdentifier** aIdentifiers,
285 : uint32_t* aCount);
286 :
287 : static bool
288 : ScriptableConstruct(NPObject* aObject,
289 : const NPVariant* aArgs,
290 : uint32_t aArgCount,
291 : NPVariant* aResult);
292 :
293 : NPObject*
294 : CreateProxyObject();
295 :
296 : // ResurrectProxyObject is only used with Proxy actors. It is called when the
297 : // parent process uses an actor whose NPObject was deleted by the child
298 : // process.
299 : bool ResurrectProxyObject();
300 :
301 : private:
302 : PluginInstanceChild* mInstance;
303 : NPObject* mObject;
304 : bool mInvalidated;
305 : int mProtectCount;
306 :
307 : ScriptableObjectType mType;
308 :
309 : static const NPClass sNPClass;
310 :
311 : static StoredIdentifier* HashIdentifier(const nsCString& aIdentifier);
312 : static void UnhashIdentifier(StoredIdentifier* aIdentifier);
313 :
314 : typedef nsDataHashtable<nsCStringHashKey, RefPtr<StoredIdentifier>> IdentifierTable;
315 : static IdentifierTable sIdentifiers;
316 :
317 0 : struct NPObjectData : public nsPtrHashKey<NPObject>
318 : {
319 0 : explicit NPObjectData(const NPObject* key)
320 0 : : nsPtrHashKey<NPObject>(key),
321 : instance(nullptr),
322 0 : actor(nullptr)
323 0 : { }
324 :
325 : // never nullptr
326 : PluginInstanceChild* instance;
327 :
328 : // sometimes nullptr (no actor associated with an NPObject)
329 : PluginScriptableObjectChild* actor;
330 : };
331 :
332 : /**
333 : * mObjectMap contains all the currently active NPObjects (from NPN_CreateObject until the
334 : * final release/dealloc, whether or not an actor is currently associated with the object.
335 : */
336 : static nsTHashtable<NPObjectData>* sObjectMap;
337 : };
338 :
339 : } /* namespace plugins */
340 : } /* namespace mozilla */
341 :
342 : #endif /* dom_plugins_PluginScriptableObjectChild_h */
|