blob: 8ca87695143d19d9c09be870303125f9ba2e037c [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;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700139 writeByteArray(obj, sessionId);
140 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700141
142 Mutex::Autolock lock(mNotifyLock);
143 listener->notify(eventType, extra, &obj);
144 }
145}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800146
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700147void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
148 int64_t expiryTimeInMS)
149{
150 mEventLock.lock();
151 sp<IDrmClient> listener = mListener;
152 mEventLock.unlock();
153
154 if (listener != NULL) {
155 Parcel obj;
156 writeByteArray(obj, sessionId);
157 obj.writeInt64(expiryTimeInMS);
158
159 Mutex::Autolock lock(mNotifyLock);
160 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
161 }
162}
163
164void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
165 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
166 bool hasNewUsableKey)
167{
168 mEventLock.lock();
169 sp<IDrmClient> listener = mListener;
170 mEventLock.unlock();
171
172 if (listener != NULL) {
173 Parcel obj;
174 writeByteArray(obj, sessionId);
175
176 size_t nkeys = keyStatusList->size();
177 obj.writeInt32(keyStatusList->size());
178 for (size_t i = 0; i < nkeys; ++i) {
179 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
180 writeByteArray(obj, &keyStatus->mKeyId);
181 obj.writeInt32(keyStatus->mType);
182 }
183 obj.writeInt32(hasNewUsableKey);
184
185 Mutex::Autolock lock(mNotifyLock);
186 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
187 }
188}
189
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800190/*
191 * Search the plugins directory for a plugin that supports the scheme
192 * specified by uuid
193 *
194 * If found:
195 * mLibrary holds a strong pointer to the dlopen'd library
196 * mFactory is set to the library's factory method
197 * mInitCheck is set to OK
198 *
199 * If not found:
200 * mLibrary is cleared and mFactory are set to NULL
201 * mInitCheck is set to an error (!OK)
202 */
203void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
204
205 closeFactory();
206
207 // lock static maps
208 Mutex::Autolock autoLock(mMapLock);
209
210 // first check cache
211 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700212 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800213 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
214 if (index >= 0) {
215 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
216 mInitCheck = OK;
217 return;
218 } else {
219 ALOGE("Failed to load from cached library path!");
220 mInitCheck = ERROR_UNSUPPORTED;
221 return;
222 }
223 }
224
225 // no luck, have to search
226 String8 dirPath("/vendor/lib/mediadrm");
227 DIR* pDir = opendir(dirPath.string());
228
229 if (pDir == NULL) {
230 mInitCheck = ERROR_UNSUPPORTED;
231 ALOGE("Failed to open plugin directory %s", dirPath.string());
232 return;
233 }
234
235
236 struct dirent* pEntry;
237 while ((pEntry = readdir(pDir))) {
238
239 String8 pluginPath = dirPath + "/" + pEntry->d_name;
240
241 if (pluginPath.getPathExtension() == ".so") {
242
243 if (loadLibraryForScheme(pluginPath, uuid)) {
244 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
245 mInitCheck = OK;
246 closedir(pDir);
247 return;
248 }
249 }
250 }
251
252 closedir(pDir);
253
254 ALOGE("Failed to find drm plugin");
255 mInitCheck = ERROR_UNSUPPORTED;
256}
257
258bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
259
260 // get strong pointer to open shared library
261 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
262 if (index >= 0) {
263 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
264 } else {
265 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
266 }
267
268 if (!mLibrary.get()) {
269 mLibrary = new SharedLibrary(path);
270 if (!*mLibrary) {
271 return false;
272 }
273
274 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
275 }
276
277 typedef DrmFactory *(*CreateDrmFactoryFunc)();
278
279 CreateDrmFactoryFunc createDrmFactory =
280 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
281
282 if (createDrmFactory == NULL ||
283 (mFactory = createDrmFactory()) == NULL ||
284 !mFactory->isCryptoSchemeSupported(uuid)) {
285 closeFactory();
286 return false;
287 }
288 return true;
289}
290
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700291bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
292
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800293 Mutex::Autolock autoLock(mLock);
294
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700295 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
296 findFactoryForScheme(uuid);
297 if (mInitCheck != OK) {
298 return false;
299 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800300 }
301
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700302 if (mimeType != "") {
303 return mFactory->isContentTypeSupported(mimeType);
304 }
305
306 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800307}
308
309status_t Drm::createPlugin(const uint8_t uuid[16]) {
310 Mutex::Autolock autoLock(mLock);
311
312 if (mPlugin != NULL) {
313 return -EINVAL;
314 }
315
316 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
317 findFactoryForScheme(uuid);
318 }
319
320 if (mInitCheck != OK) {
321 return mInitCheck;
322 }
323
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700324 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
325 mPlugin->setListener(this);
326 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800327}
328
329status_t Drm::destroyPlugin() {
330 Mutex::Autolock autoLock(mLock);
331
332 if (mInitCheck != OK) {
333 return mInitCheck;
334 }
335
336 if (mPlugin == NULL) {
337 return -EINVAL;
338 }
339
340 delete mPlugin;
341 mPlugin = NULL;
342
343 return OK;
344}
345
346status_t Drm::openSession(Vector<uint8_t> &sessionId) {
347 Mutex::Autolock autoLock(mLock);
348
349 if (mInitCheck != OK) {
350 return mInitCheck;
351 }
352
353 if (mPlugin == NULL) {
354 return -EINVAL;
355 }
356
Ronghua Wu5c3da202015-02-22 08:45:28 -0800357 status_t err = mPlugin->openSession(sessionId);
358 if (err == ERROR_DRM_RESOURCE_BUSY) {
359 bool retry = false;
360 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
361 if (retry) {
362 err = mPlugin->openSession(sessionId);
363 }
364 }
365 if (err == OK) {
366 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
367 }
368 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800369}
370
371status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
372 Mutex::Autolock autoLock(mLock);
373
374 if (mInitCheck != OK) {
375 return mInitCheck;
376 }
377
378 if (mPlugin == NULL) {
379 return -EINVAL;
380 }
381
Ronghua Wu5c3da202015-02-22 08:45:28 -0800382 status_t err = mPlugin->closeSession(sessionId);
383 if (err == OK) {
384 DrmSessionManager::Instance()->removeSession(sessionId);
385 }
386 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800387}
388
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700389status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
390 Vector<uint8_t> const &initData,
391 String8 const &mimeType, DrmPlugin::KeyType keyType,
392 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700393 Vector<uint8_t> &request, String8 &defaultUrl,
394 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800395 Mutex::Autolock autoLock(mLock);
396
397 if (mInitCheck != OK) {
398 return mInitCheck;
399 }
400
401 if (mPlugin == NULL) {
402 return -EINVAL;
403 }
404
Ronghua Wu5c3da202015-02-22 08:45:28 -0800405 DrmSessionManager::Instance()->useSession(sessionId);
406
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700407 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700408 optionalParameters, request, defaultUrl,
409 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800410}
411
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700412status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
413 Vector<uint8_t> const &response,
414 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800415 Mutex::Autolock autoLock(mLock);
416
417 if (mInitCheck != OK) {
418 return mInitCheck;
419 }
420
421 if (mPlugin == NULL) {
422 return -EINVAL;
423 }
424
Ronghua Wu5c3da202015-02-22 08:45:28 -0800425 DrmSessionManager::Instance()->useSession(sessionId);
426
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700427 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800428}
429
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700430status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800431 Mutex::Autolock autoLock(mLock);
432
433 if (mInitCheck != OK) {
434 return mInitCheck;
435 }
436
437 if (mPlugin == NULL) {
438 return -EINVAL;
439 }
440
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700441 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800442}
443
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700444status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
445 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800446 Mutex::Autolock autoLock(mLock);
447
448 if (mInitCheck != OK) {
449 return mInitCheck;
450 }
451
452 if (mPlugin == NULL) {
453 return -EINVAL;
454 }
455
Ronghua Wu5c3da202015-02-22 08:45:28 -0800456 DrmSessionManager::Instance()->useSession(sessionId);
457
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700458 return mPlugin->restoreKeys(sessionId, keySetId);
459}
460
461status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
462 KeyedVector<String8, String8> &infoMap) const {
463 Mutex::Autolock autoLock(mLock);
464
465 if (mInitCheck != OK) {
466 return mInitCheck;
467 }
468
469 if (mPlugin == NULL) {
470 return -EINVAL;
471 }
472
Ronghua Wu5c3da202015-02-22 08:45:28 -0800473 DrmSessionManager::Instance()->useSession(sessionId);
474
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700475 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800476}
477
Jeff Tinker68d9d712014-03-04 13:21:31 -0800478status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
479 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800480 Mutex::Autolock autoLock(mLock);
481
482 if (mInitCheck != OK) {
483 return mInitCheck;
484 }
485
486 if (mPlugin == NULL) {
487 return -EINVAL;
488 }
489
Jeff Tinker68d9d712014-03-04 13:21:31 -0800490 return mPlugin->getProvisionRequest(certType, certAuthority,
491 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800492}
493
Jeff Tinker68d9d712014-03-04 13:21:31 -0800494status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
495 Vector<uint8_t> &certificate,
496 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800497 Mutex::Autolock autoLock(mLock);
498
499 if (mInitCheck != OK) {
500 return mInitCheck;
501 }
502
503 if (mPlugin == NULL) {
504 return -EINVAL;
505 }
506
Jeff Tinker68d9d712014-03-04 13:21:31 -0800507 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800508}
509
Jeff Tinker68b15552014-04-30 10:19:03 -0700510status_t Drm::unprovisionDevice() {
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 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
522 return -EPERM;
523 }
524
525 return mPlugin->unprovisionDevice();
526}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800527
528status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
529 Mutex::Autolock autoLock(mLock);
530
531 if (mInitCheck != OK) {
532 return mInitCheck;
533 }
534
535 if (mPlugin == NULL) {
536 return -EINVAL;
537 }
538
539 return mPlugin->getSecureStops(secureStops);
540}
541
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700542status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
543 Mutex::Autolock autoLock(mLock);
544
545 if (mInitCheck != OK) {
546 return mInitCheck;
547 }
548
549 if (mPlugin == NULL) {
550 return -EINVAL;
551 }
552
553 return mPlugin->getSecureStop(ssid, secureStop);
554}
555
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800556status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
557 Mutex::Autolock autoLock(mLock);
558
559 if (mInitCheck != OK) {
560 return mInitCheck;
561 }
562
563 if (mPlugin == NULL) {
564 return -EINVAL;
565 }
566
567 return mPlugin->releaseSecureStops(ssRelease);
568}
569
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700570status_t Drm::releaseAllSecureStops() {
571 Mutex::Autolock autoLock(mLock);
572
573 if (mInitCheck != OK) {
574 return mInitCheck;
575 }
576
577 if (mPlugin == NULL) {
578 return -EINVAL;
579 }
580
581 return mPlugin->releaseAllSecureStops();
582}
583
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800584status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
585 Mutex::Autolock autoLock(mLock);
586
587 if (mInitCheck != OK) {
588 return mInitCheck;
589 }
590
591 if (mPlugin == NULL) {
592 return -EINVAL;
593 }
594
595 return mPlugin->getPropertyString(name, value);
596}
597
598status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
599 Mutex::Autolock autoLock(mLock);
600
601 if (mInitCheck != OK) {
602 return mInitCheck;
603 }
604
605 if (mPlugin == NULL) {
606 return -EINVAL;
607 }
608
609 return mPlugin->getPropertyByteArray(name, value);
610}
611
612status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
613 Mutex::Autolock autoLock(mLock);
614
615 if (mInitCheck != OK) {
616 return mInitCheck;
617 }
618
619 if (mPlugin == NULL) {
620 return -EINVAL;
621 }
622
623 return mPlugin->setPropertyString(name, value);
624}
625
626status_t Drm::setPropertyByteArray(String8 const &name,
627 Vector<uint8_t> const &value ) const {
628 Mutex::Autolock autoLock(mLock);
629
630 if (mInitCheck != OK) {
631 return mInitCheck;
632 }
633
634 if (mPlugin == NULL) {
635 return -EINVAL;
636 }
637
638 return mPlugin->setPropertyByteArray(name, value);
639}
640
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700641
642status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
643 String8 const &algorithm) {
644 Mutex::Autolock autoLock(mLock);
645
646 if (mInitCheck != OK) {
647 return mInitCheck;
648 }
649
650 if (mPlugin == NULL) {
651 return -EINVAL;
652 }
653
Ronghua Wu5c3da202015-02-22 08:45:28 -0800654 DrmSessionManager::Instance()->useSession(sessionId);
655
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700656 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
657}
658
659status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
660 String8 const &algorithm) {
661 Mutex::Autolock autoLock(mLock);
662
663 if (mInitCheck != OK) {
664 return mInitCheck;
665 }
666
667 if (mPlugin == NULL) {
668 return -EINVAL;
669 }
670
Ronghua Wu5c3da202015-02-22 08:45:28 -0800671 DrmSessionManager::Instance()->useSession(sessionId);
672
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700673 return mPlugin->setMacAlgorithm(sessionId, algorithm);
674}
675
676status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
677 Vector<uint8_t> const &keyId,
678 Vector<uint8_t> const &input,
679 Vector<uint8_t> const &iv,
680 Vector<uint8_t> &output) {
681 Mutex::Autolock autoLock(mLock);
682
683 if (mInitCheck != OK) {
684 return mInitCheck;
685 }
686
687 if (mPlugin == NULL) {
688 return -EINVAL;
689 }
690
Ronghua Wu5c3da202015-02-22 08:45:28 -0800691 DrmSessionManager::Instance()->useSession(sessionId);
692
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700693 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
694}
695
696status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
697 Vector<uint8_t> const &keyId,
698 Vector<uint8_t> const &input,
699 Vector<uint8_t> const &iv,
700 Vector<uint8_t> &output) {
701 Mutex::Autolock autoLock(mLock);
702
703 if (mInitCheck != OK) {
704 return mInitCheck;
705 }
706
707 if (mPlugin == NULL) {
708 return -EINVAL;
709 }
710
Ronghua Wu5c3da202015-02-22 08:45:28 -0800711 DrmSessionManager::Instance()->useSession(sessionId);
712
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700713 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
714}
715
716status_t Drm::sign(Vector<uint8_t> const &sessionId,
717 Vector<uint8_t> const &keyId,
718 Vector<uint8_t> const &message,
719 Vector<uint8_t> &signature) {
720 Mutex::Autolock autoLock(mLock);
721
722 if (mInitCheck != OK) {
723 return mInitCheck;
724 }
725
726 if (mPlugin == NULL) {
727 return -EINVAL;
728 }
729
Ronghua Wu5c3da202015-02-22 08:45:28 -0800730 DrmSessionManager::Instance()->useSession(sessionId);
731
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700732 return mPlugin->sign(sessionId, keyId, message, signature);
733}
734
735status_t Drm::verify(Vector<uint8_t> const &sessionId,
736 Vector<uint8_t> const &keyId,
737 Vector<uint8_t> const &message,
738 Vector<uint8_t> const &signature,
739 bool &match) {
740 Mutex::Autolock autoLock(mLock);
741
742 if (mInitCheck != OK) {
743 return mInitCheck;
744 }
745
746 if (mPlugin == NULL) {
747 return -EINVAL;
748 }
749
Ronghua Wu5c3da202015-02-22 08:45:28 -0800750 DrmSessionManager::Instance()->useSession(sessionId);
751
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700752 return mPlugin->verify(sessionId, keyId, message, signature, match);
753}
754
Jeff Tinker68d9d712014-03-04 13:21:31 -0800755status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
756 String8 const &algorithm,
757 Vector<uint8_t> const &message,
758 Vector<uint8_t> const &wrappedKey,
759 Vector<uint8_t> &signature) {
760 Mutex::Autolock autoLock(mLock);
761
762 if (mInitCheck != OK) {
763 return mInitCheck;
764 }
765
766 if (mPlugin == NULL) {
767 return -EINVAL;
768 }
769
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700770 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
771 return -EPERM;
772 }
773
Ronghua Wu5c3da202015-02-22 08:45:28 -0800774 DrmSessionManager::Instance()->useSession(sessionId);
775
Jeff Tinker68d9d712014-03-04 13:21:31 -0800776 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
777}
778
Lajos Molnar6d339f12015-04-17 16:15:53 -0700779void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700780{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800781 mEventLock.lock();
782 mListener.clear();
783 mEventLock.unlock();
784
785 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700786 delete mPlugin;
787 mPlugin = NULL;
788 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700789}
790
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700791void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
792{
793 if (array && array->size()) {
794 obj.writeInt32(array->size());
795 obj.write(array->array(), array->size());
796 } else {
797 obj.writeInt32(0);
798 }
799}
800
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800801} // namespace android