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:
Jeff Tinker
2013-12-11 12:47:52 -08:00
parent 68e1e7c578
commit 4ab8efc21d
2 changed files with 227 additions and 142 deletions

View File

@@ -28,9 +28,11 @@ public class KeyRequester {
mServerUrl = url;
}
public void doTransact(MediaDrm drm, byte[] sessionId) {
public boolean doTransact(MediaDrm drm, byte[] sessionId) {
boolean retryTransaction;
boolean result = false;
do {
retryTransaction = false;
@@ -52,7 +54,7 @@ public class KeyRequester {
if (drmRequest == null) {
Log.e(TAG, "Failed to get key request");
return;
return false;
}
PostRequestTask postTask = new PostRequestTask(drmRequest.getData());
@@ -80,6 +82,7 @@ public class KeyRequester {
} else {
try {
drm.provideKeyResponse(sessionId, drmResponse);
result = true;
} catch (NotProvisionedException e) {
Log.i(TAG, "Key response invalidated the certificate, reprovisioning");
ProvisionRequester provisionRequester = new ProvisionRequester();
@@ -92,6 +95,7 @@ public class KeyRequester {
}
}
} while (retryTransaction);
return result;
}
private class PostRequestTask extends AsyncTask<String, Void, Void> {

View File

@@ -11,8 +11,11 @@ import android.view.View;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.view.Surface;
import android.view.Display;
import android.content.Context;
import android.graphics.Point;
import android.media.MediaDrm;
import android.widget.TextView;
import android.media.MediaDrm.CryptoSession;
import android.media.MediaDrmException;
import android.media.NotProvisionedException;
@@ -25,6 +28,7 @@ import android.media.MediaCodec.CryptoInfo;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import android.util.TypedValue;
import android.util.AttributeSet;
import java.util.UUID;
import java.util.Arrays;
@@ -38,14 +42,17 @@ import java.lang.Exception;
import java.lang.InterruptedException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.lang.Math;
class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
{
private final String TAG = "SurfacePanel";
private boolean mIsCreated;
public SurfacePanel(Context context, AttributeSet attrSet)
{
super(context, attrSet);
mIsCreated = false;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
@@ -54,6 +61,7 @@ class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.d(TAG, "surfaceDestroyed");
mIsCreated = false;
}
@Override
@@ -67,6 +75,11 @@ class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback
public void surfaceCreated(SurfaceHolder holder)
{
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);
private boolean mTestFailed;
private TextView mTextView;
private String mDisplayText;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle 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() {
@Override
@@ -95,22 +122,48 @@ public class MediaDrmAPITest extends Activity {
testWidevineSchemeSupported();
testProperties();
testQueryKeyStatus();
testClearContentNoKeys();
testEncryptedContent();
testGenericEncryptAndDecrypt();
testGenericSign();
testGenericVerify();
testGenericMultipleKeys();
runOnUiThread(new Runnable() {
public void run() {
setContentView(R.layout.main);
}
});
testClearContentNoKeys();
testEncryptedContent();
runOnUiThread(new Runnable() {
public void run() {
setContentView(mTextView);
}
});
if (mTestFailed) {
Log.e(TAG, "TEST FAILED!");
displayText("\nTEST FAILED!");
} else {
Log.e(TAG, "TEST SUCCESS!");
displayText("\nTEST PASSED!");
}
}
}.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 Looper mLooper;
private Object mLock = new Object();
@@ -210,23 +263,22 @@ public class MediaDrmAPITest extends Activity {
private void testProperties() {
MediaDrm drm = startDrm();
Log.i(TAG, "vendor: " + drm.getPropertyString(MediaDrm.PROPERTY_VENDOR));
Log.i(TAG, "version: " + drm.getPropertyString(MediaDrm.PROPERTY_VERSION));
Log.i(TAG, "description: " + drm.getPropertyString(MediaDrm.PROPERTY_DESCRIPTION));
Log.i(TAG, "deviceId: " + Arrays.toString(drm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)));
Log.i(TAG, "algorithms: " + drm.getPropertyString(MediaDrm.PROPERTY_ALGORITHMS));
displayText("vendor: " + drm.getPropertyString(MediaDrm.PROPERTY_VENDOR));
displayText("version: " + drm.getPropertyString(MediaDrm.PROPERTY_VERSION));
displayText("description: " + drm.getPropertyString(MediaDrm.PROPERTY_DESCRIPTION));
displayText("deviceId: " + Arrays.toString(drm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)));
displayText("algorithms: " + drm.getPropertyString(MediaDrm.PROPERTY_ALGORITHMS));
// widevine-specific properties
Log.i(TAG, "security level: " + drm.getPropertyString("securityLevel"));
Log.i(TAG, "system ID: " + drm.getPropertyString("systemId"));
displayText("security level: " + drm.getPropertyString("securityLevel"));
displayText("system ID: " + drm.getPropertyString("systemId"));
stopDrm(drm);
}
private void testQueryKeyStatus() {
MediaDrm drm = startDrm();
byte[] sessionId = openSession(drm);
getKeys(drm, sessionId);
if (getKeys(drm, sessionId)) {
Log.i(TAG, "Query Key Status:");
HashMap<String, String> keyStatus = drm.queryKeyStatus(sessionId);
Iterator<String> iterator = keyStatus.keySet().iterator();
@@ -234,24 +286,31 @@ public class MediaDrmAPITest extends Activity {
String name = iterator.next();
Log.i(TAG, "\t" + name + " = " + keyStatus.get(name));
}
}
drm.closeSession(sessionId);
stopDrm(drm);
}
private void getKeys(MediaDrm drm, byte[] sessionId) {
private boolean getKeys(MediaDrm drm, byte[] sessionId) {
final byte[] kPssh = hex2ba("08011210e02562e04cd55351b14b3d748d36ed8e");
final String kClientAuth = "?source=YOUTUBE&video_id=EGHC6OHNbOo&oauth=ya.gtsqawidevine";
final String kPort = "80";
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() {
MediaDrm drm = startDrm();
byte[] sessionId = openSession(drm);
getKeys(drm, sessionId);
if (getKeys(drm, sessionId)) {
testDecrypt(sessionId);
}
drm.closeSession(sessionId);
stopDrm(drm);
}
@@ -263,8 +322,7 @@ public class MediaDrmAPITest extends Activity {
byte[] sessionId = openSession(drm);
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
keyRequester.doTransact(drm, sessionId);
if (keyRequester.doTransact(drm, sessionId)) {
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
// operator_session_key_permissions=allow_encrypt | allow_decrypt
@@ -297,6 +355,10 @@ public class MediaDrmAPITest extends Activity {
Log.d(TAG, "Encrypt test failed!");
mTestFailed = true;
}
} else {
displayText("Failed to get keys from license server!");
mTestFailed = true;
}
drm.closeSession(sessionId);
stopDrm(drm);
}
@@ -307,8 +369,7 @@ public class MediaDrmAPITest extends Activity {
MediaDrm drm = startDrm();
byte[] sessionId = openSession(drm);
KeyRequester keyRequester = new KeyRequester(kOperatorSessionSignPssh, kOperatorSessionKeyServerUrl);
keyRequester.doTransact(drm, sessionId);
if (keyRequester.doTransact(drm, sessionId)) {
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
// operator_session_key_permissions=allow_sign
@@ -329,6 +390,11 @@ public class MediaDrmAPITest extends Activity {
Log.d(TAG, "Signing test failed!");
mTestFailed = true;
}
} else {
displayText("Failed to get keys from license server!");
mTestFailed = true;
}
drm.closeSession(sessionId);
stopDrm(drm);
}
@@ -339,8 +405,7 @@ public class MediaDrmAPITest extends Activity {
final byte[] kOperatorSessionVerifyPssh = hex2ba("0801121097c003f73b1a53aa51ba54a6ef631ca0");
KeyRequester keyRequester = new KeyRequester(kOperatorSessionVerifyPssh, kOperatorSessionKeyServerUrl);
keyRequester.doTransact(drm, sessionId);
if (keyRequester.doTransact(drm, sessionId)) {
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
// operator_session_key_permissions=allow_signature_verify
@@ -360,6 +425,10 @@ public class MediaDrmAPITest extends Activity {
Log.d(TAG, "Verify test failed!");
mTestFailed = true;
}
} else {
displayText("Failed to get keys from license server!");
mTestFailed = true;
}
drm.closeSession(sessionId);
stopDrm(drm);
}
@@ -372,8 +441,7 @@ public class MediaDrmAPITest extends Activity {
byte[] sessionId = openSession(drm);
KeyRequester keyRequester = new KeyRequester(kOperatorSessionAESPssh, kOperatorSessionKeyServerUrl);
keyRequester.doTransact(drm, sessionId);
if (keyRequester.doTransact(drm, sessionId)) {
CryptoSession cs = drm.getCryptoSession(sessionId, "AES/CBC/NoPadding", "HmacSHA256");
// operator_session_key_permissions=allow_encrypt | allow_decrypt
@@ -442,7 +510,10 @@ public class MediaDrmAPITest extends Activity {
Log.d(TAG, "Multiple key verify test failed!");
mTestFailed = true;
}
} else {
displayText("Failed to get keys from license server!");
mTestFailed = true;
}
drm.closeSession(sessionId);
stopDrm(drm);
}
@@ -636,6 +707,16 @@ public class MediaDrmAPITest extends Activity {
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);
SurfaceView sv = (SurfaceView)findViewById(R.id.surface_view);
codec.configure(format, sv.getHolder().getSurface(), crypto, 0);