From 8f7ed34c3adff12755f9f4d5c4905353c7301308 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Tue, 23 Apr 2013 15:57:10 -0700 Subject: [PATCH] Wrap Init Data in PSSH Box The Java APIs only easily expose getting the PSSH data blob, not the full PSSH box. So that apps do not have to do extra work, wrapping the PSSH data blob in a PSSH box again, we do it for them in the DrmPlugin. Includes requisite changes to the Unit tests Bug: 8584241 Merge of https://widevine-internal-review.googlesource.com/#/c/5142/ from the Widevine CDM repository. Change-Id: Ifb5910dd52380e1b591ecdf1e4273c8d9f3294cc --- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 22 +++++++++++++-- .../mediadrm/test/WVDrmPlugin_test.cpp | 28 +++++++++++++------ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 164f78c2..b5893c6b 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -8,6 +8,7 @@ #include "WVDrmPlugin.h" +#include #include #include #include @@ -129,9 +130,24 @@ status_t WVDrmPlugin::getKeyRequest( } else { return android::ERROR_DRM_CANNOT_HANDLE; } - CdmSessionId cdmSessionId(sessionId.begin(), sessionId.end()); - CdmInitData cdmInitData(initData.begin(), initData.end()); + + // Build PSSH box for PSSH data in initData. + static const char psshPrefix[] = { + 0, 0, 0, 0, // Total size + 'p', 's', 's', 'h', // "PSSH" + 0, 0, 0, 0, // Flags - must be zero + 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, // Widevine UUID + 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED, + 0, 0, 0, 0 // Size of initData + }; + CdmInitData psshBox(psshPrefix, sizeof(psshPrefix) / sizeof(uint8_t)); + psshBox.append(reinterpret_cast(initData.array()), + initData.size()); + uint32_t* psshBoxSize = reinterpret_cast(&psshBox[0]); + uint32_t* initDataSize = reinterpret_cast(&psshBox[28]); + *initDataSize = htonl(initData.size()); + *psshBoxSize = htonl(psshBox.size()); CdmAppParameterMap cdmParameters; for (size_t i = 0; i < optionalParameters.size(); ++i) { @@ -147,7 +163,7 @@ status_t WVDrmPlugin::getKeyRequest( CdmKeyMessage keyRequest; string cdmDefaultUrl; - CdmResponseType res = mCDM->GenerateKeyRequest(cdmSessionId, cdmInitData, + CdmResponseType res = mCDM->GenerateKeyRequest(cdmSessionId, psshBox, cdmLicenseType, cdmParameters, &keyRequest, &cdmDefaultUrl); diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 01eeb58d..6a21ba7d 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -166,9 +166,9 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { MockCrypto crypto; WVDrmPlugin plugin(&cdm, &crypto); - static const uint32_t kInitDataSize = 128; + static const size_t kInitDataSize = 128; uint8_t initDataRaw[kInitDataSize]; - static const uint32_t kRequestSize = 256; + static const size_t kRequestSize = 256; uint8_t requestRaw[kRequestSize]; FILE* fp = fopen("/dev/urandom", "r"); fread(initDataRaw, sizeof(uint8_t), kInitDataSize, fp); @@ -178,6 +178,20 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { Vector initData; initData.appendArray(initDataRaw, kInitDataSize); + static const uint8_t psshPrefix[] = { + 0, 0, 0, 32 + kInitDataSize, // Total size + 'p', 's', 's', 'h', // "PSSH" + 0, 0, 0, 0, // Flags - must be zero + 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, // Widevine UUID + 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED, + 0, 0, 0, kInitDataSize // Size of initData + }; + static const size_t kPsshPrefixSize = sizeof(psshPrefix); + static const size_t kPsshBoxSize = kPsshPrefixSize + kInitDataSize; + uint8_t psshBox[kPsshBoxSize]; + memcpy(psshBox, psshPrefix, kPsshPrefixSize); + memcpy(psshBox + kPsshPrefixSize, initDataRaw, kInitDataSize); + CdmKeyMessage cdmRequest(requestRaw, requestRaw + kRequestSize); KeyedVector parameters; @@ -196,8 +210,7 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { InSequence calls; EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, - ElementsAreArray(initDataRaw, - kInitDataSize), + ElementsAreArray(psshBox, kPsshBoxSize), kLicenseTypeOffline, cdmParameters, _, _)) .WillOnce(DoAll(SetArgPointee<4>(cdmRequest), @@ -205,10 +218,9 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { Return(wvcdm::KEY_MESSAGE))); EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, - ElementsAreArray(initDataRaw, - kInitDataSize), - kLicenseTypeStreaming, cdmParameters, - _, _)) + ElementsAreArray(psshBox, kPsshBoxSize), + kLicenseTypeStreaming, cdmParameters, _, + _)) .WillOnce(DoAll(SetArgPointee<4>(cdmRequest), SetArgPointee<5>(kDefaultUrl), Return(wvcdm::KEY_MESSAGE)));