Coverage Report

Created: 2018-09-25 14:53

/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_