diff options
author | ycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 11:48:32 +0000 |
---|---|---|
committer | ycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 11:48:32 +0000 |
commit | c696c28ad014c9a9d141fb1a50bf7bfbd9af2036 (patch) | |
tree | b43f3a1478f8104ea09645e529802bf26765da4b | |
parent | 7eaa86ee333f3ad53594148157c6378d6d31e2f1 (diff) | |
download | chromium_src-c696c28ad014c9a9d141fb1a50bf7bfbd9af2036.zip chromium_src-c696c28ad014c9a9d141fb1a50bf7bfbd9af2036.tar.gz chromium_src-c696c28ad014c9a9d141fb1a50bf7bfbd9af2036.tar.bz2 |
Add MediaDrmBridge::AddKeySystemUuidMapping().
This method is needed to inject the other DRMs' keysystem and uuid mapping
in MediaDrmBridge.
BUG=322395
Review URL: https://codereview.chromium.org/284183003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272498 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | media/base/android/media_drm_bridge.cc | 62 | ||||
-rw-r--r-- | media/base/android/media_drm_bridge.h | 6 | ||||
-rw-r--r-- | media/base/android/media_drm_bridge_unittest.cc | 33 |
3 files changed, 90 insertions, 11 deletions
diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc index b627259..6b022df 100644 --- a/media/base/android/media_drm_bridge.cc +++ b/media/base/android/media_drm_bridge.cc @@ -10,6 +10,8 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/callback_helpers.h" +#include "base/containers/hash_tables.h" +#include "base/lazy_instance.h" #include "base/location.h" #include "base/logging.h" #include "base/message_loop/message_loop_proxy.h" @@ -64,16 +66,48 @@ const uint8 kWidevineUuid[16] = { 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; -static std::vector<uint8> GetUUID(const std::string& key_system) { - // For security reasons, we only do exact string comparisons here - we don't - // try to parse the |key_system| in any way. - if (key_system == kWidevineKeySystem) { - return std::vector<uint8>(kWidevineUuid, - kWidevineUuid + arraysize(kWidevineUuid)); - } - return std::vector<uint8>(); +typedef std::vector<uint8> UUID; + +class KeySystemUuidManager { + public: + KeySystemUuidManager(); + UUID GetUUID(const std::string& key_system); + void AddMapping(const std::string& key_system, const UUID& uuid); + + private: + typedef base::hash_map<std::string, UUID> KeySystemUuidMap; + + KeySystemUuidMap key_system_uuid_map_; + + DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager); +}; + +KeySystemUuidManager::KeySystemUuidManager() { + // Widevine is always supported in Android. + key_system_uuid_map_[kWidevineKeySystem] = + UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); +} + +UUID KeySystemUuidManager::GetUUID(const std::string& key_system) { + KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); + if (it == key_system_uuid_map_.end()) + return UUID(); + return it->second; +} + +void KeySystemUuidManager::AddMapping(const std::string& key_system, + const UUID& uuid) { + KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); + DCHECK(it == key_system_uuid_map_.end()) + << "Shouldn't overwrite an existing key system."; + if (it != key_system_uuid_map_.end()) + return; + key_system_uuid_map_[key_system] = uuid; } +base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager = + LAZY_INSTANCE_INITIALIZER; + // Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the // "Data" of the box and put it in |pssh_data|. Returns true if such a box is // found and successfully parsed. Returns false otherwise. @@ -82,7 +116,7 @@ static std::vector<uint8> GetUUID(const std::string& key_system) { // will be set in |pssh_data|. // 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. static bool GetPsshData(const uint8* data, int data_size, - const std::vector<uint8>& uuid, + const UUID& uuid, std::vector<uint8>* pssh_data) { const uint8* cur = data; const uint8* data_end = data + data_size; @@ -192,7 +226,7 @@ static bool IsKeySystemSupportedWithTypeImpl( if (!MediaDrmBridge::IsAvailable()) return false; - std::vector<uint8> scheme_uuid = GetUUID(key_system); + UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); if (scheme_uuid.empty()) return false; @@ -230,6 +264,12 @@ bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, return media_drm_bridge->SetSecurityLevel(security_level); } +//static +void MediaDrmBridge::AddKeySystemUuidMapping(const std::string& key_system, + const std::vector<uint8>& uuid) { + g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); +} + // static bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { DCHECK(!key_system.empty()); @@ -287,7 +327,7 @@ scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( if (!IsAvailable()) return media_drm_bridge.Pass(); - std::vector<uint8> scheme_uuid = GetUUID(key_system); + UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); if (scheme_uuid.empty()) return media_drm_bridge.Pass(); diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index 60b4dd8..c122ac4 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h @@ -47,6 +47,12 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { // Checks whether |key_system| is supported. static bool IsKeySystemSupported(const std::string& key_system); + // Adds a new |key_system| with the associated |uuid|. + // This is used for other platforms to have a chance to register their + // own UUID mapping. + static void AddKeySystemUuidMapping(const std::string& key_system, + const std::vector<uint8>& uuid); + // Checks whether |key_system| is supported with |container_mime_type|. // |container_mime_type| must not be empty. static bool IsKeySystemSupportedWithType( diff --git a/media/base/android/media_drm_bridge_unittest.cc b/media/base/android/media_drm_bridge_unittest.cc index a838203..11c257f 100644 --- a/media/base/android/media_drm_bridge_unittest.cc +++ b/media/base/android/media_drm_bridge_unittest.cc @@ -26,6 +26,10 @@ const char kVideoMp4[] = "video/mp4"; const char kAudioWebM[] = "audio/webm"; const char kVideoWebM[] = "video/webm"; const char kInvalidKeySystem[] = "invalid.keysystem"; +const char kFooKeySystem[] = "com.foo.keysystem"; +const uint8 kWidevineUuid[16] = { + 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, + 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; const MediaDrmBridge::SecurityLevel kLNone = MediaDrmBridge::SECURITY_LEVEL_NONE; const MediaDrmBridge::SecurityLevel kL1 = MediaDrmBridge::SECURITY_LEVEL_1; @@ -93,4 +97,33 @@ TEST(MediaDrmBridgeTest, IsKeySystemSupported_InvalidKeySystem) { EXPECT_FALSE(IsKeySystemSupportedWithType(kInvalidKeySystem, "audio/mp3")); } +TEST(MediaDrmBridgeTest, AddNewKeySystemMapping) { + EXPECT_FALSE(IsKeySystemSupported(kFooKeySystem)); + + // Use WV UUID for foo, because it is the only key system we can guarentee + // that it is installed in the test device. + std::vector<uint8> foo_uuid(kWidevineUuid, + kWidevineUuid + arraysize(kWidevineUuid)); + MediaDrmBridge::AddKeySystemUuidMapping(kFooKeySystem, foo_uuid); + + EXPECT_TRUE_IF_AVAILABLE(IsKeySystemSupported(kFooKeySystem)); + EXPECT_TRUE_IF_AVAILABLE( + IsKeySystemSupportedWithType(kFooKeySystem, kVideoMp4)); +} + +TEST(MediaDrmBridgeTest, ShouldNotOverwriteExistingKeySystem) { + EXPECT_TRUE_IF_AVAILABLE(IsKeySystemSupported(kWidevineKeySystem)); + std::vector<uint8> invalid_uuid = std::vector<uint8>(16, 99); +#if DCHECK_IS_ON + ASSERT_DEATH({ + MediaDrmBridge::AddKeySystemUuidMapping(kWidevineKeySystem, invalid_uuid); + }, ""); +#else + // Try to add WV keysystem with the invalid UUID. + MediaDrmBridge::AddKeySystemUuidMapping(kWidevineKeySystem, invalid_uuid); + + EXPECT_TRUE_IF_AVAILABLE(IsKeySystemSupported(kWidevineKeySystem)); +#endif +} + } // namespace media |