summaryrefslogtreecommitdiffstats
path: root/dom/media/gmp/GMPParent.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/media/gmp/GMPParent.h248
1 files changed, 248 insertions, 0 deletions
diff --git a/dom/media/gmp/GMPParent.h b/dom/media/gmp/GMPParent.h
new file mode 100644
index 0000000000..fa5a433c7b
--- /dev/null
+++ b/dom/media/gmp/GMPParent.h
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GMPParent_h_
+#define GMPParent_h_
+
+#include "GMPProcessParent.h"
+#include "GMPServiceParent.h"
+#include "GMPVideoDecoderParent.h"
+#include "GMPVideoEncoderParent.h"
+#include "GMPTimerParent.h"
+#include "GMPStorageParent.h"
+#include "mozilla/gmp/PGMPParent.h"
+#include "mozilla/ipc/CrashReporterHelper.h"
+#include "nsCOMPtr.h"
+#include "nscore.h"
+#include "nsISupports.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsIFile.h"
+#include "mozilla/MozPromise.h"
+
+namespace mozilla::gmp {
+
+class GMPCapability {
+ public:
+ explicit GMPCapability() = default;
+ GMPCapability(GMPCapability&& aOther)
+ : mAPIName(std::move(aOther.mAPIName)),
+ mAPITags(std::move(aOther.mAPITags)) {}
+ explicit GMPCapability(const nsACString& aAPIName) : mAPIName(aAPIName) {}
+ explicit GMPCapability(const GMPCapability& aOther) = default;
+ nsCString mAPIName;
+ CopyableTArray<nsCString> mAPITags;
+
+ static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
+ const nsACString& aAPI,
+ const nsTArray<nsCString>& aTags);
+
+ static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
+ const nsACString& aAPI, const nsCString& aTag);
+};
+
+enum GMPState {
+ GMPStateNotLoaded,
+ GMPStateLoaded,
+ GMPStateUnloading,
+ GMPStateClosing
+};
+
+class GMPContentParent;
+
+class GMPParent final
+ : public PGMPParent,
+ public ipc::CrashReporterHelper<GeckoProcessType_GMPlugin> {
+ friend class PGMPParent;
+
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPParent)
+
+ GMPParent();
+
+ RefPtr<GenericPromise> Init(GeckoMediaPluginServiceParent* aService,
+ nsIFile* aPluginDir);
+ void CloneFrom(const GMPParent* aOther);
+
+ void Crash();
+
+ nsresult LoadProcess();
+
+ // Called internally to close this if we don't need it
+ void CloseIfUnused();
+
+ // Notify all active de/encoders that we are closing, either because of
+ // normal shutdown or unexpected shutdown/crash.
+ void CloseActive(bool aDieWhenUnloaded);
+
+ // Tell the plugin to die after shutdown.
+ void MarkForDeletion();
+ bool IsMarkedForDeletion();
+
+ // Called by the GMPService to forcibly close active de/encoders at shutdown
+ void Shutdown();
+
+ // This must not be called while we're in the middle of abnormal ActorDestroy
+ void DeleteProcess();
+
+ GMPState State() const;
+ nsCOMPtr<nsISerialEventTarget> GMPEventTarget();
+
+ // A GMP can either be a single instance shared across all NodeIds (like
+ // in the OpenH264 case), or we can require a new plugin instance for every
+ // NodeIds running the plugin (as in the EME plugin case).
+ //
+ // A NodeId is a hash of the ($urlBarOrigin, $ownerDocOrigin) pair.
+ //
+ // Plugins are associated with an NodeIds by calling SetNodeId() before
+ // loading.
+ //
+ // If a plugin has no NodeId specified and it is loaded, it is assumed to
+ // be shared across NodeIds.
+
+ // Specifies that a GMP can only work with the specified NodeIds.
+ void SetNodeId(const nsACString& aNodeId);
+ const nsACString& GetNodeId() const { return mNodeId; }
+
+ const nsCString& GetDisplayName() const;
+ const nsCString& GetVersion() const;
+ uint32_t GetPluginId() const;
+ nsString GetPluginBaseName() const;
+
+ // Returns true if a plugin can be or is being used across multiple NodeIds.
+ bool CanBeSharedCrossNodeIds() const;
+
+ // A GMP can be used from a NodeId if it's already been set to work with
+ // that NodeId, or if it's not been set to work with any NodeId and has
+ // not yet been loaded (i.e. it's not shared across NodeIds).
+ bool CanBeUsedFrom(const nsACString& aNodeId) const;
+
+ already_AddRefed<nsIFile> GetDirectory() {
+ return nsCOMPtr<nsIFile>(mDirectory).forget();
+ }
+
+ void AbortAsyncShutdown();
+
+ // Called when the child process has died.
+ void ChildTerminated();
+
+ bool OpenPGMPContent();
+
+ void GetGMPContentParent(
+ UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>&& aPromiseHolder);
+ already_AddRefed<GMPContentParent> ForgetGMPContentParent();
+
+ bool EnsureProcessLoaded(base::ProcessId* aID);
+
+ void IncrementGMPContentChildCount();
+
+ const nsTArray<GMPCapability>& GetCapabilities() const {
+ return mCapabilities;
+ }
+
+ private:
+ ~GMPParent();
+
+ RefPtr<GeckoMediaPluginServiceParent> mService;
+ bool EnsureProcessLoaded();
+ RefPtr<GenericPromise> ReadGMPMetaData();
+ RefPtr<GenericPromise> ReadGMPInfoFile(nsIFile* aFile);
+ RefPtr<GenericPromise> ParseChromiumManifest(
+ const nsAString& aJSON); // Worker thread.
+ RefPtr<GenericPromise> ReadChromiumManifestFile(
+ nsIFile* aFile); // GMP thread.
+ void AddCrashAnnotations();
+ void GetCrashID(nsString& aResult);
+ void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ mozilla::ipc::IPCResult RecvPGMPStorageConstructor(
+ PGMPStorageParent* actor) override;
+ PGMPStorageParent* AllocPGMPStorageParent();
+ bool DeallocPGMPStorageParent(PGMPStorageParent* aActor);
+
+ mozilla::ipc::IPCResult RecvPGMPTimerConstructor(
+ PGMPTimerParent* actor) override;
+ PGMPTimerParent* AllocPGMPTimerParent();
+ bool DeallocPGMPTimerParent(PGMPTimerParent* aActor);
+
+ mozilla::ipc::IPCResult RecvPGMPContentChildDestroyed();
+
+ mozilla::ipc::IPCResult RecvFOGData(ByteBuf&& aBuf);
+
+ bool IsUsed() {
+ return mGMPContentChildCount > 0 || !mGetContentParentPromises.IsEmpty();
+ }
+
+ void ResolveGetContentParentPromises();
+ void RejectGetContentParentPromises();
+
+#if defined(XP_MACOSX) && defined(__aarch64__)
+ // We pre-translate XUL and our plugin file to avoid x64 child process
+ // startup delays caused by translation for instances when the child
+ // process binary translations have not already been cached. i.e., the
+ // first time we launch an x64 child process after installation or
+ // update. Measured by binary size of a recent XUL and Widevine plugin,
+ // this makes up 94% of the translation needed. Re-translating the
+ // same binary does not cause translation to occur again.
+ void PreTranslateBins();
+ void PreTranslateBinsWorker();
+#endif
+
+#if defined(XP_MACOSX)
+ nsresult GetPluginFileArch(nsIFile* aPluginDir, nsAutoString& aLeafName,
+ uint32_t& aArchSet);
+#endif
+
+ GMPState mState;
+ nsCOMPtr<nsIFile> mDirectory; // plugin directory on disk
+ nsString mName; // base name of plugin on disk, UTF-16 because used for paths
+ nsCString mDisplayName; // name of plugin displayed to users
+ nsCString mDescription; // description of plugin for display to users
+ nsCString mVersion;
+#if defined(XP_WIN) || defined(XP_LINUX)
+ nsCString mLibs;
+#endif
+ nsString mAdapter;
+ const uint32_t mPluginId;
+ nsTArray<GMPCapability> mCapabilities;
+ GMPProcessParent* mProcess;
+ bool mDeleteProcessOnlyOnUnload;
+ bool mAbnormalShutdownInProgress;
+ bool mIsBlockingDeletion;
+
+ bool mCanDecrypt;
+
+ nsTArray<RefPtr<GMPTimerParent>> mTimers;
+ nsTArray<RefPtr<GMPStorageParent>> mStorage;
+ // NodeId the plugin is assigned to, or empty if the the plugin is not
+ // assigned to a NodeId.
+ nsCString mNodeId;
+ // This is used for GMP content in the parent, there may be more of these in
+ // the content processes.
+ RefPtr<GMPContentParent> mGMPContentParent;
+ nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>>
+ mGetContentParentPromises;
+ uint32_t mGMPContentChildCount;
+
+ int mChildPid;
+
+ // We hold a self reference to ourself while the child process is alive.
+ // This ensures that if the GMPService tries to shut us down and drops
+ // its reference to us, we stay alive long enough for the child process
+ // to terminate gracefully.
+ bool mHoldingSelfRef;
+
+#if defined(XP_MACOSX) && defined(__aarch64__)
+ // The child process architecture to use.
+ uint32_t mChildLaunchArch;
+ nsCString mPluginFilePath;
+#endif
+
+ const nsCOMPtr<nsISerialEventTarget> mMainThread;
+};
+
+} // namespace mozilla::gmp
+
+#endif // GMPParent_h_