Home | History | Annotate | Download | only in ppapi
      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_CDM_ADAPTER_H_
      6 #define MEDIA_CDM_PPAPI_CDM_ADAPTER_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/compiler_specific.h"
     13 #include "build/build_config.h"
     14 #include "media/cdm/ppapi/api/content_decryption_module.h"
     15 #include "media/cdm/ppapi/cdm_helpers.h"
     16 #include "media/cdm/ppapi/cdm_wrapper.h"
     17 #include "media/cdm/ppapi/linked_ptr.h"
     18 #include "ppapi/c/pp_stdint.h"
     19 #include "ppapi/c/private/pp_content_decryptor.h"
     20 #include "ppapi/cpp/completion_callback.h"
     21 #include "ppapi/cpp/private/content_decryptor_private.h"
     22 #include "ppapi/cpp/var.h"
     23 #include "ppapi/cpp/var_array_buffer.h"
     24 #include "ppapi/utility/completion_callback_factory.h"
     25 
     26 #if defined(OS_CHROMEOS)
     27 #include "ppapi/cpp/private/output_protection_private.h"
     28 #include "ppapi/cpp/private/platform_verification.h"
     29 #endif
     30 
     31 namespace media {
     32 
     33 // GetCdmHostFunc implementation.
     34 void* GetCdmHost(int host_interface_version, void* user_data);
     35 
     36 // An adapter class for abstracting away PPAPI interaction and threading for a
     37 // Content Decryption Module (CDM).
     38 class CdmAdapter : public pp::Instance,
     39                    public pp::ContentDecryptor_Private,
     40                    public cdm::Host_4,
     41                    public cdm::Host_6 {
     42  public:
     43   CdmAdapter(PP_Instance instance, pp::Module* module);
     44   virtual ~CdmAdapter();
     45 
     46   // pp::Instance implementation.
     47   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
     48     return true;
     49   }
     50 
     51   // PPP_ContentDecryptor_Private implementation.
     52   // Note: Results of calls to these methods must be reported through the
     53   // PPB_ContentDecryptor_Private interface.
     54   virtual void Initialize(const std::string& key_system) OVERRIDE;
     55   virtual void SetServerCertificate(
     56       uint32_t promise_id,
     57       pp::VarArrayBuffer server_certificate) OVERRIDE;
     58   virtual void CreateSession(uint32_t promise_id,
     59                              const std::string& init_data_type,
     60                              pp::VarArrayBuffer init_data,
     61                              PP_SessionType session_type) OVERRIDE;
     62   virtual void LoadSession(uint32_t promise_id,
     63                            const std::string& web_session_id) OVERRIDE;
     64   virtual void UpdateSession(uint32_t promise_id,
     65                              const std::string& web_session_id,
     66                              pp::VarArrayBuffer response) OVERRIDE;
     67   virtual void CloseSession(uint32_t promise_id,
     68                             const std::string& web_session_id);
     69   virtual void RemoveSession(uint32_t promise_id,
     70                              const std::string& web_session_id) OVERRIDE;
     71   virtual void GetUsableKeyIds(uint32_t promise_id,
     72                                const std::string& web_session_id) OVERRIDE;
     73   virtual void Decrypt(
     74       pp::Buffer_Dev encrypted_buffer,
     75       const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
     76   virtual void InitializeAudioDecoder(
     77       const PP_AudioDecoderConfig& decoder_config,
     78       pp::Buffer_Dev extra_data_buffer) OVERRIDE;
     79   virtual void InitializeVideoDecoder(
     80       const PP_VideoDecoderConfig& decoder_config,
     81       pp::Buffer_Dev extra_data_buffer) OVERRIDE;
     82   virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type,
     83                                    uint32_t request_id) OVERRIDE;
     84   virtual void ResetDecoder(PP_DecryptorStreamType decoder_type,
     85                             uint32_t request_id) OVERRIDE;
     86   virtual void DecryptAndDecode(
     87       PP_DecryptorStreamType decoder_type,
     88       pp::Buffer_Dev encrypted_buffer,
     89       const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
     90 
     91   // cdm::Host_4 and cdm::Host_6 implementation.
     92   virtual cdm::Buffer* Allocate(uint32_t capacity) OVERRIDE;
     93   virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE;
     94 
     95   // cdm::Host_4 implementation.
     96   virtual double GetCurrentWallTimeInSeconds() OVERRIDE;
     97   virtual void OnSessionCreated(uint32_t session_id,
     98                                 const char* web_session_id,
     99                                 uint32_t web_session_id_length) OVERRIDE;
    100   virtual void OnSessionMessage(uint32_t session_id,
    101                                 const char* message,
    102                                 uint32_t message_length,
    103                                 const char* destination_url,
    104                                 uint32_t destination_url_length) OVERRIDE;
    105   virtual void OnSessionReady(uint32_t session_id) OVERRIDE;
    106   virtual void OnSessionClosed(uint32_t session_id) OVERRIDE;
    107   virtual void OnSessionError(uint32_t session_id,
    108                               cdm::MediaKeyError error_code,
    109                               uint32_t system_code) OVERRIDE;
    110 
    111   // cdm::Host_6 implementation.
    112   virtual cdm::Time GetCurrentWallTime() OVERRIDE;
    113   virtual void OnResolveNewSessionPromise(
    114       uint32_t promise_id,
    115       const char* web_session_id,
    116       uint32_t web_session_id_length) OVERRIDE;
    117   virtual void OnResolvePromise(uint32_t promise_id) OVERRIDE;
    118   virtual void OnResolveKeyIdsPromise(uint32_t promise_id,
    119                                       const cdm::BinaryData* usable_key_ids,
    120                                       uint32_t usable_key_ids_length) OVERRIDE;
    121   virtual void OnRejectPromise(uint32_t promise_id,
    122                                cdm::Error error,
    123                                uint32_t system_code,
    124                                const char* error_message,
    125                                uint32_t error_message_length) OVERRIDE;
    126   virtual void OnSessionMessage(const char* web_session_id,
    127                                 uint32_t web_session_id_length,
    128                                 const char* message,
    129                                 uint32_t message_length,
    130                                 const char* destination_url,
    131                                 uint32_t destination_url_length) OVERRIDE;
    132   virtual void OnSessionUsableKeysChange(
    133       const char* web_session_id,
    134       uint32_t web_session_id_length,
    135       bool has_additional_usable_key) OVERRIDE;
    136   virtual void OnExpirationChange(const char* web_session_id,
    137                                   uint32_t web_session_id_length,
    138                                   cdm::Time new_expiry_time) OVERRIDE;
    139   virtual void OnSessionClosed(const char* web_session_id,
    140                                uint32_t web_session_id_length) OVERRIDE;
    141   virtual void OnSessionError(const char* web_session_id,
    142                               uint32_t web_session_id_length,
    143                               cdm::Error error,
    144                               uint32_t system_code,
    145                               const char* error_message,
    146                               uint32_t error_message_length) OVERRIDE;
    147 
    148   // cdm::Host_4 and cdm::Host_6 implementation.
    149   virtual void SendPlatformChallenge(const char* service_id,
    150                                      uint32_t service_id_length,
    151                                      const char* challenge,
    152                                      uint32_t challenge_length) OVERRIDE;
    153   virtual void EnableOutputProtection(
    154       uint32_t desired_protection_mask) OVERRIDE;
    155   virtual void QueryOutputProtectionStatus() OVERRIDE;
    156   virtual void OnDeferredInitializationDone(
    157       cdm::StreamType stream_type,
    158       cdm::Status decoder_status) OVERRIDE;
    159   virtual cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) OVERRIDE;
    160 
    161  private:
    162   // These are reported to UMA server. Do not change the existing values!
    163   enum OutputProtectionStatus {
    164     OUTPUT_PROTECTION_QUERIED = 0,
    165     OUTPUT_PROTECTION_NO_EXTERNAL_LINK = 1,
    166     OUTPUT_PROTECTION_ALL_EXTERNAL_LINKS_PROTECTED = 2,
    167     OUTPUT_PROTECTION_MAX = 3
    168   };
    169 
    170   typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock;
    171   typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame;
    172   typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames;
    173 
    174   struct SessionError {
    175     SessionError(cdm::Error error,
    176                  uint32_t system_code,
    177                  std::string error_description);
    178     cdm::Error error;
    179     uint32_t system_code;
    180     std::string error_description;
    181   };
    182 
    183   bool CreateCdmInstance(const std::string& key_system);
    184 
    185   // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
    186   // <code>callback_factory_</code> to ensure that calls into
    187   // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
    188   void SendPromiseResolvedInternal(int32_t result, uint32_t promise_id);
    189   void SendPromiseResolvedWithSessionInternal(
    190       int32_t result,
    191       uint32_t promise_id,
    192       const std::string& web_session_id);
    193   void SendPromiseResolvedWithUsableKeyIdsInternal(
    194       int32_t result,
    195       uint32_t promise_id,
    196       std::vector<std::vector<uint8> > key_ids);
    197   void SendPromiseRejectedInternal(int32_t result,
    198                                    uint32_t promise_id,
    199                                    const SessionError& error);
    200   void SendSessionMessageInternal(int32_t result,
    201                                   const std::string& web_session_id,
    202                                   const std::vector<uint8>& message,
    203                                   const std::string& destination_url);
    204   void SendSessionReadyInternal(int32_t result,
    205                                 const std::string& web_session_id);
    206   void SendSessionClosedInternal(int32_t result,
    207                                  const std::string& web_session_id);
    208   void SendSessionErrorInternal(int32_t result,
    209                                 const std::string& web_session_id,
    210                                 const SessionError& error);
    211   void SendSessionUsableKeysChangeInternal(int32_t result,
    212                                            const std::string& web_session_id,
    213                                            bool has_additional_usable_key);
    214   void SendExpirationChangeInternal(int32_t result,
    215                                     const std::string& web_session_id,
    216                                     cdm::Time new_expiry_time);
    217   void RejectPromise(uint32_t promise_id,
    218                      cdm::Error error,
    219                      uint32_t system_code,
    220                      const std::string& error_message);
    221 
    222   void DeliverBlock(int32_t result,
    223                     const cdm::Status& status,
    224                     const LinkedDecryptedBlock& decrypted_block,
    225                     const PP_DecryptTrackingInfo& tracking_info);
    226   void DecoderInitializeDone(int32_t result,
    227                              PP_DecryptorStreamType decoder_type,
    228                              uint32_t request_id,
    229                              bool success);
    230   void DecoderDeinitializeDone(int32_t result,
    231                                PP_DecryptorStreamType decoder_type,
    232                                uint32_t request_id);
    233   void DecoderResetDone(int32_t result,
    234                         PP_DecryptorStreamType decoder_type,
    235                         uint32_t request_id);
    236   void DeliverFrame(int32_t result,
    237                     const cdm::Status& status,
    238                     const LinkedVideoFrame& video_frame,
    239                     const PP_DecryptTrackingInfo& tracking_info);
    240   void DeliverSamples(int32_t result,
    241                       const cdm::Status& status,
    242                       const LinkedAudioFrames& audio_frames,
    243                       const PP_DecryptTrackingInfo& tracking_info);
    244 
    245   // Helper for SetTimer().
    246   void TimerExpired(int32_t result, void* context);
    247 
    248   bool IsValidVideoFrame(const LinkedVideoFrame& video_frame);
    249 
    250   // Callback to report |file_size_bytes| of the first file read by FileIO.
    251   void OnFirstFileRead(int32_t file_size_bytes);
    252 
    253 #if !defined(NDEBUG)
    254   // Logs the given message to the JavaScript console associated with the
    255   // CDM adapter instance. The name of the CDM adapter issuing the log message
    256   // will be automatically prepended to the message.
    257   void LogToConsole(const pp::Var& value);
    258 #endif  // !defined(NDEBUG)
    259 
    260 #if defined(OS_CHROMEOS)
    261   void ReportOutputProtectionUMA(OutputProtectionStatus status);
    262   void ReportOutputProtectionQuery();
    263   void ReportOutputProtectionQueryResult();
    264 
    265   struct PepperPlatformChallengeResponse {
    266     pp::Var signed_data;
    267     pp::Var signed_data_signature;
    268     pp::Var platform_key_certificate;
    269   };
    270 
    271   void SendPlatformChallengeDone(
    272       int32_t result,
    273       const linked_ptr<PepperPlatformChallengeResponse>& response);
    274   void EnableProtectionDone(int32_t result);
    275   void QueryOutputProtectionStatusDone(int32_t result);
    276 
    277   pp::OutputProtection_Private output_protection_;
    278   pp::PlatformVerification platform_verification_;
    279 
    280   // Same as above, these are only read by QueryOutputProtectionStatusDone().
    281   uint32_t output_link_mask_;
    282   uint32_t output_protection_mask_;
    283   bool query_output_protection_in_progress_;
    284 
    285   // Tracks whether an output protection query and a positive query result (no
    286   // unprotected external link) have been reported to UMA.
    287   bool uma_for_output_protection_query_reported_;
    288   bool uma_for_output_protection_positive_result_reported_;
    289 #endif
    290 
    291   PpbBufferAllocator allocator_;
    292   pp::CompletionCallbackFactory<CdmAdapter> callback_factory_;
    293   linked_ptr<CdmWrapper> cdm_;
    294   std::string key_system_;
    295 
    296   // If the CDM returned kDeferredInitialization during InitializeAudioDecoder()
    297   // or InitializeVideoDecoder(), the (Audio|Video)DecoderConfig.request_id is
    298   // saved for the future call to OnDeferredInitializationDone().
    299   bool deferred_initialize_audio_decoder_;
    300   uint32_t deferred_audio_decoder_config_id_;
    301   bool deferred_initialize_video_decoder_;
    302   uint32_t deferred_video_decoder_config_id_;
    303 
    304   uint32_t last_read_file_size_kb_;
    305   bool file_size_uma_reported_;
    306 
    307   DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
    308 };
    309 
    310 }  // namespace media
    311 
    312 #endif  // MEDIA_CDM_PPAPI_CDM_ADAPTER_H_
    313