blob: d55482d40e9ac78b939772d8b9d79da66b2f0dee [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
24#include "Drm.h"
25
Ronghua Wu5c3da202015-02-22 08:45:28 -080026#include "DrmSessionClientInterface.h"
27#include "DrmSessionManager.h"
Jeff Tinkercc82dc62013-02-08 10:18:35 -080028#include <media/drm/DrmAPI.h>
29#include <media/stagefright/foundation/ADebug.h>
30#include <media/stagefright/foundation/AString.h>
31#include <media/stagefright/foundation/hexdump.h>
32#include <media/stagefright/MediaErrors.h>
Jeff Tinker81e0bd42014-04-02 16:41:38 -070033#include <binder/IServiceManager.h>
34#include <binder/IPCThreadState.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080035
36namespace android {
37
Ronghua Wu5c3da202015-02-22 08:45:28 -080038static inline int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
Jeff Tinker81e0bd42014-04-02 16:41:38 -070042static bool checkPermission(const char* permissionString) {
43#ifndef HAVE_ANDROID_OS
44 return true;
45#endif
46 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
47 bool ok = checkCallingPermission(String16(permissionString));
48 if (!ok) ALOGE("Request requires %s", permissionString);
49 return ok;
50}
51
Jeff Tinkercc82dc62013-02-08 10:18:35 -080052KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
53KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
54Mutex Drm::mMapLock;
Jeff Tinker2fb561a2015-04-22 15:58:16 -070055Mutex Drm::mLock;
Jeff Tinkercc82dc62013-02-08 10:18:35 -080056
57static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
58 if (lhs.size() < rhs.size()) {
59 return true;
60 } else if (lhs.size() > rhs.size()) {
61 return false;
62 }
63
64 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
65}
66
Ronghua Wu5c3da202015-02-22 08:45:28 -080067struct DrmSessionClient : public DrmSessionClientInterface {
68 DrmSessionClient(Drm* drm) : mDrm(drm) {}
69
70 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
71 sp<Drm> drm = mDrm.promote();
72 if (drm == NULL) {
73 return true;
74 }
75 status_t err = drm->closeSession(sessionId);
76 if (err != OK) {
77 return false;
78 }
79 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
80 return true;
81 }
82
83protected:
84 virtual ~DrmSessionClient() {}
85
86private:
87 wp<Drm> mDrm;
88
89 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
90};
91
Jeff Tinkercc82dc62013-02-08 10:18:35 -080092Drm::Drm()
93 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080094 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070095 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080096 mFactory(NULL),
97 mPlugin(NULL) {
98}
99
100Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -0800101 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800102 delete mPlugin;
103 mPlugin = NULL;
104 closeFactory();
105}
106
107void Drm::closeFactory() {
108 delete mFactory;
109 mFactory = NULL;
110 mLibrary.clear();
111}
112
113status_t Drm::initCheck() const {
114 return mInitCheck;
115}
116
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700117status_t Drm::setListener(const sp<IDrmClient>& listener)
118{
119 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700120 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800121 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700122 }
123 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800124 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700125 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700126 mListener = listener;
127 return NO_ERROR;
128}
129
130void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
131 Vector<uint8_t> const *sessionId,
132 Vector<uint8_t> const *data)
133{
134 mEventLock.lock();
135 sp<IDrmClient> listener = mListener;
136 mEventLock.unlock();
137
138 if (listener != NULL) {
139 Parcel obj;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700140 writeByteArray(obj, sessionId);
141 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700142
143 Mutex::Autolock lock(mNotifyLock);
144 listener->notify(eventType, extra, &obj);
145 }
146}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800147
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700148void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
149 int64_t expiryTimeInMS)
150{
151 mEventLock.lock();
152 sp<IDrmClient> listener = mListener;
153 mEventLock.unlock();
154
155 if (listener != NULL) {
156 Parcel obj;
157 writeByteArray(obj, sessionId);
158 obj.writeInt64(expiryTimeInMS);
159
160 Mutex::Autolock lock(mNotifyLock);
161 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
162 }
163}
164
165void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
166 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
167 bool hasNewUsableKey)
168{
169 mEventLock.lock();
170 sp<IDrmClient> listener = mListener;
171 mEventLock.unlock();
172
173 if (listener != NULL) {
174 Parcel obj;
175 writeByteArray(obj, sessionId);
176
177 size_t nkeys = keyStatusList->size();
178 obj.writeInt32(keyStatusList->size());
179 for (size_t i = 0; i < nkeys; ++i) {
180 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
181 writeByteArray(obj, &keyStatus->mKeyId);
182 obj.writeInt32(keyStatus->mType);
183 }
184 obj.writeInt32(hasNewUsableKey);
185
186 Mutex::Autolock lock(mNotifyLock);
187 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
188 }
189}
190
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800191/*
192 * Search the plugins directory for a plugin that supports the scheme
193 * specified by uuid
194 *
195 * If found:
196 * mLibrary holds a strong pointer to the dlopen'd library
197 * mFactory is set to the library's factory method
198 * mInitCheck is set to OK
199 *
200 * If not found:
201 * mLibrary is cleared and mFactory are set to NULL
202 * mInitCheck is set to an error (!OK)
203 */
204void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
205
206 closeFactory();
207
208 // lock static maps
209 Mutex::Autolock autoLock(mMapLock);
210
211 // first check cache
212 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700213 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800214 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
215 if (index >= 0) {
216 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
217 mInitCheck = OK;
218 return;
219 } else {
220 ALOGE("Failed to load from cached library path!");
221 mInitCheck = ERROR_UNSUPPORTED;
222 return;
223 }
224 }
225
226 // no luck, have to search
227 String8 dirPath("/vendor/lib/mediadrm");
228 DIR* pDir = opendir(dirPath.string());
229
230 if (pDir == NULL) {
231 mInitCheck = ERROR_UNSUPPORTED;
232 ALOGE("Failed to open plugin directory %s", dirPath.string());
233 return;
234 }
235
236
237 struct dirent* pEntry;
238 while ((pEntry = readdir(pDir))) {
239
240 String8 pluginPath = dirPath + "/" + pEntry->d_name;
241
242 if (pluginPath.getPathExtension() == ".so") {
243
244 if (loadLibraryForScheme(pluginPath, uuid)) {
245 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
246 mInitCheck = OK;
247 closedir(pDir);
248 return;
249 }
250 }
251 }
252
253 closedir(pDir);
254
255 ALOGE("Failed to find drm plugin");
256 mInitCheck = ERROR_UNSUPPORTED;
257}
258
259bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
260
261 // get strong pointer to open shared library
262 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
263 if (index >= 0) {
264 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
265 } else {
266 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
267 }
268
269 if (!mLibrary.get()) {
270 mLibrary = new SharedLibrary(path);
271 if (!*mLibrary) {
272 return false;
273 }
274
275 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
276 }
277
278 typedef DrmFactory *(*CreateDrmFactoryFunc)();
279
280 CreateDrmFactoryFunc createDrmFactory =
281 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
282
283 if (createDrmFactory == NULL ||
284 (mFactory = createDrmFactory()) == NULL ||
285 !mFactory->isCryptoSchemeSupported(uuid)) {
286 closeFactory();
287 return false;
288 }
289 return true;
290}
291
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700292bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
293
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800294 Mutex::Autolock autoLock(mLock);
295
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700296 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
297 findFactoryForScheme(uuid);
298 if (mInitCheck != OK) {
299 return false;
300 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800301 }
302
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700303 if (mimeType != "") {
304 return mFactory->isContentTypeSupported(mimeType);
305 }
306
307 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800308}
309
310status_t Drm::createPlugin(const uint8_t uuid[16]) {
311 Mutex::Autolock autoLock(mLock);
312
313 if (mPlugin != NULL) {
314 return -EINVAL;
315 }
316
317 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
318 findFactoryForScheme(uuid);
319 }
320
321 if (mInitCheck != OK) {
322 return mInitCheck;
323 }
324
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700325 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
326 mPlugin->setListener(this);
327 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800328}
329
330status_t Drm::destroyPlugin() {
331 Mutex::Autolock autoLock(mLock);
332
333 if (mInitCheck != OK) {
334 return mInitCheck;
335 }
336
337 if (mPlugin == NULL) {
338 return -EINVAL;
339 }
340
341 delete mPlugin;
342 mPlugin = NULL;
343
344 return OK;
345}
346
347status_t Drm::openSession(Vector<uint8_t> &sessionId) {
348 Mutex::Autolock autoLock(mLock);
349
350 if (mInitCheck != OK) {
351 return mInitCheck;
352 }
353
354 if (mPlugin == NULL) {
355 return -EINVAL;
356 }
357
Ronghua Wu5c3da202015-02-22 08:45:28 -0800358 status_t err = mPlugin->openSession(sessionId);
359 if (err == ERROR_DRM_RESOURCE_BUSY) {
360 bool retry = false;
361 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
362 if (retry) {
363 err = mPlugin->openSession(sessionId);
364 }
365 }
366 if (err == OK) {
367 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
368 }
369 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800370}
371
372status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
373 Mutex::Autolock autoLock(mLock);
374
375 if (mInitCheck != OK) {
376 return mInitCheck;
377 }
378
379 if (mPlugin == NULL) {
380 return -EINVAL;
381 }
382
Ronghua Wu5c3da202015-02-22 08:45:28 -0800383 status_t err = mPlugin->closeSession(sessionId);
384 if (err == OK) {
385 DrmSessionManager::Instance()->removeSession(sessionId);
386 }
387 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800388}
389
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700390status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
391 Vector<uint8_t> const &initData,
392 String8 const &mimeType, DrmPlugin::KeyType keyType,
393 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700394 Vector<uint8_t> &request, String8 &defaultUrl,
395 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800396 Mutex::Autolock autoLock(mLock);
397
398 if (mInitCheck != OK) {
399 return mInitCheck;
400 }
401
402 if (mPlugin == NULL) {
403 return -EINVAL;
404 }
405
Ronghua Wu5c3da202015-02-22 08:45:28 -0800406 DrmSessionManager::Instance()->useSession(sessionId);
407
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700408 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700409 optionalParameters, request, defaultUrl,
410 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800411}
412
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700413status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
414 Vector<uint8_t> const &response,
415 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800416 Mutex::Autolock autoLock(mLock);
417
418 if (mInitCheck != OK) {
419 return mInitCheck;
420 }
421
422 if (mPlugin == NULL) {
423 return -EINVAL;
424 }
425
Ronghua Wu5c3da202015-02-22 08:45:28 -0800426 DrmSessionManager::Instance()->useSession(sessionId);
427
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700428 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800429}
430
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700431status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800432 Mutex::Autolock autoLock(mLock);
433
434 if (mInitCheck != OK) {
435 return mInitCheck;
436 }
437
438 if (mPlugin == NULL) {
439 return -EINVAL;
440 }
441
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700442 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800443}
444
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700445status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
446 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800447 Mutex::Autolock autoLock(mLock);
448
449 if (mInitCheck != OK) {
450 return mInitCheck;
451 }
452
453 if (mPlugin == NULL) {
454 return -EINVAL;
455 }
456
Ronghua Wu5c3da202015-02-22 08:45:28 -0800457 DrmSessionManager::Instance()->useSession(sessionId);
458
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700459 return mPlugin->restoreKeys(sessionId, keySetId);
460}
461
462status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
463 KeyedVector<String8, String8> &infoMap) const {
464 Mutex::Autolock autoLock(mLock);
465
466 if (mInitCheck != OK) {
467 return mInitCheck;
468 }
469
470 if (mPlugin == NULL) {
471 return -EINVAL;
472 }
473
Ronghua Wu5c3da202015-02-22 08:45:28 -0800474 DrmSessionManager::Instance()->useSession(sessionId);
475
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700476 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800477}
478
Jeff Tinker68d9d712014-03-04 13:21:31 -0800479status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
480 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800481 Mutex::Autolock autoLock(mLock);
482
483 if (mInitCheck != OK) {
484 return mInitCheck;
485 }
486
487 if (mPlugin == NULL) {
488 return -EINVAL;
489 }
490
Jeff Tinker68d9d712014-03-04 13:21:31 -0800491 return mPlugin->getProvisionRequest(certType, certAuthority,
492 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800493}
494
Jeff Tinker68d9d712014-03-04 13:21:31 -0800495status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
496 Vector<uint8_t> &certificate,
497 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800498 Mutex::Autolock autoLock(mLock);
499
500 if (mInitCheck != OK) {
501 return mInitCheck;
502 }
503
504 if (mPlugin == NULL) {
505 return -EINVAL;
506 }
507
Jeff Tinker68d9d712014-03-04 13:21:31 -0800508 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800509}
510
Jeff Tinker68b15552014-04-30 10:19:03 -0700511status_t Drm::unprovisionDevice() {
512 Mutex::Autolock autoLock(mLock);
513
514 if (mInitCheck != OK) {
515 return mInitCheck;
516 }
517
518 if (mPlugin == NULL) {
519 return -EINVAL;
520 }
521
522 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
523 return -EPERM;
524 }
525
526 return mPlugin->unprovisionDevice();
527}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800528
529status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
530 Mutex::Autolock autoLock(mLock);
531
532 if (mInitCheck != OK) {
533 return mInitCheck;
534 }
535
536 if (mPlugin == NULL) {
537 return -EINVAL;
538 }
539
540 return mPlugin->getSecureStops(secureStops);
541}
542
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700543status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
544 Mutex::Autolock autoLock(mLock);
545
546 if (mInitCheck != OK) {
547 return mInitCheck;
548 }
549
550 if (mPlugin == NULL) {
551 return -EINVAL;
552 }
553
554 return mPlugin->getSecureStop(ssid, secureStop);
555}
556
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800557status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
558 Mutex::Autolock autoLock(mLock);
559
560 if (mInitCheck != OK) {
561 return mInitCheck;
562 }
563
564 if (mPlugin == NULL) {
565 return -EINVAL;
566 }
567
568 return mPlugin->releaseSecureStops(ssRelease);
569}
570
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700571status_t Drm::releaseAllSecureStops() {
572 Mutex::Autolock autoLock(mLock);
573
574 if (mInitCheck != OK) {
575 return mInitCheck;
576 }
577
578 if (mPlugin == NULL) {
579 return -EINVAL;
580 }
581
582 return mPlugin->releaseAllSecureStops();
583}
584
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800585status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
586 Mutex::Autolock autoLock(mLock);
587
588 if (mInitCheck != OK) {
589 return mInitCheck;
590 }
591
592 if (mPlugin == NULL) {
593 return -EINVAL;
594 }
595
596 return mPlugin->getPropertyString(name, value);
597}
598
599status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
600 Mutex::Autolock autoLock(mLock);
601
602 if (mInitCheck != OK) {
603 return mInitCheck;
604 }
605
606 if (mPlugin == NULL) {
607 return -EINVAL;
608 }
609
610 return mPlugin->getPropertyByteArray(name, value);
611}
612
613status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
614 Mutex::Autolock autoLock(mLock);
615
616 if (mInitCheck != OK) {
617 return mInitCheck;
618 }
619
620 if (mPlugin == NULL) {
621 return -EINVAL;
622 }
623
624 return mPlugin->setPropertyString(name, value);
625}
626
627status_t Drm::setPropertyByteArray(String8 const &name,
628 Vector<uint8_t> const &value ) const {
629 Mutex::Autolock autoLock(mLock);
630
631 if (mInitCheck != OK) {
632 return mInitCheck;
633 }
634
635 if (mPlugin == NULL) {
636 return -EINVAL;
637 }
638
639 return mPlugin->setPropertyByteArray(name, value);
640}
641
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700642
643status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
644 String8 const &algorithm) {
645 Mutex::Autolock autoLock(mLock);
646
647 if (mInitCheck != OK) {
648 return mInitCheck;
649 }
650
651 if (mPlugin == NULL) {
652 return -EINVAL;
653 }
654
Ronghua Wu5c3da202015-02-22 08:45:28 -0800655 DrmSessionManager::Instance()->useSession(sessionId);
656
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700657 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
658}
659
660status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
661 String8 const &algorithm) {
662 Mutex::Autolock autoLock(mLock);
663
664 if (mInitCheck != OK) {
665 return mInitCheck;
666 }
667
668 if (mPlugin == NULL) {
669 return -EINVAL;
670 }
671
Ronghua Wu5c3da202015-02-22 08:45:28 -0800672 DrmSessionManager::Instance()->useSession(sessionId);
673
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700674 return mPlugin->setMacAlgorithm(sessionId, algorithm);
675}
676
677status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
678 Vector<uint8_t> const &keyId,
679 Vector<uint8_t> const &input,
680 Vector<uint8_t> const &iv,
681 Vector<uint8_t> &output) {
682 Mutex::Autolock autoLock(mLock);
683
684 if (mInitCheck != OK) {
685 return mInitCheck;
686 }
687
688 if (mPlugin == NULL) {
689 return -EINVAL;
690 }
691
Ronghua Wu5c3da202015-02-22 08:45:28 -0800692 DrmSessionManager::Instance()->useSession(sessionId);
693
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700694 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
695}
696
697status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
698 Vector<uint8_t> const &keyId,
699 Vector<uint8_t> const &input,
700 Vector<uint8_t> const &iv,
701 Vector<uint8_t> &output) {
702 Mutex::Autolock autoLock(mLock);
703
704 if (mInitCheck != OK) {
705 return mInitCheck;
706 }
707
708 if (mPlugin == NULL) {
709 return -EINVAL;
710 }
711
Ronghua Wu5c3da202015-02-22 08:45:28 -0800712 DrmSessionManager::Instance()->useSession(sessionId);
713
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700714 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
715}
716
717status_t Drm::sign(Vector<uint8_t> const &sessionId,
718 Vector<uint8_t> const &keyId,
719 Vector<uint8_t> const &message,
720 Vector<uint8_t> &signature) {
721 Mutex::Autolock autoLock(mLock);
722
723 if (mInitCheck != OK) {
724 return mInitCheck;
725 }
726
727 if (mPlugin == NULL) {
728 return -EINVAL;
729 }
730
Ronghua Wu5c3da202015-02-22 08:45:28 -0800731 DrmSessionManager::Instance()->useSession(sessionId);
732
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700733 return mPlugin->sign(sessionId, keyId, message, signature);
734}
735
736status_t Drm::verify(Vector<uint8_t> const &sessionId,
737 Vector<uint8_t> const &keyId,
738 Vector<uint8_t> const &message,
739 Vector<uint8_t> const &signature,
740 bool &match) {
741 Mutex::Autolock autoLock(mLock);
742
743 if (mInitCheck != OK) {
744 return mInitCheck;
745 }
746
747 if (mPlugin == NULL) {
748 return -EINVAL;
749 }
750
Ronghua Wu5c3da202015-02-22 08:45:28 -0800751 DrmSessionManager::Instance()->useSession(sessionId);
752
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700753 return mPlugin->verify(sessionId, keyId, message, signature, match);
754}
755
Jeff Tinker68d9d712014-03-04 13:21:31 -0800756status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
757 String8 const &algorithm,
758 Vector<uint8_t> const &message,
759 Vector<uint8_t> const &wrappedKey,
760 Vector<uint8_t> &signature) {
761 Mutex::Autolock autoLock(mLock);
762
763 if (mInitCheck != OK) {
764 return mInitCheck;
765 }
766
767 if (mPlugin == NULL) {
768 return -EINVAL;
769 }
770
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700771 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
772 return -EPERM;
773 }
774
Ronghua Wu5c3da202015-02-22 08:45:28 -0800775 DrmSessionManager::Instance()->useSession(sessionId);
776
Jeff Tinker68d9d712014-03-04 13:21:31 -0800777 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
778}
779
Lajos Molnar6d339f12015-04-17 16:15:53 -0700780void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700781{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800782 mEventLock.lock();
783 mListener.clear();
784 mEventLock.unlock();
785
786 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700787 delete mPlugin;
788 mPlugin = NULL;
789 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700790}
791
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700792void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
793{
794 if (array && array->size()) {
795 obj.writeInt32(array->size());
796 obj.write(array->array(), array->size());
797 } else {
798 obj.writeInt32(0);
799 }
800}
801
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800802} // namespace android