198 lines
6.3 KiB
C++
198 lines
6.3 KiB
C++
/*
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "drm_hal_test@1.4"
|
|
|
|
#include "android/hardware/drm/1.4/vts/drm_hal_test.h"
|
|
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace drm {
|
|
namespace V1_4 {
|
|
namespace vts {
|
|
|
|
const char* const DrmHalTest::kVideoMp4 = "video/mp4";
|
|
const char* const DrmHalTest::kAudioMp4 = "audio/mp4";
|
|
const uint32_t DrmHalTest::kSecLevelDefault = DrmHalTest::kSecLevelMax + 1;
|
|
|
|
sp<drm::V1_4::IDrmPlugin> DrmHalTest::DrmPluginV1_4() const {
|
|
sp<drm::V1_4::IDrmPlugin> plugin(drm::V1_4::IDrmPlugin::castFrom(drmPlugin));
|
|
EXPECT_NE(nullptr, plugin.get());
|
|
return plugin;
|
|
}
|
|
|
|
sp<V1_0::ICryptoPlugin> DrmHalTest::CryptoPlugin(const SessionId& sid) {
|
|
sp<V1_0::ICryptoPlugin> crypto;
|
|
auto res = cryptoFactory->createPlugin(
|
|
getUUID(), sid,
|
|
[&](V1_0::Status status, const sp<V1_0::ICryptoPlugin>& plugin) {
|
|
EXPECT_EQ(V1_0::Status::OK, status);
|
|
EXPECT_NE(nullptr, plugin.get());
|
|
crypto = plugin;
|
|
});
|
|
EXPECT_OK(res);
|
|
return crypto;
|
|
}
|
|
|
|
SessionId DrmHalTest::OpenSession(uint32_t level = kSecLevelDefault) {
|
|
V1_0::Status err;
|
|
SessionId sessionId;
|
|
bool attemptedProvision = false;
|
|
|
|
V1_0::IDrmPlugin::openSession_cb cb = [&](
|
|
V1_0::Status status,
|
|
const hidl_vec<unsigned char> &id) {
|
|
err = status;
|
|
sessionId = id;
|
|
};
|
|
|
|
while (true) {
|
|
Return<void> res;
|
|
if (level > kSecLevelMax) {
|
|
res = drmPlugin->openSession(cb);
|
|
} else if (level >= kSecLevelMin) {
|
|
auto securityLevel = static_cast<SecurityLevel>(level);
|
|
res = drmPlugin->openSession_1_1(securityLevel, cb);
|
|
}
|
|
EXPECT_OK(res);
|
|
if (V1_0::Status::ERROR_DRM_NOT_PROVISIONED == err
|
|
&& !attemptedProvision) {
|
|
// provision once if necessary
|
|
provision();
|
|
attemptedProvision = true;
|
|
continue;
|
|
} else if (V1_0::Status::ERROR_DRM_CANNOT_HANDLE == err) {
|
|
// must be able to handle default level
|
|
EXPECT_NE(kSecLevelDefault, level);
|
|
sessionId = {};
|
|
} else {
|
|
EXPECT_EQ(V1_0::Status::OK, err);
|
|
EXPECT_NE(sessionId.size(), 0u);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return sessionId;
|
|
}
|
|
|
|
TEST_P(DrmHalTest, RequiresSecureDecoder) {
|
|
for (uint32_t level : {kSecLevelMin, kSecLevelMax, kSecLevelDefault}) {
|
|
for (auto mime : {kVideoMp4, kAudioMp4}) {
|
|
auto sid = OpenSession(level);
|
|
if (sid.size() == 0u) {
|
|
continue;
|
|
}
|
|
auto drm = DrmPluginV1_4();
|
|
sp<V1_0::ICryptoPlugin> crypto(CryptoPlugin(sid));
|
|
if (drm == nullptr || crypto == nullptr) {
|
|
continue;
|
|
}
|
|
bool r1 = crypto->requiresSecureDecoderComponent(mime);
|
|
bool r2;
|
|
if (level == kSecLevelDefault) {
|
|
r2 = drm->requiresSecureDecoderDefault(mime);
|
|
} else {
|
|
auto sL = static_cast<SecurityLevel>(level);
|
|
r2 = drm->requiresSecureDecoder(mime, sL);
|
|
}
|
|
EXPECT_EQ(r1, r2);
|
|
closeSession(sid);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_P(DrmHalTest, SetPlaybackId) {
|
|
auto testInfo = ::testing::UnitTest::GetInstance()->current_test_info();
|
|
auto testName = testInfo->name();
|
|
const hidl_string& pbId{testName};
|
|
auto sid = OpenSession();
|
|
auto drm = DrmPluginV1_4();
|
|
if (drm == nullptr) {
|
|
return;
|
|
}
|
|
V1_0::Status err = drm->setPlaybackId(sid, pbId);
|
|
EXPECT_EQ(V1_0::Status::OK, err);
|
|
closeSession(sid);
|
|
|
|
// search for playback id among metric attributes/values
|
|
bool foundPbId = false;
|
|
auto res = drmPlugin->getMetrics([&](
|
|
V1_0::Status status,
|
|
hidl_vec<V1_1::DrmMetricGroup> metricGroups) {
|
|
EXPECT_EQ(V1_0::Status::OK, status);
|
|
for (const auto& group : metricGroups) {
|
|
for (const auto& metric : group.metrics) {
|
|
for (const auto& value : metric.values) {
|
|
if (value.stringValue == pbId) {
|
|
foundPbId = true;
|
|
break;
|
|
}
|
|
}
|
|
for (const auto& attr : metric.attributes) {
|
|
if (attr.stringValue == pbId) {
|
|
foundPbId = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
EXPECT_OK(res);
|
|
EXPECT_TRUE(foundPbId);
|
|
}
|
|
|
|
TEST_P(DrmHalTest, GetLogMessages) {
|
|
auto drm = DrmPluginV1_4();
|
|
auto sid = OpenSession();
|
|
auto crypto_1_0 = CryptoPlugin(sid);
|
|
sp<V1_4::ICryptoPlugin> crypto(V1_4::ICryptoPlugin::castFrom(crypto_1_0));
|
|
|
|
hidl_vec<uint8_t> initData;
|
|
hidl_string mime{"text/plain"};
|
|
V1_0::KeyedVector optionalParameters;
|
|
auto res = drmPlugin->getKeyRequest_1_2(
|
|
sid, initData, mime, V1_0::KeyType::STREAMING,
|
|
optionalParameters, [&](V1_2::Status status, const hidl_vec<uint8_t>&,
|
|
V1_1::KeyRequestType, const hidl_string&) {
|
|
EXPECT_NE(V1_2::Status::OK, status);
|
|
});
|
|
EXPECT_OK(res);
|
|
|
|
V1_4::IDrmPlugin::getLogMessages_cb cb = [&](
|
|
V1_4::Status status,
|
|
hidl_vec<V1_4::LogMessage> logs) {
|
|
EXPECT_EQ(V1_4::Status::OK, status);
|
|
EXPECT_NE(0, logs.size());
|
|
for (auto log: logs) {
|
|
ALOGI("priority=[%u] message='%s'", log.priority, log.message.c_str());
|
|
}
|
|
};
|
|
|
|
auto res2 = drm->getLogMessages(cb);
|
|
EXPECT_OK(res2);
|
|
|
|
auto res3 = crypto->getLogMessages(cb);
|
|
EXPECT_OK(res3);
|
|
|
|
closeSession(sid);
|
|
}
|
|
|
|
} // namespace vts
|
|
} // namespace V1_4
|
|
} // namespace drm
|
|
} // namespace hardware
|
|
} // namespace android
|