blob: a7f6f8b2b70cd1755449c7156c26cbae6b399c21 [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;
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700361 mLock.unlock();
362 // reclaimSession may call back to closeSession, since mLock is shared between Drm
363 // instances, we should unlock here to avoid deadlock.
Ronghua Wu5c3da202015-02-22 08:45:28 -0800364 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700365 mLock.lock();
366 if (mInitCheck != OK) {
367 return mInitCheck;
368 }
369
370 if (mPlugin == NULL) {
371 return -EINVAL;
372 }
Ronghua Wu5c3da202015-02-22 08:45:28 -0800373 if (retry) {
374 err = mPlugin->openSession(sessionId);
375 }
376 }
377 if (err == OK) {
378 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
379 }
380 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800381}
382
383status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
384 Mutex::Autolock autoLock(mLock);
385
386 if (mInitCheck != OK) {
387 return mInitCheck;
388 }
389
390 if (mPlugin == NULL) {
391 return -EINVAL;
392 }
393
Ronghua Wu5c3da202015-02-22 08:45:28 -0800394 status_t err = mPlugin->closeSession(sessionId);
395 if (err == OK) {
396 DrmSessionManager::Instance()->removeSession(sessionId);
397 }
398 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800399}
400
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700401status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
402 Vector<uint8_t> const &initData,
403 String8 const &mimeType, DrmPlugin::KeyType keyType,
404 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700405 Vector<uint8_t> &request, String8 &defaultUrl,
406 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800407 Mutex::Autolock autoLock(mLock);
408
409 if (mInitCheck != OK) {
410 return mInitCheck;
411 }
412
413 if (mPlugin == NULL) {
414 return -EINVAL;
415 }
416
Ronghua Wu5c3da202015-02-22 08:45:28 -0800417 DrmSessionManager::Instance()->useSession(sessionId);
418
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700419 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700420 optionalParameters, request, defaultUrl,
421 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800422}
423
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700424status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
425 Vector<uint8_t> const &response,
426 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800427 Mutex::Autolock autoLock(mLock);
428
429 if (mInitCheck != OK) {
430 return mInitCheck;
431 }
432
433 if (mPlugin == NULL) {
434 return -EINVAL;
435 }
436
Ronghua Wu5c3da202015-02-22 08:45:28 -0800437 DrmSessionManager::Instance()->useSession(sessionId);
438
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700439 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800440}
441
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700442status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800443 Mutex::Autolock autoLock(mLock);
444
445 if (mInitCheck != OK) {
446 return mInitCheck;
447 }
448
449 if (mPlugin == NULL) {
450 return -EINVAL;
451 }
452
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700453 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800454}
455
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700456status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
457 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800458 Mutex::Autolock autoLock(mLock);
459
460 if (mInitCheck != OK) {
461 return mInitCheck;
462 }
463
464 if (mPlugin == NULL) {
465 return -EINVAL;
466 }
467
Ronghua Wu5c3da202015-02-22 08:45:28 -0800468 DrmSessionManager::Instance()->useSession(sessionId);
469
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700470 return mPlugin->restoreKeys(sessionId, keySetId);
471}
472
473status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
474 KeyedVector<String8, String8> &infoMap) const {
475 Mutex::Autolock autoLock(mLock);
476
477 if (mInitCheck != OK) {
478 return mInitCheck;
479 }
480
481 if (mPlugin == NULL) {
482 return -EINVAL;
483 }
484
Ronghua Wu5c3da202015-02-22 08:45:28 -0800485 DrmSessionManager::Instance()->useSession(sessionId);
486
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700487 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800488}
489
Jeff Tinker68d9d712014-03-04 13:21:31 -0800490status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
491 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800492 Mutex::Autolock autoLock(mLock);
493
494 if (mInitCheck != OK) {
495 return mInitCheck;
496 }
497
498 if (mPlugin == NULL) {
499 return -EINVAL;
500 }
501
Jeff Tinker68d9d712014-03-04 13:21:31 -0800502 return mPlugin->getProvisionRequest(certType, certAuthority,
503 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800504}
505
Jeff Tinker68d9d712014-03-04 13:21:31 -0800506status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
507 Vector<uint8_t> &certificate,
508 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800509 Mutex::Autolock autoLock(mLock);
510
511 if (mInitCheck != OK) {
512 return mInitCheck;
513 }
514
515 if (mPlugin == NULL) {
516 return -EINVAL;
517 }
518
Jeff Tinker68d9d712014-03-04 13:21:31 -0800519 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800520}
521
Jeff Tinker68b15552014-04-30 10:19:03 -0700522status_t Drm::unprovisionDevice() {
523 Mutex::Autolock autoLock(mLock);
524
525 if (mInitCheck != OK) {
526 return mInitCheck;
527 }
528
529 if (mPlugin == NULL) {
530 return -EINVAL;
531 }
532
533 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
534 return -EPERM;
535 }
536
537 return mPlugin->unprovisionDevice();
538}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800539
540status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
541 Mutex::Autolock autoLock(mLock);
542
543 if (mInitCheck != OK) {
544 return mInitCheck;
545 }
546
547 if (mPlugin == NULL) {
548 return -EINVAL;
549 }
550
551 return mPlugin->getSecureStops(secureStops);
552}
553
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700554status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
555 Mutex::Autolock autoLock(mLock);
556
557 if (mInitCheck != OK) {
558 return mInitCheck;
559 }
560
561 if (mPlugin == NULL) {
562 return -EINVAL;
563 }
564
565 return mPlugin->getSecureStop(ssid, secureStop);
566}
567
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800568status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
569 Mutex::Autolock autoLock(mLock);
570
571 if (mInitCheck != OK) {
572 return mInitCheck;
573 }
574
575 if (mPlugin == NULL) {
576 return -EINVAL;
577 }
578
579 return mPlugin->releaseSecureStops(ssRelease);
580}
581
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700582status_t Drm::releaseAllSecureStops() {
583 Mutex::Autolock autoLock(mLock);
584
585 if (mInitCheck != OK) {
586 return mInitCheck;
587 }
588
589 if (mPlugin == NULL) {
590 return -EINVAL;
591 }
592
593 return mPlugin->releaseAllSecureStops();
594}
595
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800596status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
597 Mutex::Autolock autoLock(mLock);
598
599 if (mInitCheck != OK) {
600 return mInitCheck;
601 }
602
603 if (mPlugin == NULL) {
604 return -EINVAL;
605 }
606
607 return mPlugin->getPropertyString(name, value);
608}
609
610status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
611 Mutex::Autolock autoLock(mLock);
612
613 if (mInitCheck != OK) {
614 return mInitCheck;
615 }
616
617 if (mPlugin == NULL) {
618 return -EINVAL;
619 }
620
621 return mPlugin->getPropertyByteArray(name, value);
622}
623
624status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
625 Mutex::Autolock autoLock(mLock);
626
627 if (mInitCheck != OK) {
628 return mInitCheck;
629 }
630
631 if (mPlugin == NULL) {
632 return -EINVAL;
633 }
634
635 return mPlugin->setPropertyString(name, value);
636}
637
638status_t Drm::setPropertyByteArray(String8 const &name,
639 Vector<uint8_t> const &value ) const {
640 Mutex::Autolock autoLock(mLock);
641
642 if (mInitCheck != OK) {
643 return mInitCheck;
644 }
645
646 if (mPlugin == NULL) {
647 return -EINVAL;
648 }
649
650 return mPlugin->setPropertyByteArray(name, value);
651}
652
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700653
654status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
655 String8 const &algorithm) {
656 Mutex::Autolock autoLock(mLock);
657
658 if (mInitCheck != OK) {
659 return mInitCheck;
660 }
661
662 if (mPlugin == NULL) {
663 return -EINVAL;
664 }
665
Ronghua Wu5c3da202015-02-22 08:45:28 -0800666 DrmSessionManager::Instance()->useSession(sessionId);
667
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700668 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
669}
670
671status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
672 String8 const &algorithm) {
673 Mutex::Autolock autoLock(mLock);
674
675 if (mInitCheck != OK) {
676 return mInitCheck;
677 }
678
679 if (mPlugin == NULL) {
680 return -EINVAL;
681 }
682
Ronghua Wu5c3da202015-02-22 08:45:28 -0800683 DrmSessionManager::Instance()->useSession(sessionId);
684
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700685 return mPlugin->setMacAlgorithm(sessionId, algorithm);
686}
687
688status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
689 Vector<uint8_t> const &keyId,
690 Vector<uint8_t> const &input,
691 Vector<uint8_t> const &iv,
692 Vector<uint8_t> &output) {
693 Mutex::Autolock autoLock(mLock);
694
695 if (mInitCheck != OK) {
696 return mInitCheck;
697 }
698
699 if (mPlugin == NULL) {
700 return -EINVAL;
701 }
702
Ronghua Wu5c3da202015-02-22 08:45:28 -0800703 DrmSessionManager::Instance()->useSession(sessionId);
704
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700705 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
706}
707
708status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
709 Vector<uint8_t> const &keyId,
710 Vector<uint8_t> const &input,
711 Vector<uint8_t> const &iv,
712 Vector<uint8_t> &output) {
713 Mutex::Autolock autoLock(mLock);
714
715 if (mInitCheck != OK) {
716 return mInitCheck;
717 }
718
719 if (mPlugin == NULL) {
720 return -EINVAL;
721 }
722
Ronghua Wu5c3da202015-02-22 08:45:28 -0800723 DrmSessionManager::Instance()->useSession(sessionId);
724
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700725 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
726}
727
728status_t Drm::sign(Vector<uint8_t> const &sessionId,
729 Vector<uint8_t> const &keyId,
730 Vector<uint8_t> const &message,
731 Vector<uint8_t> &signature) {
732 Mutex::Autolock autoLock(mLock);
733
734 if (mInitCheck != OK) {
735 return mInitCheck;
736 }
737
738 if (mPlugin == NULL) {
739 return -EINVAL;
740 }
741
Ronghua Wu5c3da202015-02-22 08:45:28 -0800742 DrmSessionManager::Instance()->useSession(sessionId);
743
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700744 return mPlugin->sign(sessionId, keyId, message, signature);
745}
746
747status_t Drm::verify(Vector<uint8_t> const &sessionId,
748 Vector<uint8_t> const &keyId,
749 Vector<uint8_t> const &message,
750 Vector<uint8_t> const &signature,
751 bool &match) {
752 Mutex::Autolock autoLock(mLock);
753
754 if (mInitCheck != OK) {
755 return mInitCheck;
756 }
757
758 if (mPlugin == NULL) {
759 return -EINVAL;
760 }
761
Ronghua Wu5c3da202015-02-22 08:45:28 -0800762 DrmSessionManager::Instance()->useSession(sessionId);
763
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700764 return mPlugin->verify(sessionId, keyId, message, signature, match);
765}
766
Jeff Tinker68d9d712014-03-04 13:21:31 -0800767status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
768 String8 const &algorithm,
769 Vector<uint8_t> const &message,
770 Vector<uint8_t> const &wrappedKey,
771 Vector<uint8_t> &signature) {
772 Mutex::Autolock autoLock(mLock);
773
774 if (mInitCheck != OK) {
775 return mInitCheck;
776 }
777
778 if (mPlugin == NULL) {
779 return -EINVAL;
780 }
781
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700782 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
783 return -EPERM;
784 }
785
Ronghua Wu5c3da202015-02-22 08:45:28 -0800786 DrmSessionManager::Instance()->useSession(sessionId);
787
Jeff Tinker68d9d712014-03-04 13:21:31 -0800788 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
789}
790
Lajos Molnar6d339f12015-04-17 16:15:53 -0700791void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700792{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800793 mEventLock.lock();
794 mListener.clear();
795 mEventLock.unlock();
796
797 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700798 delete mPlugin;
799 mPlugin = NULL;
800 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700801}
802
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700803void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
804{
805 if (array && array->size()) {
806 obj.writeInt32(array->size());
807 obj.write(array->array(), array->size());
808 } else {
809 obj.writeInt32(0);
810 }
811}
812
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800813} // namespace android