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