Coverage Report

Created: 2018-09-25 14:53

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