tor-browser

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

ClearKeyCDM.cpp (7362B)


      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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ClearKeyCDM.h"
      8 
      9 #include "ClearKeyUtils.h"
     10 
     11 using namespace cdm;
     12 
     13 ClearKeyCDM::ClearKeyCDM(Host_11* aHost) {
     14  mHost = aHost;
     15  mSessionManager = new ClearKeySessionManager(mHost);
     16 }
     17 
     18 void ClearKeyCDM::Initialize(bool aAllowDistinctiveIdentifier,
     19                             bool aAllowPersistentState,
     20                             bool aUseHardwareSecureCodecs) {
     21  mSessionManager->Init(aAllowDistinctiveIdentifier, aAllowPersistentState);
     22  // We call mHost->OnInitialized() in the session manager once it has
     23  // initialized.
     24 }
     25 
     26 void ClearKeyCDM::GetStatusForPolicy(uint32_t aPromiseId,
     27                                     const Policy& aPolicy) {
     28  // Pretend the device is HDCP 2.1 compliant.
     29  const cdm::HdcpVersion kDeviceHdcpVersion = cdm::kHdcpVersion2_1;
     30  if (aPolicy.min_hdcp_version <= kDeviceHdcpVersion) {
     31    mHost->OnResolveKeyStatusPromise(aPromiseId, KeyStatus::kUsable);
     32  } else {
     33    mHost->OnResolveKeyStatusPromise(aPromiseId, KeyStatus::kOutputRestricted);
     34  }
     35 }
     36 void ClearKeyCDM::SetServerCertificate(uint32_t aPromiseId,
     37                                       const uint8_t* aServerCertificateData,
     38                                       uint32_t aServerCertificateDataSize) {
     39  mSessionManager->SetServerCertificate(aPromiseId, aServerCertificateData,
     40                                        aServerCertificateDataSize);
     41 }
     42 
     43 void ClearKeyCDM::CreateSessionAndGenerateRequest(uint32_t aPromiseId,
     44                                                  SessionType aSessionType,
     45                                                  InitDataType aInitDataType,
     46                                                  const uint8_t* aInitData,
     47                                                  uint32_t aInitDataSize) {
     48  mSessionManager->CreateSession(aPromiseId, aInitDataType, aInitData,
     49                                 aInitDataSize, aSessionType);
     50 }
     51 
     52 void ClearKeyCDM::LoadSession(uint32_t aPromiseId, SessionType aSessionType,
     53                              const char* aSessionId, uint32_t aSessionIdSize) {
     54  mSessionManager->LoadSession(aPromiseId, aSessionId, aSessionIdSize);
     55 }
     56 
     57 void ClearKeyCDM::UpdateSession(uint32_t aPromiseId, const char* aSessionId,
     58                                uint32_t aSessionIdSize,
     59                                const uint8_t* aResponse,
     60                                uint32_t aResponseSize) {
     61  mSessionManager->UpdateSession(aPromiseId, aSessionId, aSessionIdSize,
     62                                 aResponse, aResponseSize);
     63 }
     64 
     65 void ClearKeyCDM::CloseSession(uint32_t aPromiseId, const char* aSessionId,
     66                               uint32_t aSessionIdSize) {
     67  mSessionManager->CloseSession(aPromiseId, aSessionId, aSessionIdSize);
     68 }
     69 
     70 void ClearKeyCDM::RemoveSession(uint32_t aPromiseId, const char* aSessionId,
     71                                uint32_t aSessionIdSize) {
     72  mSessionManager->RemoveSession(aPromiseId, aSessionId, aSessionIdSize);
     73 }
     74 
     75 void ClearKeyCDM::TimerExpired(void* aContext) {
     76  // Clearkey is not interested in timers, so this method has not been
     77  // implemented.
     78  assert(false);
     79 }
     80 
     81 Status ClearKeyCDM::Decrypt(const InputBuffer_2& aEncryptedBuffer,
     82                            DecryptedBlock* aDecryptedBuffer) {
     83  if (mIsProtectionQueryEnabled) {
     84    // Piggyback this check onto Decrypt calls. If Clearkey implements a timer
     85    // based approach for firing events, we could instead trigger the check
     86    // using that mechanism.
     87    mSessionManager->QueryOutputProtectionStatusIfNeeded();
     88  }
     89  return mSessionManager->Decrypt(aEncryptedBuffer, aDecryptedBuffer);
     90 }
     91 
     92 Status ClearKeyCDM::InitializeAudioDecoder(
     93    const AudioDecoderConfig_2& aAudioDecoderConfig) {
     94  // Audio decoding is not supported by Clearkey because Widevine doesn't
     95  // support it and Clearkey's raison d'etre is to provide test coverage
     96  // for paths that Widevine will exercise in the wild.
     97  return Status::kDecodeError;
     98 }
     99 
    100 Status ClearKeyCDM::InitializeVideoDecoder(
    101    const VideoDecoderConfig_2& aVideoDecoderConfig) {
    102 #ifdef ENABLE_WMF
    103  mVideoDecoder = new VideoDecoder(mHost);
    104  return mVideoDecoder->InitDecode(aVideoDecoderConfig);
    105 #else
    106  return Status::kDecodeError;
    107 #endif
    108 }
    109 
    110 void ClearKeyCDM::DeinitializeDecoder(StreamType aDecoderType) {
    111 #ifdef ENABLE_WMF
    112  if (aDecoderType == StreamType::kStreamTypeVideo) {
    113    mVideoDecoder->DecodingComplete();
    114    mVideoDecoder = nullptr;
    115  }
    116 #endif
    117 }
    118 
    119 void ClearKeyCDM::ResetDecoder(StreamType aDecoderType) {
    120 #ifdef ENABLE_WMF
    121  if (aDecoderType == StreamType::kStreamTypeVideo) {
    122    mVideoDecoder->Reset();
    123  }
    124 #endif
    125 }
    126 
    127 Status ClearKeyCDM::DecryptAndDecodeFrame(const InputBuffer_2& aEncryptedBuffer,
    128                                          VideoFrame* aVideoFrame) {
    129 #ifdef ENABLE_WMF
    130  if (mIsProtectionQueryEnabled) {
    131    // Piggyback this check onto Decrypt + Decode. If Clearkey implements a
    132    // timer based approach for firing events, we could instead trigger the
    133    // check using that mechanism.
    134    mSessionManager->QueryOutputProtectionStatusIfNeeded();
    135  }
    136  return mVideoDecoder->Decode(aEncryptedBuffer, aVideoFrame);
    137 #else
    138  return Status::kDecodeError;
    139 #endif
    140 }
    141 
    142 Status ClearKeyCDM::DecryptAndDecodeSamples(
    143    const InputBuffer_2& aEncryptedBuffer, AudioFrames* aAudioFrame) {
    144  // Audio decoding is not supported by Clearkey because Widevine doesn't
    145  // support it and Clearkey's raison d'etre is to provide test coverage
    146  // for paths that Widevine will exercise in the wild.
    147  return Status::kDecodeError;
    148 }
    149 
    150 void ClearKeyCDM::OnPlatformChallengeResponse(
    151    const PlatformChallengeResponse& aResponse) {
    152  // This function should never be called and is not supported.
    153  assert(false);
    154 }
    155 
    156 void ClearKeyCDM::OnQueryOutputProtectionStatus(
    157    QueryResult aResult, uint32_t aLinkMask, uint32_t aOutputProtectionMask) {
    158  // The higher level GMP machinery should not forward us query information
    159  // unless we've requested it (even if mutiple CDMs exist at once and some
    160  // others are reqeusting this info). If this assert fires we're violating
    161  // that.
    162  MOZ_ASSERT(mIsProtectionQueryEnabled,
    163             "Should only receive a protection status "
    164             "mIsProtectionQueryEnabled is true");
    165  // The session manager handles the guts of this for ClearKey.
    166  mSessionManager->OnQueryOutputProtectionStatus(aResult, aLinkMask,
    167                                                 aOutputProtectionMask);
    168 }
    169 
    170 void ClearKeyCDM::OnStorageId(uint32_t aVersion, const uint8_t* aStorageId,
    171                              uint32_t aStorageIdSize) {
    172  // This function should never be called and is not supported.
    173  assert(false);
    174 }
    175 
    176 void ClearKeyCDM::Destroy() {
    177  mSessionManager->DecryptingComplete();
    178 #ifdef ENABLE_WMF
    179  // If we have called 'DeinitializeDecoder' mVideoDecoder will be null.
    180  if (mVideoDecoder) {
    181    mVideoDecoder->DecodingComplete();
    182  }
    183 #endif
    184  delete this;
    185 }
    186 
    187 void ClearKeyCDM::EnableProtectionQuery() {
    188  MOZ_ASSERT(!mIsProtectionQueryEnabled,
    189             "Should not be called more than once per CDM");
    190  mIsProtectionQueryEnabled = true;
    191 }