/src/mozilla-central/dom/media/gmp/GMPServiceParent.h
Line | Count | Source (jump to first uncovered line) |
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 GMPServiceParent_h_ |
7 | | #define GMPServiceParent_h_ |
8 | | |
9 | | #include "GMPService.h" |
10 | | #include "mozilla/gmp/PGMPServiceParent.h" |
11 | | #include "mozIGeckoMediaPluginChromeService.h" |
12 | | #include "nsClassHashtable.h" |
13 | | #include "nsDataHashtable.h" |
14 | | #include "mozilla/Atomics.h" |
15 | | #include "nsIAsyncShutdown.h" |
16 | | #include "nsThreadUtils.h" |
17 | | #include "mozilla/MozPromise.h" |
18 | | #include "GMPStorage.h" |
19 | | |
20 | | template <class> struct already_AddRefed; |
21 | | |
22 | | namespace mozilla { |
23 | | namespace gmp { |
24 | | |
25 | | class GMPParent; |
26 | | class GMPServiceParent; |
27 | | |
28 | | class GeckoMediaPluginServiceParent final : public GeckoMediaPluginService |
29 | | , public mozIGeckoMediaPluginChromeService |
30 | | , public nsIAsyncShutdownBlocker |
31 | | { |
32 | | public: |
33 | | static already_AddRefed<GeckoMediaPluginServiceParent> GetSingleton(); |
34 | | |
35 | | GeckoMediaPluginServiceParent(); |
36 | | nsresult Init() override; |
37 | | |
38 | | NS_DECL_ISUPPORTS_INHERITED |
39 | | NS_DECL_NSIASYNCSHUTDOWNBLOCKER |
40 | | |
41 | | // mozIGeckoMediaPluginService |
42 | | NS_IMETHOD HasPluginForAPI(const nsACString& aAPI, |
43 | | nsTArray<nsCString>* aTags, |
44 | | bool *aRetVal) override; |
45 | | NS_IMETHOD GetNodeId(const nsAString& aOrigin, |
46 | | const nsAString& aTopLevelOrigin, |
47 | | const nsAString& aGMPName, |
48 | | UniquePtr<GetNodeIdCallback>&& aCallback) override; |
49 | | |
50 | | NS_DECL_MOZIGECKOMEDIAPLUGINCHROMESERVICE |
51 | | NS_DECL_NSIOBSERVER |
52 | | |
53 | | RefPtr<GenericPromise> EnsureInitialized(); |
54 | | RefPtr<GenericPromise> AsyncAddPluginDirectory(const nsAString& aDirectory); |
55 | | |
56 | | // GMP thread access only |
57 | | bool IsShuttingDown(); |
58 | | |
59 | | already_AddRefed<GMPStorage> GetMemoryStorageFor(const nsACString& aNodeId); |
60 | | nsresult ForgetThisSiteNative(const nsAString& aSite, |
61 | | const mozilla::OriginAttributesPattern& aPattern); |
62 | | |
63 | | // Notifies that some user of this class is created/destroyed. |
64 | | void ServiceUserCreated(GMPServiceParent* aServiceParent); |
65 | | void ServiceUserDestroyed(GMPServiceParent* aServiceParent); |
66 | | |
67 | | void UpdateContentProcessGMPCapabilities(); |
68 | | |
69 | 0 | AbstractThread* MainThread() const { return mMainThread; } |
70 | | |
71 | | private: |
72 | | friend class GMPServiceParent; |
73 | | |
74 | | virtual ~GeckoMediaPluginServiceParent(); |
75 | | |
76 | | void ClearStorage(); |
77 | | |
78 | | already_AddRefed<GMPParent> SelectPluginForAPI(const nsACString& aNodeId, |
79 | | const nsCString& aAPI, |
80 | | const nsTArray<nsCString>& aTags); |
81 | | |
82 | | already_AddRefed<GMPParent> FindPluginForAPIFrom(size_t aSearchStartIndex, |
83 | | const nsCString& aAPI, |
84 | | const nsTArray<nsCString>& aTags, |
85 | | size_t* aOutPluginIndex); |
86 | | |
87 | | nsresult GetNodeId(const nsAString& aOrigin, const nsAString& aTopLevelOrigin, |
88 | | const nsAString& aGMPName, nsACString& aOutId); |
89 | | |
90 | | void UnloadPlugins(); |
91 | | void CrashPlugins(); |
92 | | void NotifySyncShutdownComplete(); |
93 | | |
94 | | void ProcessPossiblePlugin(nsIFile* aDir); |
95 | | |
96 | | void RemoveOnGMPThread(const nsAString& aDirectory, |
97 | | const bool aDeleteFromDisk, |
98 | | const bool aCanDefer); |
99 | | |
100 | | struct DirectoryFilter { |
101 | | virtual bool operator()(nsIFile* aPath) = 0; |
102 | 0 | ~DirectoryFilter() {} |
103 | | }; |
104 | | void ClearNodeIdAndPlugin(DirectoryFilter& aFilter); |
105 | | void ClearNodeIdAndPlugin(nsIFile* aPluginStorageDir, |
106 | | DirectoryFilter& aFilter); |
107 | | void ForgetThisSiteOnGMPThread(const nsACString& aOrigin, |
108 | | const mozilla::OriginAttributesPattern& aPattern); |
109 | | void ClearRecentHistoryOnGMPThread(PRTime aSince); |
110 | | |
111 | | already_AddRefed<GMPParent> GetById(uint32_t aPluginId); |
112 | | |
113 | | protected: |
114 | | friend class GMPParent; |
115 | | void ReAddOnGMPThread(const RefPtr<GMPParent>& aOld); |
116 | | void PluginTerminated(const RefPtr<GMPParent>& aOld); |
117 | | void InitializePlugins(AbstractThread* aAbstractGMPThread) override; |
118 | | RefPtr<GenericPromise::AllPromiseType> LoadFromEnvironment(); |
119 | | RefPtr<GenericPromise> AddOnGMPThread(nsString aDirectory); |
120 | | |
121 | | virtual RefPtr<GetGMPContentParentPromise> GetContentParent( |
122 | | GMPCrashHelper* aHelper, |
123 | | const nsACString& aNodeIdString, |
124 | | const nsCString& aAPI, |
125 | | const nsTArray<nsCString>& aTags) override; |
126 | | |
127 | | RefPtr<GetGMPContentParentPromise> GetContentParent( |
128 | | GMPCrashHelper* aHelper, |
129 | | const NodeId& aNodeId, |
130 | | const nsCString& aAPI, |
131 | | const nsTArray<nsCString>& aTags) override; |
132 | | |
133 | | private: |
134 | | // Creates a copy of aOriginal. Note that the caller is responsible for |
135 | | // adding this to GeckoMediaPluginServiceParent::mPlugins. |
136 | | already_AddRefed<GMPParent> ClonePlugin(const GMPParent* aOriginal); |
137 | | nsresult EnsurePluginsOnDiskScanned(); |
138 | | nsresult InitStorage(); |
139 | | |
140 | | class PathRunnable : public Runnable |
141 | | { |
142 | | public: |
143 | | enum EOperation { |
144 | | REMOVE, |
145 | | REMOVE_AND_DELETE_FROM_DISK, |
146 | | }; |
147 | | |
148 | | PathRunnable(GeckoMediaPluginServiceParent* aService, |
149 | | const nsAString& aPath, |
150 | | EOperation aOperation, |
151 | | bool aDefer = false) |
152 | | : Runnable("gmp::GeckoMediaPluginServiceParent::PathRunnable") |
153 | | , mService(aService) |
154 | | , mPath(aPath) |
155 | | , mOperation(aOperation) |
156 | | , mDefer(aDefer) |
157 | 0 | { } |
158 | | |
159 | | NS_DECL_NSIRUNNABLE |
160 | | |
161 | | private: |
162 | | RefPtr<GeckoMediaPluginServiceParent> mService; |
163 | | nsString mPath; |
164 | | EOperation mOperation; |
165 | | bool mDefer; |
166 | | }; |
167 | | |
168 | | // Protected by mMutex from the base class. |
169 | | nsTArray<RefPtr<GMPParent>> mPlugins; |
170 | | bool mShuttingDown; |
171 | | |
172 | | // True if we've inspected MOZ_GMP_PATH on the GMP thread and loaded any |
173 | | // plugins found there into mPlugins. |
174 | | Atomic<bool> mScannedPluginOnDisk; |
175 | | |
176 | | template<typename T> |
177 | | class MainThreadOnly { |
178 | | public: |
179 | | MOZ_IMPLICIT MainThreadOnly(T aValue) |
180 | | : mValue(aValue) |
181 | 0 | {} |
182 | 0 | operator T&() { |
183 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
184 | 0 | return mValue; |
185 | 0 | } |
186 | | |
187 | | private: |
188 | | T mValue; |
189 | | }; |
190 | | |
191 | | MainThreadOnly<bool> mWaitingForPluginsSyncShutdown; |
192 | | |
193 | | nsTArray<nsString> mPluginsWaitingForDeletion; |
194 | | |
195 | | nsCOMPtr<nsIFile> mStorageBaseDir; |
196 | | |
197 | | // Hashes of (origin,topLevelOrigin) to the node id for |
198 | | // non-persistent sessions. |
199 | | nsClassHashtable<nsUint32HashKey, nsCString> mTempNodeIds; |
200 | | |
201 | | // Hashes node id to whether that node id is allowed to store data |
202 | | // persistently on disk. |
203 | | nsDataHashtable<nsCStringHashKey, bool> mPersistentStorageAllowed; |
204 | | |
205 | | // Synchronization for barrier that ensures we've loaded GMPs from |
206 | | // MOZ_GMP_PATH before allowing GetContentParentFrom() to proceed. |
207 | | Monitor mInitPromiseMonitor; |
208 | | MozPromiseHolder<GenericPromise> mInitPromise; |
209 | | bool mLoadPluginsFromDiskComplete; |
210 | | |
211 | | // Hashes nodeId to the hashtable of storage for that nodeId. |
212 | | nsRefPtrHashtable<nsCStringHashKey, GMPStorage> mTempGMPStorage; |
213 | | |
214 | | // Tracks how many IPC connections to GMPServices running in content |
215 | | // processes we have. When this is empty we can safely shut down. |
216 | | // Synchronized across thread via mMutex in base class. |
217 | | nsTArray<GMPServiceParent*> mServiceParents; |
218 | | |
219 | | const RefPtr<AbstractThread> mMainThread; |
220 | | }; |
221 | | |
222 | | nsresult ReadSalt(nsIFile* aPath, nsACString& aOutData); |
223 | | bool MatchOrigin(nsIFile* aPath, |
224 | | const nsACString& aSite, |
225 | | const mozilla::OriginAttributesPattern& aPattern); |
226 | | |
227 | | class GMPServiceParent final : public PGMPServiceParent |
228 | | { |
229 | | public: |
230 | | explicit GMPServiceParent(GeckoMediaPluginServiceParent* aService); |
231 | | virtual ~GMPServiceParent(); |
232 | | |
233 | | ipc::IPCResult RecvGetGMPNodeId(const nsString& aOrigin, |
234 | | const nsString& aTopLevelOrigin, |
235 | | const nsString& aGMPName, |
236 | | nsCString* aID) override; |
237 | | void ActorDestroy(ActorDestroyReason aWhy) override; |
238 | | |
239 | | static bool Create(Endpoint<PGMPServiceParent>&& aGMPService); |
240 | | |
241 | | ipc::IPCResult RecvLaunchGMP(const nsCString& aNodeId, |
242 | | const nsCString& aAPI, |
243 | | nsTArray<nsCString>&& aTags, |
244 | | nsTArray<ProcessId>&& aAlreadyBridgedTo, |
245 | | uint32_t* aOutPluginId, |
246 | | ProcessId* aOutID, |
247 | | nsCString* aOutDisplayName, |
248 | | Endpoint<PGMPContentParent>* aOutEndpoint, |
249 | | nsresult* aOutRv, |
250 | | nsCString* aOutErrorDescription) override; |
251 | | |
252 | | ipc::IPCResult RecvLaunchGMPForNodeId( |
253 | | const NodeIdData& nodeId, |
254 | | const nsCString& aAPI, |
255 | | nsTArray<nsCString>&& aTags, |
256 | | nsTArray<ProcessId>&& aAlreadyBridgedTo, |
257 | | uint32_t* aOutPluginId, |
258 | | ProcessId* aOutID, |
259 | | nsCString* aOutDisplayName, |
260 | | Endpoint<PGMPContentParent>* aOutEndpoint, |
261 | | nsresult* aOutRv, |
262 | | nsCString* aOutErrorDescription) override; |
263 | | |
264 | | private: |
265 | | void CloseTransport(Monitor* aSyncMonitor, bool* aCompleted); |
266 | | |
267 | | RefPtr<GeckoMediaPluginServiceParent> mService; |
268 | | }; |
269 | | |
270 | | } // namespace gmp |
271 | | } // namespace mozilla |
272 | | |
273 | | #endif // GMPServiceParent_h_ |