tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GMPParent.h (8567B)


      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 "GMPNativeTypes.h"
     10 #include "GMPProcessParent.h"
     11 #include "GMPServiceParent.h"
     12 #include "GMPStorageParent.h"
     13 #include "GMPTimerParent.h"
     14 #include "GMPVideoDecoderParent.h"
     15 #include "GMPVideoEncoderParent.h"
     16 #include "mozilla/Atomics.h"
     17 #include "mozilla/MozPromise.h"
     18 #include "mozilla/gmp/PGMPParent.h"
     19 #include "mozilla/ipc/CrashReporterHelper.h"
     20 #include "nsCOMPtr.h"
     21 #include "nsIFile.h"
     22 #include "nsISupports.h"
     23 #include "nsString.h"
     24 #include "nsTArray.h"
     25 #include "nscore.h"
     26 
     27 namespace mozilla::gmp {
     28 
     29 class GMPCapability {
     30 public:
     31  explicit GMPCapability() = default;
     32  GMPCapability(GMPCapability&& aOther)
     33      : mAPIName(std::move(aOther.mAPIName)),
     34        mAPITags(std::move(aOther.mAPITags)) {}
     35  explicit GMPCapability(const nsACString& aAPIName) : mAPIName(aAPIName) {}
     36  explicit GMPCapability(const GMPCapability& aOther) = default;
     37  nsCString mAPIName;
     38  CopyableTArray<nsCString> mAPITags;
     39 
     40  static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
     41                       const nsACString& aAPI,
     42                       const nsTArray<nsCString>& aTags);
     43 
     44  static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
     45                       const nsACString& aAPI, const nsCString& aTag);
     46 };
     47 
     48 enum class GMPState : uint32_t {
     49  NotLoaded,
     50  Loaded,
     51  Unloading,
     52  Closing,
     53  Closed
     54 };
     55 
     56 class GMPContentParent;
     57 
     58 class GMPParent final : public PGMPParent,
     59                        public ipc::CrashReporterHelper<GMPParent> {
     60  friend class PGMPParent;
     61 
     62 public:
     63  static constexpr GeckoProcessType PROCESS_TYPE = GeckoProcessType_GMPlugin;
     64 
     65  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPParent, final)
     66 
     67  GMPParent();
     68 
     69 #ifdef MOZ_WIDGET_ANDROID
     70  void InitForClearkey(GeckoMediaPluginServiceParent* aService);
     71 #endif
     72 
     73  RefPtr<GenericPromise> Init(GeckoMediaPluginServiceParent* aService,
     74                              nsIFile* aPluginDir);
     75  void CloneFrom(const GMPParent* aOther);
     76 
     77  void Crash();
     78 
     79  nsresult LoadProcess();
     80 
     81  // Called internally to close this if we don't need it
     82  void CloseIfUnused();
     83 
     84  // Notify all active de/encoders that we are closing, either because of
     85  // normal shutdown or unexpected shutdown/crash.
     86  void CloseActive(bool aDieWhenUnloaded);
     87 
     88  // Tell the plugin to die after shutdown.
     89  void MarkForDeletion();
     90  bool IsMarkedForDeletion();
     91 
     92  // Called by the GMPService to forcibly close active de/encoders at shutdown
     93  void Shutdown();
     94 
     95  // This must not be called while we're in the middle of abnormal ActorDestroy
     96  void DeleteProcess();
     97 
     98  GMPState State() const;
     99  nsCOMPtr<nsISerialEventTarget> GMPEventTarget();
    100 
    101  void OnPreferenceChange(const mozilla::dom::Pref& aPref);
    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  const nsACString& GetNodeId() const { return mNodeId; }
    118 
    119  const nsCString& GetDisplayName() const;
    120  const nsCString& GetVersion() const;
    121  uint32_t GetPluginId() const;
    122  GMPPluginType GetPluginType() const { return mPluginType; }
    123  nsString GetPluginBaseName() const;
    124 
    125  // Returns true if a plugin can be or is being used across multiple NodeIds.
    126  bool CanBeSharedCrossNodeIds() const;
    127 
    128  // A GMP can be used from a NodeId if it's already been set to work with
    129  // that NodeId, or if it's not been set to work with any NodeId and has
    130  // not yet been loaded (i.e. it's not shared across NodeIds).
    131  bool CanBeUsedFrom(const nsACString& aNodeId) const;
    132 
    133  already_AddRefed<nsIFile> GetDirectory() {
    134    return nsCOMPtr<nsIFile>(mDirectory).forget();
    135  }
    136 
    137  // Called when the child process has died.
    138  void ChildTerminated();
    139 
    140  bool OpenPGMPContent();
    141 
    142  void GetGMPContentParent(
    143      UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>&& aPromiseHolder);
    144  already_AddRefed<GMPContentParent> ForgetGMPContentParent();
    145 
    146  bool EnsureProcessLoaded(base::ProcessId* aID);
    147 
    148  void IncrementGMPContentChildCount();
    149 
    150  const nsTArray<GMPCapability>& GetCapabilities() const {
    151    return mCapabilities;
    152  }
    153 
    154 private:
    155  ~GMPParent();
    156  void UpdatePluginType();
    157 
    158  RefPtr<GeckoMediaPluginServiceParent> mService;
    159  bool EnsureProcessLoaded();
    160  RefPtr<GenericPromise> ReadGMPMetaData();
    161  RefPtr<GenericPromise> ReadGMPInfoFile(nsIFile* aFile);
    162  RefPtr<GenericPromise> ParseChromiumManifest(
    163      const nsAString& aJSON);  // Worker thread.
    164  RefPtr<GenericPromise> ReadChromiumManifestFile(
    165      nsIFile* aFile);  // GMP thread.
    166  void AddCrashAnnotations();
    167  void GetCrashID(nsString& aResult);
    168  void ActorDestroy(ActorDestroyReason aWhy) override;
    169 
    170  mozilla::ipc::IPCResult RecvPGMPStorageConstructor(
    171      PGMPStorageParent* actor) override;
    172  PGMPStorageParent* AllocPGMPStorageParent();
    173  bool DeallocPGMPStorageParent(PGMPStorageParent* aActor);
    174 
    175  mozilla::ipc::IPCResult RecvPGMPTimerConstructor(
    176      PGMPTimerParent* actor) override;
    177  PGMPTimerParent* AllocPGMPTimerParent();
    178  bool DeallocPGMPTimerParent(PGMPTimerParent* aActor);
    179 
    180  mozilla::ipc::IPCResult RecvPGMPContentChildDestroyed();
    181 
    182  mozilla::ipc::IPCResult RecvFOGData(ByteBuf&& aBuf);
    183 
    184 #if defined(XP_WIN)
    185  mozilla::ipc::IPCResult RecvGetModulesTrust(
    186      ModulePaths&& aModPaths, bool aRunAtNormalPriority,
    187      GetModulesTrustResolver&& aResolver);
    188 #endif  // defined(XP_WIN)
    189 
    190  bool IsUsed() {
    191    return mGMPContentChildCount > 0 || !mGetContentParentPromises.IsEmpty();
    192  }
    193 
    194  void ResolveGetContentParentPromises();
    195  void RejectGetContentParentPromises();
    196 
    197 #if defined(XP_MACOSX) && defined(__aarch64__)
    198  // We pre-translate XUL and our plugin file to avoid x64 child process
    199  // startup delays caused by translation for instances when the child
    200  // process binary translations have not already been cached. i.e., the
    201  // first time we launch an x64 child process after installation or
    202  // update. Measured by binary size of a recent XUL and Widevine plugin,
    203  // this makes up 94% of the translation needed. Re-translating the
    204  // same binary does not cause translation to occur again.
    205  void PreTranslateBins();
    206  void PreTranslateBinsWorker();
    207 #endif
    208 
    209 #if defined(XP_WIN) || defined(XP_MACOSX)
    210  nsresult GetPluginFileArch(nsIFile* aPluginDir, const nsString& aBaseName,
    211                             uint32_t& aArchSet);
    212 #endif
    213 
    214  Atomic<GMPState> mState;
    215  nsCOMPtr<nsIFile> mDirectory;  // plugin directory on disk
    216  nsString mName;  // base name of plugin on disk, UTF-16 because used for paths
    217  nsCString mDisplayName;  // name of plugin displayed to users
    218  nsCString mDescription;  // description of plugin for display to users
    219  nsCString mVersion;
    220 #if defined(XP_WIN) || defined(XP_LINUX)
    221  nsCString mLibs;
    222 #endif
    223  nsString mAdapter;
    224  const uint32_t mPluginId;
    225  GMPPluginType mPluginType = GMPPluginType::Unknown;
    226  nsTArray<GMPCapability> mCapabilities;
    227  GMPProcessParent* mProcess;
    228  bool mDeleteProcessOnlyOnUnload;
    229  bool mAbnormalShutdownInProgress;
    230  bool mIsBlockingDeletion;
    231 
    232  bool mCanDecrypt;
    233 
    234  nsTArray<RefPtr<GMPTimerParent>> mTimers;
    235  nsTArray<RefPtr<GMPStorageParent>> mStorage;
    236  // NodeId the plugin is assigned to, or empty if the the plugin is not
    237  // assigned to a NodeId.
    238  nsCString mNodeId;
    239  // This is used for GMP content in the parent, there may be more of these in
    240  // the content processes.
    241  RefPtr<GMPContentParent> mGMPContentParent;
    242  nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>>
    243      mGetContentParentPromises;
    244  uint32_t mGMPContentChildCount;
    245 
    246  int mChildPid;
    247 
    248 #ifdef ALLOW_GECKO_CHILD_PROCESS_ARCH
    249  // The child process architecture to use.
    250  uint32_t mChildLaunchArch;
    251 #endif
    252 #if defined(XP_MACOSX) && defined(__aarch64__)
    253  nsCString mPluginFilePath;
    254 #endif
    255 
    256  const nsCOMPtr<nsISerialEventTarget> mMainThread;
    257 };
    258 
    259 }  // namespace mozilla::gmp
    260 
    261 #endif  // GMPParent_h_