blob: b9cfe80d19cbd2b764b279b4b6cb2f1070556660 [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) {
Jeff Tinker81e0bd42014-04-02 16:41:38 -070043 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
44 bool ok = checkCallingPermission(String16(permissionString));
45 if (!ok) ALOGE("Request requires %s", permissionString);
46 return ok;
47}
48
Jeff Tinkercc82dc62013-02-08 10:18:35 -080049KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
50KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
51Mutex Drm::mMapLock;
Jeff Tinker2fb561a2015-04-22 15:58:16 -070052Mutex Drm::mLock;
Jeff Tinkercc82dc62013-02-08 10:18:35 -080053
54static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
55 if (lhs.size() < rhs.size()) {
56 return true;
57 } else if (lhs.size() > rhs.size()) {
58 return false;
59 }
60
61 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
62}
63
Ronghua Wu5c3da202015-02-22 08:45:28 -080064struct DrmSessionClient : public DrmSessionClientInterface {
65 DrmSessionClient(Drm* drm) : mDrm(drm) {}
66
67 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
68 sp<Drm> drm = mDrm.promote();
69 if (drm == NULL) {
70 return true;
71 }
72 status_t err = drm->closeSession(sessionId);
73 if (err != OK) {
74 return false;
75 }
76 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
77 return true;
78 }
79
80protected:
81 virtual ~DrmSessionClient() {}
82
83private:
84 wp<Drm> mDrm;
85
86 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
87};
88
Jeff Tinkercc82dc62013-02-08 10:18:35 -080089Drm::Drm()
90 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080091 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070092 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080093 mFactory(NULL),
94 mPlugin(NULL) {
95}
96
97Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -080098 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -080099 delete mPlugin;
100 mPlugin = NULL;
101 closeFactory();
102}
103
104void Drm::closeFactory() {
105 delete mFactory;
106 mFactory = NULL;
107 mLibrary.clear();
108}
109
110status_t Drm::initCheck() const {
111 return mInitCheck;
112}
113
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700114status_t Drm::setListener(const sp<IDrmClient>& listener)
115{
116 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700117 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800118 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700119 }
120 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800121 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700122 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700123 mListener = listener;
124 return NO_ERROR;
125}
126
127void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
128 Vector<uint8_t> const *sessionId,
129 Vector<uint8_t> const *data)
130{
131 mEventLock.lock();
132 sp<IDrmClient> listener = mListener;
133 mEventLock.unlock();
134
135 if (listener != NULL) {
136 Parcel obj;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700137 writeByteArray(obj, sessionId);
138 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700139
140 Mutex::Autolock lock(mNotifyLock);
141 listener->notify(eventType, extra, &obj);
142 }
143}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800144
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700145void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
146 int64_t expiryTimeInMS)
147{
148 mEventLock.lock();
149 sp<IDrmClient> listener = mListener;
150 mEventLock.unlock();
151
152 if (listener != NULL) {
153 Parcel obj;
154 writeByteArray(obj, sessionId);
155 obj.writeInt64(expiryTimeInMS);
156
157 Mutex::Autolock lock(mNotifyLock);
158 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
159 }
160}
161
162void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
163 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
164 bool hasNewUsableKey)
165{
166 mEventLock.lock();
167 sp<IDrmClient> listener = mListener;
168 mEventLock.unlock();
169
170 if (listener != NULL) {
171 Parcel obj;
172 writeByteArray(obj, sessionId);
173
174 size_t nkeys = keyStatusList->size();
175 obj.writeInt32(keyStatusList->size());
176 for (size_t i = 0; i < nkeys; ++i) {
177 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
178 writeByteArray(obj, &keyStatus->mKeyId);
179 obj.writeInt32(keyStatus->mType);
180 }
181 obj.writeInt32(hasNewUsableKey);
182
183 Mutex::Autolock lock(mNotifyLock);
184 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
185 }
186}
187
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800188/*
189 * Search the plugins directory for a plugin that supports the scheme
190 * specified by uuid
191 *
192 * If found:
193 * mLibrary holds a strong pointer to the dlopen'd library
194 * mFactory is set to the library's factory method
195 * mInitCheck is set to OK
196 *
197 * If not found:
198 * mLibrary is cleared and mFactory are set to NULL
199 * mInitCheck is set to an error (!OK)
200 */
201void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
202
203 closeFactory();
204
205 // lock static maps
206 Mutex::Autolock autoLock(mMapLock);
207
208 // first check cache
209 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700210 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800211 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
212 if (index >= 0) {
213 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
214 mInitCheck = OK;
215 return;
216 } else {
217 ALOGE("Failed to load from cached library path!");
218 mInitCheck = ERROR_UNSUPPORTED;
219 return;
220 }
221 }
222
223 // no luck, have to search
224 String8 dirPath("/vendor/lib/mediadrm");
225 DIR* pDir = opendir(dirPath.string());
226
227 if (pDir == NULL) {
228 mInitCheck = ERROR_UNSUPPORTED;
229 ALOGE("Failed to open plugin directory %s", dirPath.string());
230 return;
231 }
232
233
234 struct dirent* pEntry;
235 while ((pEntry = readdir(pDir))) {
236
237 String8 pluginPath = dirPath + "/" + pEntry->d_name;
238
239 if (pluginPath.getPathExtension() == ".so") {
240
241 if (loadLibraryForScheme(pluginPath, uuid)) {
242 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
243 mInitCheck = OK;
244 closedir(pDir);
245 return;
246 }
247 }
248 }
249
250 closedir(pDir);
251
252 ALOGE("Failed to find drm plugin");
253 mInitCheck = ERROR_UNSUPPORTED;
254}
255
256bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
257
258 // get strong pointer to open shared library
259 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
260 if (index >= 0) {
261 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
262 } else {
263 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
264 }
265
266 if (!mLibrary.get()) {
267 mLibrary = new SharedLibrary(path);
268 if (!*mLibrary) {
269 return false;
270 }
271
272 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
273 }
274
275 typedef DrmFactory *(*CreateDrmFactoryFunc)();
276
277 CreateDrmFactoryFunc createDrmFactory =
278 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
279
280 if (createDrmFactory == NULL ||
281 (mFactory = createDrmFactory()) == NULL ||
282 !mFactory->isCryptoSchemeSupported(uuid)) {
283 closeFactory();
284 return false;
285 }
286 return true;
287}
288
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700289bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
290
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800291 Mutex::Autolock autoLock(mLock);
292
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700293 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
294 findFactoryForScheme(uuid);
295 if (mInitCheck != OK) {
296 return false;
297 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800298 }
299
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700300 if (mimeType != "") {
301 return mFactory->isContentTypeSupported(mimeType);
302 }
303
304 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800305}
306
307status_t Drm::createPlugin(const uint8_t uuid[16]) {
308 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);
323 mPlugin->setListener(this);
324 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800325}
326
327status_t Drm::destroyPlugin() {
328 Mutex::Autolock autoLock(mLock);
329
330 if (mInitCheck != OK) {
331 return mInitCheck;
332 }
333
334 if (mPlugin == NULL) {
335 return -EINVAL;
336 }
337
338 delete mPlugin;
339 mPlugin = NULL;
340
341 return OK;
342}
343
344status_t Drm::openSession(Vector<uint8_t> &sessionId) {
345 Mutex::Autolock autoLock(mLock);
346
347 if (mInitCheck != OK) {
348 return mInitCheck;
349 }
350
351 if (mPlugin == NULL) {
352 return -EINVAL;
353 }
354
Ronghua Wu5c3da202015-02-22 08:45:28 -0800355 status_t err = mPlugin->openSession(sessionId);
356 if (err == ERROR_DRM_RESOURCE_BUSY) {
357 bool retry = false;
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700358 mLock.unlock();
359 // reclaimSession may call back to closeSession, since mLock is shared between Drm
360 // instances, we should unlock here to avoid deadlock.
Ronghua Wu5c3da202015-02-22 08:45:28 -0800361 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700362 mLock.lock();
363 if (mInitCheck != OK) {
364 return mInitCheck;
365 }
366
367 if (mPlugin == NULL) {
368 return -EINVAL;
369 }
Ronghua Wu5c3da202015-02-22 08:45:28 -0800370 if (retry) {
371 err = mPlugin->openSession(sessionId);
372 }
373 }
374 if (err == OK) {
375 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
376 }
377 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800378}
379
380status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
381 Mutex::Autolock autoLock(mLock);
382
383 if (mInitCheck != OK) {
384 return mInitCheck;
385 }
386
387 if (mPlugin == NULL) {
388 return -EINVAL;
389 }
390
Ronghua Wu5c3da202015-02-22 08:45:28 -0800391 status_t err = mPlugin->closeSession(sessionId);
392 if (err == OK) {
393 DrmSessionManager::Instance()->removeSession(sessionId);
394 }
395 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800396}
397
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700398status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
399 Vector<uint8_t> const &initData,
400 String8 const &mimeType, DrmPlugin::KeyType keyType,
401 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700402 Vector<uint8_t> &request, String8 &defaultUrl,
403 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800404 Mutex::Autolock autoLock(mLock);
405
406 if (mInitCheck != OK) {
407 return mInitCheck;
408 }
409
410 if (mPlugin == NULL) {
411 return -EINVAL;
412 }
413
Ronghua Wu5c3da202015-02-22 08:45:28 -0800414 DrmSessionManager::Instance()->useSession(sessionId);
415
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700416 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700417 optionalParameters, request, defaultUrl,
418 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800419}
420
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700421status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
422 Vector<uint8_t> const &response,
423 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800424 Mutex::Autolock autoLock(mLock);
425
426 if (mInitCheck != OK) {
427 return mInitCheck;
428 }
429
430 if (mPlugin == NULL) {
431 return -EINVAL;
432 }
433
Ronghua Wu5c3da202015-02-22 08:45:28 -0800434 DrmSessionManager::Instance()->useSession(sessionId);
435
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700436 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800437}
438
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700439status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800440 Mutex::Autolock autoLock(mLock);
441
442 if (mInitCheck != OK) {
443 return mInitCheck;
444 }
445
446 if (mPlugin == NULL) {
447 return -EINVAL;
448 }
449
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700450 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800451}
452
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700453status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
454 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800455 Mutex::Autolock autoLock(mLock);
456
457 if (mInitCheck != OK) {
458 return mInitCheck;
459 }
460
461 if (mPlugin == NULL) {
462 return -EINVAL;
463 }
464
Ronghua Wu5c3da202015-02-22 08:45:28 -0800465 DrmSessionManager::Instance()->useSession(sessionId);
466
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700467 return mPlugin->restoreKeys(sessionId, keySetId);
468}
469
470status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
471 KeyedVector<String8, String8> &infoMap) const {
472 Mutex::Autolock autoLock(mLock);
473
474 if (mInitCheck != OK) {
475 return mInitCheck;
476 }
477
478 if (mPlugin == NULL) {
479 return -EINVAL;
480 }
481
Ronghua Wu5c3da202015-02-22 08:45:28 -0800482 DrmSessionManager::Instance()->useSession(sessionId);
483
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700484 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800485}
486
Jeff Tinker68d9d712014-03-04 13:21:31 -0800487status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
488 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800489 Mutex::Autolock autoLock(mLock);
490
491 if (mInitCheck != OK) {
492 return mInitCheck;
493 }
494
495 if (mPlugin == NULL) {
496 return -EINVAL;
497 }
498
Jeff Tinker68d9d712014-03-04 13:21:31 -0800499 return mPlugin->getProvisionRequest(certType, certAuthority,
500 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800501}
502
Jeff Tinker68d9d712014-03-04 13:21:31 -0800503status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
504 Vector<uint8_t> &certificate,
505 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800506 Mutex::Autolock autoLock(mLock);
507
508 if (mInitCheck != OK) {
509 return mInitCheck;
510 }
511
512 if (mPlugin == NULL) {
513 return -EINVAL;
514 }
515
Jeff Tinker68d9d712014-03-04 13:21:31 -0800516 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800517}
518
Jeff Tinker68b15552014-04-30 10:19:03 -0700519status_t Drm::unprovisionDevice() {
520 Mutex::Autolock autoLock(mLock);
521
522 if (mInitCheck != OK) {
523 return mInitCheck;
524 }
525
526 if (mPlugin == NULL) {
527 return -EINVAL;
528 }
529
530 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
531 return -EPERM;
532 }
533
534 return mPlugin->unprovisionDevice();
535}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800536
537status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
538 Mutex::Autolock autoLock(mLock);
539
540 if (mInitCheck != OK) {
541 return mInitCheck;
542 }
543
544 if (mPlugin == NULL) {
545 return -EINVAL;
546 }
547
548 return mPlugin->getSecureStops(secureStops);
549}
550
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700551status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
552 Mutex::Autolock autoLock(mLock);
553
554 if (mInitCheck != OK) {
555 return mInitCheck;
556 }
557
558 if (mPlugin == NULL) {
559 return -EINVAL;
560 }
561
562 return mPlugin->getSecureStop(ssid, secureStop);
563}
564
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800565status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
566 Mutex::Autolock autoLock(mLock);
567
568 if (mInitCheck != OK) {
569 return mInitCheck;
570 }
571
572 if (mPlugin == NULL) {
573 return -EINVAL;
574 }
575
576 return mPlugin->releaseSecureStops(ssRelease);
577}
578
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700579status_t Drm::releaseAllSecureStops() {
580 Mutex::Autolock autoLock(mLock);
581
582 if (mInitCheck != OK) {
583 return mInitCheck;
584 }
585
586 if (mPlugin == NULL) {
587 return -EINVAL;
588 }
589
590 return mPlugin->releaseAllSecureStops();
591}
592
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800593status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
594 Mutex::Autolock autoLock(mLock);
595
596 if (mInitCheck != OK) {
597 return mInitCheck;
598 }
599
600 if (mPlugin == NULL) {
601 return -EINVAL;
602 }
603
604 return mPlugin->getPropertyString(name, value);
605}
606
607status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
608 Mutex::Autolock autoLock(mLock);
609
610 if (mInitCheck != OK) {
611 return mInitCheck;
612 }
613
614 if (mPlugin == NULL) {
615 return -EINVAL;
616 }
617
618 return mPlugin->getPropertyByteArray(name, value);
619}
620
621status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
622 Mutex::Autolock autoLock(mLock);
623
624 if (mInitCheck != OK) {
625 return mInitCheck;
626 }
627
628 if (mPlugin == NULL) {
629 return -EINVAL;
630 }
631
632 return mPlugin->setPropertyString(name, value);
633}
634
635status_t Drm::setPropertyByteArray(String8 const &name,
636 Vector<uint8_t> const &value ) const {
637 Mutex::Autolock autoLock(mLock);
638
639 if (mInitCheck != OK) {
640 return mInitCheck;
641 }
642
643 if (mPlugin == NULL) {
644 return -EINVAL;
645 }
646
647 return mPlugin->setPropertyByteArray(name, value);
648}
649
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700650
651status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
652 String8 const &algorithm) {
653 Mutex::Autolock autoLock(mLock);
654
655 if (mInitCheck != OK) {
656 return mInitCheck;
657 }
658
659 if (mPlugin == NULL) {
660 return -EINVAL;
661 }
662
Ronghua Wu5c3da202015-02-22 08:45:28 -0800663 DrmSessionManager::Instance()->useSession(sessionId);
664
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700665 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
666}
667
668status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
669 String8 const &algorithm) {
670 Mutex::Autolock autoLock(mLock);
671
672 if (mInitCheck != OK) {
673 return mInitCheck;
674 }
675
676 if (mPlugin == NULL) {
677 return -EINVAL;
678 }
679
Ronghua Wu5c3da202015-02-22 08:45:28 -0800680 DrmSessionManager::Instance()->useSession(sessionId);
681
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700682 return mPlugin->setMacAlgorithm(sessionId, algorithm);
683}
684
685status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
686 Vector<uint8_t> const &keyId,
687 Vector<uint8_t> const &input,
688 Vector<uint8_t> const &iv,
689 Vector<uint8_t> &output) {
690 Mutex::Autolock autoLock(mLock);
691
692 if (mInitCheck != OK) {
693 return mInitCheck;
694 }
695
696 if (mPlugin == NULL) {
697 return -EINVAL;
698 }
699
Ronghua Wu5c3da202015-02-22 08:45:28 -0800700 DrmSessionManager::Instance()->useSession(sessionId);
701
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700702 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
703}
704
705status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
706 Vector<uint8_t> const &keyId,
707 Vector<uint8_t> const &input,
708 Vector<uint8_t> const &iv,
709 Vector<uint8_t> &output) {
710 Mutex::Autolock autoLock(mLock);
711
712 if (mInitCheck != OK) {
713 return mInitCheck;
714 }
715
716 if (mPlugin == NULL) {
717 return -EINVAL;
718 }
719
Ronghua Wu5c3da202015-02-22 08:45:28 -0800720 DrmSessionManager::Instance()->useSession(sessionId);
721
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700722 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
723}
724
725status_t Drm::sign(Vector<uint8_t> const &sessionId,
726 Vector<uint8_t> const &keyId,
727 Vector<uint8_t> const &message,
728 Vector<uint8_t> &signature) {
729 Mutex::Autolock autoLock(mLock);
730
731 if (mInitCheck != OK) {
732 return mInitCheck;
733 }
734
735 if (mPlugin == NULL) {
736 return -EINVAL;
737 }
738
Ronghua Wu5c3da202015-02-22 08:45:28 -0800739 DrmSessionManager::Instance()->useSession(sessionId);
740
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700741 return mPlugin->sign(sessionId, keyId, message, signature);
742}
743
744status_t Drm::verify(Vector<uint8_t> const &sessionId,
745 Vector<uint8_t> const &keyId,
746 Vector<uint8_t> const &message,
747 Vector<uint8_t> const &signature,
748 bool &match) {
749 Mutex::Autolock autoLock(mLock);
750
751 if (mInitCheck != OK) {
752 return mInitCheck;
753 }
754
755 if (mPlugin == NULL) {
756 return -EINVAL;
757 }
758
Ronghua Wu5c3da202015-02-22 08:45:28 -0800759 DrmSessionManager::Instance()->useSession(sessionId);
760
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700761 return mPlugin->verify(sessionId, keyId, message, signature, match);
762}
763
Jeff Tinker68d9d712014-03-04 13:21:31 -0800764status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
765 String8 const &algorithm,
766 Vector<uint8_t> const &message,
767 Vector<uint8_t> const &wrappedKey,
768 Vector<uint8_t> &signature) {
769 Mutex::Autolock autoLock(mLock);
770
771 if (mInitCheck != OK) {
772 return mInitCheck;
773 }
774
775 if (mPlugin == NULL) {
776 return -EINVAL;
777 }
778
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700779 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
780 return -EPERM;
781 }
782
Ronghua Wu5c3da202015-02-22 08:45:28 -0800783 DrmSessionManager::Instance()->useSession(sessionId);
784
Jeff Tinker68d9d712014-03-04 13:21:31 -0800785 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
786}
787
Lajos Molnar6d339f12015-04-17 16:15:53 -0700788void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700789{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800790 mEventLock.lock();
791 mListener.clear();
792 mEventLock.unlock();
793
794 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700795 delete mPlugin;
796 mPlugin = NULL;
797 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700798}
799
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700800void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
801{
802 if (array && array->size()) {
803 obj.writeInt32(array->size());
804 obj.write(array->array(), array->size());
805 } else {
806 obj.writeInt32(0);
807 }
808}
809
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800810} // namespace android