/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 include_dom_media_ipc_RemoteCDMProxy_h #define include_dom_media_ipc_RemoteCDMProxy_h #include "mozilla/Atomics.h" #include "mozilla/CDMProxy.h" #include "mozilla/PRemoteCDMActor.h" #include "mozilla/RemoteCDMChild.h" #include "mozilla/RemoteMediaManagerChild.h" namespace mozilla { /** * This class implements the content process actor for managing CDM instances in * a remote process performing the decoding/decrypting. It is created via * RemoteMediaManagerChild::CreateCDM. It destroys itself when there is a single * reference left (the IPDL reference to the actor). The CDMProxy methods are * threadsafe and dispatch to the RemoteMediaManagerChild IPDL thread. * * To provide a remote implementation in another process, one must subclass * RemoteCDMParent and ensure the correct actor class is created in * RemoteMediaManagerParent::AllocPRemoteCDMParent. * * Remote decoders are supplied the PRemoteCDMActor pointer for encrypted media, * which they can integrate with depending on the particular CDM API. */ class RemoteCDMProxy final : public PRemoteCDMActor, public CDMProxy { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteCDMProxy, final); RemoteCDMProxy(nsCOMPtr&& aThread, RefPtr&& aIPDLPromise, RemoteMediaIn aLocation, dom::MediaKeys* aKeys, const nsAString& aKeySystem, bool aDistinctiveIdentifierRequired, bool aPersistentStateRequired); nsISerialEventTarget* GetManagerThread() const { return mThread; } // Called by RemoteCDMChild void OnProvision(const RemoteCDMProvisionRequestIPDL& aRequest, PRemoteCDMChild::ProvisionResolver&& aResolver); void OnSessionKeyStatus(const RemoteCDMKeyStatusIPDL& aMsg); void OnSessionKeyExpiration(RemoteCDMKeyExpirationIPDL&& aMsg); void OnSessionKeyMessage(RemoteCDMKeyMessageIPDL&& aMsg); // CDMProxy void Init(PromiseId aPromiseId, const nsAString& aOrigin, const nsAString& aTopLevelOrigin, const nsAString& aName) override; void CreateSession(uint32_t aCreateSessionToken, dom::MediaKeySessionType aSessionType, PromiseId aPromiseId, const nsAString& aInitDataType, nsTArray& aInitData) override; void LoadSession(PromiseId aPromiseId, dom::MediaKeySessionType aSessionType, const nsAString& aSessionId) override; void SetServerCertificate(PromiseId aPromiseId, nsTArray& aCert) override; void UpdateSession(const nsAString& aSessionId, PromiseId aPromiseId, nsTArray& aResponse) override; void CloseSession(const nsAString& aSessionId, PromiseId aPromiseId) override; void RemoveSession(const nsAString& aSessionId, PromiseId aPromiseId) override; void QueryOutputProtectionStatus() override; void NotifyOutputProtectionStatus( OutputProtectionCheckStatus aCheckStatus, OutputProtectionCaptureStatus aCaptureStatus) override; void Shutdown() override; void Terminated() override; void OnSetSessionId(uint32_t aCreateSessionToken, const nsAString& aSessionId) override; void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) override; void OnSessionMessage(const nsAString& aSessionId, dom::MediaKeyMessageType aMessageType, const nsTArray& aMessage) override; void OnExpirationChange(const nsAString& aSessionId, UnixTime aExpiryTime) override; void OnSessionClosed(const nsAString& aSessionId, dom::MediaKeySessionClosedReason aReason) override; void OnSessionError(const nsAString& aSessionId, nsresult aException, uint32_t aSystemCode, const nsAString& aMsg) override; void OnRejectPromise(uint32_t aPromiseId, ErrorResult&& aException, const nsCString& aMsg) override; RefPtr Decrypt(MediaRawData* aSample) override; void OnDecrypted(uint32_t aId, DecryptStatus aResult, const nsTArray& aDecryptedData) override; void RejectPromise(PromiseId aId, ErrorResult&& aException, const nsCString& aReason) override; void ResolvePromise(PromiseId aId) override; void OnKeyStatusesChange(const nsAString& aSessionId) override; void GetStatusForPolicy(PromiseId aPromiseId, const dom::HDCPVersion& aMinHdcpVersion) override; #ifdef DEBUG bool IsOnOwnerThread() override; #endif RemoteCDMProxy* AsRemoteCDMProxy() final { return this; } // PRemoteCDMActor PRemoteCDMChild* AsPRemoteCDMChild() final { return mChild; } RemoteMediaIn GetLocation() const final { return mLocation; } private: virtual ~RemoteCDMProxy(); void InitInternal(PromiseId aPromiseId, const nsCString& aOriginID); void RejectPromise(PromiseId aId, const MediaResult& aResult); void ResolveOrRejectPromise(PromiseId aId, const MediaResult& aResult); void Destroy(); const RefPtr mChild; const nsCOMPtr mThread; RefPtr mIPDLPromise; const RemoteMediaIn mLocation; Atomic mNeedsShutdown{true}; }; } // namespace mozilla #endif // include_dom_media_ipc_RemoteCDMProxy_h