|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: sw=4 ts=4 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 mozilla_plugins_PluginModuleParent_h |
|
8 #define mozilla_plugins_PluginModuleParent_h |
|
9 |
|
10 #include "base/process.h" |
|
11 #include "mozilla/FileUtils.h" |
|
12 #include "mozilla/PluginLibrary.h" |
|
13 #include "mozilla/plugins/ScopedMethodFactory.h" |
|
14 #include "mozilla/plugins/PluginProcessParent.h" |
|
15 #include "mozilla/plugins/PPluginModuleParent.h" |
|
16 #include "mozilla/plugins/PluginMessageUtils.h" |
|
17 #include "npapi.h" |
|
18 #include "npfunctions.h" |
|
19 #include "nsAutoPtr.h" |
|
20 #include "nsDataHashtable.h" |
|
21 #include "nsHashKeys.h" |
|
22 #include "nsIObserver.h" |
|
23 |
|
24 #ifdef MOZ_CRASHREPORTER |
|
25 #include "nsExceptionHandler.h" |
|
26 #endif |
|
27 |
|
28 namespace mozilla { |
|
29 namespace dom { |
|
30 class PCrashReporterParent; |
|
31 class CrashReporterParent; |
|
32 } |
|
33 |
|
34 namespace plugins { |
|
35 //----------------------------------------------------------------------------- |
|
36 |
|
37 class BrowserStreamParent; |
|
38 class PluginIdentifierParent; |
|
39 class PluginInstanceParent; |
|
40 |
|
41 #ifdef XP_WIN |
|
42 class PluginHangUIParent; |
|
43 #endif |
|
44 |
|
45 /** |
|
46 * PluginModuleParent |
|
47 * |
|
48 * This class implements the NPP API from the perspective of the rest |
|
49 * of Gecko, forwarding NPP calls along to the child process that is |
|
50 * actually running the plugin. |
|
51 * |
|
52 * This class /also/ implements a version of the NPN API, because the |
|
53 * child process needs to make these calls back into Gecko proper. |
|
54 * This class is responsible for "actually" making those function calls. |
|
55 */ |
|
56 class PluginModuleParent |
|
57 : public PPluginModuleParent |
|
58 , public PluginLibrary |
|
59 #ifdef MOZ_CRASHREPORTER_INJECTOR |
|
60 , public CrashReporter::InjectorCrashCallback |
|
61 #endif |
|
62 { |
|
63 private: |
|
64 typedef mozilla::PluginLibrary PluginLibrary; |
|
65 typedef mozilla::dom::PCrashReporterParent PCrashReporterParent; |
|
66 typedef mozilla::dom::CrashReporterParent CrashReporterParent; |
|
67 |
|
68 protected: |
|
69 |
|
70 virtual PPluginIdentifierParent* |
|
71 AllocPPluginIdentifierParent(const nsCString& aString, |
|
72 const int32_t& aInt, |
|
73 const bool& aTemporary) MOZ_OVERRIDE; |
|
74 |
|
75 virtual bool |
|
76 DeallocPPluginIdentifierParent(PPluginIdentifierParent* aActor) MOZ_OVERRIDE; |
|
77 |
|
78 PPluginInstanceParent* |
|
79 AllocPPluginInstanceParent(const nsCString& aMimeType, |
|
80 const uint16_t& aMode, |
|
81 const InfallibleTArray<nsCString>& aNames, |
|
82 const InfallibleTArray<nsCString>& aValues, |
|
83 NPError* rv) MOZ_OVERRIDE; |
|
84 |
|
85 virtual bool |
|
86 DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) MOZ_OVERRIDE; |
|
87 |
|
88 public: |
|
89 // aFilePath is UTF8, not native! |
|
90 PluginModuleParent(const char* aFilePath); |
|
91 virtual ~PluginModuleParent(); |
|
92 |
|
93 virtual void SetPlugin(nsNPAPIPlugin* plugin) MOZ_OVERRIDE |
|
94 { |
|
95 mPlugin = plugin; |
|
96 } |
|
97 |
|
98 virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; |
|
99 |
|
100 /** |
|
101 * LoadModule |
|
102 * |
|
103 * This may or may not launch a plugin child process, |
|
104 * and may or may not be very expensive. |
|
105 */ |
|
106 static PluginLibrary* LoadModule(const char* aFilePath); |
|
107 |
|
108 const NPNetscapeFuncs* GetNetscapeFuncs() { |
|
109 return mNPNIface; |
|
110 } |
|
111 |
|
112 PluginProcessParent* Process() const { return mSubprocess; } |
|
113 base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); } |
|
114 |
|
115 bool OkToCleanup() const { |
|
116 return !IsOnCxxStack(); |
|
117 } |
|
118 |
|
119 /** |
|
120 * Get an identifier actor for this NPIdentifier. If this is a temporary |
|
121 * identifier, the temporary refcount is increased by one. This method |
|
122 * is intended only for use by StackIdentifier and the scriptable |
|
123 * Enumerate hook. |
|
124 */ |
|
125 PluginIdentifierParent* |
|
126 GetIdentifierForNPIdentifier(NPP npp, NPIdentifier aIdentifier); |
|
127 |
|
128 void ProcessRemoteNativeEventsInInterruptCall(); |
|
129 |
|
130 void TerminateChildProcess(MessageLoop* aMsgLoop); |
|
131 |
|
132 #ifdef XP_WIN |
|
133 void |
|
134 ExitedCxxStack() MOZ_OVERRIDE; |
|
135 #endif // XP_WIN |
|
136 |
|
137 protected: |
|
138 virtual mozilla::ipc::RacyInterruptPolicy |
|
139 MediateInterruptRace(const Message& parent, const Message& child) MOZ_OVERRIDE |
|
140 { |
|
141 return MediateRace(parent, child); |
|
142 } |
|
143 |
|
144 virtual bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE; |
|
145 |
|
146 virtual bool |
|
147 RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE; |
|
148 |
|
149 virtual bool |
|
150 AnswerNPN_UserAgent(nsCString* userAgent) MOZ_OVERRIDE; |
|
151 |
|
152 virtual bool |
|
153 AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable, |
|
154 NPError* aError, |
|
155 bool* aBoolVal) MOZ_OVERRIDE; |
|
156 |
|
157 virtual bool AnswerProcessSomeEvents() MOZ_OVERRIDE; |
|
158 |
|
159 virtual bool |
|
160 RecvProcessNativeEventsInInterruptCall() MOZ_OVERRIDE; |
|
161 |
|
162 virtual bool |
|
163 RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal, |
|
164 const int32_t& aX, const int32_t& aY, |
|
165 const size_t& aWidth, const size_t& aHeight) MOZ_OVERRIDE; |
|
166 |
|
167 virtual bool |
|
168 RecvPluginHideWindow(const uint32_t& aWindowId) MOZ_OVERRIDE; |
|
169 |
|
170 virtual PCrashReporterParent* |
|
171 AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id, |
|
172 uint32_t* processType) MOZ_OVERRIDE; |
|
173 virtual bool |
|
174 DeallocPCrashReporterParent(PCrashReporterParent* actor) MOZ_OVERRIDE; |
|
175 |
|
176 virtual bool |
|
177 RecvSetCursor(const NSCursorInfo& aCursorInfo) MOZ_OVERRIDE; |
|
178 |
|
179 virtual bool |
|
180 RecvShowCursor(const bool& aShow) MOZ_OVERRIDE; |
|
181 |
|
182 virtual bool |
|
183 RecvPushCursor(const NSCursorInfo& aCursorInfo) MOZ_OVERRIDE; |
|
184 |
|
185 virtual bool |
|
186 RecvPopCursor() MOZ_OVERRIDE; |
|
187 |
|
188 virtual bool |
|
189 RecvGetNativeCursorsSupported(bool* supported) MOZ_OVERRIDE; |
|
190 |
|
191 virtual bool |
|
192 RecvNPN_SetException(PPluginScriptableObjectParent* aActor, |
|
193 const nsCString& aMessage) MOZ_OVERRIDE; |
|
194 |
|
195 virtual bool |
|
196 RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE; |
|
197 |
|
198 static PluginInstanceParent* InstCast(NPP instance); |
|
199 static BrowserStreamParent* StreamCast(NPP instance, NPStream* s); |
|
200 |
|
201 private: |
|
202 void SetPluginFuncs(NPPluginFuncs* aFuncs); |
|
203 |
|
204 // Implement the module-level functions from NPAPI; these are |
|
205 // normally resolved directly from the DSO. |
|
206 #ifdef OS_LINUX |
|
207 NPError NP_Initialize(const NPNetscapeFuncs* npnIface, |
|
208 NPPluginFuncs* nppIface); |
|
209 #else |
|
210 NPError NP_Initialize(const NPNetscapeFuncs* npnIface); |
|
211 NPError NP_GetEntryPoints(NPPluginFuncs* nppIface); |
|
212 #endif |
|
213 |
|
214 // NPP-like API that Gecko calls are trampolined into. These |
|
215 // messages then get forwarded along to the plugin instance, |
|
216 // and then eventually the child process. |
|
217 |
|
218 static NPError NPP_Destroy(NPP instance, NPSavedData** save); |
|
219 |
|
220 static NPError NPP_SetWindow(NPP instance, NPWindow* window); |
|
221 static NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, |
|
222 NPBool seekable, uint16_t* stype); |
|
223 static NPError NPP_DestroyStream(NPP instance, |
|
224 NPStream* stream, NPReason reason); |
|
225 static int32_t NPP_WriteReady(NPP instance, NPStream* stream); |
|
226 static int32_t NPP_Write(NPP instance, NPStream* stream, |
|
227 int32_t offset, int32_t len, void* buffer); |
|
228 static void NPP_StreamAsFile(NPP instance, |
|
229 NPStream* stream, const char* fname); |
|
230 static void NPP_Print(NPP instance, NPPrint* platformPrint); |
|
231 static int16_t NPP_HandleEvent(NPP instance, void* event); |
|
232 static void NPP_URLNotify(NPP instance, const char* url, |
|
233 NPReason reason, void* notifyData); |
|
234 static NPError NPP_GetValue(NPP instance, |
|
235 NPPVariable variable, void *ret_value); |
|
236 static NPError NPP_SetValue(NPP instance, NPNVariable variable, |
|
237 void *value); |
|
238 static void NPP_URLRedirectNotify(NPP instance, const char* url, |
|
239 int32_t status, void* notifyData); |
|
240 |
|
241 virtual bool HasRequiredFunctions(); |
|
242 virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); |
|
243 virtual nsresult GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer); |
|
244 virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize); |
|
245 virtual bool IsOOP() MOZ_OVERRIDE { return true; } |
|
246 virtual nsresult SetBackgroundUnknown(NPP instance) MOZ_OVERRIDE; |
|
247 virtual nsresult BeginUpdateBackground(NPP instance, |
|
248 const nsIntRect& aRect, |
|
249 gfxContext** aCtx) MOZ_OVERRIDE; |
|
250 virtual nsresult EndUpdateBackground(NPP instance, |
|
251 gfxContext* aCtx, |
|
252 const nsIntRect& aRect) MOZ_OVERRIDE; |
|
253 |
|
254 #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) |
|
255 virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error); |
|
256 #else |
|
257 virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error); |
|
258 #endif |
|
259 virtual nsresult NP_Shutdown(NPError* error); |
|
260 virtual nsresult NP_GetMIMEDescription(const char** mimeDesc); |
|
261 virtual nsresult NP_GetValue(void *future, NPPVariable aVariable, |
|
262 void *aValue, NPError* error); |
|
263 #if defined(XP_WIN) || defined(XP_MACOSX) |
|
264 virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error); |
|
265 #endif |
|
266 virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, |
|
267 uint16_t mode, int16_t argc, char* argn[], |
|
268 char* argv[], NPSavedData* saved, |
|
269 NPError* error); |
|
270 virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags, |
|
271 uint64_t maxAge); |
|
272 virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result); |
|
273 |
|
274 #if defined(XP_MACOSX) |
|
275 virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing); |
|
276 virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor); |
|
277 #endif |
|
278 |
|
279 private: |
|
280 CrashReporterParent* CrashReporter(); |
|
281 |
|
282 #ifdef MOZ_CRASHREPORTER |
|
283 void ProcessFirstMinidump(); |
|
284 void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes); |
|
285 #endif |
|
286 void CleanupFromTimeout(const bool aByHangUI); |
|
287 void SetChildTimeout(const int32_t aChildTimeout); |
|
288 static void TimeoutChanged(const char* aPref, void* aModule); |
|
289 void NotifyPluginCrashed(); |
|
290 |
|
291 #ifdef MOZ_ENABLE_PROFILER_SPS |
|
292 void InitPluginProfiling(); |
|
293 void ShutdownPluginProfiling(); |
|
294 #endif |
|
295 |
|
296 PluginProcessParent* mSubprocess; |
|
297 bool mShutdown; |
|
298 bool mClearSiteDataSupported; |
|
299 bool mGetSitesWithDataSupported; |
|
300 const NPNetscapeFuncs* mNPNIface; |
|
301 nsDataHashtable<nsPtrHashKey<void>, PluginIdentifierParent*> mIdentifiers; |
|
302 nsNPAPIPlugin* mPlugin; |
|
303 ScopedMethodFactory<PluginModuleParent> mTaskFactory; |
|
304 nsString mPluginDumpID; |
|
305 nsString mBrowserDumpID; |
|
306 nsString mHangID; |
|
307 nsRefPtr<nsIObserver> mProfilerObserver; |
|
308 #ifdef XP_WIN |
|
309 InfallibleTArray<float> mPluginCpuUsageOnHang; |
|
310 PluginHangUIParent *mHangUIParent; |
|
311 bool mHangUIEnabled; |
|
312 bool mIsTimerReset; |
|
313 #ifdef MOZ_CRASHREPORTER |
|
314 /** |
|
315 * This mutex protects the crash reporter when the Plugin Hang UI event |
|
316 * handler is executing off main thread. It is intended to protect both |
|
317 * the mCrashReporter variable in addition to the CrashReporterParent object |
|
318 * that mCrashReporter refers to. |
|
319 */ |
|
320 mozilla::Mutex mCrashReporterMutex; |
|
321 CrashReporterParent* mCrashReporter; |
|
322 #endif // MOZ_CRASHREPORTER |
|
323 |
|
324 |
|
325 void |
|
326 EvaluateHangUIState(const bool aReset); |
|
327 |
|
328 bool |
|
329 GetPluginName(nsAString& aPluginName); |
|
330 |
|
331 /** |
|
332 * Launches the Plugin Hang UI. |
|
333 * |
|
334 * @return true if plugin-hang-ui.exe has been successfully launched. |
|
335 * false if the Plugin Hang UI is disabled, already showing, |
|
336 * or the launch failed. |
|
337 */ |
|
338 bool |
|
339 LaunchHangUI(); |
|
340 |
|
341 /** |
|
342 * Finishes the Plugin Hang UI and cancels if it is being shown to the user. |
|
343 */ |
|
344 void |
|
345 FinishHangUI(); |
|
346 #endif |
|
347 |
|
348 #ifdef MOZ_X11 |
|
349 // Dup of plugin's X socket, used to scope its resources to this |
|
350 // object instead of the plugin process's lifetime |
|
351 ScopedClose mPluginXSocketFdDup; |
|
352 #endif |
|
353 |
|
354 friend class mozilla::dom::CrashReporterParent; |
|
355 |
|
356 #ifdef MOZ_CRASHREPORTER_INJECTOR |
|
357 void InitializeInjector(); |
|
358 |
|
359 void OnCrash(DWORD processID) MOZ_OVERRIDE; |
|
360 |
|
361 DWORD mFlashProcess1; |
|
362 DWORD mFlashProcess2; |
|
363 #endif |
|
364 }; |
|
365 |
|
366 } // namespace plugins |
|
367 } // namespace mozilla |
|
368 |
|
369 #endif // mozilla_plugins_PluginModuleParent_h |