Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 295e27ee authored by Robert Shih's avatar Robert Shih Committed by Android (Google) Code Review
Browse files

Merge "Add vts tests for new drm@1.2 methods"

parents c29e7400 456f3a64
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2019 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.
//

cc_test {
    name: "VtsHalDrmV1_2TargetTest",
    defaults: ["VtsHalTargetTestDefaults"],
    srcs: [
        "drm_hal_clearkey_module.cpp",
        "drm_hal_common.cpp",
        "drm_hal_test.cpp",
        "vendor_modules.cpp",
    ],
    include_dirs: ["hardware/interfaces/drm/1.0/vts/functional"],
    static_libs: [
        "android.hardware.drm@1.0",
        "android.hardware.drm@1.1",
        "android.hardware.drm@1.2",
        "android.hardware.drm@1.0-helper",
        "android.hidl.allocator@1.0",
        "android.hidl.memory@1.0",
        "libhidlmemory",
        "libnativehelper",
        "libssl",
        "libcrypto",
    ],
    test_suites: ["general-tests"],
}
+130 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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_clearkey_module@1.2"

#include <gtest/gtest.h>
#include "drm_hal_clearkey_module.h"

namespace android {
namespace hardware {
namespace drm {
namespace V1_2 {
namespace vts {

std::vector<uint8_t> DrmHalVTSClearkeyModule::handleProvisioningRequest(
        const std::vector<uint8_t>& /*provisioningRequest*/,
        const std::string& /*url*/) {
    EXPECT_TRUE(false) << "Clearkey doesn't support provisioning";
    return {};
}

std::vector<DrmHalVTSClearkeyModule::ContentConfiguration>
        DrmHalVTSClearkeyModule::getContentConfigurations() const {
    DrmHalVTSClearkeyModule::ContentConfiguration conf = {
        .name = "DrmHalVTSClearkeyModule", // name
        .serverUrl = "", // serverUrl
        .initData = { // initData
            // BMFF box header (4 bytes size + 'pssh')
            0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
            // full box header (version = 1 flags = 0)
            0x01, 0x00, 0x00, 0x00,
            // system id
            0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c,
            0x1e, 0x52, 0xe2, 0xfb, 0x4b,
            // number of key ids
            0x00, 0x00, 0x00, 0x01,
            // key id
            0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47, 0x7e, 0x87, 0x7e, 0x57, 0xd0,
            0x0d, 0x1e, 0xd0, 0x0d, 0x1e,
            // size of data, must be zero
            0x00, 0x00, 0x00, 0x00
        },
        .mimeType = "video/mp4", // mimeType
        .optionalParameters = {}, // optionalParameters
        .policy = { .allowOffline = true }, // allowOffline
        .keys = { // keys
            {
                .isSecure = false, // isSecure
                .keyId = { // keyId
                    0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47, 0x7e, 0x87,
                    0x7e, 0x57, 0xd0, 0x0d, 0x1e, 0xd0, 0x0d, 0x1e
                },
                .clearContentKey = { // clearContentKey
                    0x1a, 0x8a, 0x20, 0x95, 0xe4, 0xde, 0xb2, 0xd2,
                    0x9e, 0xc8, 0x16, 0xac, 0x7b, 0xae, 0x20, 0x82
                }
            }
        }
    };
    return { conf };
}

std::vector<uint8_t> DrmHalVTSClearkeyModule::handleKeyRequest(
        const std::vector<uint8_t>& keyRequest,
        const std::string& /*serverUrl*/) {

    // {"kids":["YAYeAX5Hfod-V9ANHtANHg"],"type":"temporary"}
    std::vector<uint8_t> expectedKeyRequest = {
        0x7b, 0x22, 0x6b, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x59, 0x41, 0x59, 0x65,
        0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e, 0x48, 0x74,
        0x41, 0x4e, 0x48, 0x67, 0x22, 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a,
        0x22, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x22, 0x7d};

    // {"kids":["YAYeAX5Hfod-V9ANHtANHg"],"type":"persistent-license"}
    std::vector<uint8_t> expectedKeyRequestPersistent = {
        0x7b, 0x22, 0x6b, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x59, 0x41, 0x59, 0x65,
        0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e, 0x48, 0x74,
        0x41, 0x4e, 0x48, 0x67, 0x22, 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a,
        0x22, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x69,
        0x63, 0x65, 0x6e, 0x73, 0x65, 0x22, 0x7d};

    // {"keys":[{"kty":"oct","kid":"YAYeAX5Hfod-V9ANHtANHg","k":"GoogleTestKeyBase64ggg"}]}
    std::vector<uint8_t> knownKeyResponse = {
        0x7b, 0x22, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x6b, 0x74, 0x79, 0x22,
        0x3a, 0x22, 0x6f, 0x63, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x59,
        0x41, 0x59, 0x65, 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e,
        0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22, 0x2c, 0x22, 0x6b, 0x22, 0x3a, 0x22, 0x47, 0x6f,
        0x6f, 0x67, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x61, 0x73, 0x65,
        0x36, 0x34, 0x67, 0x67, 0x67, 0x22, 0x7d, 0x5d, 0x7d};

    // {"keys":[{"kty":"oct","kid":"YAYeAX5Hfod-V9ANHtANHg","k":"GoogleTestKeyBase64ggg"}],"type":"persistent-license"}
    std::vector<uint8_t> knownKeyResponsePersistent = {
        0x7b, 0x22, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x6b, 0x74, 0x79, 0x22,
        0x3a, 0x22, 0x6f, 0x63, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x59,
        0x41, 0x59, 0x65, 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e,
        0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22, 0x2c, 0x22, 0x6b, 0x22, 0x3a, 0x22, 0x47, 0x6f,
        0x6f, 0x67, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x61, 0x73, 0x65,
        0x36, 0x34, 0x67, 0x67, 0x67, 0x22, 0x7d, 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22,
        0x3a, 0x22, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x69,
        0x63, 0x65, 0x6e, 0x73, 0x65, 0x22, 0x7d};

    std::string req(keyRequest.begin(), keyRequest.end());
    if (req.find("persistent-license") != std::string::npos) {
        EXPECT_EQ(expectedKeyRequestPersistent, keyRequest);
        return knownKeyResponsePersistent;
    } else {
        EXPECT_EQ(expectedKeyRequest, keyRequest);
        return knownKeyResponse;
    }

}

}  // namespace vts
}  // namespace V1_2
}  // namespace drm
}  // namespace hardware
}  // namespace android
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

#ifndef DRM_HAL_CLEARKEY_MODULE_H
#define DRM_HAL_CLEARKEY_MODULE_H

#include "drm_hal_vendor_module_api.h"

namespace android {
namespace hardware {
namespace drm {
namespace V1_2 {
namespace vts {

class DrmHalVTSClearkeyModule : public DrmHalVTSVendorModule_V1 {
   public:
    DrmHalVTSClearkeyModule() {}
    virtual ~DrmHalVTSClearkeyModule() {}

    virtual uint32_t getAPIVersion() const override { return 1; }

    virtual std::string getServiceName() const override { return "clearkey"; }

    virtual std::vector<uint8_t> getUUID() const override {
        return {0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
                0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E };
    }


    virtual std::vector<uint8_t> handleProvisioningRequest(
            const std::vector<uint8_t>& provisioningRequest,
            const std::string& url) override;

    virtual std::vector<DrmHalVTSClearkeyModule::ContentConfiguration>
            getContentConfigurations() const override;

    virtual std::vector<uint8_t> handleKeyRequest(
            const std::vector<uint8_t>& keyRequest,
            const std::string& serverUrl) override;
};

}  // namespace vts
}  // namespace V1_2
}  // namespace drm
}  // namespace hardware
}  // namespace android

#endif  // DRM_HAL_CLEARKEY_MODULE_H
+483 −0

File added.

Preview size limit exceeded, changes collapsed.

+198 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

#ifndef DRM_HAL_COMMON_H
#define DRM_HAL_COMMON_H

#include <android/hardware/drm/1.2/ICryptoFactory.h>
#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <android/hardware/drm/1.2/types.h>

#include <chrono>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "drm_hal_vendor_module_api.h"
#include "vendor_modules.h"
#include "VtsHalHidlTargetCallbackBase.h"
#include "VtsHalHidlTargetTestBase.h"

using ::android::hardware::drm::V1_0::EventType;
using ::android::hardware::drm::V1_0::KeyedVector;
using ::android::hardware::drm::V1_0::KeyStatus;
using ::android::hardware::drm::V1_0::KeyType;
using ::android::hardware::drm::V1_0::Mode;
using ::android::hardware::drm::V1_0::Pattern;
using ::android::hardware::drm::V1_0::SessionId;
using ::android::hardware::drm::V1_0::SubSample;

using ::android::hardware::drm::V1_1::ICryptoFactory;

using ::android::hardware::drm::V1_2::ICryptoPlugin;
using ::android::hardware::drm::V1_2::IDrmFactory;
using ::android::hardware::drm::V1_2::IDrmPlugin;
using ::android::hardware::drm::V1_2::IDrmPluginListener;
using StatusV1_2 = ::android::hardware::drm::V1_2::Status;

using ::android::hardware::hidl_array;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;

using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;

using ::testing::VtsHalHidlTargetTestBase;

using std::map;
using std::string;
using std::unique_ptr;
using std::vector;

#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())

#define RETURN_IF_SKIPPED \
    if (!vendorModule->isInstalled()) { \
        std::cout << "[  SKIPPED ] This drm scheme not supported." << \
                " library:" << GetParam() << " service-name:" << \
                vendorModule->getServiceName() << std::endl; \
        return; \
    }

namespace android {
namespace hardware {
namespace drm {
namespace V1_2 {
namespace vts {

class DrmHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
   public:
    // get the test environment singleton
    static DrmHidlEnvironment* Instance() {
        static DrmHidlEnvironment* instance = new DrmHidlEnvironment;
        return instance;
    }

    void registerTestServices() override {
        registerTestService<ICryptoFactory>();
        registerTestService<IDrmFactory>();
        setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
    }

   private:
    DrmHidlEnvironment() {}

    GTEST_DISALLOW_COPY_AND_ASSIGN_(DrmHidlEnvironment);
};

class DrmHalTest : public ::testing::TestWithParam<std::string> {
   public:
    static drm_vts::VendorModules* gVendorModules;
    DrmHalTest();
    virtual void SetUp() override;
    virtual void TearDown() override {}

   protected:
    hidl_array<uint8_t, 16> getVendorUUID();
    SessionId openSession();
    void closeSession(const SessionId& sessionId);
    hidl_vec<uint8_t> loadKeys(const SessionId& sessionId,
                               const KeyType& type = KeyType::STREAMING);
    hidl_vec<uint8_t> loadKeys(const SessionId& sessionId,
                               const DrmHalVTSVendorModule_V1::ContentConfiguration&,
                               const KeyType& type = KeyType::STREAMING);
    hidl_vec<uint8_t> getKeyRequest(const SessionId& sessionId,
                               const DrmHalVTSVendorModule_V1::ContentConfiguration&,
                               const KeyType& type);
    hidl_vec<uint8_t> provideKeyResponse(const SessionId& sessionId,
                               const hidl_vec<uint8_t>& keyResponse);
    DrmHalVTSVendorModule_V1::ContentConfiguration getContent(
            const KeyType& type = KeyType::STREAMING) const;

    KeyedVector toHidlKeyedVector(const map<string, string>& params);
    hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec);

    void fillRandom(const sp<IMemory>& memory);
    sp<IMemory> getDecryptMemory(size_t size, size_t index);
    uint32_t decrypt(Mode mode, bool isSecure,
            const hidl_array<uint8_t, 16>& keyId, uint8_t* iv,
            const hidl_vec<SubSample>& subSamples, const Pattern& pattern,
            const vector<uint8_t>& key, StatusV1_2 expectedStatus);
    void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
            const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
    void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
            const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);

    sp<IDrmFactory> drmFactory;
    sp<ICryptoFactory> cryptoFactory;
    sp<IDrmPlugin> drmPlugin;
    sp<ICryptoPlugin> cryptoPlugin;
    unique_ptr<DrmHalVTSVendorModule_V1> vendorModule;
    const vector<DrmHalVTSVendorModule_V1::ContentConfiguration> contentConfigurations;

   private:
    sp<IDrmPlugin> createDrmPlugin();
    sp<ICryptoPlugin> createCryptoPlugin();

};

class DrmHalClearkeyTest : public DrmHalTest {
   public:
    virtual void SetUp() override { DrmHalTest::SetUp(); }
    virtual void TearDown() override {}
    void decryptWithInvalidKeys(hidl_vec<uint8_t>& invalidResponse,
            vector<uint8_t>& iv, const Pattern& noPattern, const vector<SubSample>& subSamples);
};

/**
 *  Event Handling tests
 */
extern const char *kCallbackLostState;

class DrmHalPluginListener
    : public ::testing::VtsHalHidlTargetCallbackBase<SessionId>,
      public IDrmPluginListener {
public:
    DrmHalPluginListener() {
        SetWaitTimeoutDefault(std::chrono::milliseconds(500));
    }
    virtual ~DrmHalPluginListener() {}

    virtual Return<void> sendEvent(EventType, const hidl_vec<uint8_t>&,
            const hidl_vec<uint8_t>& ) override { return Void(); }

    virtual Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>&,
            int64_t) override { return Void(); }

    virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>&,
            const hidl_vec<KeyStatus>&, bool) override { return Void(); }

    virtual Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId) override;

};

}  // namespace vts
}  // namespace V1_2
}  // namespace drm
}  // namespace hardware
}  // namespace android

#endif  // DRM_HAL_COMMON_H
Loading