Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef GMPParent_h_
7 : #define GMPParent_h_
8 :
9 : #include "GMPProcessParent.h"
10 : #include "GMPServiceParent.h"
11 : #include "GMPDecryptorParent.h"
12 : #include "GMPVideoDecoderParent.h"
13 : #include "GMPVideoEncoderParent.h"
14 : #include "GMPTimerParent.h"
15 : #include "GMPStorageParent.h"
16 : #include "mozilla/gmp/PGMPParent.h"
17 : #include "nsCOMPtr.h"
18 : #include "nscore.h"
19 : #include "nsISupports.h"
20 : #include "nsString.h"
21 : #include "nsTArray.h"
22 : #include "nsIFile.h"
23 : #include "mozilla/MozPromise.h"
24 :
25 : #ifdef MOZ_CRASHREPORTER
26 : #include "nsExceptionHandler.h"
27 : #endif
28 :
29 : namespace mozilla {
30 : namespace ipc {
31 : class CrashReporterHost;
32 : } // namespace ipc
33 : namespace gmp {
34 :
35 5 : class GMPCapability
36 : {
37 : public:
38 4 : explicit GMPCapability() {}
39 4 : GMPCapability(GMPCapability&& aOther)
40 4 : : mAPIName(Move(aOther.mAPIName))
41 4 : , mAPITags(Move(aOther.mAPITags))
42 : {
43 4 : }
44 0 : explicit GMPCapability(const nsCString& aAPIName)
45 0 : : mAPIName(aAPIName)
46 0 : {}
47 0 : explicit GMPCapability(const GMPCapability& aOther) = default;
48 : nsCString mAPIName;
49 : nsTArray<nsCString> mAPITags;
50 :
51 : static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
52 : const nsCString& aAPI,
53 : const nsTArray<nsCString>& aTags);
54 :
55 : static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
56 : const nsCString& aAPI,
57 : const nsCString& aTag);
58 : };
59 :
60 : enum GMPState {
61 : GMPStateNotLoaded,
62 : GMPStateLoaded,
63 : GMPStateUnloading,
64 : GMPStateClosing
65 : };
66 :
67 : class GMPContentParent;
68 :
69 : class GMPParent final : public PGMPParent
70 : {
71 : public:
72 7 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPParent)
73 :
74 : explicit GMPParent(AbstractThread* aMainThread);
75 :
76 : RefPtr<GenericPromise> Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
77 : nsresult CloneFrom(const GMPParent* aOther);
78 :
79 : void Crash();
80 :
81 : nsresult LoadProcess();
82 :
83 : // Called internally to close this if we don't need it
84 : void CloseIfUnused();
85 :
86 : // Notify all active de/encoders that we are closing, either because of
87 : // normal shutdown or unexpected shutdown/crash.
88 : void CloseActive(bool aDieWhenUnloaded);
89 :
90 : // Tell the plugin to die after shutdown.
91 : void MarkForDeletion();
92 : bool IsMarkedForDeletion();
93 :
94 : // Called by the GMPService to forcibly close active de/encoders at shutdown
95 : void Shutdown();
96 :
97 : // This must not be called while we're in the middle of abnormal ActorDestroy
98 : void DeleteProcess();
99 :
100 : GMPState State() const;
101 : nsCOMPtr<nsISerialEventTarget> GMPEventTarget();
102 :
103 : // A GMP can either be a single instance shared across all NodeIds (like
104 : // in the OpenH264 case), or we can require a new plugin instance for every
105 : // NodeIds running the plugin (as in the EME plugin case).
106 : //
107 : // A NodeId is a hash of the ($urlBarOrigin, $ownerDocOrigin) pair.
108 : //
109 : // Plugins are associated with an NodeIds by calling SetNodeId() before
110 : // loading.
111 : //
112 : // If a plugin has no NodeId specified and it is loaded, it is assumed to
113 : // be shared across NodeIds.
114 :
115 : // Specifies that a GMP can only work with the specified NodeIds.
116 : void SetNodeId(const nsACString& aNodeId);
117 0 : const nsACString& GetNodeId() const { return mNodeId; }
118 :
119 : const nsCString& GetDisplayName() const;
120 : const nsCString& GetVersion() const;
121 : uint32_t GetPluginId() const;
122 : nsString GetPluginBaseName() const;
123 :
124 : // Returns true if a plugin can be or is being used across multiple NodeIds.
125 : bool CanBeSharedCrossNodeIds() const;
126 :
127 : // A GMP can be used from a NodeId if it's already been set to work with
128 : // that NodeId, or if it's not been set to work with any NodeId and has
129 : // not yet been loaded (i.e. it's not shared across NodeIds).
130 : bool CanBeUsedFrom(const nsACString& aNodeId) const;
131 :
132 0 : already_AddRefed<nsIFile> GetDirectory() {
133 0 : return nsCOMPtr<nsIFile>(mDirectory).forget();
134 : }
135 :
136 : void AbortAsyncShutdown();
137 :
138 : // Called when the child process has died.
139 : void ChildTerminated();
140 :
141 : bool OpenPGMPContent();
142 :
143 : void GetGMPContentParent(UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>&& aPromiseHolder);
144 : already_AddRefed<GMPContentParent> ForgetGMPContentParent();
145 :
146 : bool EnsureProcessLoaded(base::ProcessId* aID);
147 :
148 : void IncrementGMPContentChildCount();
149 :
150 3 : const nsTArray<GMPCapability>& GetCapabilities() const { return mCapabilities; }
151 :
152 : private:
153 : ~GMPParent();
154 :
155 : RefPtr<GeckoMediaPluginServiceParent> mService;
156 : bool EnsureProcessLoaded();
157 : RefPtr<GenericPromise> ReadGMPMetaData();
158 : RefPtr<GenericPromise> ReadGMPInfoFile(nsIFile* aFile);
159 : RefPtr<GenericPromise> ParseChromiumManifest(const nsAString& aJSON); // Main thread.
160 : RefPtr<GenericPromise> ReadChromiumManifestFile(nsIFile* aFile); // GMP thread.
161 : #ifdef MOZ_CRASHREPORTER
162 : void WriteExtraDataForMinidump();
163 : bool GetCrashID(nsString& aResult);
164 : #endif
165 : void ActorDestroy(ActorDestroyReason aWhy) override;
166 :
167 : mozilla::ipc::IPCResult RecvInitCrashReporter(Shmem&& shmem, const NativeThreadId& aThreadId) override;
168 :
169 : mozilla::ipc::IPCResult RecvPGMPStorageConstructor(PGMPStorageParent* actor) override;
170 : PGMPStorageParent* AllocPGMPStorageParent() override;
171 : bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
172 :
173 : mozilla::ipc::IPCResult RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
174 : PGMPTimerParent* AllocPGMPTimerParent() override;
175 : bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
176 :
177 : mozilla::ipc::IPCResult RecvPGMPContentChildDestroyed() override;
178 0 : bool IsUsed()
179 : {
180 0 : return mGMPContentChildCount > 0 ||
181 0 : !mGetContentParentPromises.IsEmpty();
182 : }
183 :
184 : void ResolveGetContentParentPromises();
185 : void RejectGetContentParentPromises();
186 :
187 : GMPState mState;
188 : nsCOMPtr<nsIFile> mDirectory; // plugin directory on disk
189 : nsString mName; // base name of plugin on disk, UTF-16 because used for paths
190 : nsCString mDisplayName; // name of plugin displayed to users
191 : nsCString mDescription; // description of plugin for display to users
192 : nsCString mVersion;
193 : #ifdef XP_WIN
194 : nsCString mLibs;
195 : #endif
196 : nsString mAdapter;
197 : uint32_t mPluginId;
198 : nsTArray<GMPCapability> mCapabilities;
199 : GMPProcessParent* mProcess;
200 : bool mDeleteProcessOnlyOnUnload;
201 : bool mAbnormalShutdownInProgress;
202 : bool mIsBlockingDeletion;
203 :
204 : bool mCanDecrypt;
205 :
206 : nsTArray<RefPtr<GMPTimerParent>> mTimers;
207 : nsTArray<RefPtr<GMPStorageParent>> mStorage;
208 : // NodeId the plugin is assigned to, or empty if the the plugin is not
209 : // assigned to a NodeId.
210 : nsCString mNodeId;
211 : // This is used for GMP content in the parent, there may be more of these in
212 : // the content processes.
213 : RefPtr<GMPContentParent> mGMPContentParent;
214 : nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>> mGetContentParentPromises;
215 : uint32_t mGMPContentChildCount;
216 :
217 : int mChildPid;
218 :
219 : // We hold a self reference to ourself while the child process is alive.
220 : // This ensures that if the GMPService tries to shut us down and drops
221 : // its reference to us, we stay alive long enough for the child process
222 : // to terminate gracefully.
223 : bool mHoldingSelfRef;
224 :
225 : #ifdef MOZ_CRASHREPORTER
226 : UniquePtr<ipc::CrashReporterHost> mCrashReporter;
227 : #endif
228 :
229 : const RefPtr<AbstractThread> mMainThread;
230 : };
231 :
232 : } // namespace gmp
233 : } // namespace mozilla
234 :
235 : #endif // GMPParent_h_
|