Merges to android Pi release (part: 1)
Below are a set of CLs being merged from the wv cdm repo to the android repo. * Fix handling of OEM Cert public key. Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/27921 ] This is a potential fix for b/36656190. Set aside public key on first call to get the public key, and use it afterwards. This gets rid of extra calls to OEMCrypto_GetOEMPublicCertificate(), which has side-effect of staging the OEM private key. This also fixes a problem where the public cert string was not being trimmed to match the size returned by OEMCrypto_GetOEMPublicCertificate(). * Complete provisioning request/response for Provisioning 3.0 Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27780 ] Fix bug on provisioning request path where GenerateDerivedKeys() was being called when preparing to generate the signature. Add message signature verification, and call correct OEMCrypto routine to rewrap the private key (OEMCrypto_RewrapDeviceRSAKey30). * Implement Cdm::deleteAllUsageRecords() Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27780 ] Delete all usage records for current origin. Removes usage records from file system and retains the PSTs. The deletes any usage entries matching those PSTs held by OEMCrypto. BUG: 35319024 * Remove stringencoders library from third_party. Author: Jacob Trimble <modmaker@google.com> [ Merge of http://go/wvgerrit/27585 ] We have a fork of the stringencoders library that we use for base64 encoding. This reimplements base64 encoding to remove the extra dependency and to reduce the amount of code. * Add Cdm::deleteUsageRecord() based on key_set_id. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27605 ] Delete specified usage record from file system usage info and from OEMCrypto. BUG: 35319024 * Modifiable OEMCrypto Author: Fred Gylys-Colwell <fredgc@google.com> [ Merge of http://go/wvgerrit/24729 ] This CL adds a new variant of the OEMCrypto mock code that adjusts its behavior based on a configuration file. This is intended for testing. For example, a tester can set current_hdcp to 2 in the options.txt file, push it to the device, and verify that a license is granted for HDCP 2.0. Then the tester can edit the value of current_hdcp to 1 and push the file to the device. Playback should stop because the license is no longer valid. This variant uses a real level 1 liboemcrypto.so to push data to a secure buffer. That means we can test playback for a license that requires secure buffers on an Android device with real secure buffers. BUG: 35141278 BUG: 37353534 BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I58443c510919e992bb455192e70373490a00e2b6
This commit is contained in:
@@ -22,7 +22,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
libcdm_protos \
|
||||
libcdm_utils \
|
||||
libcrypto \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libgmock \
|
||||
libgmock_main \
|
||||
@@ -45,10 +45,8 @@ LOCAL_MODULE := libwvdrmdrmplugin_test
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_MODULE_OWNER := widevine
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
# When built, explicitly put it in the DATA/bin directory.
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
|
||||
LOCAL_MODULE_TARGET_ARCH := arm x86 mips
|
||||
@@ -80,7 +78,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
libcdm_protos \
|
||||
libcdm_utils \
|
||||
libcrypto \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libgmock \
|
||||
libgmock_main \
|
||||
@@ -88,15 +86,19 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libwvlevel3 \
|
||||
libwvdrmdrmplugin_hidl \
|
||||
|
||||
# When the GNU linker sees a library, it discards all symbols that it doesn't
|
||||
# need. libhidl_utils must come after libwvdrmdrmplugin.
|
||||
LOCAL_STATIC_LIBRARIES += libhidl_utils
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
android.hardware.drm@1.0 \
|
||||
android.hidl.base@1.0 \
|
||||
android.hidl.memory@1.0 \
|
||||
libbinder \
|
||||
libcutils \
|
||||
libdl \
|
||||
libhidlbase \
|
||||
libhidlmemory \
|
||||
libhidltransport \
|
||||
liblog \
|
||||
libprotobuf-cpp-lite \
|
||||
libutils \
|
||||
@@ -109,10 +111,8 @@ LOCAL_MODULE := libwvdrmdrmplugin_hidl_test
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_MODULE_OWNER := widevine
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
# When built, explicitly put it in the DATA/bin directory.
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
|
||||
LOCAL_MODULE_TARGET_ARCH := arm x86 mips
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "cdm_client_property_set.h"
|
||||
#include "gmock/gmock.h"
|
||||
@@ -94,7 +93,6 @@ using wvcdm::KEY_ID_SIZE;
|
||||
using wvcdm::KEY_IV_SIZE;
|
||||
using wvcdm::KEY_SET_ID_PREFIX;
|
||||
using wvcdm::NEVER_EXPIRES;
|
||||
using wvcdm::QUERY_KEY_CURRENT_SRM_VERSION;
|
||||
using wvcdm::QUERY_KEY_DEVICE_ID;
|
||||
using wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS;
|
||||
using wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS;
|
||||
@@ -102,9 +100,7 @@ using wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION;
|
||||
using wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID;
|
||||
using wvcdm::QUERY_KEY_PROVISIONING_ID;
|
||||
using wvcdm::QUERY_KEY_SECURITY_LEVEL;
|
||||
using wvcdm::QUERY_KEY_SRM_UPDATE_SUPPORT;
|
||||
using wvcdm::QUERY_KEY_SYSTEM_ID;
|
||||
using wvcdm::QUERY_KEY_WVCDM_VERSION;
|
||||
using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1;
|
||||
using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3;
|
||||
using wvcdm::SecurityLevel;
|
||||
@@ -118,20 +114,7 @@ const std::string kAppId("com.unittest.mock.app.id");
|
||||
const uint8_t* const kUnprovisionResponse =
|
||||
reinterpret_cast<const uint8_t*>("unprovision");
|
||||
const size_t kUnprovisionResponseSize = 11;
|
||||
const std::string kDeviceId("0123456789\0ABCDEF", 17);
|
||||
|
||||
// This is a serialized MetricsGroup message containing a small amount of
|
||||
// sample data. This ensures we're able to extract it via a property.
|
||||
const char kSerializedMetrics[] = {
|
||||
0x0a, 0x0a, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x02, 0x08, 0x00,
|
||||
0x0a, 0x12, 0x0a, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x12, 0x09, 0x11,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x15, 0x0a, 0x05,
|
||||
0x74, 0x65, 0x73, 0x74, 0x33, 0x12, 0x0c, 0x1a, 0x0a, 0x74, 0x65, 0x73,
|
||||
0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65
|
||||
};
|
||||
|
||||
#define N_ELEM(a) (sizeof(a)/sizeof(a[0]))
|
||||
} // anonymous namespace
|
||||
}
|
||||
|
||||
class MockCDM : public WvContentDecryptionModule {
|
||||
public:
|
||||
@@ -181,24 +164,19 @@ class MockCDM : public WvContentDecryptionModule {
|
||||
MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel,
|
||||
const CdmIdentifier&));
|
||||
|
||||
MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD3(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmIdentifier&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD4(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmSecureStopId&,
|
||||
const CdmIdentifier&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmIdentifier&));
|
||||
MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&));
|
||||
|
||||
MOCK_METHOD2(ReleaseUsageInfo,
|
||||
CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&));
|
||||
MOCK_METHOD1(ReleaseUsageInfo,
|
||||
CdmResponseType(const CdmUsageInfoReleaseMessage&));
|
||||
|
||||
MOCK_METHOD1(IsValidServiceCertificate, bool(const std::string&));
|
||||
|
||||
MOCK_METHOD1(GetSerializedMetrics, void(std::string*));
|
||||
};
|
||||
|
||||
class MockCrypto : public WVGenericCryptoInterface {
|
||||
@@ -341,7 +319,7 @@ TEST_F(WVDrmPluginTest, ClosesSessions) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, ClosesSessionWithError) {
|
||||
TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) {
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
@@ -351,7 +329,7 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithError) {
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
Status status = plugin.closeSession(toHidlVec(sessionId));
|
||||
ASSERT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
}
|
||||
|
||||
// TODO b/35325611 Fix this disabled test
|
||||
@@ -438,7 +416,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesKeyRequests) {
|
||||
{kIsoBmffMimeType, initData, cdmPsshBox}, // ISO-BMFF, old passing style
|
||||
{kWebmMimeType, initData, cdmInitData} // WebM
|
||||
};
|
||||
size_t testSetCount = N_ELEM(testSets);
|
||||
size_t testSetCount = sizeof(testSets) / sizeof(TestSet);
|
||||
|
||||
// Set up the expected calls. Per gMock rules, this must be done for all test
|
||||
// sets prior to testing any of them.
|
||||
@@ -813,8 +791,8 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) {
|
||||
.Times(1);
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
Status res = plugin.unprovisionDevice();
|
||||
ASSERT_EQ(Status::OK, res);
|
||||
status_t res = plugin.unprovisionDevice();
|
||||
ASSERT_EQ(android::OK, res);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) {
|
||||
@@ -834,12 +812,12 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) {
|
||||
.WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR));
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
Status res = plugin.unprovisionDevice();
|
||||
ASSERT_NE(Status::OK, res);
|
||||
status_t res = plugin.unprovisionDevice();
|
||||
ASSERT_NE(android::OK, res);
|
||||
res = plugin.unprovisionDevice();
|
||||
ASSERT_NE(Status::OK, res);
|
||||
ASSERT_NE(android::OK, res);
|
||||
res = plugin.unprovisionDevice();
|
||||
ASSERT_NE(Status::OK, res);
|
||||
ASSERT_NE(android::OK, res);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
|
||||
@@ -847,6 +825,8 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
|
||||
std::vector<uint8_t> cert;
|
||||
std::vector<uint8_t> key;
|
||||
std::vector<uint8_t> specialResponse;
|
||||
specialResponse.assign(
|
||||
kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize);
|
||||
@@ -870,38 +850,16 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, UnprovisionsGloballyWithSpoid) {
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
|
||||
std::vector<uint8_t> specialResponse;
|
||||
specialResponse.assign(
|
||||
kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize);
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<2>(kDeviceId),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(EMPTY_ORIGIN)))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN)))
|
||||
.Times(1);
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, true);
|
||||
plugin.provideProvisionResponse(
|
||||
toHidlVec(specialResponse),
|
||||
[&](Status status, hidl_vec<uint8_t> /* cert */,
|
||||
hidl_vec<uint8_t> /* key */) {
|
||||
EXPECT_EQ(Status::OK, status);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOriginOrSpoid) {
|
||||
TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOrigin) {
|
||||
// This test is only valid on SPOID-free devices. SPOID devices can
|
||||
// unprovision without an origin because the empty-origin provisioning is
|
||||
// not global.
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
|
||||
std::vector<uint8_t> cert;
|
||||
std::vector<uint8_t> key;
|
||||
std::vector<uint8_t> specialResponse;
|
||||
specialResponse.assign(
|
||||
kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize);
|
||||
@@ -923,6 +881,8 @@ TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) {
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
|
||||
std::vector<uint8_t> cert;
|
||||
std::vector<uint8_t> key;
|
||||
std::vector<uint8_t> specialResponse;
|
||||
specialResponse.assign(
|
||||
kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize);
|
||||
@@ -986,8 +946,8 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) {
|
||||
}
|
||||
|
||||
const char* app_id = "my_app_id";
|
||||
EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmStops),
|
||||
EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(cdmStops),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
std::list<std::vector<uint8_t> > stops;
|
||||
@@ -1027,7 +987,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) {
|
||||
StrictMock<MockCrypto> crypto;
|
||||
std::string appPackageName;
|
||||
|
||||
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _))
|
||||
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq("")))
|
||||
.Times(1);
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
@@ -1055,8 +1015,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStop) {
|
||||
message.assign(messageRaw, messageRaw + kMessageSize);
|
||||
|
||||
EXPECT_CALL(*cdm, ReleaseUsageInfo(ElementsAreArray(messageRaw,
|
||||
kMessageSize),
|
||||
_))
|
||||
kMessageSize)))
|
||||
.Times(1);
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
@@ -1075,15 +1034,12 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
CdmQueryMap l3Map;
|
||||
l3Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3;
|
||||
|
||||
static const std::string deviceId("0123456789\0ABCDEF", 17);
|
||||
static const std::string systemId = "The Universe";
|
||||
static const std::string provisioningId("Life\0&Everything", 16);
|
||||
static const std::string openSessions = "42";
|
||||
static const std::string maxSessions = "54";
|
||||
static const std::string oemCryptoApiVersion = "13";
|
||||
static const std::string currentSRMVersion = "1";
|
||||
static const std::string cdmVersion = "Infinity Minus 1";
|
||||
std::string serializedMetrics(
|
||||
kSerializedMetrics, kSerializedMetrics + sizeof(kSerializedMetrics));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),
|
||||
@@ -1092,7 +1048,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(kDeviceId),
|
||||
.WillOnce(DoAll(SetArgPointee<2>(deviceId),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SYSTEM_ID, _))
|
||||
@@ -1115,21 +1071,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
.WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>("True"),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, GetSerializedMetrics(_))
|
||||
.WillOnce(SetArgPointee<0>(serializedMetrics));
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
std::string stringResult;
|
||||
std::vector<uint8_t> vectorResult;
|
||||
@@ -1143,7 +1084,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
plugin.getPropertyString(
|
||||
hidl_string("version"), [&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(cdmVersion.c_str(), stringResult.c_str());
|
||||
EXPECT_STREQ("1.0", stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
@@ -1160,36 +1101,36 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("securityLevel"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(QUERY_VALUE_SECURITY_LEVEL_L1.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("securityLevel"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(QUERY_VALUE_SECURITY_LEVEL_L3.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyByteArray(
|
||||
hidl_string("deviceUniqueId"),
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
std::vector<uint8_t> id(vectorResult);
|
||||
EXPECT_THAT(id, ElementsAreArray(kDeviceId.data(), kDeviceId.size()));
|
||||
EXPECT_THAT(id, ElementsAreArray(deviceId.data(), deviceId.size()));
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("systemId"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(systemId.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyByteArray(
|
||||
hidl_string("provisioningUniqueId"),
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
std::vector<uint8_t> id(vectorResult);
|
||||
EXPECT_THAT(id, ElementsAreArray(provisioningId.data(),
|
||||
@@ -1198,46 +1139,23 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("numberOfOpenSessions"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_EQ(openSessions, stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("maxNumberOfSessions"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_EQ(maxSessions, stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("oemCryptoApiVersion"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("SRMUpdateSupport"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ("True", stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("CurrentSRMVersion"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyByteArray(
|
||||
hidl_string("metrics"),
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
std::vector<uint8_t> id(vectorResult);
|
||||
EXPECT_THAT(id, ElementsAreArray(serializedMetrics.data(),
|
||||
serializedMetrics.size()));
|
||||
EXPECT_EQ(oemCryptoApiVersion, stringResult.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1289,117 +1207,6 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) {
|
||||
ASSERT_NE(Status::OK, status);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, CompliesWithSpoidVariability) {
|
||||
StrictMock<MockCrypto> crypto;
|
||||
|
||||
const std::string kDeviceIds[] = {
|
||||
kDeviceId,
|
||||
kDeviceId + " the Second",
|
||||
};
|
||||
const size_t kDeviceCount = N_ELEM(kDeviceIds);
|
||||
|
||||
const std::string kAppNames[] = {
|
||||
std::string("com.google.widevine"),
|
||||
std::string("com.youtube"),
|
||||
};
|
||||
const size_t kAppCount = N_ELEM(kAppNames);
|
||||
|
||||
const std::string kOrigins[] = {
|
||||
kOrigin,
|
||||
kOrigin + " but not that one, the other one.",
|
||||
std::string(/* Intentionally Empty */),
|
||||
};
|
||||
const size_t kOriginCount = N_ELEM(kOrigins);
|
||||
|
||||
const size_t kPluginCount = 2;
|
||||
|
||||
const size_t kPluginsPerCdm = kAppCount * kOriginCount * kPluginCount;
|
||||
|
||||
// We will get kPluginCount SPOIDs for every app package name + device id +
|
||||
// origin combination.
|
||||
std::vector<uint8_t>
|
||||
spoids[kDeviceCount][kAppCount][kOriginCount][kPluginCount];
|
||||
|
||||
for (size_t deviceIndex = 0; deviceIndex < kDeviceCount; ++deviceIndex) {
|
||||
const std::string& deviceId = kDeviceIds[deviceIndex];
|
||||
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _))
|
||||
.Times(AtLeast(kPluginsPerCdm))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<2>(deviceId),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
for (size_t appIndex = 0; appIndex < kAppCount; ++appIndex) {
|
||||
const std::string& appPackageName = kAppNames[appIndex];
|
||||
|
||||
for (size_t originIndex = 0; originIndex < kOriginCount; ++originIndex) {
|
||||
const std::string& origin = kOrigins[originIndex];
|
||||
|
||||
for (size_t pluginIndex = 0;
|
||||
pluginIndex < kPluginCount;
|
||||
++pluginIndex) {
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, true);
|
||||
|
||||
if (!origin.empty()) {
|
||||
ASSERT_EQ(Status::OK,
|
||||
plugin.setPropertyString(hidl_string("origin"),
|
||||
hidl_string(origin)));
|
||||
}
|
||||
|
||||
plugin.getPropertyByteArray(
|
||||
hidl_string("deviceUniqueId"),
|
||||
[&](Status status, hidl_vec<uint8_t> vectorResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
spoids[deviceIndex][appIndex][originIndex][pluginIndex] =
|
||||
vectorResult;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This nest of loops makes sure all the SPOIDs we retrieved above are
|
||||
// identical if their parameters were identical and dissimilar otherwise.
|
||||
for (size_t deviceIndex = 0; deviceIndex < kDeviceCount; ++deviceIndex) {
|
||||
for (size_t appIndex = 0; appIndex < kAppCount; ++appIndex) {
|
||||
for (size_t originIndex = 0; originIndex < kOriginCount; ++originIndex) {
|
||||
for (size_t pluginIndex = 0;
|
||||
pluginIndex < kPluginCount;
|
||||
++pluginIndex) {
|
||||
const std::vector<uint8_t>& firstSpoid =
|
||||
spoids[deviceIndex][appIndex][originIndex][pluginIndex];
|
||||
|
||||
for (size_t deviceIndex2 = 0;
|
||||
deviceIndex2 < kDeviceCount;
|
||||
++deviceIndex2) {
|
||||
for (size_t appIndex2 = 0; appIndex2 < kAppCount; ++appIndex2) {
|
||||
for (size_t originIndex2 = 0;
|
||||
originIndex2 < kOriginCount;
|
||||
++originIndex2) {
|
||||
for (size_t pluginIndex2 = 0;
|
||||
pluginIndex2 < kPluginCount;
|
||||
++pluginIndex2) {
|
||||
const std::vector<uint8_t>& secondSpoid =
|
||||
spoids[deviceIndex2][appIndex2][originIndex2][pluginIndex2];
|
||||
|
||||
if (deviceIndex == deviceIndex2 &&
|
||||
appIndex == appIndex2 &&
|
||||
originIndex == originIndex2) {
|
||||
EXPECT_EQ(firstSpoid, secondSpoid);
|
||||
} else {
|
||||
EXPECT_NE(firstSpoid, secondSpoid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) {
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
StrictMock<MockCrypto> crypto;
|
||||
@@ -2364,7 +2171,7 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) {
|
||||
}
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
Status res;
|
||||
status_t res;
|
||||
|
||||
// Test turning on session sharing
|
||||
Status status = plugin.setPropertyString(hidl_string("sessionSharing"),
|
||||
|
||||
@@ -32,16 +32,7 @@ const String8 kAppId("com.unittest.mock.app.id");
|
||||
const uint8_t* const kUnprovisionResponse =
|
||||
reinterpret_cast<const uint8_t*>("unprovision");
|
||||
const size_t kUnprovisionResponseSize = 11;
|
||||
|
||||
// This is a serialized MetricsGroup message containing a small amount of
|
||||
// sample data. This ensures we're able to extract it via a property.
|
||||
const char kSerializedMetrics[] = {
|
||||
0x0a, 0x0a, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x02, 0x08, 0x00,
|
||||
0x0a, 0x12, 0x0a, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x12, 0x09, 0x11,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x15, 0x0a, 0x05,
|
||||
0x74, 0x65, 0x73, 0x74, 0x33, 0x12, 0x0c, 0x1a, 0x0a, 0x74, 0x65, 0x73,
|
||||
0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65};
|
||||
} // anonymous namespace
|
||||
}
|
||||
|
||||
class MockCDM : public WvContentDecryptionModule {
|
||||
public:
|
||||
@@ -91,24 +82,19 @@ class MockCDM : public WvContentDecryptionModule {
|
||||
MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel,
|
||||
const CdmIdentifier&));
|
||||
|
||||
MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD3(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmIdentifier&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD4(GetUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmSecureStopId&,
|
||||
const CdmIdentifier&,
|
||||
CdmUsageInfo*));
|
||||
|
||||
MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&,
|
||||
const CdmIdentifier&));
|
||||
MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&));
|
||||
|
||||
MOCK_METHOD2(ReleaseUsageInfo,
|
||||
CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&));
|
||||
MOCK_METHOD1(ReleaseUsageInfo,
|
||||
CdmResponseType(const CdmUsageInfoReleaseMessage&));
|
||||
|
||||
MOCK_METHOD1(IsValidServiceCertificate, bool(const std::string&));
|
||||
|
||||
MOCK_METHOD1(GetSerializedMetrics, void(std::string*));
|
||||
};
|
||||
|
||||
class MockCrypto : public WVGenericCryptoInterface {
|
||||
@@ -241,7 +227,7 @@ TEST_F(WVDrmPluginTest, ClosesSessions) {
|
||||
ASSERT_EQ(OK, res);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, ClosesSessionWithError) {
|
||||
TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) {
|
||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||
StrictMock<MockCrypto> crypto;
|
||||
WVDrmPlugin plugin(cdm.get(), &crypto);
|
||||
@@ -251,7 +237,7 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithError) {
|
||||
|
||||
status_t res = plugin.closeSession(sessionId);
|
||||
|
||||
ASSERT_EQ(ERROR_DRM_SESSION_NOT_OPENED, res);
|
||||
ASSERT_EQ(OK, res);
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, GeneratesKeyRequests) {
|
||||
@@ -769,8 +755,8 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) {
|
||||
cdmStops.push_back(string(stopsRaw[i], stopsRaw[i] + kStopSize));
|
||||
}
|
||||
|
||||
EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmStops),
|
||||
EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(cdmStops),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
List<Vector<uint8_t> > stops;
|
||||
@@ -800,7 +786,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) {
|
||||
status_t res = plugin.setPropertyString(String8("appId"), String8(""));
|
||||
ASSERT_EQ(OK, res);
|
||||
|
||||
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _))
|
||||
EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq("")))
|
||||
.Times(1);
|
||||
|
||||
res = plugin.releaseAllSecureStops();
|
||||
@@ -822,8 +808,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStops) {
|
||||
message.appendArray(messageRaw, kMessageSize);
|
||||
|
||||
EXPECT_CALL(*cdm, ReleaseUsageInfo(ElementsAreArray(messageRaw,
|
||||
kMessageSize),
|
||||
_))
|
||||
kMessageSize)))
|
||||
.Times(1);
|
||||
|
||||
status_t res = plugin.releaseSecureStops(message);
|
||||
@@ -848,10 +833,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
static const string openSessions = "15";
|
||||
static const string maxSessions = "18";
|
||||
static const string oemCryptoApiVersion = "10";
|
||||
static const string currentSRMVersion = "1";
|
||||
static const string cdmVersion = "Infinity Minus 1";
|
||||
string serializedMetrics(kSerializedMetrics,
|
||||
kSerializedMetrics + sizeof(kSerializedMetrics));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),
|
||||
@@ -883,21 +864,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
.WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>("True"),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmVersion),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, GetSerializedMetrics(_))
|
||||
.WillOnce(SetArgPointee<0>(serializedMetrics));
|
||||
|
||||
String8 stringResult;
|
||||
Vector<uint8_t> vectorResult;
|
||||
|
||||
@@ -907,7 +873,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
res = plugin.getPropertyString(String8("version"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ(cdmVersion.c_str(), stringResult.string());
|
||||
EXPECT_STREQ("1.0", stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("description"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
@@ -948,21 +914,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
res = plugin.getPropertyString(String8("oemCryptoApiVersion"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("SRMUpdateSupport"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ("True", stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("CurrentSRMVersion"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.string());
|
||||
|
||||
vectorResult.clear();
|
||||
res = plugin.getPropertyByteArray(String8("metrics"), vectorResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_THAT(vectorResult, ElementsAreArray(serializedMetrics.data(),
|
||||
serializedMetrics.size()));
|
||||
EXPECT_EQ(oemCryptoApiVersion, stringResult.string());
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) {
|
||||
|
||||
Reference in New Issue
Block a user