/src/mozilla-central/dom/plugins/ipc/PluginScriptableObjectChild.h
Line | Count | Source (jump to first uncovered line) |
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 | | ChildNPObject() |
26 | | : NPObject(), parent(nullptr), invalidated(false) |
27 | | { |
28 | | MOZ_COUNT_CTOR(ChildNPObject); |
29 | | } |
30 | | |
31 | | ~ChildNPObject() |
32 | | { |
33 | | MOZ_COUNT_DTOR(ChildNPObject); |
34 | | } |
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 | | GetClass() |
115 | | { |
116 | | return &sNPClass; |
117 | | } |
118 | | |
119 | | PluginInstanceChild* |
120 | | GetInstance() const |
121 | | { |
122 | | 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 | | Type() const { |
157 | | return mType; |
158 | | } |
159 | | |
160 | | private: |
161 | | struct StoredIdentifier |
162 | | { |
163 | | nsCString mIdentifier; |
164 | | nsAutoRefCnt mRefCnt; |
165 | | bool mPermanent; |
166 | | |
167 | | nsrefcnt AddRef() { |
168 | | ++mRefCnt; |
169 | | return mRefCnt; |
170 | | } |
171 | | |
172 | | nsrefcnt Release() { |
173 | | --mRefCnt; |
174 | | if (mRefCnt == 0) { |
175 | | delete this; |
176 | | return 0; |
177 | | } |
178 | | return mRefCnt; |
179 | | } |
180 | | |
181 | | explicit StoredIdentifier(const nsCString& aIdentifier) |
182 | | : mIdentifier(aIdentifier), mRefCnt(), mPermanent(false) |
183 | | { MOZ_COUNT_CTOR(StoredIdentifier); } |
184 | | |
185 | | ~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 | | void MakePermanent() |
197 | 0 | { |
198 | 0 | if (mStored) { |
199 | 0 | mStored->mPermanent = true; |
200 | 0 | } |
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 | | 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 | | struct NPObjectData : public nsPtrHashKey<NPObject> |
318 | | { |
319 | | explicit NPObjectData(const NPObject* key) |
320 | | : nsPtrHashKey<NPObject>(key), |
321 | | instance(nullptr), |
322 | | actor(nullptr) |
323 | | { } |
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 */ |