blob: e3176e3985fba954ef6a30b677aa8fd1daee005c [file] [log] [blame]
Jeff Tinkercc82dc62013-02-08 10:18:35 -08001/*
2 * Copyright (C) 2013 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 "Drm"
19#include <utils/Log.h>
20
21#include <dirent.h>
22#include <dlfcn.h>
23
Jeff Tinker30038072016-04-25 13:41:35 -070024#include <media/DrmSessionClientInterface.h>
25#include <media/DrmSessionManager.h>
26#include <media/Drm.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080027#include <media/drm/DrmAPI.h>
28#include <media/stagefright/foundation/ADebug.h>
29#include <media/stagefright/foundation/AString.h>
30#include <media/stagefright/foundation/hexdump.h>
31#include <media/stagefright/MediaErrors.h>
Jeff Tinker81e0bd42014-04-02 16:41:38 -070032#include <binder/IServiceManager.h>
33#include <binder/IPCThreadState.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080034
35namespace android {
36
Ronghua Wu5c3da202015-02-22 08:45:28 -080037static inline int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
Jeff Tinker81e0bd42014-04-02 16:41:38 -070041static bool checkPermission(const char* permissionString) {
Jeff Tinker81e0bd42014-04-02 16:41:38 -070042 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
43 bool ok = checkCallingPermission(String16(permissionString));
44 if (!ok) ALOGE("Request requires %s", permissionString);
45 return ok;
46}
47
Jeff Tinkercc82dc62013-02-08 10:18:35 -080048KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
49KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
50Mutex Drm::mMapLock;
Jeff Tinker2fb561a2015-04-22 15:58:16 -070051Mutex Drm::mLock;
Jeff Tinkercc82dc62013-02-08 10:18:35 -080052
53static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
54 if (lhs.size() < rhs.size()) {
55 return true;
56 } else if (lhs.size() > rhs.size()) {
57 return false;
58 }
59
60 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
61}
62
Ronghua Wu5c3da202015-02-22 08:45:28 -080063struct DrmSessionClient : public DrmSessionClientInterface {
Chih-Hung Hsieh64a28702016-05-03 09:52:51 -070064 explicit DrmSessionClient(Drm* drm) : mDrm(drm) {}
Ronghua Wu5c3da202015-02-22 08:45:28 -080065
66 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
67 sp<Drm> drm = mDrm.promote();
68 if (drm == NULL) {
69 return true;
70 }
71 status_t err = drm->closeSession(sessionId);
72 if (err != OK) {
73 return false;
74 }
75 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
76 return true;
77 }
78
79protected:
80 virtual ~DrmSessionClient() {}
81
82private:
83 wp<Drm> mDrm;
84
85 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
86};
87
Jeff Tinkercc82dc62013-02-08 10:18:35 -080088Drm::Drm()
89 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080090 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070091 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080092 mFactory(NULL),
93 mPlugin(NULL) {
94}
95
96Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -080097 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -080098 delete mPlugin;
99 mPlugin = NULL;
100 closeFactory();
101}
102
103void Drm::closeFactory() {
104 delete mFactory;
105 mFactory = NULL;
106 mLibrary.clear();
107}
108
109status_t Drm::initCheck() const {
110 return mInitCheck;
111}
112
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700113status_t Drm::setListener(const sp<IDrmClient>& listener)
114{
115 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700116 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800117 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700118 }
119 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800120 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700121 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700122 mListener = listener;
123 return NO_ERROR;
124}
125
126void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
127 Vector<uint8_t> const *sessionId,
128 Vector<uint8_t> const *data)
129{
130 mEventLock.lock();
131 sp<IDrmClient> listener = mListener;
132 mEventLock.unlock();
133
134 if (listener != NULL) {
135 Parcel obj;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700136 writeByteArray(obj, sessionId);
137 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700138
139 Mutex::Autolock lock(mNotifyLock);
140 listener->notify(eventType, extra, &obj);
141 }
142}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800143
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700144void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
145 int64_t expiryTimeInMS)
146{
147 mEventLock.lock();
148 sp<IDrmClient> listener = mListener;
149 mEventLock.unlock();
150
151 if (listener != NULL) {
152 Parcel obj;
153 writeByteArray(obj, sessionId);
154 obj.writeInt64(expiryTimeInMS);
155
156 Mutex::Autolock lock(mNotifyLock);
157 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
158 }
159}
160
161void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
162 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
163 bool hasNewUsableKey)
164{
165 mEventLock.lock();
166 sp<IDrmClient> listener = mListener;
167 mEventLock.unlock();
168
169 if (listener != NULL) {
170 Parcel obj;
171 writeByteArray(obj, sessionId);
172
173 size_t nkeys = keyStatusList->size();
174 obj.writeInt32(keyStatusList->size());
175 for (size_t i = 0; i < nkeys; ++i) {
176 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
177 writeByteArray(obj, &keyStatus->mKeyId);
178 obj.writeInt32(keyStatus->mType);
179 }
180 obj.writeInt32(hasNewUsableKey);
181
182 Mutex::Autolock lock(mNotifyLock);
183 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
184 }
185}
186
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800187/*
188 * Search the plugins directory for a plugin that supports the scheme
189 * specified by uuid
190 *
191 * If found:
192 * mLibrary holds a strong pointer to the dlopen'd library
193 * mFactory is set to the library's factory method
194 * mInitCheck is set to OK
195 *
196 * If not found:
197 * mLibrary is cleared and mFactory are set to NULL
198 * mInitCheck is set to an error (!OK)
199 */
200void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
201
202 closeFactory();
203
204 // lock static maps
205 Mutex::Autolock autoLock(mMapLock);
206
207 // first check cache
208 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700209 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800210 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
211 if (index >= 0) {
212 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
213 mInitCheck = OK;
214 return;
215 } else {
216 ALOGE("Failed to load from cached library path!");
217 mInitCheck = ERROR_UNSUPPORTED;
218 return;
219 }
220 }
221
222 // no luck, have to search
223 String8 dirPath("/vendor/lib/mediadrm");
224 DIR* pDir = opendir(dirPath.string());
225
226 if (pDir == NULL) {
227 mInitCheck = ERROR_UNSUPPORTED;
228 ALOGE("Failed to open plugin directory %s", dirPath.string());
229 return;
230 }
231
232
233 struct dirent* pEntry;
234 while ((pEntry = readdir(pDir))) {
235
236 String8 pluginPath = dirPath + "/" + pEntry->d_name;
237
238 if (pluginPath.getPathExtension() == ".so") {
239
240 if (loadLibraryForScheme(pluginPath, uuid)) {
241 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
242 mInitCheck = OK;
243 closedir(pDir);
244 return;
245 }
246 }
247 }
248
249 closedir(pDir);
250
251 ALOGE("Failed to find drm plugin");
252 mInitCheck = ERROR_UNSUPPORTED;
253}
254
255bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
256
257 // get strong pointer to open shared library
258 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
259 if (index >= 0) {
260 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
261 } else {
262 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
263 }
264
265 if (!mLibrary.get()) {
266 mLibrary = new SharedLibrary(path);
267 if (!*mLibrary) {
268 return false;
269 }
270
271 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
272 }
273
274 typedef DrmFactory *(*CreateDrmFactoryFunc)();
275
276 CreateDrmFactoryFunc createDrmFactory =
277 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
278
279 if (createDrmFactory == NULL ||
280 (mFactory = createDrmFactory()) == NULL ||
281 !mFactory->isCryptoSchemeSupported(uuid)) {
282 closeFactory();
283 return false;
284 }
285 return true;
286}
287
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700288bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
289
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800290 Mutex::Autolock autoLock(mLock);
291
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700292 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
293 findFactoryForScheme(uuid);
294 if (mInitCheck != OK) {
295 return false;
296 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800297 }
298
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700299 if (mimeType != "") {
300 return mFactory->isContentTypeSupported(mimeType);
301 }
302
303 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800304}
305
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800306status_t Drm::createPlugin(const uint8_t uuid[16],
307 const String8& /* appPackageName */) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800308 Mutex::Autolock autoLock(mLock);
309
310 if (mPlugin != NULL) {
311 return -EINVAL;
312 }
313
314 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
315 findFactoryForScheme(uuid);
316 }
317
318 if (mInitCheck != OK) {
319 return mInitCheck;
320 }
321
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700322 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800323 if (mPlugin) {
324 mPlugin->setListener(this);
325 } else {
326 ALOGE("Failed to create plugin");
327 return UNEXPECTED_NULL;
328 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700329 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800330}
331
332status_t Drm::destroyPlugin() {
333 Mutex::Autolock autoLock(mLock);
334
335 if (mInitCheck != OK) {
336 return mInitCheck;
337 }
338
339 if (mPlugin == NULL) {
340 return -EINVAL;
341 }
342
Jeff Tinker9e27bc62016-10-19 18:20:47 -0700343 setListener(NULL);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800344 delete mPlugin;
345 mPlugin = NULL;
346
347 return OK;
348}
349
350status_t Drm::openSession(Vector<uint8_t> &sessionId) {
351 Mutex::Autolock autoLock(mLock);
352
353 if (mInitCheck != OK) {
354 return mInitCheck;
355 }
356
357 if (mPlugin == NULL) {
358 return -EINVAL;
359 }
360
Ronghua Wu5c3da202015-02-22 08:45:28 -0800361 status_t err = mPlugin->openSession(sessionId);
362 if (err == ERROR_DRM_RESOURCE_BUSY) {
363 bool retry = false;
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700364 mLock.unlock();
365 // reclaimSession may call back to closeSession, since mLock is shared between Drm
366 // instances, we should unlock here to avoid deadlock.
Ronghua Wu5c3da202015-02-22 08:45:28 -0800367 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700368 mLock.lock();
369 if (mInitCheck != OK) {
370 return mInitCheck;
371 }
372
373 if (mPlugin == NULL) {
374 return -EINVAL;
375 }
Ronghua Wu5c3da202015-02-22 08:45:28 -0800376 if (retry) {
377 err = mPlugin->openSession(sessionId);
378 }
379 }
380 if (err == OK) {
381 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
382 }
383 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800384}
385
386status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
387 Mutex::Autolock autoLock(mLock);
388
389 if (mInitCheck != OK) {
390 return mInitCheck;
391 }
392
393 if (mPlugin == NULL) {
394 return -EINVAL;
395 }
396
Ronghua Wu5c3da202015-02-22 08:45:28 -0800397 status_t err = mPlugin->closeSession(sessionId);
398 if (err == OK) {
399 DrmSessionManager::Instance()->removeSession(sessionId);
400 }
401 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800402}
403
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700404status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
405 Vector<uint8_t> const &initData,
406 String8 const &mimeType, DrmPlugin::KeyType keyType,
407 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700408 Vector<uint8_t> &request, String8 &defaultUrl,
409 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800410 Mutex::Autolock autoLock(mLock);
411
412 if (mInitCheck != OK) {
413 return mInitCheck;
414 }
415
416 if (mPlugin == NULL) {
417 return -EINVAL;
418 }
419
Ronghua Wu5c3da202015-02-22 08:45:28 -0800420 DrmSessionManager::Instance()->useSession(sessionId);
421
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700422 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700423 optionalParameters, request, defaultUrl,
424 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800425}
426
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700427status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
428 Vector<uint8_t> const &response,
429 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800430 Mutex::Autolock autoLock(mLock);
431
432 if (mInitCheck != OK) {
433 return mInitCheck;
434 }
435
436 if (mPlugin == NULL) {
437 return -EINVAL;
438 }
439
Ronghua Wu5c3da202015-02-22 08:45:28 -0800440 DrmSessionManager::Instance()->useSession(sessionId);
441
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700442 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800443}
444
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700445status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800446 Mutex::Autolock autoLock(mLock);
447
448 if (mInitCheck != OK) {
449 return mInitCheck;
450 }
451
452 if (mPlugin == NULL) {
453 return -EINVAL;
454 }
455
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700456 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800457}
458
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700459status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
460 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800461 Mutex::Autolock autoLock(mLock);
462
463 if (mInitCheck != OK) {
464 return mInitCheck;
465 }
466
467 if (mPlugin == NULL) {
468 return -EINVAL;
469 }
470
Ronghua Wu5c3da202015-02-22 08:45:28 -0800471 DrmSessionManager::Instance()->useSession(sessionId);
472
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700473 return mPlugin->restoreKeys(sessionId, keySetId);
474}
475
476status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
477 KeyedVector<String8, String8> &infoMap) const {
478 Mutex::Autolock autoLock(mLock);
479
480 if (mInitCheck != OK) {
481 return mInitCheck;
482 }
483
484 if (mPlugin == NULL) {
485 return -EINVAL;
486 }
487
Ronghua Wu5c3da202015-02-22 08:45:28 -0800488 DrmSessionManager::Instance()->useSession(sessionId);
489
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700490 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800491}
492
Jeff Tinker68d9d712014-03-04 13:21:31 -0800493status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
494 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800495 Mutex::Autolock autoLock(mLock);
496
497 if (mInitCheck != OK) {
498 return mInitCheck;
499 }
500
501 if (mPlugin == NULL) {
502 return -EINVAL;
503 }
504
Jeff Tinker68d9d712014-03-04 13:21:31 -0800505 return mPlugin->getProvisionRequest(certType, certAuthority,
506 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800507}
508
Jeff Tinker68d9d712014-03-04 13:21:31 -0800509status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
510 Vector<uint8_t> &certificate,
511 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800512 Mutex::Autolock autoLock(mLock);
513
514 if (mInitCheck != OK) {
515 return mInitCheck;
516 }
517
518 if (mPlugin == NULL) {
519 return -EINVAL;
520 }
521
Jeff Tinker68d9d712014-03-04 13:21:31 -0800522 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800523}
524
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800525status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
526 Mutex::Autolock autoLock(mLock);
527
528 if (mInitCheck != OK) {
529 return mInitCheck;
530 }
531
532 if (mPlugin == NULL) {
533 return -EINVAL;
534 }
535
536 return mPlugin->getSecureStops(secureStops);
537}
538
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700539status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
540 Mutex::Autolock autoLock(mLock);
541
542 if (mInitCheck != OK) {
543 return mInitCheck;
544 }
545
546 if (mPlugin == NULL) {
547 return -EINVAL;
548 }
549
550 return mPlugin->getSecureStop(ssid, secureStop);
551}
552
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800553status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
554 Mutex::Autolock autoLock(mLock);
555
556 if (mInitCheck != OK) {
557 return mInitCheck;
558 }
559
560 if (mPlugin == NULL) {
561 return -EINVAL;
562 }
563
564 return mPlugin->releaseSecureStops(ssRelease);
565}
566
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700567status_t Drm::releaseAllSecureStops() {
568 Mutex::Autolock autoLock(mLock);
569
570 if (mInitCheck != OK) {
571 return mInitCheck;
572 }
573
574 if (mPlugin == NULL) {
575 return -EINVAL;
576 }
577
578 return mPlugin->releaseAllSecureStops();
579}
580
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800581status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
582 Mutex::Autolock autoLock(mLock);
583
584 if (mInitCheck != OK) {
585 return mInitCheck;
586 }
587
588 if (mPlugin == NULL) {
589 return -EINVAL;
590 }
591
592 return mPlugin->getPropertyString(name, value);
593}
594
595status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
596 Mutex::Autolock autoLock(mLock);
597
598 if (mInitCheck != OK) {
599 return mInitCheck;
600 }
601
602 if (mPlugin == NULL) {
603 return -EINVAL;
604 }
605
606 return mPlugin->getPropertyByteArray(name, value);
607}
608
609status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
610 Mutex::Autolock autoLock(mLock);
611
612 if (mInitCheck != OK) {
613 return mInitCheck;
614 }
615
616 if (mPlugin == NULL) {
617 return -EINVAL;
618 }
619
620 return mPlugin->setPropertyString(name, value);
621}
622
623status_t Drm::setPropertyByteArray(String8 const &name,
624 Vector<uint8_t> const &value ) const {
625 Mutex::Autolock autoLock(mLock);
626
627 if (mInitCheck != OK) {
628 return mInitCheck;
629 }
630
631 if (mPlugin == NULL) {
632 return -EINVAL;
633 }
634
635 return mPlugin->setPropertyByteArray(name, value);
636}
637
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700638
639status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
640 String8 const &algorithm) {
641 Mutex::Autolock autoLock(mLock);
642
643 if (mInitCheck != OK) {
644 return mInitCheck;
645 }
646
647 if (mPlugin == NULL) {
648 return -EINVAL;
649 }
650
Ronghua Wu5c3da202015-02-22 08:45:28 -0800651 DrmSessionManager::Instance()->useSession(sessionId);
652
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700653 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
654}
655
656status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
657 String8 const &algorithm) {
658 Mutex::Autolock autoLock(mLock);
659
660 if (mInitCheck != OK) {
661 return mInitCheck;
662 }
663
664 if (mPlugin == NULL) {
665 return -EINVAL;
666 }
667
Ronghua Wu5c3da202015-02-22 08:45:28 -0800668 DrmSessionManager::Instance()->useSession(sessionId);
669
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700670 return mPlugin->setMacAlgorithm(sessionId, algorithm);
671}
672
673status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
674 Vector<uint8_t> const &keyId,
675 Vector<uint8_t> const &input,
676 Vector<uint8_t> const &iv,
677 Vector<uint8_t> &output) {
678 Mutex::Autolock autoLock(mLock);
679
680 if (mInitCheck != OK) {
681 return mInitCheck;
682 }
683
684 if (mPlugin == NULL) {
685 return -EINVAL;
686 }
687
Ronghua Wu5c3da202015-02-22 08:45:28 -0800688 DrmSessionManager::Instance()->useSession(sessionId);
689
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700690 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
691}
692
693status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
694 Vector<uint8_t> const &keyId,
695 Vector<uint8_t> const &input,
696 Vector<uint8_t> const &iv,
697 Vector<uint8_t> &output) {
698 Mutex::Autolock autoLock(mLock);
699
700 if (mInitCheck != OK) {
701 return mInitCheck;
702 }
703
704 if (mPlugin == NULL) {
705 return -EINVAL;
706 }
707
Ronghua Wu5c3da202015-02-22 08:45:28 -0800708 DrmSessionManager::Instance()->useSession(sessionId);
709
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700710 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
711}
712
713status_t Drm::sign(Vector<uint8_t> const &sessionId,
714 Vector<uint8_t> const &keyId,
715 Vector<uint8_t> const &message,
716 Vector<uint8_t> &signature) {
717 Mutex::Autolock autoLock(mLock);
718
719 if (mInitCheck != OK) {
720 return mInitCheck;
721 }
722
723 if (mPlugin == NULL) {
724 return -EINVAL;
725 }
726
Ronghua Wu5c3da202015-02-22 08:45:28 -0800727 DrmSessionManager::Instance()->useSession(sessionId);
728
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700729 return mPlugin->sign(sessionId, keyId, message, signature);
730}
731
732status_t Drm::verify(Vector<uint8_t> const &sessionId,
733 Vector<uint8_t> const &keyId,
734 Vector<uint8_t> const &message,
735 Vector<uint8_t> const &signature,
736 bool &match) {
737 Mutex::Autolock autoLock(mLock);
738
739 if (mInitCheck != OK) {
740 return mInitCheck;
741 }
742
743 if (mPlugin == NULL) {
744 return -EINVAL;
745 }
746
Ronghua Wu5c3da202015-02-22 08:45:28 -0800747 DrmSessionManager::Instance()->useSession(sessionId);
748
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700749 return mPlugin->verify(sessionId, keyId, message, signature, match);
750}
751
Jeff Tinker68d9d712014-03-04 13:21:31 -0800752status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
753 String8 const &algorithm,
754 Vector<uint8_t> const &message,
755 Vector<uint8_t> const &wrappedKey,
756 Vector<uint8_t> &signature) {
757 Mutex::Autolock autoLock(mLock);
758
759 if (mInitCheck != OK) {
760 return mInitCheck;
761 }
762
763 if (mPlugin == NULL) {
764 return -EINVAL;
765 }
766
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700767 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
768 return -EPERM;
769 }
770
Ronghua Wu5c3da202015-02-22 08:45:28 -0800771 DrmSessionManager::Instance()->useSession(sessionId);
772
Jeff Tinker68d9d712014-03-04 13:21:31 -0800773 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
774}
775
Lajos Molnar6d339f12015-04-17 16:15:53 -0700776void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700777{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800778 mEventLock.lock();
779 mListener.clear();
780 mEventLock.unlock();
781
782 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700783 delete mPlugin;
784 mPlugin = NULL;
785 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700786}
787
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700788void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
789{
790 if (array && array->size()) {
791 obj.writeInt32(array->size());
792 obj.write(array->array(), array->size());
793 } else {
794 obj.writeInt32(0);
795 }
796}
797
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800798} // namespace android