Files
android/libwvdrmengine/test/java/MediaDrmApiTest/src/com/widevine/test/KeyRequester.java
Edwin Wong d81904ec78 Move MediaDrmApiTest to its own folder.
Merged from http://go/wvgerrit/67523

This is in preparation for adding the Full Decryption Path Test
android application so it will reside under
vendor/widevine/libwvdrmengine/test/java.

Test: build and run MediaDrmAPITest.apk from the new directory

bug: 113594822
Change-Id: If4adb51ba7bb24a5e28e04956909c2d5a1af3c53
2018-12-04 15:21:09 -08:00

196 lines
6.6 KiB
Java

package com.widevine.test;
import android.media.MediaDrm;
import android.media.NotProvisionedException;
import android.media.DeniedByServerException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import android.os.AsyncTask;
import android.util.Log;
public class KeyRequester {
private final String TAG = "KeyRequester";
private byte[] mPssh;
private String mServerUrl;
public KeyRequester(byte[] pssh, String url) {
mPssh = pssh;
mServerUrl = url;
}
public boolean doTransact(MediaDrm drm, byte[] sessionId) {
boolean retryTransaction;
boolean result = false;
do {
retryTransaction = false;
MediaDrm.KeyRequest drmRequest = null;
boolean retryRequest;
do {
retryRequest = false;
try {
drmRequest = drm.getKeyRequest(sessionId, mPssh, "cenc",
MediaDrm.KEY_TYPE_STREAMING, null);
} catch (NotProvisionedException e) {
Log.i(TAG, "Invalid certificate, reprovisioning");
ProvisionRequester provisionRequester = new ProvisionRequester();
provisionRequester.doTransact(drm);
retryRequest = true;
}
} while (retryRequest);
if (drmRequest == null) {
Log.e(TAG, "Failed to get key request");
return false;
}
PostRequestTask postTask = new PostRequestTask(drmRequest.getData());
postTask.execute(mServerUrl);
// wait for post task to complete
byte[] responseBody;
long startTime = System.currentTimeMillis();
do {
responseBody = postTask.getResponseBody();
if (responseBody == null) {
sleep(100);
} else {
break;
}
} while (System.currentTimeMillis() - startTime < 5000);
if (responseBody == null) {
Log.e(TAG, "No response from license server!");
} else {
byte[] drmResponse = parseResponseBody(responseBody);
if (drmResponse == null) {
Log.e(TAG, "No response body in response");
} else {
try {
drm.provideKeyResponse(sessionId, drmResponse);
result = true;
} catch (NotProvisionedException e) {
Log.i(TAG, "Key response invalidated the certificate, reprovisioning");
ProvisionRequester provisionRequester = new ProvisionRequester();
provisionRequester.doTransact(drm);
retryTransaction = true;
} catch (DeniedByServerException e) {
// informational, the event handler will take care of provisioning
Log.e(TAG, "Server rejected the key request");
}
}
}
} while (retryTransaction);
return result;
}
private class PostRequestTask extends AsyncTask<String, Void, Void> {
private final String TAG = "PostRequestTask";
private byte[] mDrmRequest;
private byte[] mResponseBody;
public PostRequestTask(byte[] drmRequest) {
mDrmRequest = drmRequest;
}
protected Void doInBackground(String... urls) {
mResponseBody = postRequest(urls[0], mDrmRequest);
Log.d(TAG, "response length=" + mResponseBody.length);
return null;
}
public byte[] getResponseBody() {
return mResponseBody;
}
private byte[] postRequest(String url, byte[] drmRequest) {
Log.d(TAG, "PostRequest url=" + url);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
try {
// Add data
ByteArrayEntity entity = new ByteArrayEntity(drmRequest);
httppost.setEntity(entity);
httppost.setHeader("User-Agent", "Widevine CDM v1.0");
httppost.setHeader("Connection", "close");
Log.d(TAG, "request line=" + httppost.getRequestLine().toString());
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
byte[] responseBody;
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 200) {
responseBody = EntityUtils.toByteArray(response.getEntity());
} else {
Log.d(TAG, "Server returned HTTP error code " + responseCode);
return null;
}
return responseBody;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
// validate the response body and return the drmResponse blob
private byte[] parseResponseBody(byte[] responseBody) {
String bodyString = null;
try {
bodyString = new String(responseBody, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (bodyString == null) {
return null;
}
if (bodyString.startsWith("GLS/")) {
if (!bodyString.startsWith("GLS/1.")) {
Log.e(TAG, "Invalid server version, expected 1.x");
return null;
}
int drmMessageOffset = bodyString.indexOf("\r\n\r\n");
if (drmMessageOffset == -1) {
Log.e(TAG, "Invalid server response, could not locate drm message");
return null;
}
responseBody = Arrays.copyOfRange(responseBody, drmMessageOffset + 4, responseBody.length);
}
return responseBody;
}
private void sleep(int msec) {
try {
Thread.sleep(msec);
} catch (InterruptedException e) {
}
}
}