Home | History | Annotate | Download | only in external_clear_key
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_
      6 #define MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/synchronization/lock.h"
     16 #include "media/cdm/aes_decryptor.h"
     17 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h"
     18 
     19 // Enable this to use the fake decoder for testing.
     20 // TODO(tomfinegan): Move fake audio decoder into a separate class.
     21 #if 0
     22 #define CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
     23 #endif
     24 
     25 namespace media {
     26 class FileIOTestRunner;
     27 class CdmVideoDecoder;
     28 class DecoderBuffer;
     29 class FFmpegCdmAudioDecoder;
     30 
     31 // Clear key implementation of the cdm::ContentDecryptionModule interface.
     32 class ClearKeyCdm : public ClearKeyCdmInterface {
     33  public:
     34   ClearKeyCdm(Host* host, const std::string& key_system);
     35   virtual ~ClearKeyCdm();
     36 
     37   // ContentDecryptionModule implementation.
     38   virtual void CreateSession(uint32 promise_id,
     39                              const char* init_data_type,
     40                              uint32 init_data_type_size,
     41                              const uint8* init_data,
     42                              uint32 init_data_size,
     43                              cdm::SessionType session_type) OVERRIDE;
     44   virtual void LoadSession(uint32 promise_id,
     45                            const char* web_session_id,
     46                            uint32_t web_session_id_length) OVERRIDE;
     47   virtual void UpdateSession(uint32 promise_id,
     48                              const char* web_session_id,
     49                              uint32_t web_session_id_length,
     50                              const uint8* response,
     51                              uint32 response_size) OVERRIDE;
     52   virtual void CloseSession(uint32 promise_id,
     53                             const char* web_session_id,
     54                             uint32_t web_session_id_length) OVERRIDE;
     55   virtual void RemoveSession(uint32 promise_id,
     56                              const char* web_session_id,
     57                              uint32_t web_session_id_length) OVERRIDE;
     58   virtual void GetUsableKeyIds(uint32_t promise_id,
     59                                const char* web_session_id,
     60                                uint32_t web_session_id_length) OVERRIDE;
     61   virtual void SetServerCertificate(
     62       uint32 promise_id,
     63       const uint8_t* server_certificate_data,
     64       uint32_t server_certificate_data_size) OVERRIDE;
     65   virtual void TimerExpired(void* context) OVERRIDE;
     66   virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
     67                               cdm::DecryptedBlock* decrypted_block) OVERRIDE;
     68   virtual cdm::Status InitializeAudioDecoder(
     69       const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE;
     70   virtual cdm::Status InitializeVideoDecoder(
     71       const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE;
     72   virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE;
     73   virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE;
     74   virtual cdm::Status DecryptAndDecodeFrame(
     75       const cdm::InputBuffer& encrypted_buffer,
     76       cdm::VideoFrame* video_frame) OVERRIDE;
     77   virtual cdm::Status DecryptAndDecodeSamples(
     78       const cdm::InputBuffer& encrypted_buffer,
     79       cdm::AudioFrames* audio_frames) OVERRIDE;
     80   virtual void Destroy() OVERRIDE;
     81   virtual void OnPlatformChallengeResponse(
     82       const cdm::PlatformChallengeResponse& response) OVERRIDE;
     83   virtual void OnQueryOutputProtectionStatus(
     84       uint32_t link_mask, uint32_t output_protection_mask) OVERRIDE;
     85 
     86  private:
     87   // Emulates a session stored for |session_id_for_emulated_loadsession_|. This
     88   // is necessary since aes_decryptor.cc does not support storing sessions.
     89   void LoadLoadableSession();
     90 
     91   // ContentDecryptionModule callbacks.
     92   void OnSessionMessage(const std::string& web_session_id,
     93                         const std::vector<uint8>& message,
     94                         const GURL& destination_url);
     95   void OnSessionKeysChange(const std::string& web_session_id,
     96                            bool has_additional_usable_key);
     97   void OnSessionClosed(const std::string& web_session_id);
     98 
     99   // Handle the success/failure of a promise. These methods are responsible for
    100   // calling |host_| to resolve or reject the promise.
    101   void OnSessionCreated(uint32 promise_id, const std::string& web_session_id);
    102   void OnSessionLoaded(uint32 promise_id, const std::string& web_session_id);
    103   void OnSessionUpdated(uint32 promise_id, const std::string& web_session_id);
    104   void OnUsableKeyIdsObtained(uint32 promise_id, const KeyIdsVector& key_ids);
    105   void OnPromiseResolved(uint32 promise_id);
    106   void OnPromiseFailed(uint32 promise_id,
    107                        MediaKeys::Exception exception_code,
    108                        uint32 system_code,
    109                        const std::string& error_message);
    110 
    111   // Prepares next heartbeat message and sets a timer for it.
    112   void ScheduleNextHeartBeat();
    113 
    114   // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
    115   // Returns cdm::kSuccess if decryption succeeded. The decrypted result is
    116   // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
    117   // |decrypted_buffer| is set to an empty (EOS) buffer.
    118   // Returns cdm::kNoKey if no decryption key was available. In this case
    119   // |decrypted_buffer| should be ignored by the caller.
    120   // Returns cdm::kDecryptError if any decryption error occurred. In this case
    121   // |decrypted_buffer| should be ignored by the caller.
    122   cdm::Status DecryptToMediaDecoderBuffer(
    123       const cdm::InputBuffer& encrypted_buffer,
    124       scoped_refptr<DecoderBuffer>* decrypted_buffer);
    125 
    126 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
    127   int64 CurrentTimeStampInMicroseconds() const;
    128 
    129   // Generates fake video frames with |duration_in_microseconds|.
    130   // Returns the number of samples generated in the |audio_frames|.
    131   int GenerateFakeAudioFramesFromDuration(int64 duration_in_microseconds,
    132                                           cdm::AudioFrames* audio_frames) const;
    133 
    134   // Generates fake video frames given |input_timestamp|.
    135   // Returns cdm::kSuccess if any audio frame is successfully generated.
    136   cdm::Status GenerateFakeAudioFrames(int64 timestamp_in_microseconds,
    137                                       cdm::AudioFrames* audio_frames);
    138 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
    139 
    140   void StartFileIOTest();
    141 
    142   // Callback for CDM File IO test.
    143   void OnFileIOTestComplete(bool success);
    144 
    145   // Keep track of the last session created.
    146   void SetSessionId(const std::string& web_session_id);
    147 
    148   AesDecryptor decryptor_;
    149 
    150   ClearKeyCdmHost* host_;
    151 
    152   const std::string key_system_;
    153 
    154   std::string last_session_id_;
    155   std::string next_heartbeat_message_;
    156 
    157   // In order to simulate LoadSession(), CreateSession() and then
    158   // UpdateSession() will be called to create a session with known keys.
    159   // |session_id_for_emulated_loadsession_| is used to keep track of the
    160   // session_id allocated by aes_decryptor, as the session_id will be returned
    161   // as |kLoadableWebSessionId|. Future requests for this simulated session
    162   // need to use |session_id_for_emulated_loadsession_| for all calls
    163   // to aes_decryptor.
    164   // |promise_id_for_emulated_loadsession_| is used to keep track of the
    165   // original LoadSession() promise, as it is not resolved until the
    166   // UpdateSession() call succeeds.
    167   // TODO(xhwang): Extract testing code from main implementation.
    168   // See http://crbug.com/341751
    169   std::string session_id_for_emulated_loadsession_;
    170   uint32_t promise_id_for_emulated_loadsession_;
    171 
    172   // Timer delay in milliseconds for the next host_->SetTimer() call.
    173   int64 timer_delay_ms_;
    174 
    175   // Indicates whether a heartbeat timer has been set to prevent multiple timers
    176   // from running.
    177   bool heartbeat_timer_set_;
    178 
    179 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
    180   int channel_count_;
    181   int bits_per_channel_;
    182   int samples_per_second_;
    183   int64 output_timestamp_base_in_microseconds_;
    184   int total_samples_generated_;
    185 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
    186 
    187 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
    188   scoped_ptr<FFmpegCdmAudioDecoder> audio_decoder_;
    189 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
    190 
    191   scoped_ptr<CdmVideoDecoder> video_decoder_;
    192 
    193   scoped_ptr<FileIOTestRunner> file_io_test_runner_;
    194 
    195   DISALLOW_COPY_AND_ASSIGN(ClearKeyCdm);
    196 };
    197 
    198 }  // namespace media
    199 
    200 #endif  // MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_
    201