OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/android/media_drm_bridge.h" | 5 #include "media/base/android/media_drm_bridge.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
11 #include "base/android/jni_string.h" | 11 #include "base/android/jni_string.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/containers/hash_tables.h" | 13 #include "base/containers/hash_tables.h" |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/message_loop/message_loop_proxy.h" | 17 #include "base/message_loop/message_loop_proxy.h" |
18 #include "base/numerics/safe_conversions.h" | |
19 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
20 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
21 #include "base/sys_byteorder.h" | 20 #include "base/sys_byteorder.h" |
22 #include "base/sys_info.h" | 21 #include "base/sys_info.h" |
23 #include "jni/MediaDrmBridge_jni.h" | 22 #include "jni/MediaDrmBridge_jni.h" |
| 23 #include "media/base/android/media_client_android.h" |
| 24 #include "media/base/android/media_drm_bridge_delegate.h" |
24 #include "media/base/cdm_key_information.h" | 25 #include "media/base/cdm_key_information.h" |
25 | 26 |
26 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 27 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
27 | 28 |
28 using base::android::AttachCurrentThread; | 29 using base::android::AttachCurrentThread; |
29 using base::android::ConvertUTF8ToJavaString; | 30 using base::android::ConvertUTF8ToJavaString; |
30 using base::android::ConvertJavaStringToUTF8; | 31 using base::android::ConvertJavaStringToUTF8; |
31 using base::android::JavaByteArrayToByteVector; | 32 using base::android::JavaByteArrayToByteVector; |
32 using base::android::ScopedJavaLocalRef; | 33 using base::android::ScopedJavaLocalRef; |
33 | 34 |
34 namespace media { | 35 namespace media { |
35 | 36 |
36 namespace { | 37 namespace { |
37 | 38 |
38 // DrmBridge supports session expiration event but doesn't provide detailed | 39 // DrmBridge supports session expiration event but doesn't provide detailed |
39 // status for each key ID, which is required by the EME spec. Use a dummy key ID | 40 // status for each key ID, which is required by the EME spec. Use a dummy key ID |
40 // here to report session expiration info. | 41 // here to report session expiration info. |
41 const char kDummyKeyId[] = "Dummy Key Id"; | 42 const char kDummyKeyId[] = "Dummy Key Id"; |
42 | 43 |
43 uint32 ReadUint32(const uint8_t* data) { | |
44 uint32 value = 0; | |
45 for (int i = 0; i < 4; ++i) | |
46 value = (value << 8) | data[i]; | |
47 return value; | |
48 } | |
49 | |
50 uint64 ReadUint64(const uint8_t* data) { | |
51 uint64 value = 0; | |
52 for (int i = 0; i < 8; ++i) | |
53 value = (value << 8) | data[i]; | |
54 return value; | |
55 } | |
56 | |
57 // Returns string session ID from jbyteArray (byte[] in Java). | 44 // Returns string session ID from jbyteArray (byte[] in Java). |
58 std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) { | 45 std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) { |
59 std::vector<uint8> session_id_vector; | 46 std::vector<uint8> session_id_vector; |
60 JavaByteArrayToByteVector(env, j_session_id, &session_id_vector); | 47 JavaByteArrayToByteVector(env, j_session_id, &session_id_vector); |
61 return std::string(session_id_vector.begin(), session_id_vector.end()); | 48 return std::string(session_id_vector.begin(), session_id_vector.end()); |
62 } | 49 } |
63 | 50 |
64 // The structure of an ISO CENC Protection System Specific Header (PSSH) box is | |
65 // as follows. (See ISO/IEC FDIS 23001-7:2011(E).) | |
66 // Note: ISO boxes use big-endian values. | |
67 // | |
68 // PSSH { | |
69 // uint32 Size | |
70 // uint32 Type | |
71 // uint64 LargeSize # Field is only present if value(Size) == 1. | |
72 // uint32 VersionAndFlags | |
73 // uint8[16] SystemId | |
74 // uint32 DataSize | |
75 // uint8[DataSize] Data | |
76 // } | |
77 const int kBoxHeaderSize = 8; // Box's header contains Size and Type. | |
78 const int kBoxLargeSizeSize = 8; | |
79 const int kPsshVersionFlagSize = 4; | |
80 const int kPsshSystemIdSize = 16; | |
81 const int kPsshDataSizeSize = 4; | |
82 const uint32 kTencType = 0x74656e63; | |
83 const uint32 kPsshType = 0x70737368; | |
84 const uint8 kWidevineUuid[16] = { | 51 const uint8 kWidevineUuid[16] = { |
85 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, | 52 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
86 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; | 53 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
87 | 54 |
88 typedef std::vector<uint8> UUID; | |
89 | |
90 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the | |
91 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is | |
92 // found and successfully parsed. Returns false otherwise. | |
93 // Notes: | |
94 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box | |
95 // will be set in |pssh_data|. | |
96 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. | |
97 bool GetPsshData(const std::vector<uint8_t>& data, | |
98 const UUID& uuid, | |
99 std::vector<uint8>* pssh_data) { | |
100 int bytes_left = base::checked_cast<int>(data.size()); | |
101 const uint8_t* cur = &data[0]; | |
102 const uint8_t* data_end = cur + bytes_left; | |
103 | |
104 while (bytes_left > 0) { | |
105 const uint8* box_head = cur; | |
106 | |
107 if (bytes_left < kBoxHeaderSize) | |
108 return false; | |
109 | |
110 uint64_t box_size = ReadUint32(cur); | |
111 uint32 type = ReadUint32(cur + 4); | |
112 cur += kBoxHeaderSize; | |
113 bytes_left -= kBoxHeaderSize; | |
114 | |
115 if (box_size == 1) { // LargeSize is present. | |
116 if (bytes_left < kBoxLargeSizeSize) | |
117 return false; | |
118 | |
119 box_size = ReadUint64(cur); | |
120 cur += kBoxLargeSizeSize; | |
121 bytes_left -= kBoxLargeSizeSize; | |
122 } else if (box_size == 0) { | |
123 box_size = bytes_left + kBoxHeaderSize; | |
124 } | |
125 | |
126 const uint8* box_end = box_head + box_size; | |
127 if (data_end < box_end) | |
128 return false; | |
129 | |
130 if (type == kTencType) { | |
131 // Skip 'tenc' box. | |
132 cur = box_end; | |
133 bytes_left = data_end - cur; | |
134 continue; | |
135 } else if (type != kPsshType) { | |
136 return false; | |
137 } | |
138 | |
139 const int kPsshBoxMinimumSize = | |
140 kPsshVersionFlagSize + kPsshSystemIdSize + kPsshDataSizeSize; | |
141 if (box_end < cur + kPsshBoxMinimumSize) | |
142 return false; | |
143 | |
144 uint32 version_and_flags = ReadUint32(cur); | |
145 cur += kPsshVersionFlagSize; | |
146 bytes_left -= kPsshVersionFlagSize; | |
147 if (version_and_flags != 0) | |
148 return false; | |
149 | |
150 DCHECK_GE(bytes_left, kPsshSystemIdSize); | |
151 if (!std::equal(uuid.begin(), uuid.end(), cur)) { | |
152 cur = box_end; | |
153 bytes_left = data_end - cur; | |
154 continue; | |
155 } | |
156 | |
157 cur += kPsshSystemIdSize; | |
158 bytes_left -= kPsshSystemIdSize; | |
159 | |
160 uint32 data_size = ReadUint32(cur); | |
161 cur += kPsshDataSizeSize; | |
162 bytes_left -= kPsshDataSizeSize; | |
163 | |
164 if (box_end < cur + data_size) | |
165 return false; | |
166 | |
167 pssh_data->assign(cur, cur + data_size); | |
168 return true; | |
169 } | |
170 | |
171 return false; | |
172 } | |
173 | |
174 // Convert |init_data_type| to a string supported by MediaDRM. | 55 // Convert |init_data_type| to a string supported by MediaDRM. |
175 // "audio"/"video" does not matter, so use "video". | 56 // "audio"/"video" does not matter, so use "video". |
176 std::string ConvertInitDataType(media::EmeInitDataType init_data_type) { | 57 std::string ConvertInitDataType(media::EmeInitDataType init_data_type) { |
177 // TODO(jrummell): API level >=20 supports "webm" and "cenc", so switch | 58 // TODO(jrummell): API level >=20 supports "webm" and "cenc", so switch |
178 // to those strings. | 59 // to those strings. |
179 switch (init_data_type) { | 60 switch (init_data_type) { |
180 case media::EmeInitDataType::WEBM: | 61 case media::EmeInitDataType::WEBM: |
181 return "video/webm"; | 62 return "video/webm"; |
182 case media::EmeInitDataType::CENC: | 63 case media::EmeInitDataType::CENC: |
183 return "video/mp4"; | 64 return "video/mp4"; |
184 default: | 65 default: |
185 NOTREACHED(); | 66 NOTREACHED(); |
186 return "video/unknown"; | 67 return "video/unknown"; |
187 } | 68 } |
188 } | 69 } |
189 | 70 |
190 class KeySystemUuidManager { | 71 class KeySystemManager { |
191 public: | 72 public: |
192 KeySystemUuidManager(); | 73 KeySystemManager(); |
193 UUID GetUUID(const std::string& key_system); | 74 UUID GetUUID(const std::string& key_system); |
194 void AddMapping(const std::string& key_system, const UUID& uuid); | |
195 std::vector<std::string> GetPlatformKeySystemNames(); | 75 std::vector<std::string> GetPlatformKeySystemNames(); |
196 | 76 |
197 private: | 77 private: |
198 typedef base::hash_map<std::string, UUID> KeySystemUuidMap; | 78 using KeySystemUuidMap = MediaClientAndroid::KeySystemUuidMap; |
199 | 79 |
200 KeySystemUuidMap key_system_uuid_map_; | 80 KeySystemUuidMap key_system_uuid_map_; |
201 | 81 |
202 DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager); | 82 DISALLOW_COPY_AND_ASSIGN(KeySystemManager); |
203 }; | 83 }; |
204 | 84 |
205 KeySystemUuidManager::KeySystemUuidManager() { | 85 KeySystemManager::KeySystemManager() { |
206 // Widevine is always supported in Android. | 86 // Widevine is always supported in Android. |
207 key_system_uuid_map_[kWidevineKeySystem] = | 87 key_system_uuid_map_[kWidevineKeySystem] = |
208 UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); | 88 UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); |
| 89 MediaClientAndroid* client = GetMediaClientAndroid(); |
| 90 if (client) |
| 91 client->AddKeySystemUUIDMappings(&key_system_uuid_map_); |
209 } | 92 } |
210 | 93 |
211 UUID KeySystemUuidManager::GetUUID(const std::string& key_system) { | 94 UUID KeySystemManager::GetUUID(const std::string& key_system) { |
212 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | 95 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); |
213 if (it == key_system_uuid_map_.end()) | 96 if (it == key_system_uuid_map_.end()) |
214 return UUID(); | 97 return UUID(); |
215 return it->second; | 98 return it->second; |
216 } | 99 } |
217 | 100 |
218 void KeySystemUuidManager::AddMapping(const std::string& key_system, | 101 std::vector<std::string> KeySystemManager::GetPlatformKeySystemNames() { |
219 const UUID& uuid) { | |
220 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | |
221 DCHECK(it == key_system_uuid_map_.end()) | |
222 << "Shouldn't overwrite an existing key system."; | |
223 if (it != key_system_uuid_map_.end()) | |
224 return; | |
225 key_system_uuid_map_[key_system] = uuid; | |
226 } | |
227 | |
228 std::vector<std::string> KeySystemUuidManager::GetPlatformKeySystemNames() { | |
229 std::vector<std::string> key_systems; | 102 std::vector<std::string> key_systems; |
230 for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); | 103 for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); |
231 it != key_system_uuid_map_.end(); ++it) { | 104 it != key_system_uuid_map_.end(); ++it) { |
232 // Rule out the key system handled by Chrome explicitly. | 105 // Rule out the key system handled by Chrome explicitly. |
233 if (it->first != kWidevineKeySystem) | 106 if (it->first != kWidevineKeySystem) |
234 key_systems.push_back(it->first); | 107 key_systems.push_back(it->first); |
235 } | 108 } |
236 return key_systems; | 109 return key_systems; |
237 } | 110 } |
238 | 111 |
239 base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager = | 112 base::LazyInstance<KeySystemManager>::Leaky g_key_system_manager = |
240 LAZY_INSTANCE_INITIALIZER; | 113 LAZY_INSTANCE_INITIALIZER; |
241 | 114 |
242 // Checks whether |key_system| is supported with |container_mime_type|. Only | 115 // Checks whether |key_system| is supported with |container_mime_type|. Only |
243 // checks |key_system| support if |container_mime_type| is empty. | 116 // checks |key_system| support if |container_mime_type| is empty. |
244 // TODO(xhwang): The |container_mime_type| is not the same as contentType in | 117 // TODO(xhwang): The |container_mime_type| is not the same as contentType in |
245 // the EME spec. Revisit this once the spec issue with initData type is | 118 // the EME spec. Revisit this once the spec issue with initData type is |
246 // resolved. | 119 // resolved. |
247 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, | 120 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, |
248 const std::string& container_mime_type) { | 121 const std::string& container_mime_type) { |
249 if (!MediaDrmBridge::IsAvailable()) | 122 if (!MediaDrmBridge::IsAvailable()) |
250 return false; | 123 return false; |
251 | 124 |
252 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); | 125 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
253 if (scheme_uuid.empty()) | 126 if (scheme_uuid.empty()) |
254 return false; | 127 return false; |
255 | 128 |
256 JNIEnv* env = AttachCurrentThread(); | 129 JNIEnv* env = AttachCurrentThread(); |
257 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 130 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
258 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 131 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
259 ScopedJavaLocalRef<jstring> j_container_mime_type = | 132 ScopedJavaLocalRef<jstring> j_container_mime_type = |
260 ConvertUTF8ToJavaString(env, container_mime_type); | 133 ConvertUTF8ToJavaString(env, container_mime_type); |
261 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 134 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
262 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 135 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
(...skipping 17 matching lines...) Expand all Loading... |
280 case MediaDrmBridge::SECURITY_LEVEL_1: | 153 case MediaDrmBridge::SECURITY_LEVEL_1: |
281 return "L1"; | 154 return "L1"; |
282 case MediaDrmBridge::SECURITY_LEVEL_3: | 155 case MediaDrmBridge::SECURITY_LEVEL_3: |
283 return "L3"; | 156 return "L3"; |
284 } | 157 } |
285 return ""; | 158 return ""; |
286 } | 159 } |
287 | 160 |
288 } // namespace | 161 } // namespace |
289 | 162 |
290 // Called by Java. | |
291 static void AddKeySystemUuidMapping(JNIEnv* env, | |
292 jclass clazz, | |
293 jstring j_key_system, | |
294 jobject j_buffer) { | |
295 std::string key_system = ConvertJavaStringToUTF8(env, j_key_system); | |
296 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer)); | |
297 UUID uuid(buffer, buffer + 16); | |
298 g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); | |
299 } | |
300 | |
301 // static | 163 // static |
302 bool MediaDrmBridge::IsAvailable() { | 164 bool MediaDrmBridge::IsAvailable() { |
303 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) | 165 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) |
304 return false; | 166 return false; |
305 | 167 |
306 int32 os_major_version = 0; | 168 int32 os_major_version = 0; |
307 int32 os_minor_version = 0; | 169 int32 os_minor_version = 0; |
308 int32 os_bugfix_version = 0; | 170 int32 os_bugfix_version = 0; |
309 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, | 171 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, |
310 &os_minor_version, | 172 &os_minor_version, |
311 &os_bugfix_version); | 173 &os_bugfix_version); |
312 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) | 174 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) |
313 return false; | 175 return false; |
314 | 176 |
315 return true; | 177 return true; |
316 } | 178 } |
317 | 179 |
318 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 180 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
319 // static | 181 // static |
320 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 182 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
321 DCHECK(IsAvailable()); | 183 DCHECK(IsAvailable()); |
322 return SECURITY_LEVEL_1 == security_level; | 184 return SECURITY_LEVEL_1 == security_level; |
323 } | 185 } |
324 | 186 |
325 // static | 187 // static |
326 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 188 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
327 return g_key_system_uuid_manager.Get().GetPlatformKeySystemNames(); | 189 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
328 } | 190 } |
329 | 191 |
330 // static | 192 // static |
331 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 193 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
332 DCHECK(!key_system.empty()); | 194 DCHECK(!key_system.empty()); |
333 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 195 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
334 } | 196 } |
335 | 197 |
336 // static | 198 // static |
337 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 199 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 const std::string& key_system, | 240 const std::string& key_system, |
379 const SessionMessageCB& session_message_cb, | 241 const SessionMessageCB& session_message_cb, |
380 const SessionClosedCB& session_closed_cb, | 242 const SessionClosedCB& session_closed_cb, |
381 const LegacySessionErrorCB& legacy_session_error_cb, | 243 const LegacySessionErrorCB& legacy_session_error_cb, |
382 const SessionKeysChangeCB& session_keys_change_cb, | 244 const SessionKeysChangeCB& session_keys_change_cb, |
383 const SessionExpirationUpdateCB& /* session_expiration_update_cb */) { | 245 const SessionExpirationUpdateCB& /* session_expiration_update_cb */) { |
384 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 246 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
385 if (!IsAvailable()) | 247 if (!IsAvailable()) |
386 return media_drm_bridge.Pass(); | 248 return media_drm_bridge.Pass(); |
387 | 249 |
388 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); | 250 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
389 if (scheme_uuid.empty()) | 251 if (scheme_uuid.empty()) |
390 return media_drm_bridge.Pass(); | 252 return media_drm_bridge.Pass(); |
391 | 253 |
392 media_drm_bridge.reset( | 254 media_drm_bridge.reset( |
393 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, | 255 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, |
394 legacy_session_error_cb, session_keys_change_cb)); | 256 legacy_session_error_cb, session_keys_change_cb)); |
395 | 257 |
396 if (media_drm_bridge->j_media_drm_.is_null()) | 258 if (media_drm_bridge->j_media_drm_.is_null()) |
397 media_drm_bridge.reset(); | 259 media_drm_bridge.reset(); |
398 | 260 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 DVLOG(1) << __FUNCTION__; | 304 DVLOG(1) << __FUNCTION__; |
443 | 305 |
444 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { | 306 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { |
445 promise->reject(NOT_SUPPORTED_ERROR, 0, | 307 promise->reject(NOT_SUPPORTED_ERROR, 0, |
446 "Only the temporary session type is supported."); | 308 "Only the temporary session type is supported."); |
447 return; | 309 return; |
448 } | 310 } |
449 | 311 |
450 JNIEnv* env = AttachCurrentThread(); | 312 JNIEnv* env = AttachCurrentThread(); |
451 ScopedJavaLocalRef<jbyteArray> j_init_data; | 313 ScopedJavaLocalRef<jbyteArray> j_init_data; |
| 314 ScopedJavaLocalRef<jobjectArray> j_optional_parameters; |
452 | 315 |
453 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as | 316 MediaClientAndroid* client = GetMediaClientAndroid(); |
454 // the init data when using MP4 container. | 317 if (client) { |
455 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && | 318 MediaDrmBridgeDelegate* delegate = |
456 init_data_type == media::EmeInitDataType::CENC) { | 319 client->GetMediaDrmBridgeDelegate(scheme_uuid_); |
457 std::vector<uint8> pssh_data; | 320 if (delegate) { |
458 if (!GetPsshData(init_data, scheme_uuid_, &pssh_data)) { | 321 std::vector<uint8> init_data_from_delegate; |
459 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid PSSH data."); | 322 std::vector<std::string> optional_parameters_from_delegate; |
460 return; | 323 if (!delegate->OnCreateSession(init_data_type, init_data, |
| 324 &init_data_from_delegate, |
| 325 &optional_parameters_from_delegate)) { |
| 326 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid init data."); |
| 327 } |
| 328 j_init_data = base::android::ToJavaByteArray( |
| 329 env, vector_as_array(&init_data_from_delegate), |
| 330 init_data_from_delegate.size()); |
| 331 if (!optional_parameters_from_delegate.empty()) { |
| 332 j_optional_parameters = base::android::ToJavaArrayOfStrings( |
| 333 env, optional_parameters_from_delegate); |
| 334 } |
461 } | 335 } |
462 j_init_data = base::android::ToJavaByteArray( | 336 } |
463 env, vector_as_array(&pssh_data), pssh_data.size()); | 337 |
464 } else { | 338 if (j_init_data.is_null()) { |
465 j_init_data = base::android::ToJavaByteArray( | 339 j_init_data = base::android::ToJavaByteArray( |
466 env, vector_as_array(&init_data), init_data.size()); | 340 env, vector_as_array(&init_data), init_data.size()); |
467 } | 341 } |
468 | 342 |
469 ScopedJavaLocalRef<jstring> j_mime = | 343 ScopedJavaLocalRef<jstring> j_mime = |
470 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); | 344 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); |
471 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 345 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
472 Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(), | 346 Java_MediaDrmBridge_createSessionFromNative(env, j_media_drm_.obj(), |
473 j_mime.obj(), promise_id); | 347 j_init_data.obj(), j_mime.obj(), |
| 348 j_optional_parameters.obj(), |
| 349 promise_id); |
474 } | 350 } |
475 | 351 |
476 void MediaDrmBridge::LoadSession( | 352 void MediaDrmBridge::LoadSession( |
477 SessionType session_type, | 353 SessionType session_type, |
478 const std::string& session_id, | 354 const std::string& session_id, |
479 scoped_ptr<media::NewSessionCdmPromise> promise) { | 355 scoped_ptr<media::NewSessionCdmPromise> promise) { |
480 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); | 356 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); |
481 } | 357 } |
482 | 358 |
483 void MediaDrmBridge::UpdateSession( | 359 void MediaDrmBridge::UpdateSession( |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 JNIEnv* env = AttachCurrentThread(); | 533 JNIEnv* env = AttachCurrentThread(); |
658 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 534 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
659 } | 535 } |
660 | 536 |
661 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 537 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
662 JNIEnv* env, jobject, bool success) { | 538 JNIEnv* env, jobject, bool success) { |
663 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 539 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
664 } | 540 } |
665 | 541 |
666 } // namespace media | 542 } // namespace media |
OLD | NEW |