blob: c8956bf1a906b8095a0c1f534be57926dfb103f6 [file] [log] [blame]
Robert Shih28c2ed32019-10-27 22:55:12 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmUtils"
19
Robert Shih10fe9432019-11-09 08:26:49 -080020#include <android/hardware/drm/1.0/ICryptoFactory.h>
21#include <android/hardware/drm/1.0/ICryptoPlugin.h>
22#include <android/hardware/drm/1.1/ICryptoFactory.h>
23#include <android/hardware/drm/1.2/ICryptoFactory.h>
24#include <android/hidl/manager/1.0/IServiceManager.h>
25#include <hidl/HidlSupport.h>
26
27#include <utils/Errors.h>
28#include <utils/Log.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070029#include <utils/String16.h>
30#include <binder/IInterface.h>
31#include <binder/IServiceManager.h>
32#include <cutils/properties.h>
33
34#include <mediadrm/CryptoHal.h>
35#include <mediadrm/DrmHal.h>
36#include <mediadrm/DrmUtils.h>
37#include <mediadrm/ICrypto.h>
38#include <mediadrm/IDrm.h>
39#include <mediadrm/IMediaDrmService.h>
40
Robert Shih10fe9432019-11-09 08:26:49 -080041using HServiceManager = ::android::hidl::manager::V1_0::IServiceManager;
42using ::android::hardware::hidl_array;
43using ::android::hardware::hidl_string;
44using ::android::hardware::hidl_vec;
45using namespace ::android::hardware::drm;
46
Robert Shih28c2ed32019-10-27 22:55:12 -070047namespace android {
48namespace DrmUtils {
49
50namespace {
51template<typename Iface>
52sp<Iface> MakeObjectWithService(status_t *pstatus) {
53 status_t err = OK;
54 status_t &status = pstatus ? *pstatus : err;
55 sp<IServiceManager> sm = defaultServiceManager();
56 sp<IBinder> binder = sm->getService(String16("media.drm"));
57
58 sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
59 if (service == NULL) {
60 status = UNKNOWN_ERROR;
61 return NULL;
62 }
63
64 auto obj = service->makeObject<Iface>();
65 if (obj == NULL) {
66 status = UNKNOWN_ERROR;
67 return NULL;
68 }
69
70 status = obj->initCheck();
71 if (status != OK && status != NO_INIT) {
72 return NULL;
73 }
74 return obj;
75}
76
77template<typename Iface, typename Hal>
78sp<Iface> MakeObject(status_t *pstatus) {
79 if (UseDrmService()) {
80 return MakeObjectWithService<Iface>(pstatus);
81 } else {
82 return new Hal();
83 }
84}
Robert Shih10fe9432019-11-09 08:26:49 -080085
86template <typename Hal, typename V>
87void MakeCryptoFactories(const uint8_t uuid[16], V &cryptoFactories) {
88 sp<HServiceManager> serviceManager = HServiceManager::getService();
89 if (serviceManager == nullptr) {
90 ALOGE("Failed to get service manager");
91 exit(-1);
92 }
93
94 serviceManager->listByInterface(Hal::descriptor, [&](const hidl_vec<hidl_string> &registered) {
95 for (const auto &instance : registered) {
96 auto factory = Hal::getService(instance);
97 if (factory != nullptr) {
98 ALOGI("found %s %s", Hal::descriptor, instance.c_str());
99 if (factory->isCryptoSchemeSupported(uuid)) {
100 cryptoFactories.push_back(factory);
101 }
102 }
103 }
104 });
105}
106
107hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) {
108 hidl_vec<uint8_t> vec(size);
109 if (ptr != nullptr) {
110 memcpy(vec.data(), ptr, size);
111 }
112 return vec;
113}
114
115hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) {
116 if (ptr == nullptr) {
117 return hidl_array<uint8_t, 16>();
118 }
119 return hidl_array<uint8_t, 16>(ptr);
120}
121
122sp<::V1_0::ICryptoPlugin> MakeCryptoPlugin(const sp<::V1_0::ICryptoFactory> &factory,
123 const uint8_t uuid[16], const void *initData,
124 size_t initDataSize) {
125 sp<::V1_0::ICryptoPlugin> plugin;
126 factory->createPlugin(toHidlArray16(uuid), toHidlVec(initData, initDataSize),
127 [&](::V1_0::Status status, const sp<::V1_0::ICryptoPlugin> &hPlugin) {
128 if (status != ::V1_0::Status::OK) {
129 return;
130 }
131 plugin = hPlugin;
132 });
133 return plugin;
134}
135
Robert Shih28c2ed32019-10-27 22:55:12 -0700136} // namespace
137
138bool UseDrmService() {
Robert Shih17c6d822019-11-07 11:31:43 -0800139 return property_get_bool("mediadrm.use_mediadrmserver", true);
Robert Shih28c2ed32019-10-27 22:55:12 -0700140}
141
142sp<IDrm> MakeDrm(status_t *pstatus) {
143 return MakeObject<IDrm, DrmHal>(pstatus);
144}
145
146sp<ICrypto> MakeCrypto(status_t *pstatus) {
147 return MakeObject<ICrypto, CryptoHal>(pstatus);
148}
149
Robert Shih10fe9432019-11-09 08:26:49 -0800150std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]) {
151 std::vector<sp<::V1_0::ICryptoFactory>> cryptoFactories;
152 MakeCryptoFactories<::V1_0::ICryptoFactory>(uuid, cryptoFactories);
153 MakeCryptoFactories<::V1_1::ICryptoFactory>(uuid, cryptoFactories);
154 MakeCryptoFactories<::V1_2::ICryptoFactory>(uuid, cryptoFactories);
155 return cryptoFactories;
156}
157
158std::vector<sp<ICryptoPlugin>> MakeCryptoPlugins(const uint8_t uuid[16], const void *initData,
159 size_t initDataSize) {
160 std::vector<sp<ICryptoPlugin>> plugins;
161 for (const auto &factory : MakeCryptoFactories(uuid)) {
162 plugins.push_back(MakeCryptoPlugin(factory, uuid, initData, initDataSize));
163 }
164 return plugins;
165}
166
Robert Shih28c2ed32019-10-27 22:55:12 -0700167} // namespace DrmUtils
168} // namespace android