Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(619)

Side by Side Diff: media/base/android/media_drm_bridge.cc

Issue 284183003: Add MediaDrmBridge::AddKeySystemUuidMapping(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/message_loop/message_loop_proxy.h" 15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "jni/MediaDrmBridge_jni.h" 17 #include "jni/MediaDrmBridge_jni.h"
18 #include "media/base/android/media_player_manager.h" 18 #include "media/base/android/media_player_manager.h"
19 19
20 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 20 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
21 21
22 using base::android::AttachCurrentThread; 22 using base::android::AttachCurrentThread;
23 using base::android::ConvertUTF8ToJavaString; 23 using base::android::ConvertUTF8ToJavaString;
24 using base::android::ConvertJavaStringToUTF8; 24 using base::android::ConvertJavaStringToUTF8;
25 using base::android::JavaByteArrayToByteVector; 25 using base::android::JavaByteArrayToByteVector;
26 using base::android::ScopedJavaLocalRef; 26 using base::android::ScopedJavaLocalRef;
27 27
28 namespace media { 28 namespace media {
29 29
30 static uint32 ReadUint32(const uint8_t* data) { 30 namespace {
xhwang 2014/05/15 15:10:29 In media code, we use "static" a lot. Some people
ycheo (away) 2014/05/16 04:53:38 Got it. I'll revert it to static.
31
32 uint32 ReadUint32(const uint8_t* data) {
31 uint32 value = 0; 33 uint32 value = 0;
32 for (int i = 0; i < 4; ++i) 34 for (int i = 0; i < 4; ++i)
33 value = (value << 8) | data[i]; 35 value = (value << 8) | data[i];
34 return value; 36 return value;
35 } 37 }
36 38
37 static uint64 ReadUint64(const uint8_t* data) { 39 uint64 ReadUint64(const uint8_t* data) {
38 uint64 value = 0; 40 uint64 value = 0;
39 for (int i = 0; i < 8; ++i) 41 for (int i = 0; i < 8; ++i)
40 value = (value << 8) | data[i]; 42 value = (value << 8) | data[i];
41 return value; 43 return value;
42 } 44 }
43 45
44 // The structure of an ISO CENC Protection System Specific Header (PSSH) box is 46 // The structure of an ISO CENC Protection System Specific Header (PSSH) box is
45 // as follows. (See ISO/IEC FDIS 23001-7:2011(E).) 47 // as follows. (See ISO/IEC FDIS 23001-7:2011(E).)
46 // Note: ISO boxes use big-endian values. 48 // Note: ISO boxes use big-endian values.
47 // 49 //
(...skipping 10 matching lines...) Expand all
58 const int kBoxLargeSizeSize = 8; 60 const int kBoxLargeSizeSize = 8;
59 const int kPsshVersionFlagSize = 4; 61 const int kPsshVersionFlagSize = 4;
60 const int kPsshSystemIdSize = 16; 62 const int kPsshSystemIdSize = 16;
61 const int kPsshDataSizeSize = 4; 63 const int kPsshDataSizeSize = 4;
62 const uint32 kTencType = 0x74656e63; 64 const uint32 kTencType = 0x74656e63;
63 const uint32 kPsshType = 0x70737368; 65 const uint32 kPsshType = 0x70737368;
64 const uint8 kWidevineUuid[16] = { 66 const uint8 kWidevineUuid[16] = {
65 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, 67 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
66 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; 68 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
67 69
68 static std::vector<uint8> GetUUID(const std::string& key_system) { 70 typedef std::pair<std::string, std::vector<uint8> > KeySystemUuidPair;
69 // For security reasons, we only do exact string comparisons here - we don't 71 // Use std::vector<>, not std::map<> since the size of the table will be
70 // try to parse the |key_system| in any way. 72 // expected to be resonably small.
71 if (key_system == kWidevineKeySystem) { 73 typedef std::vector<KeySystemUuidPair> KeySystemUuidTable;
xhwang 2014/05/15 15:10:29 Since we use UUID a lot now, how about typedef st
ddorwin 2014/05/15 19:00:45 This would also allow s/Table/Map/. "Map" is used
ycheo (away) 2014/05/16 04:53:38 Done.
ycheo (away) 2014/05/16 04:53:38 Done.
72 return std::vector<uint8>(kWidevineUuid, 74 KeySystemUuidTable* key_system_uuid_table = NULL;
xhwang 2014/05/15 15:10:29 global variable needs to be named as g_foo
ycheo (away) 2014/05/16 04:53:38 Done.
73 kWidevineUuid + arraysize(kWidevineUuid)); 75
76 void InitializeKeySystemUuidTable() {
77 key_system_uuid_table = new KeySystemUuidTable();
78
79 key_system_uuid_table->push_back(make_pair(
80 kWidevineKeySystem,
81 std::vector<uint8>(kWidevineUuid,
82 kWidevineUuid + arraysize(kWidevineUuid))));
83 }
84
85 KeySystemUuidTable::iterator FindKeySystem(const std::string& key_system) {
ddorwin 2014/05/15 19:00:45 This name does not accurately describe the behavio
ycheo (away) 2014/05/16 04:53:38 The method is removed by using hash_map.
86 KeySystemUuidTable::iterator it;
87 for (it = key_system_uuid_table->begin();
88 it != key_system_uuid_table->end(); ++it) {
89 // For security reasons, we only do exact string comparisons here - we don't
90 // try to parse the |key_system| in any way.
91 if (key_system == it->first)
92 return it;
74 } 93 }
94 return it;
95 }
xhwang 2014/05/15 15:10:29 If you use a hashmap, you don't need this function
ycheo (away) 2014/05/16 04:53:38 Done.
96
97 std::vector<uint8> GetUUID(const std::string& key_system) {
98 if (key_system_uuid_table == NULL)
ddorwin 2014/05/15 19:00:45 This code appears twice. Why not initialize the ta
ycheo (away) 2014/05/16 04:53:38 Removed by using the lazy initializer.
99 InitializeKeySystemUuidTable();
100
101 KeySystemUuidTable::iterator it = FindKeySystem(key_system);
102 if (it != key_system_uuid_table->end())
103 return it->second;
75 return std::vector<uint8>(); 104 return std::vector<uint8>();
xhwang 2014/05/15 15:10:29 nit: we like to handle abnormal cases first, i.e.
ycheo (away) 2014/05/16 04:53:38 Done.
76 } 105 }
77 106
78 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the 107 // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the
79 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is 108 // "Data" of the box and put it in |pssh_data|. Returns true if such a box is
80 // found and successfully parsed. Returns false otherwise. 109 // found and successfully parsed. Returns false otherwise.
81 // Notes: 110 // Notes:
82 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box 111 // 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box
83 // will be set in |pssh_data|. 112 // will be set in |pssh_data|.
84 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. 113 // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped.
85 static bool GetPsshData(const uint8* data, int data_size, 114 bool GetPsshData(const uint8* data, int data_size,
86 const std::vector<uint8>& uuid, 115 const std::vector<uint8>& uuid,
87 std::vector<uint8>* pssh_data) { 116 std::vector<uint8>* pssh_data) {
88 const uint8* cur = data; 117 const uint8* cur = data;
89 const uint8* data_end = data + data_size; 118 const uint8* data_end = data + data_size;
90 int bytes_left = data_size; 119 int bytes_left = data_size;
91 120
92 while (bytes_left > 0) { 121 while (bytes_left > 0) {
93 const uint8* box_head = cur; 122 const uint8* box_head = cur;
94 123
95 if (bytes_left < kBoxHeaderSize) 124 if (bytes_left < kBoxHeaderSize)
96 return false; 125 return false;
97 126
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 if (box_end < cur + data_size) 181 if (box_end < cur + data_size)
153 return false; 182 return false;
154 183
155 pssh_data->assign(cur, cur + data_size); 184 pssh_data->assign(cur, cur + data_size);
156 return true; 185 return true;
157 } 186 }
158 187
159 return false; 188 return false;
160 } 189 }
161 190
162 static MediaDrmBridge::SecurityLevel GetSecurityLevelFromString( 191 MediaDrmBridge::SecurityLevel GetSecurityLevelFromString(
163 const std::string& security_level_str) { 192 const std::string& security_level_str) {
164 if (0 == security_level_str.compare("L1")) 193 if (0 == security_level_str.compare("L1"))
165 return MediaDrmBridge::SECURITY_LEVEL_1; 194 return MediaDrmBridge::SECURITY_LEVEL_1;
166 if (0 == security_level_str.compare("L3")) 195 if (0 == security_level_str.compare("L3"))
167 return MediaDrmBridge::SECURITY_LEVEL_3; 196 return MediaDrmBridge::SECURITY_LEVEL_3;
168 DCHECK(security_level_str.empty()); 197 DCHECK(security_level_str.empty());
169 return MediaDrmBridge::SECURITY_LEVEL_NONE; 198 return MediaDrmBridge::SECURITY_LEVEL_NONE;
170 } 199 }
171 200
172 static std::string GetSecurityLevelString( 201 std::string GetSecurityLevelString(
173 MediaDrmBridge::SecurityLevel security_level) { 202 MediaDrmBridge::SecurityLevel security_level) {
174 switch (security_level) { 203 switch (security_level) {
175 case MediaDrmBridge::SECURITY_LEVEL_NONE: 204 case MediaDrmBridge::SECURITY_LEVEL_NONE:
176 return ""; 205 return "";
177 case MediaDrmBridge::SECURITY_LEVEL_1: 206 case MediaDrmBridge::SECURITY_LEVEL_1:
178 return "L1"; 207 return "L1";
179 case MediaDrmBridge::SECURITY_LEVEL_3: 208 case MediaDrmBridge::SECURITY_LEVEL_3:
180 return "L3"; 209 return "L3";
181 } 210 }
182 return ""; 211 return "";
183 } 212 }
184 213
185 // Checks whether |key_system| is supported with |container_mime_type|. Only 214 // Checks whether |key_system| is supported with |container_mime_type|. Only
186 // checks |key_system| support if |container_mime_type| is empty. 215 // checks |key_system| support if |container_mime_type| is empty.
187 // TODO(xhwang): The |container_mime_type| is not the same as contentType in 216 // TODO(xhwang): The |container_mime_type| is not the same as contentType in
188 // the EME spec. Revisit this once the spec issue with initData type is 217 // the EME spec. Revisit this once the spec issue with initData type is
189 // resolved. 218 // resolved.
190 static bool IsKeySystemSupportedWithTypeImpl( 219 bool IsKeySystemSupportedWithTypeImpl(
191 const std::string& key_system, 220 const std::string& key_system,
192 const std::string& container_mime_type) { 221 const std::string& container_mime_type) {
193 if (!MediaDrmBridge::IsAvailable()) 222 if (!MediaDrmBridge::IsAvailable())
194 return false; 223 return false;
195 224
196 std::vector<uint8> scheme_uuid = GetUUID(key_system); 225 std::vector<uint8> scheme_uuid = GetUUID(key_system);
197 if (scheme_uuid.empty()) 226 if (scheme_uuid.empty())
198 return false; 227 return false;
199 228
200 JNIEnv* env = AttachCurrentThread(); 229 JNIEnv* env = AttachCurrentThread();
201 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 230 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid =
202 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 231 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size());
203 ScopedJavaLocalRef<jstring> j_container_mime_type = 232 ScopedJavaLocalRef<jstring> j_container_mime_type =
204 ConvertUTF8ToJavaString(env, container_mime_type); 233 ConvertUTF8ToJavaString(env, container_mime_type);
205 return Java_MediaDrmBridge_isCryptoSchemeSupported( 234 return Java_MediaDrmBridge_isCryptoSchemeSupported(
206 env, j_scheme_uuid.obj(), j_container_mime_type.obj()); 235 env, j_scheme_uuid.obj(), j_container_mime_type.obj());
207 } 236 }
208 237
238 } // namespace
239
209 // static 240 // static
210 bool MediaDrmBridge::IsAvailable() { 241 bool MediaDrmBridge::IsAvailable() {
211 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; 242 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
212 } 243 }
213 244
214 // static 245 // static
215 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { 246 bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) {
216 DCHECK(IsAvailable()); 247 DCHECK(IsAvailable());
217 return SECURITY_LEVEL_1 == security_level; 248 return SECURITY_LEVEL_1 == security_level;
218 } 249 }
219 250
220 // static 251 // static
221 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, 252 bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system,
222 SecurityLevel security_level) { 253 SecurityLevel security_level) {
223 if (!IsAvailable()) 254 if (!IsAvailable())
224 return false; 255 return false;
225 256
226 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in 257 // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in
227 // creation time of MediaDrmBridge. 258 // creation time of MediaDrmBridge.
228 scoped_ptr<MediaDrmBridge> media_drm_bridge = 259 scoped_ptr<MediaDrmBridge> media_drm_bridge =
229 MediaDrmBridge::Create(0, key_system, GURL(), NULL); 260 MediaDrmBridge::Create(0, key_system, GURL(), NULL);
230 if (!media_drm_bridge) 261 if (!media_drm_bridge)
231 return false; 262 return false;
232 263
233 return media_drm_bridge->SetSecurityLevel(security_level); 264 return media_drm_bridge->SetSecurityLevel(security_level);
234 } 265 }
235 266
267 //static
268 void MediaDrmBridge::AddKeySystem(const std::string& key_system,
xhwang 2014/05/15 15:10:29 nit: This name is ambiguous. People may think that
ycheo (away) 2014/05/16 04:53:38 Renamed AddKeySystemUuidMapping().
269 const std::vector<uint8>& uuid) {
270 if (key_system_uuid_table == NULL)
271 InitializeKeySystemUuidTable();
272
273 KeySystemUuidTable::iterator it = FindKeySystem(key_system);
274 // Shouldn't overwrite the existing keysystem.
xhwang 2014/05/15 15:10:29 DCHECK this condition as well?
ycheo (away) 2014/05/16 04:53:38 Done.
275 if (it == key_system_uuid_table->end())
276 key_system_uuid_table->push_back(make_pair(key_system, uuid));
277 }
278
236 // static 279 // static
237 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { 280 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) {
238 DCHECK(!key_system.empty()); 281 DCHECK(!key_system.empty());
239 return IsKeySystemSupportedWithTypeImpl(key_system, ""); 282 return IsKeySystemSupportedWithTypeImpl(key_system, "");
240 } 283 }
241 284
242 // static 285 // static
243 bool MediaDrmBridge::IsKeySystemSupportedWithType( 286 bool MediaDrmBridge::IsKeySystemSupportedWithType(
244 const std::string& key_system, 287 const std::string& key_system,
245 const std::string& container_mime_type) { 288 const std::string& container_mime_type) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 JNIEnv* env = AttachCurrentThread(); 500 JNIEnv* env = AttachCurrentThread();
458 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); 501 Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj());
459 } 502 }
460 503
461 void MediaDrmBridge::OnResetDeviceCredentialsCompleted( 504 void MediaDrmBridge::OnResetDeviceCredentialsCompleted(
462 JNIEnv* env, jobject, bool success) { 505 JNIEnv* env, jobject, bool success) {
463 base::ResetAndReturn(&reset_credentials_cb_).Run(success); 506 base::ResetAndReturn(&reset_credentials_cb_).Run(success);
464 } 507 }
465 508
466 } // namespace media 509 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698