blob: 59c11032f03e3805ea96d93dea87ebe52003fe49 [file] [log] [blame]
Jeff Tinker497ca092014-05-13 09:31:15 -07001/*
2 * Copyright (C) 2014 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
Marco Nelissenc7a11b22014-05-30 10:13:25 -070017//#define LOG_NDEBUG 0
Jeff Tinker497ca092014-05-13 09:31:15 -070018#define LOG_TAG "NdkMediaDrm"
19
Edwin Wongad02cc62018-08-23 13:48:27 -070020#include <inttypes.h>
John W. Bruce9c4e0fa2019-05-03 17:12:44 -070021#include <unistd.h>
Edwin Wongad02cc62018-08-23 13:48:27 -070022
Robert Shihce811b42019-11-19 15:52:33 -080023#include <iostream>
24#include <fstream>
25#include <string>
26
Colin Cross7e8d4ba2017-05-04 16:17:42 -070027#include <media/NdkMediaDrm.h>
Jeff Tinker497ca092014-05-13 09:31:15 -070028
Jeff Tinkera69729d2016-02-12 08:47:00 -080029#include <cutils/properties.h>
Jeff Tinker497ca092014-05-13 09:31:15 -070030#include <utils/Log.h>
31#include <utils/StrongPointer.h>
32#include <gui/Surface.h>
33
John W. Bruce9c4e0fa2019-05-03 17:12:44 -070034#include <android-base/properties.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070035#include <mediadrm/DrmUtils.h>
Marco Nelissen13aa1a42019-09-27 10:21:55 -070036#include <mediadrm/IDrm.h>
37#include <mediadrm/IDrmClient.h>
Jeff Tinker497ca092014-05-13 09:31:15 -070038#include <media/stagefright/MediaErrors.h>
Colin Cross7e8d4ba2017-05-04 16:17:42 -070039#include <media/NdkMediaCrypto.h>
Jeff Tinker497ca092014-05-13 09:31:15 -070040
41
42using namespace android;
43
44typedef Vector<uint8_t> idvec_t;
45
Robert Shiha54e81f2019-08-02 14:15:01 -070046struct DrmListener: virtual public IDrmClient
Jeff Tinker3305b992014-05-14 18:39:25 -070047{
48private:
49 AMediaDrm *mObj;
Edwin Wongad02cc62018-08-23 13:48:27 -070050 AMediaDrmEventListener mEventListener;
51 AMediaDrmExpirationUpdateListener mExpirationUpdateListener;
52 AMediaDrmKeysChangeListener mKeysChangeListener;
Jeff Tinker3305b992014-05-14 18:39:25 -070053
54public:
Edwin Wongad02cc62018-08-23 13:48:27 -070055 DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj),
56 mEventListener(listener), mExpirationUpdateListener(NULL), mKeysChangeListener(NULL) {}
57
58 DrmListener(AMediaDrm *obj, AMediaDrmExpirationUpdateListener listener) : mObj(obj),
59 mEventListener(NULL), mExpirationUpdateListener(listener), mKeysChangeListener(NULL) {}
60
61 DrmListener(AMediaDrm *obj, AMediaDrmKeysChangeListener listener) : mObj(obj),
62 mEventListener(NULL), mExpirationUpdateListener(NULL), mKeysChangeListener(listener) {}
63
64 void setEventListener(AMediaDrmEventListener listener) {
65 mEventListener = listener;
66 }
67
68 void setExpirationUpdateListener(AMediaDrmExpirationUpdateListener listener) {
69 mExpirationUpdateListener = listener;
70 }
71
72 void setKeysChangeListener(AMediaDrmKeysChangeListener listener) {
73 mKeysChangeListener = listener;
74 }
75
Robert Shih61e1c762019-10-31 21:26:58 -070076 void sendEvent(
77 DrmPlugin::EventType eventType,
78 const hardware::hidl_vec<uint8_t> &sessionId,
79 const hardware::hidl_vec<uint8_t> &data) override;
80
81 void sendExpirationUpdate(
82 const hardware::hidl_vec<uint8_t> &sessionId,
83 int64_t expiryTimeInMS) override;
84
85 void sendKeysChange(
86 const hardware::hidl_vec<uint8_t> &sessionId,
87 const std::vector<DrmKeyStatus> &keyStatusList,
88 bool hasNewUsableKey) override;
89
90 void sendSessionLostState(
91 const hardware::hidl_vec<uint8_t> &) override {}
92
Jeff Tinker3305b992014-05-14 18:39:25 -070093};
94
Jeff Tinker497ca092014-05-13 09:31:15 -070095struct AMediaDrm {
96 sp<IDrm> mDrm;
Jeff Tinker497ca092014-05-13 09:31:15 -070097 List<idvec_t> mIds;
98 KeyedVector<String8, String8> mQueryResults;
99 Vector<uint8_t> mKeyRequest;
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000100 String8 mDefaultUrl;
101 AMediaDrmKeyRequestType mkeyRequestType;
Jeff Tinker497ca092014-05-13 09:31:15 -0700102 Vector<uint8_t> mProvisionRequest;
103 String8 mProvisionUrl;
104 String8 mPropertyString;
105 Vector<uint8_t> mPropertyByteArray;
106 List<Vector<uint8_t> > mSecureStops;
Jeff Tinker3305b992014-05-14 18:39:25 -0700107 sp<DrmListener> mListener;
Jeff Tinker497ca092014-05-13 09:31:15 -0700108};
109
Robert Shih61e1c762019-10-31 21:26:58 -0700110void DrmListener::sendExpirationUpdate(
111 const hardware::hidl_vec<uint8_t> &sessionId,
112 int64_t expiryTimeInMS) {
113 if (!mExpirationUpdateListener) {
114 ALOGE("No ExpirationUpdateListener specified");
Jeff Tinker3305b992014-05-14 18:39:25 -0700115 return;
116 }
117
Robert Shih61e1c762019-10-31 21:26:58 -0700118 if (expiryTimeInMS >= 0) {
119 AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
120 (*mExpirationUpdateListener)(mObj, &asid, expiryTimeInMS);
121 } else {
122 ALOGE("expiry time negative, status=%" PRId64 "", expiryTimeInMS);
123 }
124}
Edwin Wongad02cc62018-08-23 13:48:27 -0700125
Robert Shih61e1c762019-10-31 21:26:58 -0700126void DrmListener::sendKeysChange(
127 const hardware::hidl_vec<uint8_t> &sessionId,
128 const std::vector<DrmKeyStatus> &keyStatusList,
129 bool hasNewUsableKey) {
130 if (!mKeysChangeListener) {
131 ALOGE("No KeysChangeListener specified");
Edwin Wongad02cc62018-08-23 13:48:27 -0700132 return;
Jeff Tinker3305b992014-05-14 18:39:25 -0700133 }
134
Robert Shih61e1c762019-10-31 21:26:58 -0700135 Vector<AMediaDrmKeyStatus> keysStatus;
136 for (const auto &drmKeyStatus : keyStatusList) {
Edwin Wongad02cc62018-08-23 13:48:27 -0700137 AMediaDrmKeyStatus keyStatus;
Robert Shih61e1c762019-10-31 21:26:58 -0700138 keyStatus.keyId.ptr = drmKeyStatus.keyId.data();
139 keyStatus.keyId.length = drmKeyStatus.keyId.size();
140 keyStatus.keyType = static_cast<AMediaDrmKeyStatusType>(drmKeyStatus.type);
141 keysStatus.push(keyStatus);
142 }
Edwin Wongad02cc62018-08-23 13:48:27 -0700143
Robert Shih61e1c762019-10-31 21:26:58 -0700144 AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
145 int32_t numKeys = keyStatusList.size();
146 (*mKeysChangeListener)(mObj, &asid, keysStatus.array(), numKeys, hasNewUsableKey);
147 return;
148}
Edwin Wongad02cc62018-08-23 13:48:27 -0700149
Robert Shih61e1c762019-10-31 21:26:58 -0700150void DrmListener::sendEvent(
151 DrmPlugin::EventType eventType,
152 const hardware::hidl_vec<uint8_t> &sessionId,
153 const hardware::hidl_vec<uint8_t> &data) {
154 if (!mEventListener) {
155 ALOGE("No EventListener specified");
Edwin Wongad02cc62018-08-23 13:48:27 -0700156 return;
157 }
158
159 // Handles AMediaDrmEventListener below:
160 // translates DrmPlugin event types into their NDK equivalents
Jeff Tinker3305b992014-05-14 18:39:25 -0700161 AMediaDrmEventType ndkEventType;
162 switch(eventType) {
163 case DrmPlugin::kDrmPluginEventProvisionRequired:
164 ndkEventType = EVENT_PROVISION_REQUIRED;
165 break;
166 case DrmPlugin::kDrmPluginEventKeyNeeded:
167 ndkEventType = EVENT_KEY_REQUIRED;
168 break;
169 case DrmPlugin::kDrmPluginEventKeyExpired:
170 ndkEventType = EVENT_KEY_EXPIRED;
171 break;
172 case DrmPlugin::kDrmPluginEventVendorDefined:
173 ndkEventType = EVENT_VENDOR_DEFINED;
174 break;
Edwin Wongad02cc62018-08-23 13:48:27 -0700175 case DrmPlugin::kDrmPluginEventSessionReclaimed:
176 ndkEventType = EVENT_SESSION_RECLAIMED;
177 break;
Jeff Tinker3305b992014-05-14 18:39:25 -0700178 default:
Robert Shih61e1c762019-10-31 21:26:58 -0700179 ALOGE("Invalid event DrmPlugin::EventType %d, ignored", eventType);
Edwin Wongad02cc62018-08-23 13:48:27 -0700180 return;
Jeff Tinker3305b992014-05-14 18:39:25 -0700181 }
182
Robert Shih61e1c762019-10-31 21:26:58 -0700183 AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
184 int32_t dataSize = data.size();
185 const uint8_t *dataPtr = data.data();
Edwin Wongad02cc62018-08-23 13:48:27 -0700186 if (dataSize > 0) {
Robert Shih61e1c762019-10-31 21:26:58 -0700187 (*mEventListener)(mObj, &asid, ndkEventType, 0, dataPtr, dataSize);
Edwin Wongad02cc62018-08-23 13:48:27 -0700188 } else {
Robert Shih61e1c762019-10-31 21:26:58 -0700189 ALOGE("invalid event data size=%d", dataSize);
Edwin Wongad02cc62018-08-23 13:48:27 -0700190 }
Jeff Tinker3305b992014-05-14 18:39:25 -0700191}
192
Jeff Tinker497ca092014-05-13 09:31:15 -0700193extern "C" {
194
Marco Nelissene419d7c2014-05-15 14:17:25 -0700195static media_status_t translateStatus(status_t status) {
196 media_status_t result = AMEDIA_ERROR_UNKNOWN;
Jeff Tinker497ca092014-05-13 09:31:15 -0700197 switch (status) {
198 case OK:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700199 result = AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700200 break;
201 case android::ERROR_DRM_NOT_PROVISIONED:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700202 result = AMEDIA_DRM_NOT_PROVISIONED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700203 break;
204 case android::ERROR_DRM_RESOURCE_BUSY:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700205 result = AMEDIA_DRM_RESOURCE_BUSY;
Jeff Tinker497ca092014-05-13 09:31:15 -0700206 break;
207 case android::ERROR_DRM_DEVICE_REVOKED:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700208 result = AMEDIA_DRM_DEVICE_REVOKED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700209 break;
210 case android::ERROR_DRM_CANNOT_HANDLE:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700211 result = AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700212 break;
213 case android::ERROR_DRM_TAMPER_DETECTED:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700214 result = AMEDIA_DRM_TAMPER_DETECTED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700215 break;
216 case android::ERROR_DRM_SESSION_NOT_OPENED:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700217 result = AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700218 break;
219 case android::ERROR_DRM_NO_LICENSE:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700220 result = AMEDIA_DRM_NEED_KEY;
Jeff Tinker497ca092014-05-13 09:31:15 -0700221 break;
222 case android::ERROR_DRM_LICENSE_EXPIRED:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700223 result = AMEDIA_DRM_LICENSE_EXPIRED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700224 break;
225 default:
Jeff Tinker497ca092014-05-13 09:31:15 -0700226 break;
227 }
228 return result;
229}
230
John W. Bruce9c4e0fa2019-05-03 17:12:44 -0700231static bool ShouldGetAppPackageName(void) {
232 // Check what this device's first API level was.
233 int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
234 if (firstApiLevel == 0) {
235 // First API Level is 0 on factory ROMs, but we can assume the current SDK
236 // version is the first if it's a factory ROM.
237 firstApiLevel = android::base::GetIntProperty<int32_t>("ro.build.version.sdk", 0);
238 }
239 return firstApiLevel >= 29; // Android Q
240}
241
242static status_t GetAppPackageName(String8 *packageName) {
Robert Shihce811b42019-11-19 15:52:33 -0800243 // todo(robertshih): use refactored/renamed libneuralnetworks_packageinfo which is stable
244 std::string appName;
245 std::ifstream cmdline("/proc/self/cmdline");
246 std::getline(cmdline, appName);
247 cmdline.close();
248 if (appName.empty()) {
John W. Bruce9c4e0fa2019-05-03 17:12:44 -0700249 return UNKNOWN_ERROR;
250 }
Robert Shihce811b42019-11-19 15:52:33 -0800251 *packageName = String8(appName.c_str());
John W. Bruce9c4e0fa2019-05-03 17:12:44 -0700252 return OK;
253}
254
Jeff Tinker497ca092014-05-13 09:31:15 -0700255static sp<IDrm> CreateDrm() {
Robert Shih28c2ed32019-10-27 22:55:12 -0700256 return DrmUtils::MakeDrm();
Jeff Tinker497ca092014-05-13 09:31:15 -0700257}
258
259
260static sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) {
261 sp<IDrm> drm = CreateDrm();
262
263 if (drm == NULL) {
264 return NULL;
265 }
266
John W. Bruce9c4e0fa2019-05-03 17:12:44 -0700267 String8 packageName;
268 if (ShouldGetAppPackageName()) {
269 status_t err = GetAppPackageName(&packageName);
270
271 if (err != OK) {
272 return NULL;
273 }
274 }
275
276 status_t err = drm->createPlugin(uuid, packageName);
Jeff Tinker497ca092014-05-13 09:31:15 -0700277
278 if (err != OK) {
279 return NULL;
280 }
281
282 return drm;
283}
284
Marco Nelissen3425fd52014-05-14 11:12:46 -0700285EXPORT
Jeff Tinker497ca092014-05-13 09:31:15 -0700286bool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) {
287 sp<IDrm> drm = CreateDrm();
288
289 if (drm == NULL) {
290 return false;
291 }
292
293 String8 mimeStr = mimeType ? String8(mimeType) : String8("");
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800294 bool isSupported = false;
295 status_t status = drm->isCryptoSchemeSupported(uuid, mimeStr,
296 DrmPlugin::kSecurityLevelUnknown, &isSupported);
297 return (status == OK) && isSupported;
Jeff Tinker497ca092014-05-13 09:31:15 -0700298}
299
Marco Nelissen3425fd52014-05-14 11:12:46 -0700300EXPORT
Jeff Tinker497ca092014-05-13 09:31:15 -0700301AMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
302 AMediaDrm *mObj = new AMediaDrm();
303 mObj->mDrm = CreateDrmFromUUID(uuid);
Edwin Wongad02cc62018-08-23 13:48:27 -0700304
305 mObj->mListener.clear();
Jeff Tinker497ca092014-05-13 09:31:15 -0700306 return mObj;
307}
308
Marco Nelissen3425fd52014-05-14 11:12:46 -0700309EXPORT
Jeff Tinker497ca092014-05-13 09:31:15 -0700310void AMediaDrm_release(AMediaDrm *mObj) {
311 if (mObj->mDrm != NULL) {
312 mObj->mDrm->setListener(NULL);
313 mObj->mDrm->destroyPlugin();
314 mObj->mDrm.clear();
315 }
316 delete mObj;
317}
318
Jeff Tinker3305b992014-05-14 18:39:25 -0700319EXPORT
Marco Nelissen7c96d532014-05-15 15:26:14 -0700320media_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) {
Jeff Tinker3305b992014-05-14 18:39:25 -0700321 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissen7c96d532014-05-15 15:26:14 -0700322 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker3305b992014-05-14 18:39:25 -0700323 }
Edwin Wongad02cc62018-08-23 13:48:27 -0700324
325 if (mObj->mListener.get()) {
326 mObj->mListener->setEventListener(listener);
327 } else {
328 mObj->mListener = new DrmListener(mObj, listener);
329 }
Jeff Tinker3305b992014-05-14 18:39:25 -0700330 mObj->mDrm->setListener(mObj->mListener);
Marco Nelissen7c96d532014-05-15 15:26:14 -0700331 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700332}
Jeff Tinker497ca092014-05-13 09:31:15 -0700333
Edwin Wongad02cc62018-08-23 13:48:27 -0700334EXPORT
335media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *mObj,
336 AMediaDrmExpirationUpdateListener listener) {
337 if (!mObj || mObj->mDrm == NULL) {
338 return AMEDIA_ERROR_INVALID_OBJECT;
339 }
340
341 if (mObj->mListener.get()) {
342 mObj->mListener->setExpirationUpdateListener(listener);
343 } else {
344 mObj->mListener = new DrmListener(mObj, listener);
345 }
346 mObj->mDrm->setListener(mObj->mListener);
347 return AMEDIA_OK;
348}
349
350EXPORT
351media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *mObj,
352 AMediaDrmKeysChangeListener listener) {
353 if (!mObj || mObj->mDrm == NULL) {
354 return AMEDIA_ERROR_INVALID_OBJECT;
355 }
356
357 if (mObj->mListener.get()) {
358 mObj->mListener->setKeysChangeListener(listener);
359 } else {
360 mObj->mListener = new DrmListener(mObj, listener);
361 }
362 mObj->mDrm->setListener(mObj->mListener);
363 return AMEDIA_OK;
364}
Jeff Tinker497ca092014-05-13 09:31:15 -0700365
366static bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
Edwin Wong21030442016-10-18 12:34:05 -0700367 for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) {
Jeff Tinkerc5f013f2017-04-05 10:28:27 -0700368 if (id.length == iter->size() && memcmp(iter->array(), id.ptr, iter->size()) == 0) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700369 return true;
370 }
371 }
372 return false;
373}
374
Marco Nelissen3425fd52014-05-14 11:12:46 -0700375EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700376media_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700377 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700378 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700379 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700380 if (!sessionId) {
381 return AMEDIA_ERROR_INVALID_PARAMETER;
382 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700383 Vector<uint8_t> session;
Jeff Tinker41d279a2018-02-11 19:52:08 +0000384 status_t status = mObj->mDrm->openSession(DrmPlugin::kSecurityLevelMax, session);
Rahul Frias814fd712021-02-02 01:42:38 -0800385 if (status != OK) {
386 sessionId->ptr = NULL;
387 sessionId->length = 0;
388 return translateStatus(status);
Jeff Tinker497ca092014-05-13 09:31:15 -0700389 }
Rahul Frias814fd712021-02-02 01:42:38 -0800390 mObj->mIds.push_front(session);
391 List<idvec_t>::iterator iter = mObj->mIds.begin();
392 sessionId->ptr = iter->array();
393 sessionId->length = iter->size();
Marco Nelissene419d7c2014-05-15 14:17:25 -0700394 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700395}
396
Marco Nelissen3425fd52014-05-14 11:12:46 -0700397EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700398media_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700399 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700400 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700401 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700402 if (!sessionId) {
403 return AMEDIA_ERROR_INVALID_PARAMETER;
404 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700405
406 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700407 if (!findId(mObj, *sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700408 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700409 }
410 mObj->mDrm->closeSession(*iter);
411 mObj->mIds.erase(iter);
Marco Nelissene419d7c2014-05-15 14:17:25 -0700412 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700413}
414
Marco Nelissen3425fd52014-05-14 11:12:46 -0700415EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700416media_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
Jeff Tinker497ca092014-05-13 09:31:15 -0700417 const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
418 const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700419 const uint8_t **keyRequest, size_t *keyRequestSize) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700420
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000421 return AMediaDrm_getKeyRequestWithDefaultUrlAndType(mObj,
422 scope, init, initSize, mimeType, keyType, optionalParameters,
423 numOptionalParameters, keyRequest,
424 keyRequestSize, NULL, NULL);
425}
426
427EXPORT
428media_status_t AMediaDrm_getKeyRequestWithDefaultUrlAndType(AMediaDrm *mObj,
429 const AMediaDrmScope *scope, const uint8_t *init, size_t initSize,
430 const char *mimeType, AMediaDrmKeyType keyType,
431 const AMediaDrmKeyValue *optionalParameters,
432 size_t numOptionalParameters, const uint8_t **keyRequest,
433 size_t *keyRequestSize, const char **defaultUrl,
434 AMediaDrmKeyRequestType *keyRequestType) {
435
Jeff Tinker497ca092014-05-13 09:31:15 -0700436 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700437 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700438 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700439 if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700440 return AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700441 }
442
443 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700444 if (!findId(mObj, *scope, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700445 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700446 }
447
448 Vector<uint8_t> mdInit;
449 mdInit.appendArray(init, initSize);
450 DrmPlugin::KeyType mdKeyType;
451 switch (keyType) {
452 case KEY_TYPE_STREAMING:
453 mdKeyType = DrmPlugin::kKeyType_Streaming;
454 break;
455 case KEY_TYPE_OFFLINE:
456 mdKeyType = DrmPlugin::kKeyType_Offline;
457 break;
458 case KEY_TYPE_RELEASE:
459 mdKeyType = DrmPlugin::kKeyType_Release;
460 break;
461 default:
Marco Nelissene419d7c2014-05-15 14:17:25 -0700462 return AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700463 }
464 KeyedVector<String8, String8> mdOptionalParameters;
465 for (size_t i = 0; i < numOptionalParameters; i++) {
466 mdOptionalParameters.add(String8(optionalParameters[i].mKey),
467 String8(optionalParameters[i].mValue));
468 }
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000469
470 DrmPlugin::KeyRequestType requestType;
Edwin Wongb5c8f212018-07-06 17:29:24 -0700471 mObj->mKeyRequest.clear();
Jeff Tinker497ca092014-05-13 09:31:15 -0700472 status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000473 mdKeyType, mdOptionalParameters, mObj->mKeyRequest, mObj->mDefaultUrl,
474 &requestType);
Jeff Tinker497ca092014-05-13 09:31:15 -0700475 if (status != OK) {
476 return translateStatus(status);
477 } else {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700478 *keyRequest = mObj->mKeyRequest.array();
479 *keyRequestSize = mObj->mKeyRequest.size();
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000480 if (defaultUrl != NULL)
481 *defaultUrl = mObj->mDefaultUrl.string();
482 switch(requestType) {
483 case DrmPlugin::kKeyRequestType_Initial:
484 mObj->mkeyRequestType = KEY_REQUEST_TYPE_INITIAL;
485 break;
486 case DrmPlugin::kKeyRequestType_Renewal:
487 mObj->mkeyRequestType = KEY_REQUEST_TYPE_RENEWAL;
488 break;
489 case DrmPlugin::kKeyRequestType_Release:
490 mObj->mkeyRequestType = KEY_REQUEST_TYPE_RELEASE;
491 break;
492 case DrmPlugin::kKeyRequestType_None:
493 mObj->mkeyRequestType = KEY_REQUEST_TYPE_NONE;
494 break;
495 case DrmPlugin::kKeyRequestType_Update:
496 mObj->mkeyRequestType = KEY_REQUEST_TYPE_UPDATE;
497 break;
498 default:
499 return AMEDIA_ERROR_UNKNOWN;
500 }
501
502 if (keyRequestType != NULL)
503 *keyRequestType = mObj->mkeyRequestType;
Jeff Tinker497ca092014-05-13 09:31:15 -0700504 }
Kyle Zhangb5a9b972021-12-03 21:46:51 +0000505
Marco Nelissene419d7c2014-05-15 14:17:25 -0700506 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700507}
508
Marco Nelissen3425fd52014-05-14 11:12:46 -0700509EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700510media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
511 const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700512
513 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700514 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700515 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700516 if (!scope || !response || !responseSize || !keySetId) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700517 return AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700518 }
519
520 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700521 if (!findId(mObj, *scope, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700522 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700523 }
524 Vector<uint8_t> mdResponse;
525 mdResponse.appendArray(response, responseSize);
526
527 Vector<uint8_t> mdKeySetId;
528 status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId);
529 if (status == OK) {
530 mObj->mIds.push_front(mdKeySetId);
531 List<idvec_t>::iterator iter = mObj->mIds.begin();
Marco Nelissen18a1b592014-05-20 08:45:18 -0700532 keySetId->ptr = iter->array();
533 keySetId->length = iter->size();
Jeff Tinker497ca092014-05-13 09:31:15 -0700534 } else {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700535 keySetId->ptr = NULL;
536 keySetId->length = 0;
Rahul Frias814fd712021-02-02 01:42:38 -0800537 return translateStatus(status);
Jeff Tinker497ca092014-05-13 09:31:15 -0700538 }
Marco Nelissene419d7c2014-05-15 14:17:25 -0700539 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700540}
541
Marco Nelissen3425fd52014-05-14 11:12:46 -0700542EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700543media_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
544 const AMediaDrmKeySetId *keySetId) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700545
546 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700547 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700548 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700549 if (!sessionId || !keySetId) {
550 return AMEDIA_ERROR_INVALID_PARAMETER;
551 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700552 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700553 if (!findId(mObj, *sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700554 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700555 }
556 Vector<uint8_t> keySet;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700557 keySet.appendArray(keySetId->ptr, keySetId->length);
Jeff Tinker497ca092014-05-13 09:31:15 -0700558 return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
559}
560
Marco Nelissen3425fd52014-05-14 11:12:46 -0700561EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700562media_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700563 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700564 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700565 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700566 if (!keySetId) {
567 return AMEDIA_ERROR_INVALID_PARAMETER;
568 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700569 List<idvec_t>::iterator iter;
570 status_t status;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700571 if (!findId(mObj, *keySetId, iter)) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700572 Vector<uint8_t> keySet;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700573 keySet.appendArray(keySetId->ptr, keySetId->length);
Jeff Tinker497ca092014-05-13 09:31:15 -0700574 status = mObj->mDrm->removeKeys(keySet);
575 } else {
576 status = mObj->mDrm->removeKeys(*iter);
577 mObj->mIds.erase(iter);
578 }
579 return translateStatus(status);
580}
581
Marco Nelissen3425fd52014-05-14 11:12:46 -0700582EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700583media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
584 AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700585
586 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700587 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700588 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700589 if (!sessionId || !numPairs) {
590 return AMEDIA_ERROR_INVALID_PARAMETER;
591 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700592 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700593 if (!findId(mObj, *sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700594 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700595 }
596
597 status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
598 if (status != OK) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700599 *numPairs = 0;
Jeff Tinker497ca092014-05-13 09:31:15 -0700600 return translateStatus(status);
601 }
602
Marco Nelissen18a1b592014-05-20 08:45:18 -0700603 if (mObj->mQueryResults.size() > *numPairs) {
604 *numPairs = mObj->mQueryResults.size();
Marco Nelissene419d7c2014-05-15 14:17:25 -0700605 return AMEDIA_DRM_SHORT_BUFFER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700606 }
607
608 for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
609 keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
Edwin Wong815c9252017-08-30 17:47:20 -0700610 keyValuePairs[i].mValue = mObj->mQueryResults.valueAt(i).string();
Jeff Tinker497ca092014-05-13 09:31:15 -0700611 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700612 *numPairs = mObj->mQueryResults.size();
Marco Nelissene419d7c2014-05-15 14:17:25 -0700613 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700614}
615
Marco Nelissen3425fd52014-05-14 11:12:46 -0700616EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700617media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
618 size_t *provisionRequestSize, const char **serverUrl) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700619 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700620 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700621 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700622 if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700623 return AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700624 }
625
626 status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""),
627 mObj->mProvisionRequest, mObj->mProvisionUrl);
628 if (status != OK) {
629 return translateStatus(status);
630 } else {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700631 *provisionRequest = mObj->mProvisionRequest.array();
632 *provisionRequestSize = mObj->mProvisionRequest.size();
633 *serverUrl = mObj->mProvisionUrl.string();
Jeff Tinker497ca092014-05-13 09:31:15 -0700634 }
Marco Nelissene419d7c2014-05-15 14:17:25 -0700635 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700636}
637
Marco Nelissen3425fd52014-05-14 11:12:46 -0700638EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700639media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
Jeff Tinker497ca092014-05-13 09:31:15 -0700640 const uint8_t *response, size_t responseSize) {
641 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700642 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700643 }
644 if (!response || !responseSize) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700645 return AMEDIA_ERROR_INVALID_PARAMETER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700646 }
647
648 Vector<uint8_t> mdResponse;
649 mdResponse.appendArray(response, responseSize);
650
651 Vector<uint8_t> unused;
652 return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused));
653}
654
Marco Nelissen3425fd52014-05-14 11:12:46 -0700655EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700656media_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700657 AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700658
659 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700660 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700661 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700662 if (!numSecureStops) {
663 return AMEDIA_ERROR_INVALID_PARAMETER;
664 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700665 status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
666 if (status != OK) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700667 *numSecureStops = 0;
Jeff Tinker497ca092014-05-13 09:31:15 -0700668 return translateStatus(status);
669 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700670 if (*numSecureStops < mObj->mSecureStops.size()) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700671 return AMEDIA_DRM_SHORT_BUFFER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700672 }
673 List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
674 size_t i = 0;
675 while (iter != mObj->mSecureStops.end()) {
676 secureStops[i].ptr = iter->array();
677 secureStops[i].length = iter->size();
678 ++iter;
679 ++i;
680 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700681 *numSecureStops = mObj->mSecureStops.size();
Marco Nelissene419d7c2014-05-15 14:17:25 -0700682 return AMEDIA_OK;
Jeff Tinker497ca092014-05-13 09:31:15 -0700683}
684
Marco Nelissen3425fd52014-05-14 11:12:46 -0700685EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700686media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700687 const AMediaDrmSecureStop *ssRelease) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700688
689 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700690 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700691 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700692 if (!ssRelease) {
693 return AMEDIA_ERROR_INVALID_PARAMETER;
694 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700695
696 Vector<uint8_t> release;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700697 release.appendArray(ssRelease->ptr, ssRelease->length);
Jeff Tinker497ca092014-05-13 09:31:15 -0700698 return translateStatus(mObj->mDrm->releaseSecureStops(release));
699}
700
701
Marco Nelissen3425fd52014-05-14 11:12:46 -0700702EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700703media_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700704 const char **propertyValue) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700705
706 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700707 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700708 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700709 if (!propertyName || !propertyValue) {
710 return AMEDIA_ERROR_INVALID_PARAMETER;
711 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700712
713 status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
714 mObj->mPropertyString);
715
716 if (status == OK) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700717 *propertyValue = mObj->mPropertyString.string();
Jeff Tinker497ca092014-05-13 09:31:15 -0700718 } else {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700719 *propertyValue = NULL;
Jeff Tinker497ca092014-05-13 09:31:15 -0700720 }
721 return translateStatus(status);
722}
723
Marco Nelissen3425fd52014-05-14 11:12:46 -0700724EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700725media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700726 const char *propertyName, AMediaDrmByteArray *propertyValue) {
Jeff Tinker497ca092014-05-13 09:31:15 -0700727 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700728 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700729 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700730 if (!propertyName || !propertyValue) {
731 return AMEDIA_ERROR_INVALID_PARAMETER;
732 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700733
734 status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
735 mObj->mPropertyByteArray);
736
737 if (status == OK) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700738 propertyValue->ptr = mObj->mPropertyByteArray.array();
739 propertyValue->length = mObj->mPropertyByteArray.size();
Jeff Tinker497ca092014-05-13 09:31:15 -0700740 } else {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700741 propertyValue->ptr = NULL;
742 propertyValue->length = 0;
Jeff Tinker497ca092014-05-13 09:31:15 -0700743 }
744 return translateStatus(status);
745}
746
Marco Nelissen3425fd52014-05-14 11:12:46 -0700747EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700748media_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj,
Jeff Tinker497ca092014-05-13 09:31:15 -0700749 const char *propertyName, const char *value) {
750 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700751 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700752 }
753
754 return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName),
755 String8(value)));
756}
757
Marco Nelissen3425fd52014-05-14 11:12:46 -0700758EXPORT
Marco Nelissene419d7c2014-05-15 14:17:25 -0700759media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
Jeff Tinker497ca092014-05-13 09:31:15 -0700760 const char *propertyName, const uint8_t *value, size_t valueSize) {
761
762 Vector<uint8_t> byteArray;
763 byteArray.appendArray(value, valueSize);
764
Praveen Chavanc7822ef2018-10-04 10:39:33 -0700765 return translateStatus(mObj->mDrm->setPropertyByteArray(String8(propertyName),
Jeff Tinker497ca092014-05-13 09:31:15 -0700766 byteArray));
767}
768
769
Marco Nelissene419d7c2014-05-15 14:17:25 -0700770static media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
Jeff Tinker497ca092014-05-13 09:31:15 -0700771 const AMediaDrmSessionId &sessionId,
772 const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
773 const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) {
774
775 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700776 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700777 }
778 List<idvec_t>::iterator iter;
779 if (!findId(mObj, sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700780 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700781 }
782
783 status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm));
784 if (status != OK) {
785 return translateStatus(status);
786 }
787
788 Vector<uint8_t> keyIdVec;
789 const size_t kKeyIdSize = 16;
790 keyIdVec.appendArray(keyId, kKeyIdSize);
791
792 Vector<uint8_t> inputVec;
793 inputVec.appendArray(input, dataSize);
794
795 Vector<uint8_t> ivVec;
796 const size_t kIvSize = 16;
797 ivVec.appendArray(iv, kIvSize);
798
799 Vector<uint8_t> outputVec;
800 if (encrypt) {
Aurimas Liutikas214c8332016-02-19 14:48:23 -0800801 status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
Jeff Tinker497ca092014-05-13 09:31:15 -0700802 } else {
Aurimas Liutikas214c8332016-02-19 14:48:23 -0800803 status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
Jeff Tinker497ca092014-05-13 09:31:15 -0700804 }
805 if (status == OK) {
806 memcpy(output, outputVec.array(), outputVec.size());
807 }
808 return translateStatus(status);
809}
810
Marco Nelissen3425fd52014-05-14 11:12:46 -0700811EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700812media_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700813 const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
814 const uint8_t *input, uint8_t *output, size_t dataSize) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700815 if (!sessionId) {
816 return AMEDIA_ERROR_INVALID_PARAMETER;
817 }
818 return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
Jeff Tinker497ca092014-05-13 09:31:15 -0700819 input, output, dataSize, true);
820}
821
Marco Nelissen3425fd52014-05-14 11:12:46 -0700822EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700823media_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700824 const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
825 const uint8_t *input, uint8_t *output, size_t dataSize) {
Marco Nelissen18a1b592014-05-20 08:45:18 -0700826 if (!sessionId) {
827 return AMEDIA_ERROR_INVALID_PARAMETER;
828 }
829 return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
Jeff Tinker497ca092014-05-13 09:31:15 -0700830 input, output, dataSize, false);
831}
832
Marco Nelissen3425fd52014-05-14 11:12:46 -0700833EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700834media_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700835 const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
836 uint8_t *signature, size_t *signatureSize) {
837
838 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700839 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700840 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700841 if (!sessionId) {
842 return AMEDIA_ERROR_INVALID_PARAMETER;
843 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700844 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700845 if (!findId(mObj, *sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700846 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700847 }
848
849 status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
850 if (status != OK) {
851 return translateStatus(status);
852 }
853
854 Vector<uint8_t> keyIdVec;
855 const size_t kKeyIdSize = 16;
856 keyIdVec.appendArray(keyId, kKeyIdSize);
857
858 Vector<uint8_t> messageVec;
859 messageVec.appendArray(message, messageSize);
860
861 Vector<uint8_t> signatureVec;
862 status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec);
863 if (signatureVec.size() > *signatureSize) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700864 return AMEDIA_DRM_SHORT_BUFFER;
Jeff Tinker497ca092014-05-13 09:31:15 -0700865 }
866 if (status == OK) {
867 memcpy(signature, signatureVec.array(), signatureVec.size());
868 }
869 return translateStatus(status);
870}
871
Marco Nelissen3425fd52014-05-14 11:12:46 -0700872EXPORT
Marco Nelissen18a1b592014-05-20 08:45:18 -0700873media_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700874 const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
875 const uint8_t *signature, size_t signatureSize) {
876
877 if (!mObj || mObj->mDrm == NULL) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700878 return AMEDIA_ERROR_INVALID_OBJECT;
Jeff Tinker497ca092014-05-13 09:31:15 -0700879 }
Marco Nelissen18a1b592014-05-20 08:45:18 -0700880 if (!sessionId) {
881 return AMEDIA_ERROR_INVALID_PARAMETER;
882 }
Jeff Tinker497ca092014-05-13 09:31:15 -0700883 List<idvec_t>::iterator iter;
Marco Nelissen18a1b592014-05-20 08:45:18 -0700884 if (!findId(mObj, *sessionId, iter)) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700885 return AMEDIA_DRM_SESSION_NOT_OPENED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700886 }
887
888 status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
889 if (status != OK) {
890 return translateStatus(status);
891 }
892
893 Vector<uint8_t> keyIdVec;
894 const size_t kKeyIdSize = 16;
895 keyIdVec.appendArray(keyId, kKeyIdSize);
896
897 Vector<uint8_t> messageVec;
898 messageVec.appendArray(message, messageSize);
899
900 Vector<uint8_t> signatureVec;
901 signatureVec.appendArray(signature, signatureSize);
902
903 bool match;
904 status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match);
905 if (status == OK) {
Marco Nelissene419d7c2014-05-15 14:17:25 -0700906 return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED;
Jeff Tinker497ca092014-05-13 09:31:15 -0700907 }
908 return translateStatus(status);
909}
910
911} // extern "C"