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