blob: 49e01d1cb8f935356577f66e5a5eb381d25fb464 [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;
55
56static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
57 if (lhs.size() < rhs.size()) {
58 return true;
59 } else if (lhs.size() > rhs.size()) {
60 return false;
61 }
62
63 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
64}
65
Ronghua Wu5c3da202015-02-22 08:45:28 -080066struct DrmSessionClient : public DrmSessionClientInterface {
67 DrmSessionClient(Drm* drm) : mDrm(drm) {}
68
69 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
70 sp<Drm> drm = mDrm.promote();
71 if (drm == NULL) {
72 return true;
73 }
74 status_t err = drm->closeSession(sessionId);
75 if (err != OK) {
76 return false;
77 }
78 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
79 return true;
80 }
81
82protected:
83 virtual ~DrmSessionClient() {}
84
85private:
86 wp<Drm> mDrm;
87
88 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
89};
90
Jeff Tinkercc82dc62013-02-08 10:18:35 -080091Drm::Drm()
92 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080093 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070094 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080095 mFactory(NULL),
96 mPlugin(NULL) {
97}
98
99Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -0800100 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800101 delete mPlugin;
102 mPlugin = NULL;
103 closeFactory();
104}
105
106void Drm::closeFactory() {
107 delete mFactory;
108 mFactory = NULL;
109 mLibrary.clear();
110}
111
112status_t Drm::initCheck() const {
113 return mInitCheck;
114}
115
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700116status_t Drm::setListener(const sp<IDrmClient>& listener)
117{
118 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700119 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800120 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700121 }
122 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800123 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700124 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700125 mListener = listener;
126 return NO_ERROR;
127}
128
129void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
130 Vector<uint8_t> const *sessionId,
131 Vector<uint8_t> const *data)
132{
133 mEventLock.lock();
134 sp<IDrmClient> listener = mListener;
135 mEventLock.unlock();
136
137 if (listener != NULL) {
138 Parcel obj;
139 if (sessionId && sessionId->size()) {
140 obj.writeInt32(sessionId->size());
141 obj.write(sessionId->array(), sessionId->size());
142 } else {
143 obj.writeInt32(0);
144 }
145
146 if (data && data->size()) {
147 obj.writeInt32(data->size());
148 obj.write(data->array(), data->size());
149 } else {
150 obj.writeInt32(0);
151 }
152
153 Mutex::Autolock lock(mNotifyLock);
154 listener->notify(eventType, extra, &obj);
155 }
156}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800157
158/*
159 * Search the plugins directory for a plugin that supports the scheme
160 * specified by uuid
161 *
162 * If found:
163 * mLibrary holds a strong pointer to the dlopen'd library
164 * mFactory is set to the library's factory method
165 * mInitCheck is set to OK
166 *
167 * If not found:
168 * mLibrary is cleared and mFactory are set to NULL
169 * mInitCheck is set to an error (!OK)
170 */
171void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
172
173 closeFactory();
174
175 // lock static maps
176 Mutex::Autolock autoLock(mMapLock);
177
178 // first check cache
179 Vector<uint8_t> uuidVector;
180 uuidVector.appendArray(uuid, sizeof(uuid));
181 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
182 if (index >= 0) {
183 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
184 mInitCheck = OK;
185 return;
186 } else {
187 ALOGE("Failed to load from cached library path!");
188 mInitCheck = ERROR_UNSUPPORTED;
189 return;
190 }
191 }
192
193 // no luck, have to search
194 String8 dirPath("/vendor/lib/mediadrm");
195 DIR* pDir = opendir(dirPath.string());
196
197 if (pDir == NULL) {
198 mInitCheck = ERROR_UNSUPPORTED;
199 ALOGE("Failed to open plugin directory %s", dirPath.string());
200 return;
201 }
202
203
204 struct dirent* pEntry;
205 while ((pEntry = readdir(pDir))) {
206
207 String8 pluginPath = dirPath + "/" + pEntry->d_name;
208
209 if (pluginPath.getPathExtension() == ".so") {
210
211 if (loadLibraryForScheme(pluginPath, uuid)) {
212 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
213 mInitCheck = OK;
214 closedir(pDir);
215 return;
216 }
217 }
218 }
219
220 closedir(pDir);
221
222 ALOGE("Failed to find drm plugin");
223 mInitCheck = ERROR_UNSUPPORTED;
224}
225
226bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
227
228 // get strong pointer to open shared library
229 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
230 if (index >= 0) {
231 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
232 } else {
233 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
234 }
235
236 if (!mLibrary.get()) {
237 mLibrary = new SharedLibrary(path);
238 if (!*mLibrary) {
239 return false;
240 }
241
242 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
243 }
244
245 typedef DrmFactory *(*CreateDrmFactoryFunc)();
246
247 CreateDrmFactoryFunc createDrmFactory =
248 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
249
250 if (createDrmFactory == NULL ||
251 (mFactory = createDrmFactory()) == NULL ||
252 !mFactory->isCryptoSchemeSupported(uuid)) {
253 closeFactory();
254 return false;
255 }
256 return true;
257}
258
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700259bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
260
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800261 Mutex::Autolock autoLock(mLock);
262
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700263 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
264 findFactoryForScheme(uuid);
265 if (mInitCheck != OK) {
266 return false;
267 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800268 }
269
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700270 if (mimeType != "") {
271 return mFactory->isContentTypeSupported(mimeType);
272 }
273
274 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800275}
276
277status_t Drm::createPlugin(const uint8_t uuid[16]) {
278 Mutex::Autolock autoLock(mLock);
279
280 if (mPlugin != NULL) {
281 return -EINVAL;
282 }
283
284 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
285 findFactoryForScheme(uuid);
286 }
287
288 if (mInitCheck != OK) {
289 return mInitCheck;
290 }
291
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700292 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
293 mPlugin->setListener(this);
294 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800295}
296
297status_t Drm::destroyPlugin() {
298 Mutex::Autolock autoLock(mLock);
299
300 if (mInitCheck != OK) {
301 return mInitCheck;
302 }
303
304 if (mPlugin == NULL) {
305 return -EINVAL;
306 }
307
308 delete mPlugin;
309 mPlugin = NULL;
310
311 return OK;
312}
313
314status_t Drm::openSession(Vector<uint8_t> &sessionId) {
315 Mutex::Autolock autoLock(mLock);
316
317 if (mInitCheck != OK) {
318 return mInitCheck;
319 }
320
321 if (mPlugin == NULL) {
322 return -EINVAL;
323 }
324
Ronghua Wu5c3da202015-02-22 08:45:28 -0800325 status_t err = mPlugin->openSession(sessionId);
326 if (err == ERROR_DRM_RESOURCE_BUSY) {
327 bool retry = false;
328 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
329 if (retry) {
330 err = mPlugin->openSession(sessionId);
331 }
332 }
333 if (err == OK) {
334 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
335 }
336 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800337}
338
339status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
340 Mutex::Autolock autoLock(mLock);
341
342 if (mInitCheck != OK) {
343 return mInitCheck;
344 }
345
346 if (mPlugin == NULL) {
347 return -EINVAL;
348 }
349
Ronghua Wu5c3da202015-02-22 08:45:28 -0800350 status_t err = mPlugin->closeSession(sessionId);
351 if (err == OK) {
352 DrmSessionManager::Instance()->removeSession(sessionId);
353 }
354 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800355}
356
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700357status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
358 Vector<uint8_t> const &initData,
359 String8 const &mimeType, DrmPlugin::KeyType keyType,
360 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700361 Vector<uint8_t> &request, String8 &defaultUrl,
362 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800363 Mutex::Autolock autoLock(mLock);
364
365 if (mInitCheck != OK) {
366 return mInitCheck;
367 }
368
369 if (mPlugin == NULL) {
370 return -EINVAL;
371 }
372
Ronghua Wu5c3da202015-02-22 08:45:28 -0800373 DrmSessionManager::Instance()->useSession(sessionId);
374
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700375 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700376 optionalParameters, request, defaultUrl,
377 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800378}
379
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700380status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
381 Vector<uint8_t> const &response,
382 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800383 Mutex::Autolock autoLock(mLock);
384
385 if (mInitCheck != OK) {
386 return mInitCheck;
387 }
388
389 if (mPlugin == NULL) {
390 return -EINVAL;
391 }
392
Ronghua Wu5c3da202015-02-22 08:45:28 -0800393 DrmSessionManager::Instance()->useSession(sessionId);
394
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700395 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800396}
397
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700398status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800399 Mutex::Autolock autoLock(mLock);
400
401 if (mInitCheck != OK) {
402 return mInitCheck;
403 }
404
405 if (mPlugin == NULL) {
406 return -EINVAL;
407 }
408
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700409 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800410}
411
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700412status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
413 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800414 Mutex::Autolock autoLock(mLock);
415
416 if (mInitCheck != OK) {
417 return mInitCheck;
418 }
419
420 if (mPlugin == NULL) {
421 return -EINVAL;
422 }
423
Ronghua Wu5c3da202015-02-22 08:45:28 -0800424 DrmSessionManager::Instance()->useSession(sessionId);
425
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700426 return mPlugin->restoreKeys(sessionId, keySetId);
427}
428
429status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
430 KeyedVector<String8, String8> &infoMap) const {
431 Mutex::Autolock autoLock(mLock);
432
433 if (mInitCheck != OK) {
434 return mInitCheck;
435 }
436
437 if (mPlugin == NULL) {
438 return -EINVAL;
439 }
440
Ronghua Wu5c3da202015-02-22 08:45:28 -0800441 DrmSessionManager::Instance()->useSession(sessionId);
442
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700443 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800444}
445
Jeff Tinker68d9d712014-03-04 13:21:31 -0800446status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
447 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800448 Mutex::Autolock autoLock(mLock);
449
450 if (mInitCheck != OK) {
451 return mInitCheck;
452 }
453
454 if (mPlugin == NULL) {
455 return -EINVAL;
456 }
457
Jeff Tinker68d9d712014-03-04 13:21:31 -0800458 return mPlugin->getProvisionRequest(certType, certAuthority,
459 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800460}
461
Jeff Tinker68d9d712014-03-04 13:21:31 -0800462status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
463 Vector<uint8_t> &certificate,
464 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800465 Mutex::Autolock autoLock(mLock);
466
467 if (mInitCheck != OK) {
468 return mInitCheck;
469 }
470
471 if (mPlugin == NULL) {
472 return -EINVAL;
473 }
474
Jeff Tinker68d9d712014-03-04 13:21:31 -0800475 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800476}
477
Jeff Tinker68b15552014-04-30 10:19:03 -0700478status_t Drm::unprovisionDevice() {
479 Mutex::Autolock autoLock(mLock);
480
481 if (mInitCheck != OK) {
482 return mInitCheck;
483 }
484
485 if (mPlugin == NULL) {
486 return -EINVAL;
487 }
488
489 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
490 return -EPERM;
491 }
492
493 return mPlugin->unprovisionDevice();
494}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800495
496status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
497 Mutex::Autolock autoLock(mLock);
498
499 if (mInitCheck != OK) {
500 return mInitCheck;
501 }
502
503 if (mPlugin == NULL) {
504 return -EINVAL;
505 }
506
507 return mPlugin->getSecureStops(secureStops);
508}
509
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700510status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
511 Mutex::Autolock autoLock(mLock);
512
513 if (mInitCheck != OK) {
514 return mInitCheck;
515 }
516
517 if (mPlugin == NULL) {
518 return -EINVAL;
519 }
520
521 return mPlugin->getSecureStop(ssid, secureStop);
522}
523
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800524status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
525 Mutex::Autolock autoLock(mLock);
526
527 if (mInitCheck != OK) {
528 return mInitCheck;
529 }
530
531 if (mPlugin == NULL) {
532 return -EINVAL;
533 }
534
535 return mPlugin->releaseSecureStops(ssRelease);
536}
537
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700538status_t Drm::releaseAllSecureStops() {
539 Mutex::Autolock autoLock(mLock);
540
541 if (mInitCheck != OK) {
542 return mInitCheck;
543 }
544
545 if (mPlugin == NULL) {
546 return -EINVAL;
547 }
548
549 return mPlugin->releaseAllSecureStops();
550}
551
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800552status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
553 Mutex::Autolock autoLock(mLock);
554
555 if (mInitCheck != OK) {
556 return mInitCheck;
557 }
558
559 if (mPlugin == NULL) {
560 return -EINVAL;
561 }
562
563 return mPlugin->getPropertyString(name, value);
564}
565
566status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
567 Mutex::Autolock autoLock(mLock);
568
569 if (mInitCheck != OK) {
570 return mInitCheck;
571 }
572
573 if (mPlugin == NULL) {
574 return -EINVAL;
575 }
576
577 return mPlugin->getPropertyByteArray(name, value);
578}
579
580status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
581 Mutex::Autolock autoLock(mLock);
582
583 if (mInitCheck != OK) {
584 return mInitCheck;
585 }
586
587 if (mPlugin == NULL) {
588 return -EINVAL;
589 }
590
591 return mPlugin->setPropertyString(name, value);
592}
593
594status_t Drm::setPropertyByteArray(String8 const &name,
595 Vector<uint8_t> const &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->setPropertyByteArray(name, value);
607}
608
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700609
610status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
611 String8 const &algorithm) {
612 Mutex::Autolock autoLock(mLock);
613
614 if (mInitCheck != OK) {
615 return mInitCheck;
616 }
617
618 if (mPlugin == NULL) {
619 return -EINVAL;
620 }
621
Ronghua Wu5c3da202015-02-22 08:45:28 -0800622 DrmSessionManager::Instance()->useSession(sessionId);
623
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700624 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
625}
626
627status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
628 String8 const &algorithm) {
629 Mutex::Autolock autoLock(mLock);
630
631 if (mInitCheck != OK) {
632 return mInitCheck;
633 }
634
635 if (mPlugin == NULL) {
636 return -EINVAL;
637 }
638
Ronghua Wu5c3da202015-02-22 08:45:28 -0800639 DrmSessionManager::Instance()->useSession(sessionId);
640
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700641 return mPlugin->setMacAlgorithm(sessionId, algorithm);
642}
643
644status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
645 Vector<uint8_t> const &keyId,
646 Vector<uint8_t> const &input,
647 Vector<uint8_t> const &iv,
648 Vector<uint8_t> &output) {
649 Mutex::Autolock autoLock(mLock);
650
651 if (mInitCheck != OK) {
652 return mInitCheck;
653 }
654
655 if (mPlugin == NULL) {
656 return -EINVAL;
657 }
658
Ronghua Wu5c3da202015-02-22 08:45:28 -0800659 DrmSessionManager::Instance()->useSession(sessionId);
660
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700661 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
662}
663
664status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
665 Vector<uint8_t> const &keyId,
666 Vector<uint8_t> const &input,
667 Vector<uint8_t> const &iv,
668 Vector<uint8_t> &output) {
669 Mutex::Autolock autoLock(mLock);
670
671 if (mInitCheck != OK) {
672 return mInitCheck;
673 }
674
675 if (mPlugin == NULL) {
676 return -EINVAL;
677 }
678
Ronghua Wu5c3da202015-02-22 08:45:28 -0800679 DrmSessionManager::Instance()->useSession(sessionId);
680
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700681 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
682}
683
684status_t Drm::sign(Vector<uint8_t> const &sessionId,
685 Vector<uint8_t> const &keyId,
686 Vector<uint8_t> const &message,
687 Vector<uint8_t> &signature) {
688 Mutex::Autolock autoLock(mLock);
689
690 if (mInitCheck != OK) {
691 return mInitCheck;
692 }
693
694 if (mPlugin == NULL) {
695 return -EINVAL;
696 }
697
Ronghua Wu5c3da202015-02-22 08:45:28 -0800698 DrmSessionManager::Instance()->useSession(sessionId);
699
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700700 return mPlugin->sign(sessionId, keyId, message, signature);
701}
702
703status_t Drm::verify(Vector<uint8_t> const &sessionId,
704 Vector<uint8_t> const &keyId,
705 Vector<uint8_t> const &message,
706 Vector<uint8_t> const &signature,
707 bool &match) {
708 Mutex::Autolock autoLock(mLock);
709
710 if (mInitCheck != OK) {
711 return mInitCheck;
712 }
713
714 if (mPlugin == NULL) {
715 return -EINVAL;
716 }
717
Ronghua Wu5c3da202015-02-22 08:45:28 -0800718 DrmSessionManager::Instance()->useSession(sessionId);
719
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700720 return mPlugin->verify(sessionId, keyId, message, signature, match);
721}
722
Jeff Tinker68d9d712014-03-04 13:21:31 -0800723status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
724 String8 const &algorithm,
725 Vector<uint8_t> const &message,
726 Vector<uint8_t> const &wrappedKey,
727 Vector<uint8_t> &signature) {
728 Mutex::Autolock autoLock(mLock);
729
730 if (mInitCheck != OK) {
731 return mInitCheck;
732 }
733
734 if (mPlugin == NULL) {
735 return -EINVAL;
736 }
737
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700738 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
739 return -EPERM;
740 }
741
Ronghua Wu5c3da202015-02-22 08:45:28 -0800742 DrmSessionManager::Instance()->useSession(sessionId);
743
Jeff Tinker68d9d712014-03-04 13:21:31 -0800744 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
745}
746
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700747void Drm::binderDied(const wp<IBinder> &the_late_who)
748{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800749 mEventLock.lock();
750 mListener.clear();
751 mEventLock.unlock();
752
753 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700754 delete mPlugin;
755 mPlugin = NULL;
756 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700757}
758
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800759} // namespace android