410 lines
23 KiB
Java
Executable File
410 lines
23 KiB
Java
Executable File
////////////////////////////////////////////////////////////////////////////////
|
|
//// Copyright 2018 Google LLC
|
|
////
|
|
//// This software is licensed under the terms defined in the Widevine Master
|
|
//// License Agreement. For a copy of this agreement, please contact
|
|
//// widevine-licensing@google.com.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
package com.google.video.widevine.sdk.wvpl;
|
|
|
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.Arrays;
|
|
import java.util.Base64;
|
|
import java.util.Map;
|
|
|
|
/** Tests for {@link WvPLProxySession} Java API in Widevine Proxy Server SDK. */
|
|
public class WvPLProxyExample {
|
|
/* Creates WvTestRunner to run wvpl proxy test */
|
|
public static String loadCertificateStatusListFromFile(String certificateStatusListFile)
|
|
throws IOException {
|
|
BufferedReader br = Files.newBufferedReader(Path.of(certificateStatusListFile), UTF_8);
|
|
StringBuilder sb = new StringBuilder();
|
|
String line = br.readLine();
|
|
while (line != null) {
|
|
sb.append(line);
|
|
sb.append(System.lineSeparator());
|
|
line = br.readLine();
|
|
}
|
|
br.close();
|
|
return sb.toString();
|
|
}
|
|
|
|
static class WvTestRunner extends Thread {
|
|
private int loops;
|
|
private String threadName;
|
|
private WvPLProxyEnvironment env;
|
|
|
|
public WvTestRunner(WvPLProxyEnvironment env, ThreadGroup group, String threadName, int loops) {
|
|
super(group, threadName);
|
|
this.loops = loops;
|
|
this.threadName = threadName;
|
|
this.env = env;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
System.out.println("Thread Started: " + threadName);
|
|
try {
|
|
Thread.sleep(2000);
|
|
} catch (InterruptedException e) {
|
|
System.out.println("Unexpected error when starting thread = " + threadName);
|
|
}
|
|
String testSessionId = "TestSessionId";
|
|
String testPurchaseId = "TestPurchaseId";
|
|
String testProviderClientToken = "TestProviderClientToken";
|
|
byte[] testMasterSigningKeys = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
boolean testOverrideProviderClientToken = true;
|
|
String b64LicenseRequest =
|
|
"CAES9AwKlQwIARLtCQquAggCEhDEmqLqtzGkARd0kTEo0I1IGJSf2qkFIo4CMIIBCgKCAQEA0NXBS5-DGcEt_vnp"
|
|
+ "kWgiYUrrlKjddGnSLPuloU5fNHN-TTtF2HwCbKHxv-71EeYwl4omrd36XZ7N6cRPE78G1BQoJy57z2wgCJZ8_3"
|
|
+ "jPsMnQSadynMxDdvVBqQde87T66-KqqBMTBOI3dC_LtX1Ydj04OR3yIKSlmTGGPwW37BfvsmNWGAHOHa0i7kP3"
|
|
+ "C1HkUyBixNJLArnNmQSfLi5jf8EyRu6-yJwFRyY1EcXXcDouUgJbWFGey6oK26-HI87rs4bEJyjxk3fr0BJcfh"
|
|
+ "QSVm-Awmyp4TU0J_A_PLoatG0yzjvPLT0ymsujLta0ZT6xHLSSeD3JfDyrlyS196GS2QIDAQABKIchEoACUqrZ"
|
|
+ "8CzIzCe-j4BI0cqjvQ7C_spcMjwdlO9E5pb-FIcP5fDdOSa8Op6gpkB7HwEv-HC8ITXjdQ3MRl5BcLB8elBDBw"
|
|
+ "Tl-nfw4AUqVRwSyPKfpOTU9w7MloiFBD8j2zP0Fbb3gub_G-JCMBYlpi8ObTiE5a3olWIl__trUgj-huLSKkIs"
|
|
+ "dH7dtaK55vvHIM7h7UcwomnxjJN1phHxB0c4iyHBAQfGaVSIUz3N7nXqsW__QO7qRIa7XCA-uiXpYF17wwTc4w"
|
|
+ "_X_fOKoYJ8mly85Sunm-XvxKZGzzcjyJuOsO_cK_KUiqt-TzeVmiohpmrEDK68ozm6LMFIFO3yBFpNgxq2BQqw"
|
|
+ "AggBEhDbPKzP3nYDjtzFHkw5JPr6GMLSg44FIo4CMIIBCgKCAQEAuVISqq1KZKOCyoJdYCxsMcBmzUvOotSUG2"
|
|
+ "c3VlJz_7Kq4MY65zff4_8AXtnsT4q4WWiREgiewPWe0n8x8_FI8z3r5cLKzwh_wRUwHlV5Sn2dw4I8VTzdPMH5"
|
|
+ "bfmgtCpM1NV5NhzT-YagPth3xrcwCnIP54oCLuKCDxG_rKcmKcHiyMVZnqdYHDNO5b8Tn21EV3JHZsLjpEfo_J"
|
|
+ "Og6mv1Z0r-vP6VJQT43KSJns5VSKx-RAHoff2ZTBuDWU2YOqFZpi_oeupPiHT_prwF9bIZiGhbEFNK-2T_t2BG"
|
|
+ "SzBpGNkQPb3VLek7WcctcqZTZ-eFQrzboRV0L5O8pho2cjVTswIDAQABKIchMAESgAMB8IopgGaBVAPSQnh6PI"
|
|
+ "VhD9nt9H_BgEMsW_pXJ5ij4PMltfdr8y03yF2GHJ_ZTeRYJpL_Mn8Mh5sLCaNF44S3nxSw5dT7bH35ZIFiB-uC"
|
|
+ "OH60js6UKadq099NZkPUtLCJAX5U_ggkSq2UMAMeRCyTo7XghUEaf_JyECh6rI5fKAjzIX7MfTLU32yHeiGkjN"
|
|
+ "Aj2_SoUnZH91Kb_wbStm6GSQdnw7G2kyKp6I6MJclgQZn7fJVCmRJugC57fDiBVv-sfl3Zp2SYQ9hwRBR9byMn"
|
|
+ "Vp5KLedB_v-9nnHniMLgSiDK-HASpZA-5C0OO27jHcdvdMgVjXoyJY05YYW1BcKKnGHit82fMY5zEDVG5mfmgq"
|
|
+ "d8ZYVlLAxJLWHZ7XCs1pIcAG1LjEy5rKzQtlT2DdwBzsF5mdybWKCLr-fbEqFo_ftp9HIc6EL70pZ07ofHbl0e"
|
|
+ "-PCkn5mJJYPbTNv7UxZgUU_2IqUJTxtwZD2GannSnwAPjd6D7u0W6CwFk-rhBe4aFAoMY29tcGFueV9uYW1lEg"
|
|
+ "Rhc3VzGhUKCm1vZGVsX25hbWUSB05leHVzIDcaIAoRYXJjaGl0ZWN0dXJlX25hbWUSC2FybWVhYmktdjdhGhIK"
|
|
+ "C2RldmljZV9uYW1lEgNkZWIaFgoMcHJvZHVjdF9uYW1lEgZyYXpvcmcaRQoKYnVpbGRfaW5mbxI3Z29vZ2xlL3"
|
|
+ "Jhem9yZy9kZWI6TU5DL01BU1RFUi8xODU1NjM3OnVzZXJkZWJ1Zy9kZXYta2V5cxotCglkZXZpY2VfaWQSIEpR"
|
|
+ "NVpJWkVMVUpBQlBVQzNLMkg1Q0NXNklVAAAAAAAAGiYKFHdpZGV2aW5lX2NkbV92ZXJzaW9uEg52My4wLjAtYW"
|
|
+ "5kcm9pZDIIEAEgBCgJMAASSgpICiIIARoNd2lkZXZpbmVfdGVzdCIPc3RyZWFtaW5nX2NsaXAxEAEaIDE3NEQ4"
|
|
+ "MkUyRjA0QzZGQkEwNjAwMDAwMDAwMDAwMDAwGAEgmZ_aqQUwFTij79WWBRqAAsguK-RkA18-zOzwX38JDpT877"
|
|
+ "woGiL-kUhQ9w2NuDxolgFovFqp-VNEESpG9GG-dp8sFXAABy4Xk3YJnyVvAtI6MtiSPjDLt87QPSie6WCLgqvL"
|
|
+ "zHoGSGuo4ij4HBX23QM0jZNDz_u_1rdZLKfV-nIWQ1sVI2u-QYnTYCztRmpMd1Gp1mZzLpcOL9PNGIYbuJSmQe"
|
|
+ "fi3FDGdwfmKLRYg8peJXj2OPHKNyyJCfRMZ42PmBvg4bxI36Ets_TU_6m2RMKARnTLYoGq0bw0fl9GeV_27mDU"
|
|
+ "Kvl0SIWXh0Jup8xxCO_iFQzw_7rCyW2FtrzXqq2qEmPRK5HjY-_c_0XVWh0=";
|
|
|
|
byte[] decodedLicenseRequest = Base64.getUrlDecoder().decode(b64LicenseRequest);
|
|
for (int i = 0; i < loops; i++) {
|
|
try {
|
|
byte[] bad = {1, 2, 3, 4};
|
|
env.createSession(bad);
|
|
} catch (WvPLStatusException e) {
|
|
System.out.println("Message for bad session: " + e.getMessage());
|
|
System.out.println("Status message for bad session: " + e.getStatus().getMessage());
|
|
}
|
|
try {
|
|
byte[] serviceCertificateRequest = Base64.getUrlDecoder().decode("CAQ=");
|
|
env.createSession(serviceCertificateRequest);
|
|
} catch (WvPLStatusException e) {
|
|
System.out.println("Message for failed to create session with service certificate "
|
|
+ "request: " + e.getMessage());
|
|
assertEquals(WvPLStatus.StatusCode.SERVICE_CERTIFICATE_REQUEST_MESSAGE,
|
|
e.getStatus().getStatusCode());
|
|
try {
|
|
byte[] serviceCert = env.generateDrmServiceCertificateResponse();
|
|
System.out.println("Returning service certificate: "
|
|
+ Base64.getUrlEncoder().encodeToString(serviceCert));
|
|
} catch (WvPLStatusException wvplE) {
|
|
System.out.println("Failed to get the DRM Service Certifidate: "
|
|
+ wvplE.getStatus().getMessage());
|
|
}
|
|
}
|
|
WvPLProxySession session = null;
|
|
try {
|
|
session = env.createSession(decodedLicenseRequest);
|
|
} catch (WvPLStatusException e) {
|
|
System.out.println("Message: " + e.getMessage());
|
|
System.out.println("Status message: " + e.getStatus().getMessage());
|
|
}
|
|
System.out.println("Version: " + WvPLProxySession.getVersionString());
|
|
WvPLRequestType requestType = session.getRequestType();
|
|
System.out.println("Message type : " + requestType.getMessageType());
|
|
if (requestType.getMessageType() != WvPLMessageType.MessageType.LICENSE_REQUEST) {
|
|
System.out.println(
|
|
"Expected LICENSE_REQUEST, Unexpected message type : " + requestType.getMessageType());
|
|
System.exit(3);
|
|
}
|
|
System.out.println("License type : " + requestType.getLicenseType());
|
|
System.out.println("LicenseRequest type : " + requestType.getLicenseRequestType());
|
|
WvPLStatus status;
|
|
try {
|
|
WvPLClientInfo clientInfo = session.getClientInfo();
|
|
WvPLHdcp.HDCP maxHdcpVersion = clientInfo.getMaxHdcpVersion();
|
|
System.out.println("max hdcp version = " + maxHdcpVersion.getHDCP()
|
|
+ ", oem crypto api version = " + clientInfo.getOemCryptoApiVersion()
|
|
+ ", provider client token = " + clientInfo.getProviderClientToken());
|
|
Map<String, String> namesValues = clientInfo.getNamesValues();
|
|
for (Map.Entry<String, String> nameValue : namesValues.entrySet()) {
|
|
System.out.println("Key = " + nameValue.getKey() + ", Value = " + nameValue.getValue());
|
|
}
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("GetClientInfo WvPLStatus: code = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
|
|
// Set parameters on the created session.
|
|
// Validate setting/getting WvPLPlaybackPolicy for a session
|
|
WvPLPlaybackPolicy policy = new WvPLPlaybackPolicy();
|
|
policy.setLicenseDurationSeconds(10000000L);
|
|
session.setPolicy(policy);
|
|
assertEquals(
|
|
policy.getLicenseDurationSeconds(), session.getPolicy().getLicenseDurationSeconds());
|
|
|
|
WvPLKey key1 = new WvPLKey();
|
|
byte[] data1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
key1.setKeyId(data1);
|
|
key1.setKeyBytes(data1);
|
|
key1.setTrackType(WvPLTrackType.TrackType.AUDIO);
|
|
status = session.addKey(key1);
|
|
assertEquals(WvPLStatus.StatusCode.OK, status.getStatusCode());
|
|
|
|
// Adding a TrackType.VIDEO_SD key (without keyId)
|
|
WvPLKey key2 = new WvPLKey();
|
|
byte[] data2 = {10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
key2.setKeyBytes(data2);
|
|
key2.setTrackType(WvPLTrackType.TrackType.VIDEO_SD);
|
|
status = session.addKey(key2);
|
|
assertEquals(WvPLStatus.StatusCode.OK, status.getStatusCode());
|
|
|
|
// Adding a TrackType.VIDEO_HD key
|
|
WvPLKey key3 = new WvPLKey();
|
|
byte[] data3 = {10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
key3.setKeyId(data3);
|
|
key3.setKeyBytes(data3);
|
|
key3.setTrackType(WvPLTrackType.TrackType.VIDEO_HD);
|
|
|
|
// Validate setting/getting WvPLOutputProtection values
|
|
WvPLOutputProtection outputProtection = new WvPLOutputProtection();
|
|
outputProtection.setHdcp(WvPLHdcp.HDCP.HDCP_V2_2);
|
|
assertEquals(WvPLHdcp.HDCP.HDCP_V2_2, outputProtection.getHdcp());
|
|
outputProtection.setSecurityLevel(WvPLSecurityLevel.SecurityLevel.SW_SECURE_DECODE);
|
|
assertEquals(
|
|
WvPLSecurityLevel.SecurityLevel.SW_SECURE_DECODE, outputProtection.getSecurityLevel());
|
|
key3.setOutputProtection(outputProtection);
|
|
|
|
// Validate setting/getting WvPLVideoResolutionConstraints
|
|
WvPLVideoResolutionConstraint videoResolutionConstraint1 =
|
|
new WvPLVideoResolutionConstraint();
|
|
videoResolutionConstraint1.setMinResolutionPixels(300);
|
|
videoResolutionConstraint1.setMaxResolutionPixels(600);
|
|
videoResolutionConstraint1.setHdcp(WvPLHdcp.HDCP.HDCP_V2);
|
|
|
|
WvPLVideoResolutionConstraint videoResolutionConstraint2 =
|
|
new WvPLVideoResolutionConstraint();
|
|
videoResolutionConstraint2.setMinResolutionPixels(3000);
|
|
videoResolutionConstraint2.setMaxResolutionPixels(6000);
|
|
videoResolutionConstraint2.setHdcp(WvPLHdcp.HDCP.HDCP_V1);
|
|
|
|
// Validate adding constraints and output protection values to key3 (VIDEO_HD)
|
|
key3.addVideoResolutionConstraint(videoResolutionConstraint1);
|
|
key3.addVideoResolutionConstraint(videoResolutionConstraint2);
|
|
assertEquals(2, key3.getVideoResolutionConstraint().size());
|
|
|
|
for (WvPLVideoResolutionConstraint vrc : key3.getVideoResolutionConstraint()) {
|
|
if (vrc.getHdcp() == WvPLHdcp.HDCP.HDCP_V2) {
|
|
assertEquals(videoResolutionConstraint1, vrc);
|
|
} else {
|
|
assertEquals(videoResolutionConstraint2, vrc);
|
|
}
|
|
}
|
|
|
|
WvPLOutputProtection requestedOutputProtection = new WvPLOutputProtection();
|
|
requestedOutputProtection.setHdcp(WvPLHdcp.HDCP.HDCP_V2);
|
|
key3.setRequestedOutputProtection(requestedOutputProtection);
|
|
status = session.addKey(key3);
|
|
assertEquals(WvPLStatus.StatusCode.OK, status.getStatusCode());
|
|
|
|
// We also could use filterKey to filter out the key.
|
|
WvPLKey filteredKey1 = new WvPLKey();
|
|
byte[] filteredKeyData1 = {10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
filteredKey1.setKeyId(filteredKeyData1);
|
|
filteredKey1.setKeyBytes(filteredKeyData1);
|
|
filteredKey1.setTrackType(WvPLTrackType.TrackType.VIDEO_HD);
|
|
WvPLCapabilityStatus capabilityStatus = session.filterKey(filteredKey1);
|
|
assertEquals(
|
|
WvPLCapabilityStatus.DeviceCapabilityStatus.CAPABILITY_OK,
|
|
capabilityStatus.getStatus());
|
|
|
|
// Validate setting/getting sessionInit values
|
|
WvPLSessionInit sessionInit = new WvPLSessionInit();
|
|
sessionInit.setSessionId(testSessionId);
|
|
sessionInit.setPurchaseId(testPurchaseId);
|
|
sessionInit.setMasterSigningKey(testMasterSigningKeys);
|
|
sessionInit.setProviderClientToken(testProviderClientToken);
|
|
sessionInit.setOverrideProviderClientToken(testOverrideProviderClientToken);
|
|
|
|
session.setSessionInit(sessionInit);
|
|
assertEquals(testSessionId, session.getSessionInit().getSessionId());
|
|
assertEquals(testPurchaseId, session.getSessionInit().getPurchaseId());
|
|
assertEquals(Arrays.toString(testMasterSigningKeys),
|
|
Arrays.toString(session.getSessionInit().getMasterSigningKey()));
|
|
assertEquals(testProviderClientToken, session.getSessionInit().getProviderClientToken());
|
|
assertEquals(testOverrideProviderClientToken,
|
|
session.getSessionInit().getOverrideProviderClientToken());
|
|
// Test getDeviceInfo() function.
|
|
try {
|
|
WvPLDeviceInfo deviceInfo = session.getDeviceInfo();
|
|
System.out.println("soc = " + deviceInfo.getSoc() + ", manufacturer = "
|
|
+ deviceInfo.getManufacturer() + ", model = " + deviceInfo.getModel()
|
|
+ ", device_type = " + deviceInfo.getDeviceType()
|
|
+ ", system_id = " + deviceInfo.getSystemId());
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("GetDeviceInfo WvPLStatus: code = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
try {
|
|
WvPLWidevinePsshData widevinePsshData = session.getPsshData();
|
|
if (!widevinePsshData.getKeyIds().isEmpty()) {
|
|
for (byte[] keyId : widevinePsshData.getKeyIds()) {
|
|
System.out.println("keyId from Widevine Pssh = " + Arrays.toString(keyId));
|
|
}
|
|
System.out.println("Content Id" + Arrays.toString(widevinePsshData.getContentId()));
|
|
} else {
|
|
System.out.println("KeyIds from Widevine Pssh is empty");
|
|
}
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("Get WvPLStatus: code = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
// Test generateEncodedLicenseRequest() function.
|
|
// TODO(yawenyu): Check if licenseRequest can be base64 decoded and parsed into the proto.
|
|
try {
|
|
String licenseRequest = session.generateLicenseRequest();
|
|
if (licenseRequest.length() == 0) {
|
|
System.out.println("Base64 encoded license request is empty");
|
|
System.exit(-1);
|
|
}
|
|
System.out.println("License request is : " + licenseRequest);
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("GenerateEncodedLicenseReques failed. WvPLStatus: code = "
|
|
+ status.getStatusCode() + ", message = " + status.getMessage());
|
|
}
|
|
// Test getResponseStatus.
|
|
String input =
|
|
"{\"status\":\"OK\",\"license\":\"CAISdgpKCiBBOEVEMDBBQUVEODM2RThFODMwNDAwMDAwMDAwMDAwMBIgQThFRDAwQUFFRDgzNkU4RTgzMDQwMDAwMDAwMDAwMDAaACABKAQSBggBEAEYARoWIANCEgoQa2MxMwAAAAAuNBxJAAAACCDe1eziBSgBUAMaIDn9npcVDpyEU7RpVHPvVCAmlTDVEbaBDUdi+LWCCWBL\"}";
|
|
try {
|
|
String responseStatus = session.getResponseStatus(input);
|
|
assertEquals("OK", responseStatus);
|
|
} catch (WvPLStatusException e) {
|
|
System.out.println("Failed to getResponseStatus.");
|
|
}
|
|
try {
|
|
session.getLicense(input);
|
|
} catch (WvPLStatusException e) {
|
|
System.out.println("getResponseStatus status = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
try {
|
|
WvPLClientCapabilities wvplClientCapabilities = session.getClientCapabilities();
|
|
System.out.println("WvPLClientCapabilities = " + wvplClientCapabilities);
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("GetClientInfo WvPLStatus: code = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
try {
|
|
env.destroySession(session);
|
|
} catch (IOException e) {
|
|
System.out.println("IOException when closing: " + e.getMessage());
|
|
}
|
|
// TODO(yawenyu): Add more test cases for getResponseStatus.
|
|
}
|
|
System.out.println("Thread Ended: " + threadName);
|
|
}
|
|
}
|
|
|
|
public static void main(String[] argv) throws Exception {
|
|
int numberOfRunners = 10;
|
|
int numberOfLoops = 100;
|
|
String b64DrmServiceCertificate =
|
|
"CscCCAMSEGMj4kXUq6vl6Zu3yX-iATQY8YHR4wUijgIwggEKAoIBAQCQ4zD-Na1NJ-_R5EukD3ZwnkJUVijD5Bs70gBbvYrskXADVMSC-YnFgN5_lQ7Y1jqG1Vo_o2MBLNu4wCoGjD9Vfnw2uOVs5lccs5hKGgxqHPgKit3PvVJYe0fXRi571pE-bI9FKsKlt02VkC0OopgqCui-494J9mVvTfmkwg24F0BBn6JnzNMKKLYXqNmEVyL-xF5AprYbYQwQ2RsYx0xHJ5ggh5J9LOJHuCfePTykRmdvkJfh0bnoBRrcR9VJzU--6ZMwFhsD3SEmGnyjfh9_rD1De01xdMIU1tumBDR7CsFmWFB-s8GPFEy14lkG7LWRZYOUagSf2FPh2V8O3rK3AgMBAAE6GHdpZGV2aW5lLXRlc3QuZ29vZ2xlLmNvbUACEoADqy10oin03kb2QW1t7OiNAx9Y5leFlqUaBveD93qtip5BC-4TPmB2CqKEGr_uUoR7YSOfoSsc8XJy5aGK6s05ci-LNxcQsHMbZr6nieDVO56AQhk6KvP2tB9qvPBKxtg7FKpxDjF43Fv2IeVUHnTy8JzuToOHLwgGDhT90RYnEqCTpVcssalc7XF8iVNERyMCakuud4TH8EL_bCqmoVY4Emdqdiu1uSMsTSQuSGu5GeFlK3FXxEjmKCw2ItKCiB3z6HGwMB0VpvX-CCQThc46O2D8b4fnN529cBOAmqeBI7ELZXJjybjD9EiUXrLx6IKLiCpjp-aWiwsRK1hZN6yEH-cRfSiXX_8mON4qi-aUkdsyVlNSn4WNp5GpOoY5MSfTq4EisngTSBzoo_UgXMoS0xf-DOsj614TngSDgXRNPrKnf19K8KetqFTv7BTxLUQbFuNHqHWcqSnimmo4lIsYdDA4Ed76kRERtbMnqeyI__UNSbY0eEZ3uxO95OxZMgye";
|
|
String b64PrivateKey =
|
|
"MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIGRMrX1uPR0sCAggAMB0GCWCGSAFlAwQBKgQQ8yhCy0bstsUeTLwl7saOrwSCBNDLB7oZx7Ypfodc9OR5aolJ6yMmKcvrB0jxRGioPLsT5flz_kWe4JMp25xR1c8Y0_ZrugU12zBbw9siyvfXhenrW0JVzxoqNGysggA_p-ZLXMxeQKcGwXHemWRMxlvO7wZG7gPANQhhkPnHzEN2kevvmsVTWIT7JVYGFALDg2mYgNsRslkblkfY51HvFS8vMOkL3YOG72NHnmpV4jMpiz9m7qiOcJ39oG2IldUb57e39LfnMO5WWafgrak2DEwL9zH6T3dxETcLK9hX19A_JDmsSUZk1EDyMh_JVIcjeDJASko3obeLavPLDZky_Nrl6tuht7vKhv0f_2PKxTCzJWCA7dtzNUymhszcxwRecV76lDMn6OcQ6DJblae423fJ9iDBOIHLFUDMfDoQDkRgFTAr4AagXurjipwRGu059khs4p60dHtGgkh0Rk5JuGv4pha4lUKtBP60ENFMV8MXc5na9p4rHVdRU7mQ2uetKTQN6uVInGXFhBH2oyPvxzTWcqh-xgOBdDUH5cWOEDdvvKFuNAj-URND8ypQVbnJ-mOBv3hdNil_ZQfOxf9MEWksT9ApoM9g-zAblIrh9wRavz_NlRy8AarSnxTLmlvxsNPsd_lPmLce0HZSdyGrUYgKBjWCabKPN-bA9o2FINdFSsztJrmUeTsFLJqujSB5oMjMeotmXKAkZgbwjEG-Agi5a4UMPw8Krl1dUlGxC42tVLnaucrWRnlKiqfQc4rncgUJ05cDUr8n2KY1RqfQGk-EuTiiiLA8eU_HhDSqPazpDT_yL6ZUgbswLVhd52_bK0vCXX4NsUsa3jF31Qq5vE56mnr7qrKpwzHuHxrIFiXiYtaH_dnhzasuOpCJbTZPRAebjWWf2eXpikJN4jA_J4q2smvENR82D9laATxLHzF41baHfvCPYjchNGA08P183-_YBaYGiJvnaNcnL_H7FDOT99V_gcwk1MixDy7AaRsiUG8ZuJQEEPi8J03GpSX8UTy9yDXRzXrgsuJZ5REAh5_bCu8OgI-y_RJ9bPvSKRere4VIdLj6YvVN1L68C1R-Z6HhHTQ6H4vaTLsYskGXN4N6wR-he6RYPq0EhCHRg0zNEVxRAqOxmwdUZKQ7IetqMT0geO30AwiUnCmJOIpku-lsCCGj8ECIIK198HN25mBnHcFWYyQbHGe73Z0rDjgWuiivvGC7pvsa6WjHwCtLVF8hTxal6ViGBN7-5zQ6YFZsmA5t8BloZBcohc5-jZUS62lgfyETHBmHVY8etQOm9L5dja7I18xlurZybwgUeMQQBZiwV3ynb0s_B1wQriAAdboFuglRD-dVqyobGMOk_ECePQ5LWQv6D5fqLaXzVyqLUJ_gpPQ6JAYbTywy5SIxx4JpIbqk17cBqaoYRP-RRA4DQGU_qrdh-HGqCesOL_yYqq2o7Gc-M-PWMlqYiEv8T2QbSywtWutqIkkok4Kqlo6zKn7Cgynhe0QsdXNVAlbNDzpdBTm6scKHl2PzLfuHOdwRe7BFkQAJJnMQuyrsGOMq4uEsKg0LMJm2hYOJ7PtMgFtIdXmdHQdsRkgkmHYZ5ryen-kjd7rIUtU1UjH2WPG3ROhdgMFw84uZGtt-WpsT4SrTrreC_QV_PlsOmqlHPBJg8w==";
|
|
String passphrase = "encryptallthekitties";
|
|
byte[] passphraseBytes = passphrase.getBytes(UTF_8);
|
|
|
|
byte[] decodedDrmServiceCertificate = Base64.getUrlDecoder().decode(b64DrmServiceCertificate);
|
|
byte[] decodedPrivateKey = Base64.getUrlDecoder().decode(b64PrivateKey);
|
|
|
|
java.util.Map<String, String> configValues = new java.util.HashMap<String, String>();
|
|
String providerIv = "d58ce954203b7c9a9a9d467f59839249";
|
|
String providerKey = "1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9";
|
|
|
|
// Define the configuration that is to be used for WvPLEnvironment.
|
|
configValues.put("drm_certificate_type", "dev");
|
|
configValues.put("allow_unknown_device", "1");
|
|
configValues.put("provider", "widevine_test");
|
|
configValues.put("provider_iv", providerIv);
|
|
configValues.put("provider_key", providerKey);
|
|
// Set the device certificate expiration time to 10 years (10 * 365 * 24 * 3600). Note that in
|
|
// practice, the expiration should not be 10 years long. Certificate status list should be
|
|
// updated periodically.
|
|
configValues.put("device_certificate_expiration", "315360000");
|
|
|
|
WvPLProxyEnvironment env = new WvPLProxyEnvironment(configValues);
|
|
WvPLStatus status = env.setServiceCertificate(
|
|
decodedDrmServiceCertificate, decodedPrivateKey, passphraseBytes);
|
|
if (status.getStatusCode() != WvPLStatus.StatusCode.OK) {
|
|
System.out.println("setServiceCertificate status = " + status.getStatusCode()
|
|
+ ", message = " + status.getMessage());
|
|
}
|
|
|
|
// Get Service certificate response.
|
|
try {
|
|
byte[] serviceCertificateResponse = env.generateDrmServiceCertificateResponse();
|
|
System.out.println(
|
|
"Service certificate response = " + Arrays.toString(serviceCertificateResponse));
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("getServiceCertificateResponse exception Message: "
|
|
+ e.getMessage() + ", exception status message: " + e.getStatus().getMessage());
|
|
}
|
|
String certificateStatusListFile =
|
|
"sdk/testing/sampleTestCertificateStatusList.json";
|
|
String certList = "";
|
|
try {
|
|
certList = loadCertificateStatusListFromFile(certificateStatusListFile);
|
|
} catch (FileNotFoundException e) {
|
|
System.out.println("FileNotFoundException in reading input cert list.");
|
|
} catch (IOException e) {
|
|
System.out.println("IOException in reading input cert list.");
|
|
}
|
|
try {
|
|
status = env.setDeviceCertificateStatusList(certList.getBytes(UTF_8));
|
|
} catch (WvPLStatusException e) {
|
|
status = e.getStatus();
|
|
System.out.println("setDeviceCertificateStatusList exception Message: "
|
|
+ e.getMessage() + ", exception status message: " + e.getStatus().getMessage()
|
|
+ ", numeric code = " + e.getStatus().getNumericCode());
|
|
}
|
|
assertEquals(WvPLStatus.StatusCode.OK, status.getStatusCode());
|
|
System.out.println("Successful set DeviceCertificateStatusList in WvPLProxyEnvironment.");
|
|
|
|
WvTestRunner[] runner = new WvTestRunner[numberOfRunners];
|
|
ThreadGroup group = new ThreadGroup("Test Runner");
|
|
for (int i = 0; i < runner.length; i++) {
|
|
runner[i] = new WvTestRunner(env, group, "thread_runner_" + i, numberOfLoops);
|
|
runner[i].start();
|
|
}
|
|
for (int i = 0; i < runner.length; i++) {
|
|
runner[i].join();
|
|
}
|
|
env.close();
|
|
}
|
|
}
|