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