Commit 452f2e9d authored by ycheo@chromium.org's avatar ycheo@chromium.org

aw: Support the platform specific key-systems.

BUG=322395

Change-Id: Ie0376052892349f18db5d60737f6329b8c92eb1c

Review URL: https://codereview.chromium.org/333003003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278207 0039d316-1c4b-4281-b951-d872f2087c98
parent 913bd0ac
...@@ -2,4 +2,5 @@ include_rules = [ ...@@ -2,4 +2,5 @@ include_rules = [
"+content/public/android/java", "+content/public/android/java",
"+components/navigation_interception/android/java", "+components/navigation_interception/android/java",
"+components/web_contents_delegate_android/android/java", "+components/web_contents_delegate_android/android/java",
"+media/base/android/java",
] ]
...@@ -5,13 +5,16 @@ ...@@ -5,13 +5,16 @@
package org.chromium.android_webview; package org.chromium.android_webview;
import android.content.Context; import android.content.Context;
import android.util.Log;
import org.chromium.base.PathUtils; import org.chromium.base.PathUtils;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.content.browser.BrowserStartupController; import org.chromium.content.browser.BrowserStartupController;
import org.chromium.media.MediaDrmBridge;
import java.util.UUID;
/** /**
* Wrapper for the steps needed to initialize the java and native sides of webview chromium. * Wrapper for the steps needed to initialize the java and native sides of webview chromium.
...@@ -50,10 +53,25 @@ public abstract class AwBrowserProcess { ...@@ -50,10 +53,25 @@ public abstract class AwBrowserProcess {
try { try {
BrowserStartupController.get(context).startBrowserProcessesSync( BrowserStartupController.get(context).startBrowserProcessesSync(
BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS); BrowserStartupController.MAX_RENDERERS_SINGLE_PROCESS);
initializePlatformKeySystem();
} catch (ProcessInitException e) { } catch (ProcessInitException e) {
throw new RuntimeException("Cannot initialize WebView", e); throw new RuntimeException("Cannot initialize WebView", e);
} }
} }
}); });
} }
private static void initializePlatformKeySystem() {
String[] mappings = AwResource.getConfigKeySystemUuidMapping();
for (String mapping : mappings) {
try {
String fragments[] = mapping.split(",");
String keySystem = fragments[0].trim();
UUID uuid = UUID.fromString(fragments[1]);
MediaDrmBridge.addKeySystemUuidMapping(keySystem, uuid);
} catch (java.lang.RuntimeException e) {
Log.e(TAG, "Can't parse key-system mapping: " + mapping);
}
}
}
} }
...@@ -35,6 +35,9 @@ public class AwResource { ...@@ -35,6 +35,9 @@ public class AwResource {
// String resource ID for the default text encoding to use. // String resource ID for the default text encoding to use.
private static int STRING_DEFAULT_TEXT_ENCODING; private static int STRING_DEFAULT_TEXT_ENCODING;
// Array resource ID for the configuration of platform specific key-systems.
private static int STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING;
// The embedder should inject a Resources object that will be used // The embedder should inject a Resources object that will be used
// to resolve Resource IDs into the actual resources. // to resolve Resource IDs into the actual resources.
private static Resources sResources; private static Resources sResources;
...@@ -59,6 +62,10 @@ public class AwResource { ...@@ -59,6 +62,10 @@ public class AwResource {
STRING_DEFAULT_TEXT_ENCODING = encoding; STRING_DEFAULT_TEXT_ENCODING = encoding;
} }
public static void setConfigKeySystemUuidMapping(int config) {
STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING = config;
}
@CalledByNative @CalledByNative
public static String getDefaultTextEncoding() { public static String getDefaultTextEncoding() {
return getResource(STRING_DEFAULT_TEXT_ENCODING, TYPE_STRING); return getResource(STRING_DEFAULT_TEXT_ENCODING, TYPE_STRING);
...@@ -74,6 +81,11 @@ public class AwResource { ...@@ -74,6 +81,11 @@ public class AwResource {
return getResource(RAW_LOAD_ERROR, TYPE_RAW); return getResource(RAW_LOAD_ERROR, TYPE_RAW);
} }
public static String[] getConfigKeySystemUuidMapping() {
// No need to cache, since this should be called only once.
return sResources.getStringArray(STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING);
}
private static String getResource(int resid, int type) { private static String getResource(int resid, int type) {
assert resid != 0; assert resid != 0;
assert sResources != null; assert sResources != null;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.android_webview.test; package org.chromium.android_webview.test;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContents;
import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
...@@ -65,4 +66,10 @@ public class KeySystemTest extends AwTestBase { ...@@ -65,4 +66,10 @@ public class KeySystemTest extends AwTestBase {
public void testNotSupportFooKeySystem() throws Throwable { public void testNotSupportFooKeySystem() throws Throwable {
assertEquals("\"\"", IsKeySystemSupported("com.foo.keysystem")); assertEquals("\"\"", IsKeySystemSupported("com.foo.keysystem"));
} }
@Feature({"AndroidWebView"})
@SmallTest
public void testSupportPlatformKeySystem() throws Throwable {
assertEquals("\"maybe\"", IsKeySystemSupported("com.oem.test-keysystem"));
}
} }
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<resources>
<!-- Array of "[keySystemName],[UuidOfMediaDrm]" -->
<string-array name="config_key_system_uuid_mapping" translatable="false">
<!-- Use Widevine's UUID to pass the availability-test of MediaDRM plugin -->
<item>"com.oem.test-keysystem,EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED"</item>
</string-array>
</resources>
...@@ -25,6 +25,8 @@ public class AwShellResourceProvider { ...@@ -25,6 +25,8 @@ public class AwShellResourceProvider {
AwResource.setDefaultTextEncoding(R.string.default_encoding); AwResource.setDefaultTextEncoding(R.string.default_encoding);
AwResource.setConfigKeySystemUuidMapping(R.array.config_key_system_uuid_mapping);
sInitialized = true; sInitialized = true;
} }
} }
...@@ -22,6 +22,7 @@ import org.chromium.base.JNINamespace; ...@@ -22,6 +22,7 @@ import org.chromium.base.JNINamespace;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
...@@ -31,7 +32,7 @@ import java.util.UUID; ...@@ -31,7 +32,7 @@ import java.util.UUID;
* sessions for a single MediaSourcePlayer. * sessions for a single MediaSourcePlayer.
*/ */
@JNINamespace("media") @JNINamespace("media")
class MediaDrmBridge { public class MediaDrmBridge {
// Implementation Notes: // Implementation Notes:
// - A media crypto session (mMediaCryptoSession) is opened after MediaDrm // - A media crypto session (mMediaCryptoSession) is opened after MediaDrm
// is created. This session will be added to mSessionIds. // is created. This session will be added to mSessionIds.
...@@ -876,6 +877,15 @@ class MediaDrmBridge { ...@@ -876,6 +877,15 @@ class MediaDrmBridge {
} }
} }
public static void addKeySystemUuidMapping(String keySystem, UUID uuid) {
ByteBuffer uuidBuffer = ByteBuffer.allocateDirect(16);
// MSB (byte) should be positioned at the first element.
uuidBuffer.order(ByteOrder.BIG_ENDIAN);
uuidBuffer.putLong(uuid.getMostSignificantBits());
uuidBuffer.putLong(uuid.getLeastSignificantBits());
nativeAddKeySystemUuidMapping(keySystem, uuidBuffer);
}
private native void nativeOnMediaCryptoReady(long nativeMediaDrmBridge); private native void nativeOnMediaCryptoReady(long nativeMediaDrmBridge);
private native void nativeOnSessionCreated(long nativeMediaDrmBridge, int sessionId, private native void nativeOnSessionCreated(long nativeMediaDrmBridge, int sessionId,
...@@ -892,4 +902,6 @@ class MediaDrmBridge { ...@@ -892,4 +902,6 @@ class MediaDrmBridge {
private native void nativeOnResetDeviceCredentialsCompleted( private native void nativeOnResetDeviceCredentialsCompleted(
long nativeMediaDrmBridge, boolean success); long nativeMediaDrmBridge, boolean success);
private static native void nativeAddKeySystemUuidMapping(String keySystem, ByteBuffer uuid);
} }
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h" #include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/sys_byteorder.h"
#include "jni/MediaDrmBridge_jni.h" #include "jni/MediaDrmBridge_jni.h"
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
...@@ -276,9 +277,12 @@ bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, ...@@ -276,9 +277,12 @@ bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system,
return media_drm_bridge->SetSecurityLevel(security_level); return media_drm_bridge->SetSecurityLevel(security_level);
} }
// static static void AddKeySystemUuidMapping(JNIEnv* env, jclass clazz,
void MediaDrmBridge::AddKeySystemUuidMapping(const std::string& key_system, jstring j_key_system,
const std::vector<uint8>& uuid) { jobject j_buffer) {
std::string key_system = ConvertJavaStringToUTF8(env, j_key_system);
uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer));
UUID uuid(buffer, buffer + 16);
g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); g_key_system_uuid_manager.Get().AddMapping(key_system, uuid);
} }
......
...@@ -52,12 +52,6 @@ class MEDIA_EXPORT MediaDrmBridge : public BrowserCdm { ...@@ -52,12 +52,6 @@ class MEDIA_EXPORT MediaDrmBridge : public BrowserCdm {
// are not handled by Chrome explicitly. // are not handled by Chrome explicitly.
static std::vector<std::string> GetPlatformKeySystemNames(); static std::vector<std::string> GetPlatformKeySystemNames();
// 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|. // Checks whether |key_system| is supported with |container_mime_type|.
// |container_mime_type| must not be empty. // |container_mime_type| must not be empty.
static bool IsKeySystemSupportedWithType( static bool IsKeySystemSupportedWithType(
......
...@@ -26,10 +26,6 @@ const char kVideoMp4[] = "video/mp4"; ...@@ -26,10 +26,6 @@ const char kVideoMp4[] = "video/mp4";
const char kAudioWebM[] = "audio/webm"; const char kAudioWebM[] = "audio/webm";
const char kVideoWebM[] = "video/webm"; const char kVideoWebM[] = "video/webm";
const char kInvalidKeySystem[] = "invalid.keysystem"; 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 = const MediaDrmBridge::SecurityLevel kLNone =
MediaDrmBridge::SECURITY_LEVEL_NONE; MediaDrmBridge::SECURITY_LEVEL_NONE;
const MediaDrmBridge::SecurityLevel kL1 = MediaDrmBridge::SECURITY_LEVEL_1; const MediaDrmBridge::SecurityLevel kL1 = MediaDrmBridge::SECURITY_LEVEL_1;
...@@ -97,33 +93,4 @@ TEST(MediaDrmBridgeTest, IsKeySystemSupported_InvalidKeySystem) { ...@@ -97,33 +93,4 @@ TEST(MediaDrmBridgeTest, IsKeySystemSupported_InvalidKeySystem) {
EXPECT_FALSE(IsKeySystemSupportedWithType(kInvalidKeySystem, "audio/mp3")); 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 } // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment