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