diff --git a/libwvdrmengine/Android.mk b/libwvdrmengine/Android.mk index 13ede4d8..bf289115 100644 --- a/libwvdrmengine/Android.mk +++ b/libwvdrmengine/Android.mk @@ -234,3 +234,4 @@ include vendor/widevine/libwvdrmengine/cdm/Android.mk include vendor/widevine/libwvdrmengine/level3/Android.mk include vendor/widevine/libwvdrmengine/mediacrypto/Android.mk include vendor/widevine/libwvdrmengine/mediadrm/Android.mk +include vendor/widevine/libwvdrmengine/vts/vendor_module/Android.mk diff --git a/libwvdrmengine/vts/vendor_module/Android.mk b/libwvdrmengine/vts/vendor_module/Android.mk new file mode 100644 index 00000000..2f1f0a33 --- /dev/null +++ b/libwvdrmengine/vts/vendor_module/Android.mk @@ -0,0 +1,39 @@ +# ---------------------------------------------------------------- +# Builds libvtswidevine.so +# +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES := \ + hardware/interfaces/drm/1.0/vts/functional \ + vendor/widevine/libwvdrmengine/cdm/include \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/cdm/core/test \ + system/libhidl/base/include \ + system/core/base/include \ + system/libvintf/include \ + +LOCAL_SRC_FILES := \ + factory.cpp \ + vts_module.cpp \ + ../../cdm/core/test/url_request.cpp \ + ../../cdm/core/test/license_request.cpp \ + ../../cdm/core/test/http_socket.cpp \ + +LOCAL_STATIC_LIBRARIES := \ + libgtest \ + libcdm \ + libcdm_utils \ + libcrypto_static + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + liblog \ + libssl \ + libutils \ + +LOCAL_MODULE := libvtswidevine +LOCAL_MODULE_TAGS := optional + + +include $(BUILD_SHARED_LIBRARY) diff --git a/libwvdrmengine/vts/vendor_module/factory.cpp b/libwvdrmengine/vts/vendor_module/factory.cpp new file mode 100644 index 00000000..0ed3684d --- /dev/null +++ b/libwvdrmengine/vts/vendor_module/factory.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "drm_hal_vendor_module_api.h" +#include "vts_module.h" + +namespace widevine_vts { + extern "C" { + DrmHalVTSVendorModule *vendorModuleFactory() { + return new WidevineVTSVendorModule_V1(); + } + }; +}; // namespace widevine_vts + + diff --git a/libwvdrmengine/vts/vendor_module/vts_module.cpp b/libwvdrmengine/vts/vendor_module/vts_module.cpp new file mode 100644 index 00000000..3daec72c --- /dev/null +++ b/libwvdrmengine/vts/vendor_module/vts_module.cpp @@ -0,0 +1,127 @@ +// +// Copyright 2017 Google Inc. All Rights Reserved. +// +#include "gtest/gtest.h" +#include "license_request.h" +#include "string_conversions.h" +#include "url_request.h" +#include "utils/Log.h" +#include "vts_module.h" + +using std::array; +using std::map; +using std::string; +using std::vector; +using wvcdm::a2b_hex; +using wvcdm::b2a_hex; +using wvcdm::LicenseRequest; +using wvcdm::UrlRequest; + + +namespace widevine_vts { + + const int kHttpOk = 200; + + vector WidevineVTSVendorModule_V1::getUUID() { + uint8_t uuid[16] = { + 0xED,0xEF,0x8B,0xA9,0x79,0xD6,0x4A,0xCE, + 0xA3,0xC8,0x27,0xDC,0xD5,0x1D,0x21,0xED + }; + return vector(uuid, uuid + sizeof(uuid)); + } + + void LogResponseError(const string& message, int http_status_code) { + ALOGD("HTTP Status code = %d", http_status_code); + ALOGD("HTTP response(%d): %s", message.size(), b2a_hex(message).c_str()); + } + + vector WidevineVTSVendorModule_V1::handleProvisioningRequest( + const vector& provisioning_request, + const string& server_url) { + + // Use secure connection and chunk transfer coding. + UrlRequest url_request(server_url); + EXPECT_TRUE(url_request.is_connected()) << "Fail to connect to " + << server_url; + url_request.PostCertRequestInQueryString(toString(provisioning_request)); + string reply; + EXPECT_TRUE(url_request.GetResponse(&reply)); + + int http_status_code = url_request.GetStatusCode(reply); + if (kHttpOk != http_status_code) { + LogResponseError(reply, http_status_code); + } + EXPECT_EQ(kHttpOk, http_status_code); + vector result(reply.begin(), reply.end()); + return vector(result); + } + + vector WidevineVTSVendorModule_V1::handleKeyRequest( + const vector&key_request, const string& server_url) { + + // Use secure connection and chunk transfer coding. + UrlRequest url_request(server_url); + EXPECT_TRUE(url_request.is_connected()) << "Fail to connect to " + << server_url; + url_request.PostRequest(toString(key_request)); + string reply; + EXPECT_TRUE(url_request.GetResponse(&reply)); + + int httpStatusCode = url_request.GetStatusCode(reply); + if (httpStatusCode != kHttpOk) { + LogResponseError(reply, httpStatusCode); + } + EXPECT_EQ(httpStatusCode, kHttpOk); + + string drm_msg; + if (kHttpOk == httpStatusCode) { + LicenseRequest lic_request; + lic_request.GetDrmMessage(reply, drm_msg); + ALOGV("HTTP response body: (%u bytes)", drm_msg.size()); + } + vector result(drm_msg.begin(), drm_msg.end()); + return result; + } + + vector + WidevineVTSVendorModule_V1::getContentConfigurations() { + + vector configurations; + { + const string serverUrl = "https://proxy.uat.widevine.com/proxy"; + const vector initData = a2b_hex( + "00000042" // blob size + "70737368" // "pssh" + "00000000" // flags + "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id + "00000022" // pssh data size + "08011a0d7769646576696e655f746573" // pssh data... + "74220f73747265616d696e675f636c69" + "7031"); + vector keyIdVec; + const vector keyId = a2b_hex("371EA35E1A985D75D198A7F41020DC23"); + const vector keyValue = a2b_hex("371EA35E1A985D75D198A7F41020DC23"); + const vector keys = { + { + .isSecure = false, + .keyId = keyId, + .keyValue = keyValue + } + }; + + ContentConfiguration config = { + .name = "UAT-asset1", + .serverUrl = serverUrl, + .initData = initData, + .mimeType = "cenc", + .optionalParameters = map(), + .keys = keys + }; + configurations.push_back(config); + }; + return configurations; + } + +}; // namespace widevine_vts + + diff --git a/libwvdrmengine/vts/vendor_module/vts_module.h b/libwvdrmengine/vts/vendor_module/vts_module.h new file mode 100644 index 00000000..46be8a78 --- /dev/null +++ b/libwvdrmengine/vts/vendor_module/vts_module.h @@ -0,0 +1,48 @@ +// +// Copyright 2017 Google Inc. All Rights Reserved. +// +#ifndef WIDEVINE_VENDOR_VTS_MODULE +#define WIDEVINE_VENDOR_VTS_MODULE + +#include + +#include "drm_hal_vendor_module_api.h" + +using std::vector; + +/** + * Define the DrmHalVTSVendorModule_V1 for Widevine. Refer to + * drm_hal_vendor_module_api.h for more details. + */ +namespace widevine_vts { + + class WidevineVTSVendorModule_V1 : public DrmHalVTSVendorModule_V1 { + public: + WidevineVTSVendorModule_V1() {} + virtual ~WidevineVTSVendorModule_V1() {} + + virtual vector getUUID(); + + virtual vector handleProvisioningRequest(const vector& + provisioningRequest, const std::string& url); + + virtual vector handleKeyRequest(const vector& + keyRequest, const std::string& serverUrl); + + virtual std::vector getContentConfigurations(); + + // TODO: change to "widevine" when HAL service is available + virtual std::string getServiceName() {return "default";} + + private: + WidevineVTSVendorModule_V1(const WidevineVTSVendorModule_V1&) = delete; + void operator=(const WidevineVTSVendorModule_V1&) = delete; + + std::string toString(std::vector vector) { + return std::string(vector.begin(), vector.end()); + } + }; +}; // namespace widevine_vts + +#endif //WIDEVINE_VENDOR_VTS_MODULE +