blob: 321ccbfb5eaa67f27a9e4c4b7542753bc7b93801 [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 Tinkercc82dc62013-02-08 10:18:35 -0800519status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
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 return mPlugin->getSecureStops(secureStops);
531}
532
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700533status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
534 Mutex::Autolock autoLock(mLock);
535
536 if (mInitCheck != OK) {
537 return mInitCheck;
538 }
539
540 if (mPlugin == NULL) {
541 return -EINVAL;
542 }
543
544 return mPlugin->getSecureStop(ssid, secureStop);
545}
546
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800547status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
548 Mutex::Autolock autoLock(mLock);
549
550 if (mInitCheck != OK) {
551 return mInitCheck;
552 }
553
554 if (mPlugin == NULL) {
555 return -EINVAL;
556 }
557
558 return mPlugin->releaseSecureStops(ssRelease);
559}
560
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700561status_t Drm::releaseAllSecureStops() {
562 Mutex::Autolock autoLock(mLock);
563
564 if (mInitCheck != OK) {
565 return mInitCheck;
566 }
567
568 if (mPlugin == NULL) {
569 return -EINVAL;
570 }
571
572 return mPlugin->releaseAllSecureStops();
573}
574
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800575status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
576 Mutex::Autolock autoLock(mLock);
577
578 if (mInitCheck != OK) {
579 return mInitCheck;
580 }
581
582 if (mPlugin == NULL) {
583 return -EINVAL;
584 }
585
586 return mPlugin->getPropertyString(name, value);
587}
588
589status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
590 Mutex::Autolock autoLock(mLock);
591
592 if (mInitCheck != OK) {
593 return mInitCheck;
594 }
595
596 if (mPlugin == NULL) {
597 return -EINVAL;
598 }
599
600 return mPlugin->getPropertyByteArray(name, value);
601}
602
603status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
604 Mutex::Autolock autoLock(mLock);
605
606 if (mInitCheck != OK) {
607 return mInitCheck;
608 }
609
610 if (mPlugin == NULL) {
611 return -EINVAL;
612 }
613
614 return mPlugin->setPropertyString(name, value);
615}
616
617status_t Drm::setPropertyByteArray(String8 const &name,
618 Vector<uint8_t> const &value ) const {
619 Mutex::Autolock autoLock(mLock);
620
621 if (mInitCheck != OK) {
622 return mInitCheck;
623 }
624
625 if (mPlugin == NULL) {
626 return -EINVAL;
627 }
628
629 return mPlugin->setPropertyByteArray(name, value);
630}
631
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700632
633status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
634 String8 const &algorithm) {
635 Mutex::Autolock autoLock(mLock);
636
637 if (mInitCheck != OK) {
638 return mInitCheck;
639 }
640
641 if (mPlugin == NULL) {
642 return -EINVAL;
643 }
644
Ronghua Wu5c3da202015-02-22 08:45:28 -0800645 DrmSessionManager::Instance()->useSession(sessionId);
646
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700647 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
648}
649
650status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
651 String8 const &algorithm) {
652 Mutex::Autolock autoLock(mLock);
653
654 if (mInitCheck != OK) {
655 return mInitCheck;
656 }
657
658 if (mPlugin == NULL) {
659 return -EINVAL;
660 }
661
Ronghua Wu5c3da202015-02-22 08:45:28 -0800662 DrmSessionManager::Instance()->useSession(sessionId);
663
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700664 return mPlugin->setMacAlgorithm(sessionId, algorithm);
665}
666
667status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
668 Vector<uint8_t> const &keyId,
669 Vector<uint8_t> const &input,
670 Vector<uint8_t> const &iv,
671 Vector<uint8_t> &output) {
672 Mutex::Autolock autoLock(mLock);
673
674 if (mInitCheck != OK) {
675 return mInitCheck;
676 }
677
678 if (mPlugin == NULL) {
679 return -EINVAL;
680 }
681
Ronghua Wu5c3da202015-02-22 08:45:28 -0800682 DrmSessionManager::Instance()->useSession(sessionId);
683
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700684 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
685}
686
687status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
688 Vector<uint8_t> const &keyId,
689 Vector<uint8_t> const &input,
690 Vector<uint8_t> const &iv,
691 Vector<uint8_t> &output) {
692 Mutex::Autolock autoLock(mLock);
693
694 if (mInitCheck != OK) {
695 return mInitCheck;
696 }
697
698 if (mPlugin == NULL) {
699 return -EINVAL;
700 }
701
Ronghua Wu5c3da202015-02-22 08:45:28 -0800702 DrmSessionManager::Instance()->useSession(sessionId);
703
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700704 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
705}
706
707status_t Drm::sign(Vector<uint8_t> const &sessionId,
708 Vector<uint8_t> const &keyId,
709 Vector<uint8_t> const &message,
710 Vector<uint8_t> &signature) {
711 Mutex::Autolock autoLock(mLock);
712
713 if (mInitCheck != OK) {
714 return mInitCheck;
715 }
716
717 if (mPlugin == NULL) {
718 return -EINVAL;
719 }
720
Ronghua Wu5c3da202015-02-22 08:45:28 -0800721 DrmSessionManager::Instance()->useSession(sessionId);
722
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700723 return mPlugin->sign(sessionId, keyId, message, signature);
724}
725
726status_t Drm::verify(Vector<uint8_t> const &sessionId,
727 Vector<uint8_t> const &keyId,
728 Vector<uint8_t> const &message,
729 Vector<uint8_t> const &signature,
730 bool &match) {
731 Mutex::Autolock autoLock(mLock);
732
733 if (mInitCheck != OK) {
734 return mInitCheck;
735 }
736
737 if (mPlugin == NULL) {
738 return -EINVAL;
739 }
740
Ronghua Wu5c3da202015-02-22 08:45:28 -0800741 DrmSessionManager::Instance()->useSession(sessionId);
742
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700743 return mPlugin->verify(sessionId, keyId, message, signature, match);
744}
745
Jeff Tinker68d9d712014-03-04 13:21:31 -0800746status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
747 String8 const &algorithm,
748 Vector<uint8_t> const &message,
749 Vector<uint8_t> const &wrappedKey,
750 Vector<uint8_t> &signature) {
751 Mutex::Autolock autoLock(mLock);
752
753 if (mInitCheck != OK) {
754 return mInitCheck;
755 }
756
757 if (mPlugin == NULL) {
758 return -EINVAL;
759 }
760
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700761 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
762 return -EPERM;
763 }
764
Ronghua Wu5c3da202015-02-22 08:45:28 -0800765 DrmSessionManager::Instance()->useSession(sessionId);
766
Jeff Tinker68d9d712014-03-04 13:21:31 -0800767 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
768}
769
Lajos Molnar6d339f12015-04-17 16:15:53 -0700770void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700771{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800772 mEventLock.lock();
773 mListener.clear();
774 mEventLock.unlock();
775
776 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700777 delete mPlugin;
778 mPlugin = NULL;
779 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700780}
781
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700782void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
783{
784 if (array && array->size()) {
785 obj.writeInt32(array->size());
786 obj.write(array->array(), array->size());
787 } else {
788 obj.writeInt32(0);
789 }
790}
791
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800792} // namespace android