Add additional MediaDrm API tests
bug: 12033958 Merge of https://widevine-internal-review.googlesource.com/#/c/8402/ from the Widevine CDM repo. Change-Id: I441eb816db69620feff0bd72c485bd3ad7ec8031
This commit is contained in:
@@ -28,9 +28,11 @@ public class KeyRequester {
|
|||||||
mServerUrl = url;
|
mServerUrl = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doTransact(MediaDrm drm, byte[] sessionId) {
|
public boolean doTransact(MediaDrm drm, byte[] sessionId) {
|
||||||
|
|
||||||
boolean retryTransaction;
|
boolean retryTransaction;
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
retryTransaction = false;
|
retryTransaction = false;
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ public class KeyRequester {
|
|||||||
|
|
||||||
if (drmRequest == null) {
|
if (drmRequest == null) {
|
||||||
Log.e(TAG, "Failed to get key request");
|
Log.e(TAG, "Failed to get key request");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostRequestTask postTask = new PostRequestTask(drmRequest.getData());
|
PostRequestTask postTask = new PostRequestTask(drmRequest.getData());
|
||||||
@@ -80,6 +82,7 @@ public class KeyRequester {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
drm.provideKeyResponse(sessionId, drmResponse);
|
drm.provideKeyResponse(sessionId, drmResponse);
|
||||||
|
result = true;
|
||||||
} catch (NotProvisionedException e) {
|
} catch (NotProvisionedException e) {
|
||||||
Log.i(TAG, "Key response invalidated the certificate, reprovisioning");
|
Log.i(TAG, "Key response invalidated the certificate, reprovisioning");
|
||||||
ProvisionRequester provisionRequester = new ProvisionRequester();
|
ProvisionRequester provisionRequester = new ProvisionRequester();
|
||||||
@@ -92,6 +95,7 @@ public class KeyRequester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (retryTransaction);
|
} while (retryTransaction);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PostRequestTask extends AsyncTask<String, Void, Void> {
|
private class PostRequestTask extends AsyncTask<String, Void, Void> {
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ import android.view.View;
|
|||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
import android.view.Display;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Point;
|
||||||
import android.media.MediaDrm;
|
import android.media.MediaDrm;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.media.MediaDrm.CryptoSession;
|
import android.media.MediaDrm.CryptoSession;
|
||||||
import android.media.MediaDrmException;
|
import android.media.MediaDrmException;
|
||||||
import android.media.NotProvisionedException;
|
import android.media.NotProvisionedException;
|
||||||
@@ -25,6 +28,7 @@ import android.media.MediaCodec.CryptoInfo;
|
|||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -38,14 +42,17 @@ import java.lang.Exception;
|
|||||||
import java.lang.InterruptedException;
|
import java.lang.InterruptedException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.lang.Math;
|
||||||
|
|
||||||
class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
|
class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
|
||||||
{
|
{
|
||||||
private final String TAG = "SurfacePanel";
|
private final String TAG = "SurfacePanel";
|
||||||
|
private boolean mIsCreated;
|
||||||
|
|
||||||
public SurfacePanel(Context context, AttributeSet attrSet)
|
public SurfacePanel(Context context, AttributeSet attrSet)
|
||||||
{
|
{
|
||||||
super(context, attrSet);
|
super(context, attrSet);
|
||||||
|
mIsCreated = false;
|
||||||
SurfaceHolder holder = getHolder();
|
SurfaceHolder holder = getHolder();
|
||||||
holder.addCallback(this);
|
holder.addCallback(this);
|
||||||
}
|
}
|
||||||
@@ -54,6 +61,7 @@ class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
|
|||||||
public void surfaceDestroyed(SurfaceHolder holder)
|
public void surfaceDestroyed(SurfaceHolder holder)
|
||||||
{
|
{
|
||||||
Log.d(TAG, "surfaceDestroyed");
|
Log.d(TAG, "surfaceDestroyed");
|
||||||
|
mIsCreated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,6 +75,11 @@ class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
|
|||||||
public void surfaceCreated(SurfaceHolder holder)
|
public void surfaceCreated(SurfaceHolder holder)
|
||||||
{
|
{
|
||||||
Log.d(TAG, "surfaceCreated");
|
Log.d(TAG, "surfaceCreated");
|
||||||
|
mIsCreated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreated() {
|
||||||
|
return mIsCreated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,13 +92,27 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
static final UUID kWidevineScheme = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
|
static final UUID kWidevineScheme = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
|
||||||
|
|
||||||
private boolean mTestFailed;
|
private boolean mTestFailed;
|
||||||
|
private TextView mTextView;
|
||||||
|
private String mDisplayText;
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.main);
|
mTextView = new TextView(this);
|
||||||
|
mDisplayText = new String("MediaDrm API Test\n\n");
|
||||||
|
|
||||||
|
Display display = getWindowManager().getDefaultDisplay();
|
||||||
|
Point size = new Point();
|
||||||
|
display.getSize(size);
|
||||||
|
int width = size.x;
|
||||||
|
int height = size.y;
|
||||||
|
final int max_lines = 20;
|
||||||
|
int textSize = Math.min(width, height) / max_lines;
|
||||||
|
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||||
|
setContentView(mTextView);
|
||||||
|
Log.i(TAG, "width=" + width + " height=" + height + " size=" + textSize);
|
||||||
|
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
@@ -95,22 +122,48 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
testWidevineSchemeSupported();
|
testWidevineSchemeSupported();
|
||||||
testProperties();
|
testProperties();
|
||||||
testQueryKeyStatus();
|
testQueryKeyStatus();
|
||||||
testClearContentNoKeys();
|
|
||||||
testEncryptedContent();
|
|
||||||
testGenericEncryptAndDecrypt();
|
testGenericEncryptAndDecrypt();
|
||||||
testGenericSign();
|
testGenericSign();
|
||||||
testGenericVerify();
|
testGenericVerify();
|
||||||
testGenericMultipleKeys();
|
testGenericMultipleKeys();
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
setContentView(R.layout.main);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testClearContentNoKeys();
|
||||||
|
testEncryptedContent();
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
setContentView(mTextView);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (mTestFailed) {
|
if (mTestFailed) {
|
||||||
Log.e(TAG, "TEST FAILED!");
|
displayText("\nTEST FAILED!");
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "TEST SUCCESS!");
|
displayText("\nTEST PASSED!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw text on the surface view
|
||||||
|
private void displayText(String text) {
|
||||||
|
Log.i(TAG, text);
|
||||||
|
mDisplayText += text + "\n";
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mTextView.setText(mDisplayText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private MediaDrm mDrm;
|
private MediaDrm mDrm;
|
||||||
private Looper mLooper;
|
private Looper mLooper;
|
||||||
private Object mLock = new Object();
|
private Object mLock = new Object();
|
||||||
@@ -210,48 +263,54 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
|
|
||||||
private void testProperties() {
|
private void testProperties() {
|
||||||
MediaDrm drm = startDrm();
|
MediaDrm drm = startDrm();
|
||||||
Log.i(TAG, "vendor: " + drm.getPropertyString(MediaDrm.PROPERTY_VENDOR));
|
displayText("vendor: " + drm.getPropertyString(MediaDrm.PROPERTY_VENDOR));
|
||||||
Log.i(TAG, "version: " + drm.getPropertyString(MediaDrm.PROPERTY_VERSION));
|
displayText("version: " + drm.getPropertyString(MediaDrm.PROPERTY_VERSION));
|
||||||
Log.i(TAG, "description: " + drm.getPropertyString(MediaDrm.PROPERTY_DESCRIPTION));
|
displayText("description: " + drm.getPropertyString(MediaDrm.PROPERTY_DESCRIPTION));
|
||||||
Log.i(TAG, "deviceId: " + Arrays.toString(drm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)));
|
displayText("deviceId: " + Arrays.toString(drm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)));
|
||||||
Log.i(TAG, "algorithms: " + drm.getPropertyString(MediaDrm.PROPERTY_ALGORITHMS));
|
displayText("algorithms: " + drm.getPropertyString(MediaDrm.PROPERTY_ALGORITHMS));
|
||||||
|
|
||||||
// widevine-specific properties
|
// widevine-specific properties
|
||||||
Log.i(TAG, "security level: " + drm.getPropertyString("securityLevel"));
|
displayText("security level: " + drm.getPropertyString("securityLevel"));
|
||||||
Log.i(TAG, "system ID: " + drm.getPropertyString("systemId"));
|
displayText("system ID: " + drm.getPropertyString("systemId"));
|
||||||
stopDrm(drm);
|
stopDrm(drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testQueryKeyStatus() {
|
private void testQueryKeyStatus() {
|
||||||
MediaDrm drm = startDrm();
|
MediaDrm drm = startDrm();
|
||||||
byte[] sessionId = openSession(drm);
|
byte[] sessionId = openSession(drm);
|
||||||
getKeys(drm, sessionId);
|
if (getKeys(drm, sessionId)) {
|
||||||
|
Log.i(TAG, "Query Key Status:");
|
||||||
Log.i(TAG, "Query Key Status:");
|
HashMap<String, String> keyStatus = drm.queryKeyStatus(sessionId);
|
||||||
HashMap<String, String> keyStatus = drm.queryKeyStatus(sessionId);
|
Iterator<String> iterator = keyStatus.keySet().iterator();
|
||||||
Iterator<String> iterator = keyStatus.keySet().iterator();
|
while (iterator.hasNext()) {
|
||||||
while (iterator.hasNext()) {
|
String name = iterator.next();
|
||||||
String name = iterator.next();
|
Log.i(TAG, "\t" + name + " = " + keyStatus.get(name));
|
||||||
Log.i(TAG, "\t" + name + " = " + keyStatus.get(name));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
stopDrm(drm);
|
stopDrm(drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getKeys(MediaDrm drm, byte[] sessionId) {
|
private boolean getKeys(MediaDrm drm, byte[] sessionId) {
|
||||||
final byte[] kPssh = hex2ba("08011210e02562e04cd55351b14b3d748d36ed8e");
|
final byte[] kPssh = hex2ba("08011210e02562e04cd55351b14b3d748d36ed8e");
|
||||||
final String kClientAuth = "?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
|
final String kClientAuth = "?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
|
||||||
final String kPort = "80";
|
final String kPort = "80";
|
||||||
KeyRequester keyRequester = new KeyRequester(kPssh, kKeyServerUrl + ":" + kPort + kClientAuth);
|
KeyRequester keyRequester = new KeyRequester(kPssh, kKeyServerUrl + ":" + kPort + kClientAuth);
|
||||||
keyRequester.doTransact(drm, sessionId);
|
boolean result = keyRequester.doTransact(drm, sessionId);
|
||||||
|
if (!result) {
|
||||||
|
displayText("Failed to get keys from license server!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testEncryptedContent() {
|
private void testEncryptedContent() {
|
||||||
MediaDrm drm = startDrm();
|
MediaDrm drm = startDrm();
|
||||||
byte[] sessionId = openSession(drm);
|
byte[] sessionId = openSession(drm);
|
||||||
getKeys(drm, sessionId);
|
if (getKeys(drm, sessionId)) {
|
||||||
testDecrypt(sessionId);
|
testDecrypt(sessionId);
|
||||||
|
}
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
stopDrm(drm);
|
stopDrm(drm);
|
||||||
}
|
}
|
||||||
@@ -263,38 +322,41 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
byte[] sessionId = openSession(drm);
|
byte[] sessionId = openSession(drm);
|
||||||
|
|
||||||
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
|
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
|
||||||
keyRequester.doTransact(drm, sessionId);
|
if (keyRequester.doTransact(drm, sessionId)) {
|
||||||
|
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
||||||
|
|
||||||
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
// operator_session_key_permissions=allow_encrypt | allow_decrypt
|
||||||
|
byte[] aes_key_id = hex2ba("3be2b25db355fc64a0e69a50f4dbb298");
|
||||||
|
byte[] aes_key = hex2ba("5762d22a5e17d5402dc310a7c33ce539");
|
||||||
|
|
||||||
// operator_session_key_permissions=allow_encrypt | allow_decrypt
|
byte[] clr_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
byte[] aes_key_id = hex2ba("3be2b25db355fc64a0e69a50f4dbb298");
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
byte[] aes_key = hex2ba("5762d22a5e17d5402dc310a7c33ce539");
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
byte[] enc_data = hex2ba("ee92d402f55f1d7eef4844803d9d43a603a4dd13f4a2ad5ea7653adcefa74b06" +
|
||||||
|
"ff459ab476a497567198c7cfa06d6fdd66b7924c2ca430baf534c5e00c800a06" +
|
||||||
|
"d0c108057ceab2ea33671d83e35eaaf1f1ff0f7e1618d05810a47b12cbc0806f" +
|
||||||
|
"d6ba8127a5e411f49b4e1790b1a6cb963e33d6cbc6569c44b4e1b28005fd1dde");
|
||||||
|
|
||||||
byte[] clr_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
byte[] iv = hex2ba("3ec0f3d3970fbd541ac4e7e1d06a6131");
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
|
||||||
byte[] enc_data = hex2ba("ee92d402f55f1d7eef4844803d9d43a603a4dd13f4a2ad5ea7653adcefa74b06" +
|
|
||||||
"ff459ab476a497567198c7cfa06d6fdd66b7924c2ca430baf534c5e00c800a06" +
|
|
||||||
"d0c108057ceab2ea33671d83e35eaaf1f1ff0f7e1618d05810a47b12cbc0806f" +
|
|
||||||
"d6ba8127a5e411f49b4e1790b1a6cb963e33d6cbc6569c44b4e1b28005fd1dde");
|
|
||||||
|
|
||||||
byte[] iv = hex2ba("3ec0f3d3970fbd541ac4e7e1d06a6131");
|
byte[] result = cs.decrypt(aes_key_id, enc_data, iv);
|
||||||
|
if (Arrays.equals(clr_data, result)) {
|
||||||
|
Log.d(TAG, "Decrypt test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Decrypt test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] result = cs.decrypt(aes_key_id, enc_data, iv);
|
result = cs.encrypt(aes_key_id, clr_data, iv);
|
||||||
if (Arrays.equals(clr_data, result)) {
|
if (Arrays.equals(enc_data, result)) {
|
||||||
Log.d(TAG, "Decrypt test passed!");
|
Log.d(TAG, "Encrypt test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Encrypt test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Decrypt test failed!");
|
displayText("Failed to get keys from license server!");
|
||||||
mTestFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = cs.encrypt(aes_key_id, clr_data, iv);
|
|
||||||
if (Arrays.equals(enc_data, result)) {
|
|
||||||
Log.d(TAG, "Encrypt test passed!");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Encrypt test failed!");
|
|
||||||
mTestFailed = true;
|
mTestFailed = true;
|
||||||
}
|
}
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
@@ -307,28 +369,32 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
MediaDrm drm = startDrm();
|
MediaDrm drm = startDrm();
|
||||||
byte[] sessionId = openSession(drm);
|
byte[] sessionId = openSession(drm);
|
||||||
KeyRequester keyRequester = new KeyRequester(kOperatorSessionSignPssh, kOperatorSessionKeyServerUrl);
|
KeyRequester keyRequester = new KeyRequester(kOperatorSessionSignPssh, kOperatorSessionKeyServerUrl);
|
||||||
keyRequester.doTransact(drm, sessionId);
|
if (keyRequester.doTransact(drm, sessionId)) {
|
||||||
|
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
||||||
|
|
||||||
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
// operator_session_key_permissions=allow_sign
|
||||||
|
byte[] signing_key_id = hex2ba("2685086ee9cb5835b063ab20786ffd78");
|
||||||
|
byte[] signing_key = hex2ba("b3dddf87d1cfc0b04c9253231ff89b9e374ef2f424edc7b7f4b2c10e39768ee8");
|
||||||
|
|
||||||
// operator_session_key_permissions=allow_sign
|
byte[] data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
byte[] signing_key_id = hex2ba("2685086ee9cb5835b063ab20786ffd78");
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
byte[] signing_key = hex2ba("b3dddf87d1cfc0b04c9253231ff89b9e374ef2f424edc7b7f4b2c10e39768ee8");
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
|
||||||
byte[] data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
byte[] hmacsha256 = hex2ba("5fc29a4c15fcf9e1e26b63b3be169d7f53e61e1564b92876f70c9ffd17697437");
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
|
||||||
|
|
||||||
byte[] hmacsha256 = hex2ba("5fc29a4c15fcf9e1e26b63b3be169d7f53e61e1564b92876f70c9ffd17697437");
|
byte[] result = cs.sign(signing_key_id, data);
|
||||||
|
if (Arrays.equals(hmacsha256, result)) {
|
||||||
byte[] result = cs.sign(signing_key_id, data);
|
Log.d(TAG, "Signing test passed!");
|
||||||
if (Arrays.equals(hmacsha256, result)) {
|
} else {
|
||||||
Log.d(TAG, "Signing test passed!");
|
Log.d(TAG, "Signing test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Signing test failed!");
|
displayText("Failed to get keys from license server!");
|
||||||
mTestFailed = true;
|
mTestFailed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
stopDrm(drm);
|
stopDrm(drm);
|
||||||
}
|
}
|
||||||
@@ -339,25 +405,28 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
final byte[] kOperatorSessionVerifyPssh = hex2ba("0801121097c003f73b1a53aa51ba54a6ef631ca0");
|
final byte[] kOperatorSessionVerifyPssh = hex2ba("0801121097c003f73b1a53aa51ba54a6ef631ca0");
|
||||||
|
|
||||||
KeyRequester keyRequester = new KeyRequester(kOperatorSessionVerifyPssh, kOperatorSessionKeyServerUrl);
|
KeyRequester keyRequester = new KeyRequester(kOperatorSessionVerifyPssh, kOperatorSessionKeyServerUrl);
|
||||||
keyRequester.doTransact(drm, sessionId);
|
if (keyRequester.doTransact(drm, sessionId)) {
|
||||||
|
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
||||||
|
|
||||||
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
// operator_session_key_permissions=allow_signature_verify
|
||||||
|
byte[] verify_key_id = hex2ba("97c003f73b1a53aa51ba54a6ef631ca0");
|
||||||
|
byte[] verify_key = hex2ba("cfe2acb04ad5169153690c1932d5d2c6062a4607d274901e935d27b77ad48b2e");
|
||||||
|
|
||||||
// operator_session_key_permissions=allow_signature_verify
|
byte[] data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
byte[] verify_key_id = hex2ba("97c003f73b1a53aa51ba54a6ef631ca0");
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
byte[] verify_key = hex2ba("cfe2acb04ad5169153690c1932d5d2c6062a4607d274901e935d27b77ad48b2e");
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
|
||||||
byte[] data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
byte[] hmacsha256 = hex2ba("6bd61722e5cc3e698d536317309940328ab973be3a3b5705650aa09a48ebbf61");
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
|
||||||
|
|
||||||
byte[] hmacsha256 = hex2ba("6bd61722e5cc3e698d536317309940328ab973be3a3b5705650aa09a48ebbf61");
|
if (cs.verify(verify_key_id, data, hmacsha256)) {
|
||||||
|
Log.d(TAG, "Verify test passed!");
|
||||||
if (cs.verify(verify_key_id, data, hmacsha256)) {
|
} else {
|
||||||
Log.d(TAG, "Verify test passed!");
|
Log.d(TAG, "Verify test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Verify test failed!");
|
displayText("Failed to get keys from license server!");
|
||||||
mTestFailed = true;
|
mTestFailed = true;
|
||||||
}
|
}
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
@@ -372,77 +441,79 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
byte[] sessionId = openSession(drm);
|
byte[] sessionId = openSession(drm);
|
||||||
|
|
||||||
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
|
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
|
||||||
keyRequester.doTransact(drm, sessionId);
|
if (keyRequester.doTransact(drm, sessionId)) {
|
||||||
|
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
||||||
|
|
||||||
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
|
// operator_session_key_permissions=allow_encrypt | allow_decrypt
|
||||||
|
byte[] aes_key_id = hex2ba("3be2b25db355fc64a0e69a50f4dbb298");
|
||||||
|
byte[] aes_key = hex2ba("5762d22a5e17d5402dc310a7c33ce539");
|
||||||
|
|
||||||
// operator_session_key_permissions=allow_encrypt | allow_decrypt
|
byte[] clr_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
byte[] aes_key_id = hex2ba("3be2b25db355fc64a0e69a50f4dbb298");
|
|
||||||
byte[] aes_key = hex2ba("5762d22a5e17d5402dc310a7c33ce539");
|
|
||||||
|
|
||||||
byte[] clr_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
|
||||||
byte[] enc_data = hex2ba("ee92d402f55f1d7eef4844803d9d43a603a4dd13f4a2ad5ea7653adcefa74b06" +
|
|
||||||
"ff459ab476a497567198c7cfa06d6fdd66b7924c2ca430baf534c5e00c800a06" +
|
|
||||||
"d0c108057ceab2ea33671d83e35eaaf1f1ff0f7e1618d05810a47b12cbc0806f" +
|
|
||||||
"d6ba8127a5e411f49b4e1790b1a6cb963e33d6cbc6569c44b4e1b28005fd1dde");
|
|
||||||
|
|
||||||
byte[] iv = hex2ba("3ec0f3d3970fbd541ac4e7e1d06a6131");
|
|
||||||
|
|
||||||
byte[] result = cs.decrypt(aes_key_id, enc_data, iv);
|
|
||||||
if (Arrays.equals(clr_data, result)) {
|
|
||||||
Log.d(TAG, "Multiple key decrypt test passed!");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Multiple key decrypt test failed!");
|
|
||||||
mTestFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = cs.encrypt(aes_key_id, clr_data, iv);
|
|
||||||
if (Arrays.equals(enc_data, result)) {
|
|
||||||
Log.d(TAG, "Multiple key encrypt test passed!");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Multiple key encrypt test failed!");
|
|
||||||
mTestFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] signing_key_id = hex2ba("2685086ee9cb5835b063ab20786ffd78");
|
|
||||||
byte[] signing_key = hex2ba("b3dddf87d1cfc0b04c9253231ff89b9e374ef2f424edc7b7f4b2c10e39768ee8");
|
|
||||||
|
|
||||||
byte[] signing_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
byte[] enc_data = hex2ba("ee92d402f55f1d7eef4844803d9d43a603a4dd13f4a2ad5ea7653adcefa74b06" +
|
||||||
|
"ff459ab476a497567198c7cfa06d6fdd66b7924c2ca430baf534c5e00c800a06" +
|
||||||
|
"d0c108057ceab2ea33671d83e35eaaf1f1ff0f7e1618d05810a47b12cbc0806f" +
|
||||||
|
"d6ba8127a5e411f49b4e1790b1a6cb963e33d6cbc6569c44b4e1b28005fd1dde");
|
||||||
|
|
||||||
byte[] hmacsha256 = hex2ba("5fc29a4c15fcf9e1e26b63b3be169d7f53e61e1564b92876f70c9ffd17697437");
|
byte[] iv = hex2ba("3ec0f3d3970fbd541ac4e7e1d06a6131");
|
||||||
|
|
||||||
result = cs.sign(signing_key_id, signing_data);
|
byte[] result = cs.decrypt(aes_key_id, enc_data, iv);
|
||||||
if (Arrays.equals(hmacsha256, result)) {
|
if (Arrays.equals(clr_data, result)) {
|
||||||
Log.d(TAG, "Multiple key signing test passed!");
|
Log.d(TAG, "Multiple key decrypt test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Multiple key decrypt test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = cs.encrypt(aes_key_id, clr_data, iv);
|
||||||
|
if (Arrays.equals(enc_data, result)) {
|
||||||
|
Log.d(TAG, "Multiple key encrypt test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Multiple key encrypt test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] signing_key_id = hex2ba("2685086ee9cb5835b063ab20786ffd78");
|
||||||
|
byte[] signing_key = hex2ba("b3dddf87d1cfc0b04c9253231ff89b9e374ef2f424edc7b7f4b2c10e39768ee8");
|
||||||
|
|
||||||
|
byte[] signing_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
|
||||||
|
byte[] hmacsha256 = hex2ba("5fc29a4c15fcf9e1e26b63b3be169d7f53e61e1564b92876f70c9ffd17697437");
|
||||||
|
|
||||||
|
result = cs.sign(signing_key_id, signing_data);
|
||||||
|
if (Arrays.equals(hmacsha256, result)) {
|
||||||
|
Log.d(TAG, "Multiple key signing test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Multiple key signing test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// operator_session_key_permissions=allow_signature_verify
|
||||||
|
byte[] verify_key_id = hex2ba("97c003f73b1a53aa51ba54a6ef631ca0");
|
||||||
|
byte[] verify_key = hex2ba("cfe2acb04ad5169153690c1932d5d2c6062a4607d274901e935d27b77ad48b2e");
|
||||||
|
|
||||||
|
byte[] verify_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
||||||
|
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
||||||
|
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
||||||
|
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
||||||
|
|
||||||
|
hmacsha256 = hex2ba("6bd61722e5cc3e698d536317309940328ab973be3a3b5705650aa09a48ebbf61");
|
||||||
|
|
||||||
|
if (cs.verify(verify_key_id, verify_data, hmacsha256)) {
|
||||||
|
Log.d(TAG, "Multiple key verify test passed!");
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Multiple key verify test failed!");
|
||||||
|
mTestFailed = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Multiple key signing test failed!");
|
displayText("Failed to get keys from license server!");
|
||||||
mTestFailed = true;
|
mTestFailed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator_session_key_permissions=allow_signature_verify
|
|
||||||
byte[] verify_key_id = hex2ba("97c003f73b1a53aa51ba54a6ef631ca0");
|
|
||||||
byte[] verify_key = hex2ba("cfe2acb04ad5169153690c1932d5d2c6062a4607d274901e935d27b77ad48b2e");
|
|
||||||
|
|
||||||
byte[] verify_data = hex2ba("4c02bcc3943aa828ecf7bbb16420572d00cabb21c3084c422217fee7fadd766d" +
|
|
||||||
"4bf726a232d029a81830e40e1e12ba34ba005ca6ce8033a0e3602a52b9b8d3d4" +
|
|
||||||
"b15dc458730f8affebbf35b1536c1a5d42370cf93c5b4094c0920bb1b2333f6a" +
|
|
||||||
"1897c5dd62eadfc1060786b0f69f228d5d7241cc644b85c35b9a7f4b893b5b85");
|
|
||||||
|
|
||||||
hmacsha256 = hex2ba("6bd61722e5cc3e698d536317309940328ab973be3a3b5705650aa09a48ebbf61");
|
|
||||||
|
|
||||||
if (cs.verify(verify_key_id, verify_data, hmacsha256)) {
|
|
||||||
Log.d(TAG, "Multiple key verify test passed!");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Multiple key verify test failed!");
|
|
||||||
mTestFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
drm.closeSession(sessionId);
|
drm.closeSession(sessionId);
|
||||||
stopDrm(drm);
|
stopDrm(drm);
|
||||||
}
|
}
|
||||||
@@ -636,6 +707,16 @@ public class MediaDrmAPITest extends Activity {
|
|||||||
codec = MediaCodec.createDecoderByType(mime);
|
codec = MediaCodec.createDecoderByType(mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure the surface view has been created
|
||||||
|
SurfacePanel sp = (SurfacePanel)findViewById(R.id.surface_view);
|
||||||
|
int max_retries = 500; // 5 seconds
|
||||||
|
while (!sp.isCreated()) {
|
||||||
|
sleep(10);
|
||||||
|
if (--max_retries == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MediaFormat format = MediaFormat.createVideoFormat(mime, 1280, 720);
|
MediaFormat format = MediaFormat.createVideoFormat(mime, 1280, 720);
|
||||||
SurfaceView sv = (SurfaceView)findViewById(R.id.surface_view);
|
SurfaceView sv = (SurfaceView)findViewById(R.id.surface_view);
|
||||||
codec.configure(format, sv.getHolder().getSurface(), crypto, 0);
|
codec.configure(format, sv.getHolder().getSurface(), crypto, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user