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" |
22 #include "media/base/cdm_key_information.h" | 23 #include "media/base/cdm_key_information.h" |
23 | 24 |
24 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. | 25 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. |
25 | 26 |
26 using base::android::AttachCurrentThread; | 27 using base::android::AttachCurrentThread; |
27 using base::android::ConvertUTF8ToJavaString; | 28 using base::android::ConvertUTF8ToJavaString; |
28 using base::android::ConvertJavaStringToUTF8; | 29 using base::android::ConvertJavaStringToUTF8; |
29 using base::android::JavaByteArrayToByteVector; | 30 using base::android::JavaByteArrayToByteVector; |
30 using base::android::ScopedJavaLocalRef; | 31 using base::android::ScopedJavaLocalRef; |
31 | 32 |
32 namespace media { | 33 namespace media { |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
36 // DrmBridge supports session expiration event but doesn't provide detailed | 37 // 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 | 38 // status for each key ID, which is required by the EME spec. Use a dummy key ID |
38 // here to report session expiration info. | 39 // here to report session expiration info. |
39 const char kDummyKeyId[] = "Dummy Key Id"; | 40 const char kDummyKeyId[] = "Dummy Key Id"; |
40 | 41 |
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). | 42 // Returns string session ID from jbyteArray (byte[] in Java). |
56 std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) { | 43 std::string GetSessionId(JNIEnv* env, jbyteArray j_session_id) { |
57 std::vector<uint8> session_id_vector; | 44 std::vector<uint8> session_id_vector; |
58 JavaByteArrayToByteVector(env, j_session_id, &session_id_vector); | 45 JavaByteArrayToByteVector(env, j_session_id, &session_id_vector); |
59 return std::string(session_id_vector.begin(), session_id_vector.end()); | 46 return std::string(session_id_vector.begin(), session_id_vector.end()); |
60 } | 47 } |
61 | 48 |
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] = { | 49 const uint8 kWidevineUuid[16] = { |
83 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, | 50 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, |
84 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; | 51 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; |
85 | 52 |
86 typedef std::vector<uint8> UUID; | 53 typedef std::vector<uint8> UUID; |
87 | 54 |
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. | 55 // Convert |init_data_type| to a string supported by MediaDRM. |
174 // "audio"/"video" does not matter, so use "video". | 56 // "audio"/"video" does not matter, so use "video". |
175 std::string ConvertInitDataType(media::EmeInitDataType init_data_type) { | 57 std::string ConvertInitDataType(media::EmeInitDataType init_data_type) { |
176 // TODO(jrummell): API level >=20 supports "webm" and "cenc", so switch | 58 // TODO(jrummell): API level >=20 supports "webm" and "cenc", so switch |
177 // to those strings. | 59 // to those strings. |
178 switch (init_data_type) { | 60 switch (init_data_type) { |
179 case media::EmeInitDataType::WEBM: | 61 case media::EmeInitDataType::WEBM: |
180 return "video/webm"; | 62 return "video/webm"; |
181 case media::EmeInitDataType::CENC: | 63 case media::EmeInitDataType::CENC: |
182 return "video/mp4"; | 64 return "video/mp4"; |
183 default: | 65 default: |
184 NOTREACHED(); | 66 NOTREACHED(); |
185 return "video/unknown"; | 67 return "video/unknown"; |
186 } | 68 } |
187 } | 69 } |
188 | 70 |
189 class KeySystemUuidManager { | 71 class KeySystemManager { |
190 public: | 72 public: |
191 KeySystemUuidManager(); | 73 KeySystemManager(); |
192 UUID GetUUID(const std::string& key_system); | 74 UUID GetUUID(const std::string& key_system); |
193 void AddMapping(const std::string& key_system, const UUID& uuid); | 75 void AddMapping(const std::string& key_system, const UUID& uuid); |
76 void RegisterDelegate(const std::string& key_system, | |
77 MediaDrmBridge::Delegate* delegate); | |
78 MediaDrmBridge::Delegate* GetDelegate(const std::string& key_system); | |
194 std::vector<std::string> GetPlatformKeySystemNames(); | 79 std::vector<std::string> GetPlatformKeySystemNames(); |
195 | 80 |
196 private: | 81 private: |
197 typedef base::hash_map<std::string, UUID> KeySystemUuidMap; | 82 typedef base::hash_map<std::string, UUID> KeySystemUuidMap; |
83 typedef base::hash_map<std::string, MediaDrmBridge::Delegate*> | |
84 KeySystemDelegateMap; | |
198 | 85 |
86 KeySystemDelegateMap key_system_delegates_; | |
199 KeySystemUuidMap key_system_uuid_map_; | 87 KeySystemUuidMap key_system_uuid_map_; |
200 | 88 |
201 DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager); | 89 DISALLOW_COPY_AND_ASSIGN(KeySystemManager); |
202 }; | 90 }; |
203 | 91 |
204 KeySystemUuidManager::KeySystemUuidManager() { | 92 KeySystemManager::KeySystemManager() { |
205 // Widevine is always supported in Android. | 93 // Widevine is always supported in Android. |
206 key_system_uuid_map_[kWidevineKeySystem] = | 94 key_system_uuid_map_[kWidevineKeySystem] = |
207 UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); | 95 UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); |
208 } | 96 } |
209 | 97 |
210 UUID KeySystemUuidManager::GetUUID(const std::string& key_system) { | 98 UUID KeySystemManager::GetUUID(const std::string& key_system) { |
211 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | 99 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); |
212 if (it == key_system_uuid_map_.end()) | 100 if (it == key_system_uuid_map_.end()) |
213 return UUID(); | 101 return UUID(); |
214 return it->second; | 102 return it->second; |
215 } | 103 } |
216 | 104 |
217 void KeySystemUuidManager::AddMapping(const std::string& key_system, | 105 void KeySystemManager::AddMapping(const std::string& key_system, |
218 const UUID& uuid) { | 106 const UUID& uuid) { |
219 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); | 107 KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); |
220 DCHECK(it == key_system_uuid_map_.end()) | 108 DCHECK(it == key_system_uuid_map_.end()) |
221 << "Shouldn't overwrite an existing key system."; | 109 << "Shouldn't overwrite an existing key system."; |
222 if (it != key_system_uuid_map_.end()) | 110 if (it != key_system_uuid_map_.end()) |
223 return; | 111 return; |
224 key_system_uuid_map_[key_system] = uuid; | 112 key_system_uuid_map_[key_system] = uuid; |
225 } | 113 } |
226 | 114 |
227 std::vector<std::string> KeySystemUuidManager::GetPlatformKeySystemNames() { | 115 void KeySystemManager::RegisterDelegate( |
116 const std::string& key_system, MediaDrmBridge::Delegate* delegate) { | |
117 DCHECK(!ContainsKey(key_system_delegates_, key_system)) | |
118 << "Shouldn't overwrite an existing delegate."; | |
119 key_system_delegates_[key_system] = delegate; | |
120 } | |
121 | |
122 MediaDrmBridge::Delegate* KeySystemManager::GetDelegate( | |
123 const std::string& key_system) { | |
124 KeySystemDelegateMap::iterator it = key_system_delegates_.find(key_system); | |
125 if (it == key_system_delegates_.end()) | |
126 return nullptr; | |
127 return it->second; | |
128 } | |
129 | |
130 std::vector<std::string> KeySystemManager::GetPlatformKeySystemNames() { | |
228 std::vector<std::string> key_systems; | 131 std::vector<std::string> key_systems; |
229 for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); | 132 for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); |
230 it != key_system_uuid_map_.end(); ++it) { | 133 it != key_system_uuid_map_.end(); ++it) { |
231 // Rule out the key system handled by Chrome explicitly. | 134 // Rule out the key system handled by Chrome explicitly. |
232 if (it->first != kWidevineKeySystem) | 135 if (it->first != kWidevineKeySystem) |
233 key_systems.push_back(it->first); | 136 key_systems.push_back(it->first); |
234 } | 137 } |
235 return key_systems; | 138 return key_systems; |
236 } | 139 } |
237 | 140 |
238 base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager = | 141 base::LazyInstance<KeySystemManager>::Leaky g_key_system_manager = |
239 LAZY_INSTANCE_INITIALIZER; | 142 LAZY_INSTANCE_INITIALIZER; |
240 | 143 |
241 // Checks whether |key_system| is supported with |container_mime_type|. Only | 144 // Checks whether |key_system| is supported with |container_mime_type|. Only |
242 // checks |key_system| support if |container_mime_type| is empty. | 145 // checks |key_system| support if |container_mime_type| is empty. |
243 // TODO(xhwang): The |container_mime_type| is not the same as contentType in | 146 // 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 | 147 // the EME spec. Revisit this once the spec issue with initData type is |
245 // resolved. | 148 // resolved. |
246 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, | 149 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, |
247 const std::string& container_mime_type) { | 150 const std::string& container_mime_type) { |
248 if (!MediaDrmBridge::IsAvailable()) | 151 if (!MediaDrmBridge::IsAvailable()) |
249 return false; | 152 return false; |
250 | 153 |
251 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); | 154 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
252 if (scheme_uuid.empty()) | 155 if (scheme_uuid.empty()) |
253 return false; | 156 return false; |
254 | 157 |
255 JNIEnv* env = AttachCurrentThread(); | 158 JNIEnv* env = AttachCurrentThread(); |
256 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 159 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
257 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 160 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
258 ScopedJavaLocalRef<jstring> j_container_mime_type = | 161 ScopedJavaLocalRef<jstring> j_container_mime_type = |
259 ConvertUTF8ToJavaString(env, container_mime_type); | 162 ConvertUTF8ToJavaString(env, container_mime_type); |
260 return Java_MediaDrmBridge_isCryptoSchemeSupported( | 163 return Java_MediaDrmBridge_isCryptoSchemeSupported( |
261 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); | 164 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); |
(...skipping 25 matching lines...) Expand all Loading... | |
287 } // namespace | 190 } // namespace |
288 | 191 |
289 // Called by Java. | 192 // Called by Java. |
290 static void AddKeySystemUuidMapping(JNIEnv* env, | 193 static void AddKeySystemUuidMapping(JNIEnv* env, |
291 jclass clazz, | 194 jclass clazz, |
292 jstring j_key_system, | 195 jstring j_key_system, |
293 jobject j_buffer) { | 196 jobject j_buffer) { |
294 std::string key_system = ConvertJavaStringToUTF8(env, j_key_system); | 197 std::string key_system = ConvertJavaStringToUTF8(env, j_key_system); |
295 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer)); | 198 uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer)); |
296 UUID uuid(buffer, buffer + 16); | 199 UUID uuid(buffer, buffer + 16); |
297 g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); | 200 g_key_system_manager.Get().AddMapping(key_system, uuid); |
201 } | |
202 | |
203 MediaDrmBridge::Delegate::Delegate() { | |
204 } | |
205 | |
206 MediaDrmBridge::Delegate::~Delegate() { | |
207 } | |
208 | |
209 bool MediaDrmBridge::Delegate::OnCreateSession( | |
210 const EmeInitDataType init_data_type, | |
211 const uint8* init_data, | |
212 int init_data_length, | |
213 std::vector<uint8>& init_data_out, | |
214 std::vector<std::string>& optional_parameters_out) { | |
215 return true; | |
298 } | 216 } |
299 | 217 |
300 // static | 218 // static |
301 bool MediaDrmBridge::IsAvailable() { | 219 bool MediaDrmBridge::IsAvailable() { |
302 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) | 220 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) |
303 return false; | 221 return false; |
304 | 222 |
305 int32 os_major_version = 0; | 223 int32 os_major_version = 0; |
306 int32 os_minor_version = 0; | 224 int32 os_minor_version = 0; |
307 int32 os_bugfix_version = 0; | 225 int32 os_bugfix_version = 0; |
308 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, | 226 base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, |
309 &os_minor_version, | 227 &os_minor_version, |
310 &os_bugfix_version); | 228 &os_bugfix_version); |
311 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) | 229 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) |
312 return false; | 230 return false; |
313 | 231 |
314 return true; | 232 return true; |
315 } | 233 } |
316 | 234 |
317 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 | 235 // TODO(ddorwin): This is specific to Widevine. http://crbug.com/459400 |
318 // static | 236 // static |
319 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { | 237 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { |
320 DCHECK(IsAvailable()); | 238 DCHECK(IsAvailable()); |
321 return SECURITY_LEVEL_1 == security_level; | 239 return SECURITY_LEVEL_1 == security_level; |
322 } | 240 } |
323 | 241 |
324 // static | 242 // static |
325 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 243 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
326 return g_key_system_uuid_manager.Get().GetPlatformKeySystemNames(); | 244 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
327 } | 245 } |
328 | 246 |
329 // static | 247 // static |
330 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 248 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
331 DCHECK(!key_system.empty()); | 249 DCHECK(!key_system.empty()); |
332 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 250 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
333 } | 251 } |
334 | 252 |
335 // static | 253 // static |
336 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 254 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
337 const std::string& key_system, | 255 const std::string& key_system, |
338 const std::string& container_mime_type) { | 256 const std::string& container_mime_type) { |
339 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 257 DCHECK(!key_system.empty() && !container_mime_type.empty()); |
340 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 258 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
341 } | 259 } |
342 | 260 |
261 // static | |
262 void MediaDrmBridge::RegisterDelegate(const std::string& key_system, | |
263 Delegate* delegate) { | |
264 g_key_system_manager.Get().RegisterDelegate(key_system, delegate); | |
265 } | |
266 | |
343 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 267 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
344 return RegisterNativesImpl(env); | 268 return RegisterNativesImpl(env); |
345 } | 269 } |
346 | 270 |
347 MediaDrmBridge::MediaDrmBridge( | 271 MediaDrmBridge::MediaDrmBridge( |
348 const std::vector<uint8>& scheme_uuid, | 272 const std::vector<uint8>& scheme_uuid, |
349 const SessionMessageCB& session_message_cb, | 273 const SessionMessageCB& session_message_cb, |
350 const SessionClosedCB& session_closed_cb, | 274 const SessionClosedCB& session_closed_cb, |
351 const LegacySessionErrorCB& legacy_session_error_cb, | 275 const LegacySessionErrorCB& legacy_session_error_cb, |
352 const SessionKeysChangeCB& session_keys_change_cb) | 276 const SessionKeysChangeCB& session_keys_change_cb, |
277 Delegate* delegate) | |
353 : scheme_uuid_(scheme_uuid), | 278 : scheme_uuid_(scheme_uuid), |
279 delegate_(delegate), | |
354 session_message_cb_(session_message_cb), | 280 session_message_cb_(session_message_cb), |
355 session_closed_cb_(session_closed_cb), | 281 session_closed_cb_(session_closed_cb), |
356 legacy_session_error_cb_(legacy_session_error_cb), | 282 legacy_session_error_cb_(legacy_session_error_cb), |
357 session_keys_change_cb_(session_keys_change_cb) { | 283 session_keys_change_cb_(session_keys_change_cb) { |
358 JNIEnv* env = AttachCurrentThread(); | 284 JNIEnv* env = AttachCurrentThread(); |
359 CHECK(env); | 285 CHECK(env); |
360 | 286 |
361 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = | 287 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = |
362 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); | 288 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); |
363 j_media_drm_.Reset(Java_MediaDrmBridge_create( | 289 j_media_drm_.Reset(Java_MediaDrmBridge_create( |
(...skipping 13 matching lines...) Expand all Loading... | |
377 const std::string& key_system, | 303 const std::string& key_system, |
378 const SessionMessageCB& session_message_cb, | 304 const SessionMessageCB& session_message_cb, |
379 const SessionClosedCB& session_closed_cb, | 305 const SessionClosedCB& session_closed_cb, |
380 const LegacySessionErrorCB& legacy_session_error_cb, | 306 const LegacySessionErrorCB& legacy_session_error_cb, |
381 const SessionKeysChangeCB& session_keys_change_cb, | 307 const SessionKeysChangeCB& session_keys_change_cb, |
382 const SessionExpirationUpdateCB& /* session_expiration_update_cb */) { | 308 const SessionExpirationUpdateCB& /* session_expiration_update_cb */) { |
383 scoped_ptr<MediaDrmBridge> media_drm_bridge; | 309 scoped_ptr<MediaDrmBridge> media_drm_bridge; |
384 if (!IsAvailable()) | 310 if (!IsAvailable()) |
385 return media_drm_bridge.Pass(); | 311 return media_drm_bridge.Pass(); |
386 | 312 |
387 UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); | 313 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
388 if (scheme_uuid.empty()) | 314 if (scheme_uuid.empty()) |
389 return media_drm_bridge.Pass(); | 315 return media_drm_bridge.Pass(); |
390 | 316 |
317 Delegate* delegate = g_key_system_manager.Get().GetDelegate(key_system); | |
391 media_drm_bridge.reset( | 318 media_drm_bridge.reset( |
392 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, | 319 new MediaDrmBridge(scheme_uuid, session_message_cb, session_closed_cb, |
393 legacy_session_error_cb, session_keys_change_cb)); | 320 legacy_session_error_cb, session_keys_change_cb, |
321 delegate)); | |
394 | 322 |
395 if (media_drm_bridge->j_media_drm_.is_null()) | 323 if (media_drm_bridge->j_media_drm_.is_null()) |
396 media_drm_bridge.reset(); | 324 media_drm_bridge.reset(); |
397 | 325 |
398 return media_drm_bridge.Pass(); | 326 return media_drm_bridge.Pass(); |
399 } | 327 } |
400 | 328 |
401 // static | 329 // static |
402 scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( | 330 scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( |
403 const std::string& key_system) { | 331 const std::string& key_system) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 DVLOG(1) << __FUNCTION__; | 371 DVLOG(1) << __FUNCTION__; |
444 | 372 |
445 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { | 373 if (session_type != media::MediaKeys::TEMPORARY_SESSION) { |
446 promise->reject(NOT_SUPPORTED_ERROR, 0, | 374 promise->reject(NOT_SUPPORTED_ERROR, 0, |
447 "Only the temporary session type is supported."); | 375 "Only the temporary session type is supported."); |
448 return; | 376 return; |
449 } | 377 } |
450 | 378 |
451 JNIEnv* env = AttachCurrentThread(); | 379 JNIEnv* env = AttachCurrentThread(); |
452 ScopedJavaLocalRef<jbyteArray> j_init_data; | 380 ScopedJavaLocalRef<jbyteArray> j_init_data; |
381 ScopedJavaLocalRef<jobjectArray> j_optional_parameters; | |
453 | 382 |
454 // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as | 383 if (delegate_) { |
xhwang
2015/04/09 22:37:10
Just call g_key_system_manager.Get().GetDelegate(k
gunsch
2015/04/10 00:20:53
Can't right now: MediaDrmBridge doesn't actually t
xhwang
2015/04/10 16:41:13
(3) makes sense to me. MediaDrmBridge only talks U
gunsch
2015/04/11 00:18:16
Done.
| |
455 // the init data when using MP4 container. | 384 std::vector<uint8> init_data_from_delegate; |
456 if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && | 385 std::vector<std::string> optional_parameters_from_delegate; |
457 init_data_type == media::EmeInitDataType::CENC) { | 386 if (!delegate_->OnCreateSession(init_data_type, init_data, init_data_length, |
458 std::vector<uint8> pssh_data; | 387 init_data_from_delegate, |
459 if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) { | 388 optional_parameters_from_delegate)) { |
460 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid PSSH data."); | 389 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid data."); |
461 return; | |
462 } | 390 } |
463 j_init_data = | 391 if (!init_data_from_delegate.empty()) { |
464 base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); | 392 j_init_data = base::android::ToJavaByteArray( |
465 } else { | 393 env, &init_data_from_delegate[0], init_data_from_delegate.size()); |
394 } | |
395 if (!optional_parameters_from_delegate.empty()) { | |
396 j_optional_parameters = base::android::ToJavaArrayOfStrings( | |
397 env, optional_parameters_from_delegate); | |
398 } | |
399 } | |
400 | |
401 if (j_init_data.is_null()) { | |
466 j_init_data = | 402 j_init_data = |
467 base::android::ToJavaByteArray(env, init_data, init_data_length); | 403 base::android::ToJavaByteArray(env, init_data, init_data_length); |
468 } | 404 } |
469 | 405 |
470 ScopedJavaLocalRef<jstring> j_mime = | 406 ScopedJavaLocalRef<jstring> j_mime = |
471 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); | 407 ConvertUTF8ToJavaString(env, ConvertInitDataType(init_data_type)); |
472 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 408 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
473 Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(), | 409 Java_MediaDrmBridge_createSession(env, j_media_drm_.obj(), j_init_data.obj(), |
474 j_mime.obj(), promise_id); | 410 j_mime.obj(), j_optional_parameters.obj(), |
411 promise_id); | |
475 } | 412 } |
476 | 413 |
477 void MediaDrmBridge::LoadSession( | 414 void MediaDrmBridge::LoadSession( |
478 SessionType session_type, | 415 SessionType session_type, |
479 const std::string& session_id, | 416 const std::string& session_id, |
480 scoped_ptr<media::NewSessionCdmPromise> promise) { | 417 scoped_ptr<media::NewSessionCdmPromise> promise) { |
481 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); | 418 promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); |
482 } | 419 } |
483 | 420 |
484 void MediaDrmBridge::UpdateSession( | 421 void MediaDrmBridge::UpdateSession( |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
659 JNIEnv* env = AttachCurrentThread(); | 596 JNIEnv* env = AttachCurrentThread(); |
660 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); | 597 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); |
661 } | 598 } |
662 | 599 |
663 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( | 600 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( |
664 JNIEnv* env, jobject, bool success) { | 601 JNIEnv* env, jobject, bool success) { |
665 base::ResetAndReturn(&reset_credentials_cb_).Run(success); | 602 base::ResetAndReturn(&reset_credentials_cb_).Run(success); |
666 } | 603 } |
667 | 604 |
668 } // namespace media | 605 } // namespace media |
OLD | NEW |