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_1, 41 public cdm::Host_2, 42 public cdm::Host_3 { 43 public: 44 CdmAdapter(PP_Instance instance, pp::Module* module); 45 virtual ~CdmAdapter(); 46 47 // pp::Instance implementation. 48 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 49 return true; 50 } 51 52 // PPP_ContentDecryptor_Private implementation. 53 // Note: Results of calls to these methods must be reported through the 54 // PPB_ContentDecryptor_Private interface. 55 virtual void Initialize(const std::string& key_system) OVERRIDE; 56 virtual void CreateSession(uint32_t session_id, 57 const std::string& type, 58 pp::VarArrayBuffer init_data) OVERRIDE; 59 virtual void UpdateSession(uint32_t session_id, 60 pp::VarArrayBuffer response) OVERRIDE; 61 virtual void ReleaseSession(uint32_t session_id) OVERRIDE; 62 virtual void Decrypt( 63 pp::Buffer_Dev encrypted_buffer, 64 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 65 virtual void InitializeAudioDecoder( 66 const PP_AudioDecoderConfig& decoder_config, 67 pp::Buffer_Dev extra_data_buffer) OVERRIDE; 68 virtual void InitializeVideoDecoder( 69 const PP_VideoDecoderConfig& decoder_config, 70 pp::Buffer_Dev extra_data_buffer) OVERRIDE; 71 virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type, 72 uint32_t request_id) OVERRIDE; 73 virtual void ResetDecoder(PP_DecryptorStreamType decoder_type, 74 uint32_t request_id) OVERRIDE; 75 virtual void DecryptAndDecode( 76 PP_DecryptorStreamType decoder_type, 77 pp::Buffer_Dev encrypted_buffer, 78 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 79 80 // cdm::Host implementation. 81 virtual cdm::Buffer* Allocate(uint32_t capacity) OVERRIDE; 82 virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE; 83 virtual double GetCurrentWallTimeInSeconds() OVERRIDE; 84 virtual void SendKeyMessage( 85 const char* session_id, uint32_t session_id_length, 86 const char* message, uint32_t message_length, 87 const char* default_url, uint32_t default_url_length) OVERRIDE; 88 virtual void SendKeyError(const char* session_id, 89 uint32_t session_id_length, 90 cdm::MediaKeyError error_code, 91 uint32_t system_code) OVERRIDE; 92 virtual void GetPrivateData(int32_t* instance, 93 GetPrivateInterface* get_interface) OVERRIDE; 94 95 // cdm::Host_2 implementation. 96 virtual void SendPlatformChallenge( 97 const char* service_id, uint32_t service_id_length, 98 const char* challenge, uint32_t challenge_length) OVERRIDE; 99 virtual void EnableOutputProtection( 100 uint32_t desired_protection_mask) OVERRIDE; 101 virtual void QueryOutputProtectionStatus() OVERRIDE; 102 virtual void OnDeferredInitializationDone( 103 cdm::StreamType stream_type, 104 cdm::Status decoder_status) OVERRIDE; 105 106 // cdm::Host_3 implementation. 107 virtual void OnSessionCreated(uint32_t session_id, 108 const char* web_session_id, 109 uint32_t web_session_id_length) OVERRIDE; 110 virtual void OnSessionMessage(uint32_t session_id, 111 const char* message, 112 uint32_t message_length, 113 const char* destination_url, 114 uint32_t destination_url_length) OVERRIDE; 115 virtual void OnSessionReady(uint32_t session_id) OVERRIDE; 116 virtual void OnSessionClosed(uint32_t session_id) OVERRIDE; 117 virtual void OnSessionError(uint32_t session_id, 118 cdm::MediaKeyError error_code, 119 uint32_t system_code) OVERRIDE; 120 121 private: 122 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; 123 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; 124 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; 125 126 bool CreateCdmInstance(const std::string& key_system); 127 128 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to 129 // <code>callback_factory_</code> to ensure that calls into 130 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 131 void SendSessionCreatedInternal(int32_t result, 132 uint32_t session_id, 133 const std::string& web_session_id); 134 void SendSessionMessageInternal(int32_t result, 135 uint32_t session_id, 136 const std::vector<uint8>& message, 137 const std::string& default_url); 138 void SendSessionReadyInternal(int32_t result, uint32_t session_id); 139 void SendSessionClosedInternal(int32_t result, uint32_t session_id); 140 void SendSessionErrorInternal(int32_t result, 141 uint32_t session_id, 142 cdm::MediaKeyError error_code, 143 uint32_t system_code); 144 145 void DeliverBlock(int32_t result, 146 const cdm::Status& status, 147 const LinkedDecryptedBlock& decrypted_block, 148 const PP_DecryptTrackingInfo& tracking_info); 149 void DecoderInitializeDone(int32_t result, 150 PP_DecryptorStreamType decoder_type, 151 uint32_t request_id, 152 bool success); 153 void DecoderDeinitializeDone(int32_t result, 154 PP_DecryptorStreamType decoder_type, 155 uint32_t request_id); 156 void DecoderResetDone(int32_t result, 157 PP_DecryptorStreamType decoder_type, 158 uint32_t request_id); 159 void DeliverFrame(int32_t result, 160 const cdm::Status& status, 161 const LinkedVideoFrame& video_frame, 162 const PP_DecryptTrackingInfo& tracking_info); 163 void DeliverSamples(int32_t result, 164 const cdm::Status& status, 165 const LinkedAudioFrames& audio_frames, 166 const PP_DecryptTrackingInfo& tracking_info); 167 168 // Helper for SetTimer(). 169 void TimerExpired(int32_t result, void* context); 170 171 bool IsValidVideoFrame(const LinkedVideoFrame& video_frame); 172 173 #if !defined(NDEBUG) 174 // Logs the given message to the JavaScript console associated with the 175 // CDM adapter instance. The name of the CDM adapter issuing the log message 176 // will be automatically prepended to the message. 177 void LogToConsole(const pp::Var& value); 178 #endif // !defined(NDEBUG) 179 180 #if defined(OS_CHROMEOS) 181 void SendPlatformChallengeDone(int32_t result); 182 void EnableProtectionDone(int32_t result); 183 void QueryOutputProtectionStatusDone(int32_t result); 184 185 pp::OutputProtection_Private output_protection_; 186 pp::PlatformVerification platform_verification_; 187 188 // Since PPAPI doesn't provide handlers for CompletionCallbacks with more than 189 // one output we need to manage our own. These values are only read by 190 // SendPlatformChallengeDone(). 191 pp::Var signed_data_output_; 192 pp::Var signed_data_signature_output_; 193 pp::Var platform_key_certificate_output_; 194 bool challenge_in_progress_; 195 196 // Same as above, these are only read by QueryOutputProtectionStatusDone(). 197 uint32_t output_link_mask_; 198 uint32_t output_protection_mask_; 199 bool query_output_protection_in_progress_; 200 #endif 201 202 PpbBufferAllocator allocator_; 203 pp::CompletionCallbackFactory<CdmAdapter> callback_factory_; 204 linked_ptr<CdmWrapper> cdm_; 205 std::string key_system_; 206 207 // If the CDM returned kDeferredInitialization during InitializeAudioDecoder() 208 // or InitializeVideoDecoder(), the (Audio|Video)DecoderConfig.request_id is 209 // saved for the future call to OnDeferredInitializationDone(). 210 bool deferred_initialize_audio_decoder_; 211 uint32_t deferred_audio_decoder_config_id_; 212 bool deferred_initialize_video_decoder_; 213 uint32_t deferred_video_decoder_config_id_; 214 215 DISALLOW_COPY_AND_ASSIGN(CdmAdapter); 216 }; 217 218 } // namespace media 219 220 #endif // MEDIA_CDM_PPAPI_CDM_ADAPTER_H_ 221