MediaDrmRemoteCDMParent.h (5502B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MediaDrmRemoteCDMParent_h_ 8 #define MediaDrmRemoteCDMParent_h_ 9 10 #include <map> 11 12 #include "media/NdkMediaCodec.h" 13 #include "media/NdkMediaCrypto.h" 14 #include "media/NdkMediaDrm.h" 15 #include "media/NdkMediaError.h" 16 #include "mozilla/Mutex.h" 17 #include "mozilla/RemoteCDMParent.h" 18 #include "mozilla/StaticPtr.h" 19 20 namespace mozilla { 21 22 class MediaDrmCrypto final { 23 template <typename T, typename... Args> 24 friend RefPtr<T> MakeRefPtr(Args&&...); 25 26 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCrypto); 27 28 public: 29 AMediaCrypto* GetNdkCrypto() const { return mCrypto; } 30 31 private: 32 explicit MediaDrmCrypto(AMediaCrypto* aCrypto) : mCrypto(aCrypto) {} 33 34 ~MediaDrmCrypto(); 35 36 AMediaCrypto* mCrypto; 37 }; 38 39 class MediaDrmCryptoInfo final { 40 template <typename T, typename... Args> 41 friend already_AddRefed<T> MakeAndAddRef(Args&&...); 42 43 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCryptoInfo); 44 45 public: 46 AMediaCodecCryptoInfo* GetNdkCryptoInfo() const { return mCryptoInfo; } 47 48 private: 49 explicit MediaDrmCryptoInfo(AMediaCodecCryptoInfo* aCryptoInfo) 50 : mCryptoInfo(aCryptoInfo) {} 51 52 ~MediaDrmCryptoInfo(); 53 54 AMediaCodecCryptoInfo* mCryptoInfo; 55 }; 56 57 class MediaDrmRemoteCDMParent final : public RemoteCDMParent { 58 friend class MediaDrmCrypto; 59 friend class MediaDrmCryptoInfo; 60 61 public: 62 explicit MediaDrmRemoteCDMParent(const nsAString& aKeySystem); 63 64 already_AddRefed<MediaDrmCrypto> GetCrypto() const { 65 MutexAutoLock lock(mMutex); 66 return do_AddRef(mCrypto); 67 } 68 69 bool HasCrypto() const { 70 MutexAutoLock lock(mMutex); 71 return !!mCrypto; 72 } 73 74 already_AddRefed<MediaDrmCryptoInfo> CreateCryptoInfo(MediaRawData* aSample); 75 76 // PRemoteCDMParent 77 mozilla::ipc::IPCResult RecvInit(const RemoteCDMInitRequestIPDL& aRequest, 78 InitResolver&& aResolver) override; 79 80 mozilla::ipc::IPCResult RecvCreateSession( 81 RemoteCDMCreateSessionRequestIPDL&& aRequest, 82 CreateSessionResolver&& aResolver) override; 83 84 mozilla::ipc::IPCResult RecvLoadSession( 85 const RemoteCDMLoadSessionRequestIPDL& aRequest, 86 LoadSessionResolver&& aResolver) override; 87 88 mozilla::ipc::IPCResult RecvUpdateSession( 89 const RemoteCDMUpdateSessionRequestIPDL& aRequest, 90 UpdateSessionResolver&& aResolver) override; 91 92 mozilla::ipc::IPCResult RecvRemoveSession( 93 const nsString& aSessionId, RemoveSessionResolver&& aResolver) override; 94 95 mozilla::ipc::IPCResult RecvCloseSession( 96 const nsString& aSessionId, CloseSessionResolver&& aResolver) override; 97 98 mozilla::ipc::IPCResult RecvSetServerCertificate( 99 mozilla::Span<uint8_t const> aCertificate, 100 SetServerCertificateResolver&& aResolver) override; 101 102 void ActorDestroy(ActorDestroyReason aWhy) override; 103 104 private: 105 virtual ~MediaDrmRemoteCDMParent(); 106 107 static constexpr uint8_t CLEARKEY_UUID[] = { 108 0xe2, 0x71, 0x9d, 0x58, 0xa9, 0x85, 0xb3, 0xc9, 109 0x78, 0x1a, 0xb0, 0x30, 0xaf, 0x78, 0xd3, 0x0e}; 110 111 static constexpr uint8_t WIDEVINE_UUID[] = { 112 0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0xce, 113 0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed}; 114 115 static void InitializeStatics(); 116 117 static void HandleEventCb(AMediaDrm* aMediaDrm, 118 const AMediaDrmSessionId* aSessionId, 119 AMediaDrmEventType aEventType, int aExtra, 120 const uint8_t* aData, size_t aDataSize); 121 122 static void HandleExpirationUpdateCb(AMediaDrm* aDrm, 123 const AMediaDrmSessionId* aSessionId, 124 int64_t aExpiryTimeInMS); 125 126 static void HandleKeysChangeCb(AMediaDrm* aDrm, 127 const AMediaDrmSessionId* aSessionId, 128 const AMediaDrmKeyStatus* aKeyStatus, 129 size_t aNumKeys, bool aHasNewUsableKey); 130 131 void HandleEvent(nsString&& aSessionId, AMediaDrmEventType aEventType, 132 int aExtra, nsTArray<uint8_t>&& aData); 133 134 void HandleExpirationUpdate(nsString&& aSessionId, int64_t aExpiryTimeInMS); 135 136 void HandleKeysChange(nsString&& aSessionId, bool aHasNewUsableKey, 137 nsTArray<CDMKeyInfo>&& aKeyInfo); 138 139 using InternalPromise = 140 MozPromise<bool, MediaResult, /* IsExclusive */ false>; 141 142 RefPtr<InternalPromise> EnsureHasAMediaCrypto(); 143 RefPtr<InternalPromise> EnsureProvisioned(); 144 145 void Destroy(); 146 147 using DrmCallbackMap = std::map<AMediaDrm*, MediaDrmRemoteCDMParent*>; 148 static StaticAutoPtr<DrmCallbackMap> sCbMap; 149 150 struct SessionEntry { 151 AMediaDrmSessionId id; 152 nsAutoCString mimeType; 153 }; 154 155 std::map<nsString, SessionEntry> mSessions; 156 MozPromiseHolder<InternalPromise> mProvisionPromise; 157 158 mutable Mutex mMutex; 159 RefPtr<MediaDrmCrypto> mCrypto MOZ_GUARDED_BY(mMutex); 160 161 // Points to a static constexpr buffer set in the constructor. 162 const uint8_t* mUuid = nullptr; 163 164 // Allocated in RecvInit, freed in ActorDestroy/Destroy. 165 AMediaDrm* mDrm = nullptr; 166 167 AMediaDrmSessionId mCryptoSessionId; 168 Maybe<MediaResult> mCryptoError; 169 Maybe<MediaResult> mProvisionError; 170 }; 171 172 } // namespace mozilla 173 174 #endif // MediaDrmRemoteCDMParent_h_