blob: 07e9414fc680fc60e5e71404b1cd4fff35a2cb09 [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
Jeff Tinker30038072016-04-25 13:41:35 -070024#include <media/DrmSessionClientInterface.h>
25#include <media/DrmSessionManager.h>
26#include <media/Drm.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080027#include <media/drm/DrmAPI.h>
28#include <media/stagefright/foundation/ADebug.h>
29#include <media/stagefright/foundation/AString.h>
30#include <media/stagefright/foundation/hexdump.h>
31#include <media/stagefright/MediaErrors.h>
Jeff Tinker81e0bd42014-04-02 16:41:38 -070032#include <binder/IServiceManager.h>
33#include <binder/IPCThreadState.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080034
35namespace android {
36
Ronghua Wu5c3da202015-02-22 08:45:28 -080037static inline int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
Jeff Tinker81e0bd42014-04-02 16:41:38 -070041static bool checkPermission(const char* permissionString) {
Jeff Tinker81e0bd42014-04-02 16:41:38 -070042 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
43 bool ok = checkCallingPermission(String16(permissionString));
44 if (!ok) ALOGE("Request requires %s", permissionString);
45 return ok;
46}
47
Jeff Tinkercc82dc62013-02-08 10:18:35 -080048KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
49KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
50Mutex Drm::mMapLock;
Jeff Tinker2fb561a2015-04-22 15:58:16 -070051Mutex Drm::mLock;
Jeff Tinkercc82dc62013-02-08 10:18:35 -080052
53static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
54 if (lhs.size() < rhs.size()) {
55 return true;
56 } else if (lhs.size() > rhs.size()) {
57 return false;
58 }
59
60 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
61}
62
Ronghua Wu5c3da202015-02-22 08:45:28 -080063struct DrmSessionClient : public DrmSessionClientInterface {
Chih-Hung Hsieh64a28702016-05-03 09:52:51 -070064 explicit DrmSessionClient(Drm* drm) : mDrm(drm) {}
Ronghua Wu5c3da202015-02-22 08:45:28 -080065
66 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
67 sp<Drm> drm = mDrm.promote();
68 if (drm == NULL) {
69 return true;
70 }
71 status_t err = drm->closeSession(sessionId);
72 if (err != OK) {
73 return false;
74 }
75 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
76 return true;
77 }
78
79protected:
80 virtual ~DrmSessionClient() {}
81
82private:
83 wp<Drm> mDrm;
84
85 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
86};
87
Jeff Tinkercc82dc62013-02-08 10:18:35 -080088Drm::Drm()
89 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080090 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070091 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080092 mFactory(NULL),
93 mPlugin(NULL) {
94}
95
96Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -080097 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -080098 delete mPlugin;
99 mPlugin = NULL;
100 closeFactory();
101}
102
103void Drm::closeFactory() {
104 delete mFactory;
105 mFactory = NULL;
106 mLibrary.clear();
107}
108
109status_t Drm::initCheck() const {
110 return mInitCheck;
111}
112
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700113status_t Drm::setListener(const sp<IDrmClient>& listener)
114{
115 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700116 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800117 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700118 }
119 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800120 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700121 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700122 mListener = listener;
123 return NO_ERROR;
124}
125
126void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
127 Vector<uint8_t> const *sessionId,
128 Vector<uint8_t> const *data)
129{
130 mEventLock.lock();
131 sp<IDrmClient> listener = mListener;
132 mEventLock.unlock();
133
134 if (listener != NULL) {
135 Parcel obj;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700136 writeByteArray(obj, sessionId);
137 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700138
139 Mutex::Autolock lock(mNotifyLock);
140 listener->notify(eventType, extra, &obj);
141 }
142}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800143
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700144void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
145 int64_t expiryTimeInMS)
146{
147 mEventLock.lock();
148 sp<IDrmClient> listener = mListener;
149 mEventLock.unlock();
150
151 if (listener != NULL) {
152 Parcel obj;
153 writeByteArray(obj, sessionId);
154 obj.writeInt64(expiryTimeInMS);
155
156 Mutex::Autolock lock(mNotifyLock);
157 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
158 }
159}
160
161void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
162 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
163 bool hasNewUsableKey)
164{
165 mEventLock.lock();
166 sp<IDrmClient> listener = mListener;
167 mEventLock.unlock();
168
169 if (listener != NULL) {
170 Parcel obj;
171 writeByteArray(obj, sessionId);
172
173 size_t nkeys = keyStatusList->size();
174 obj.writeInt32(keyStatusList->size());
175 for (size_t i = 0; i < nkeys; ++i) {
176 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
177 writeByteArray(obj, &keyStatus->mKeyId);
178 obj.writeInt32(keyStatus->mType);
179 }
180 obj.writeInt32(hasNewUsableKey);
181
182 Mutex::Autolock lock(mNotifyLock);
183 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
184 }
185}
186
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800187/*
188 * Search the plugins directory for a plugin that supports the scheme
189 * specified by uuid
190 *
191 * If found:
192 * mLibrary holds a strong pointer to the dlopen'd library
193 * mFactory is set to the library's factory method
194 * mInitCheck is set to OK
195 *
196 * If not found:
197 * mLibrary is cleared and mFactory are set to NULL
198 * mInitCheck is set to an error (!OK)
199 */
200void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
201
202 closeFactory();
203
204 // lock static maps
205 Mutex::Autolock autoLock(mMapLock);
206
207 // first check cache
208 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700209 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800210 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
211 if (index >= 0) {
212 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
213 mInitCheck = OK;
214 return;
215 } else {
216 ALOGE("Failed to load from cached library path!");
217 mInitCheck = ERROR_UNSUPPORTED;
218 return;
219 }
220 }
221
222 // no luck, have to search
223 String8 dirPath("/vendor/lib/mediadrm");
224 DIR* pDir = opendir(dirPath.string());
225
226 if (pDir == NULL) {
227 mInitCheck = ERROR_UNSUPPORTED;
228 ALOGE("Failed to open plugin directory %s", dirPath.string());
229 return;
230 }
231
232
233 struct dirent* pEntry;
234 while ((pEntry = readdir(pDir))) {
235
236 String8 pluginPath = dirPath + "/" + pEntry->d_name;
237
238 if (pluginPath.getPathExtension() == ".so") {
239
240 if (loadLibraryForScheme(pluginPath, uuid)) {
241 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
242 mInitCheck = OK;
243 closedir(pDir);
244 return;
245 }
246 }
247 }
248
249 closedir(pDir);
250
251 ALOGE("Failed to find drm plugin");
252 mInitCheck = ERROR_UNSUPPORTED;
253}
254
255bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
256
257 // get strong pointer to open shared library
258 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
259 if (index >= 0) {
260 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
261 } else {
262 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
263 }
264
265 if (!mLibrary.get()) {
266 mLibrary = new SharedLibrary(path);
267 if (!*mLibrary) {
268 return false;
269 }
270
271 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
272 }
273
274 typedef DrmFactory *(*CreateDrmFactoryFunc)();
275
276 CreateDrmFactoryFunc createDrmFactory =
277 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
278
279 if (createDrmFactory == NULL ||
280 (mFactory = createDrmFactory()) == NULL ||
281 !mFactory->isCryptoSchemeSupported(uuid)) {
282 closeFactory();
283 return false;
284 }
285 return true;
286}
287
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700288bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
289
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800290 Mutex::Autolock autoLock(mLock);
291
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700292 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
293 findFactoryForScheme(uuid);
294 if (mInitCheck != OK) {
295 return false;
296 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800297 }
298
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700299 if (mimeType != "") {
300 return mFactory->isContentTypeSupported(mimeType);
301 }
302
303 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800304}
305
306status_t Drm::createPlugin(const uint8_t uuid[16]) {
307 Mutex::Autolock autoLock(mLock);
308
309 if (mPlugin != NULL) {
310 return -EINVAL;
311 }
312
313 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
314 findFactoryForScheme(uuid);
315 }
316
317 if (mInitCheck != OK) {
318 return mInitCheck;
319 }
320
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700321 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
322 mPlugin->setListener(this);
323 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800324}
325
326status_t Drm::destroyPlugin() {
327 Mutex::Autolock autoLock(mLock);
328
329 if (mInitCheck != OK) {
330 return mInitCheck;
331 }
332
333 if (mPlugin == NULL) {
334 return -EINVAL;
335 }
336
Jeff Tinker9e27bc62016-10-19 18:20:47 -0700337 setListener(NULL);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800338 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