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)));