blob: 9ab08dbeb7fb7310b5919a466d76fe76d9c0d3f6 [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
337 delete mPlugin;
338 mPlugin = NULL;
339
340 return OK;
341}
342
343status_t Drm::openSession(Vector<uint8_t> &sessionId) {
344 Mutex::Autolock autoLock(mLock);
345
346 if (mInitCheck != OK) {
347 return mInitCheck;
348 }
349
350 if (mPlugin == NULL) {
351 return -EINVAL;
352 }
353
Ronghua Wu5c3da202015-02-22 08:45:28 -0800354 status_t err = mPlugin->openSession(sessionId);
355 if (err == ERROR_DRM_RESOURCE_BUSY) {
356 bool retry = false;
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700357 mLock.unlock();
358 // reclaimSession may call back to closeSession, since mLock is shared between Drm
359 // instances, we should unlock here to avoid deadlock.
Ronghua Wu5c3da202015-02-22 08:45:28 -0800360 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700361 mLock.lock();
362 if (mInitCheck != OK) {
363 return mInitCheck;
364 }
365
366 if (mPlugin == NULL) {
367 return -EINVAL;
368 }
Ronghua Wu5c3da202015-02-22 08:45:28 -0800369 if (retry) {
370 err = mPlugin->openSession(sessionId);
371 }
372 }
373 if (err == OK) {
374 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
375 }
376 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800377}
378
379status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
380 Mutex::Autolock autoLock(mLock);
381
382 if (mInitCheck != OK) {
383 return mInitCheck;
384 }
385
386 if (mPlugin == NULL) {
387 return -EINVAL;
388 }
389
Ronghua Wu5c3da202015-02-22 08:45:28 -0800390 status_t err = mPlugin->closeSession(sessionId);
391 if (err == OK) {
392 DrmSessionManager::Instance()->removeSession(sessionId);
393 }
394 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800395}
396
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700397status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
398 Vector<uint8_t> const &initData,
399 String8 const &mimeType, DrmPlugin::KeyType keyType,
400 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700401 Vector<uint8_t> &request, String8 &defaultUrl,
402 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800403 Mutex::Autolock autoLock(mLock);
404
405 if (mInitCheck != OK) {
406 return mInitCheck;
407 }
408
409 if (mPlugin == NULL) {
410 return -EINVAL;
411 }
412
Ronghua Wu5c3da202015-02-22 08:45:28 -0800413 DrmSessionManager::Instance()->useSession(sessionId);
414
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700415 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700416 optionalParameters, request, defaultUrl,
417 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800418}
419
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700420status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
421 Vector<uint8_t> const &response,
422 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800423 Mutex::Autolock autoLock(mLock);
424
425 if (mInitCheck != OK) {
426 return mInitCheck;
427 }
428
429 if (mPlugin == NULL) {
430 return -EINVAL;
431 }
432
Ronghua Wu5c3da202015-02-22 08:45:28 -0800433 DrmSessionManager::Instance()->useSession(sessionId);
434
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700435 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800436}
437
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700438status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800439 Mutex::Autolock autoLock(mLock);
440
441 if (mInitCheck != OK) {
442 return mInitCheck;
443 }
444
445 if (mPlugin == NULL) {
446 return -EINVAL;
447 }
448
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700449 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800450}
451
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700452status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
453 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800454 Mutex::Autolock autoLock(mLock);
455
456 if (mInitCheck != OK) {
457 return mInitCheck;
458 }
459
460 if (mPlugin == NULL) {
461 return -EINVAL;
462 }
463
Ronghua Wu5c3da202015-02-22 08:45:28 -0800464 DrmSessionManager::Instance()->useSession(sessionId);
465
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700466 return mPlugin->restoreKeys(sessionId, keySetId);
467}
468
469status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
470 KeyedVector<String8, String8> &infoMap) const {
471 Mutex::Autolock autoLock(mLock);
472
473 if (mInitCheck != OK) {
474 return mInitCheck;
475 }
476
477 if (mPlugin == NULL) {
478 return -EINVAL;
479 }
480
Ronghua Wu5c3da202015-02-22 08:45:28 -0800481 DrmSessionManager::Instance()->useSession(sessionId);
482
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700483 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800484}
485
Jeff Tinker68d9d712014-03-04 13:21:31 -0800486status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
487 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800488 Mutex::Autolock autoLock(mLock);
489
490 if (mInitCheck != OK) {
491 return mInitCheck;
492 }
493
494 if (mPlugin == NULL) {
495 return -EINVAL;
496 }
497
Jeff Tinker68d9d712014-03-04 13:21:31 -0800498 return mPlugin->getProvisionRequest(certType, certAuthority,
499 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800500}
501
Jeff Tinker68d9d712014-03-04 13:21:31 -0800502status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
503 Vector<uint8_t> &certificate,
504 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800505 Mutex::Autolock autoLock(mLock);
506
507 if (mInitCheck != OK) {
508 return mInitCheck;
509 }
510
511 if (mPlugin == NULL) {
512 return -EINVAL;
513 }
514
Jeff Tinker68d9d712014-03-04 13:21:31 -0800515 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800516}
517
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800518status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
519 Mutex::Autolock autoLock(mLock);
520
521 if (mInitCheck != OK) {
522 return mInitCheck;
523 }
524
525 if (mPlugin == NULL) {
526 return -EINVAL;
527 }
528
529 return mPlugin->getSecureStops(secureStops);
530}
531
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700532status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
533 Mutex::Autolock autoLock(mLock);
534
535 if (mInitCheck != OK) {
536 return mInitCheck;
537 }
538
539 if (mPlugin == NULL) {
540 return -EINVAL;
541 }
542
543 return mPlugin->getSecureStop(ssid, secureStop);
544}
545
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800546status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
547 Mutex::Autolock autoLock(mLock);
548
549 if (mInitCheck != OK) {
550 return mInitCheck;
551 }
552
553 if (mPlugin == NULL) {
554 return -EINVAL;
555 }
556
557 return mPlugin->releaseSecureStops(ssRelease);
558}
559
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700560status_t Drm::releaseAllSecureStops() {
561 Mutex::Autolock autoLock(mLock);
562
563 if (mInitCheck != OK) {
564 return mInitCheck;
565 }
566
567 if (mPlugin == NULL) {
568 return -EINVAL;
569 }
570
571 return mPlugin->releaseAllSecureStops();
572}
573
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800574status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
575 Mutex::Autolock autoLock(mLock);
576
577 if (mInitCheck != OK) {
578 return mInitCheck;
579 }
580
581 if (mPlugin == NULL) {
582 return -EINVAL;
583 }
584
585 return mPlugin->getPropertyString(name, value);
586}
587
588status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
589 Mutex::Autolock autoLock(mLock);
590
591 if (mInitCheck != OK) {
592 return mInitCheck;
593 }
594
595 if (mPlugin == NULL) {
596 return -EINVAL;
597 }
598
599 return mPlugin->getPropertyByteArray(name, value);
600}
601
602status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
603 Mutex::Autolock autoLock(mLock);
604
605 if (mInitCheck != OK) {
606 return mInitCheck;
607 }
608
609 if (mPlugin == NULL) {
610 return -EINVAL;
611 }
612
613 return mPlugin->setPropertyString(name, value);
614}
615
616status_t Drm::setPropertyByteArray(String8 const &name,
617 Vector<uint8_t> const &value ) const {
618 Mutex::Autolock autoLock(mLock);
619
620 if (mInitCheck != OK) {
621 return mInitCheck;
622 }
623
624 if (mPlugin == NULL) {
625 return -EINVAL;
626 }
627
628 return mPlugin->setPropertyByteArray(name, value);
629}
630
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700631
632status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
633 String8 const &algorithm) {
634 Mutex::Autolock autoLock(mLock);
635
636 if (mInitCheck != OK) {
637 return mInitCheck;
638 }
639
640 if (mPlugin == NULL) {
641 return -EINVAL;
642 }
643
Ronghua Wu5c3da202015-02-22 08:45:28 -0800644 DrmSessionManager::Instance()->useSession(sessionId);
645
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700646 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
647}
648
649status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
650 String8 const &algorithm) {
651 Mutex::Autolock autoLock(mLock);
652
653 if (mInitCheck != OK) {
654 return mInitCheck;
655 }
656
657 if (mPlugin == NULL) {
658 return -EINVAL;
659 }
660
Ronghua Wu5c3da202015-02-22 08:45:28 -0800661 DrmSessionManager::Instance()->useSession(sessionId);
662
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700663 return mPlugin->setMacAlgorithm(sessionId, algorithm);
664}
665
666status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
667 Vector<uint8_t> const &keyId,
668 Vector<uint8_t> const &input,
669 Vector<uint8_t> const &iv,
670 Vector<uint8_t> &output) {
671 Mutex::Autolock autoLock(mLock);
672
673 if (mInitCheck != OK) {
674 return mInitCheck;
675 }
676
677 if (mPlugin == NULL) {
678 return -EINVAL;
679 }
680
Ronghua Wu5c3da202015-02-22 08:45:28 -0800681 DrmSessionManager::Instance()->useSession(sessionId);
682
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700683 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
684}
685
686status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
687 Vector<uint8_t> const &keyId,
688 Vector<uint8_t> const &input,
689 Vector<uint8_t> const &iv,
690 Vector<uint8_t> &output) {
691 Mutex::Autolock autoLock(mLock);
692
693 if (mInitCheck != OK) {
694 return mInitCheck;
695 }
696
697 if (mPlugin == NULL) {
698 return -EINVAL;
699 }
700
Ronghua Wu5c3da202015-02-22 08:45:28 -0800701 DrmSessionManager::Instance()->useSession(sessionId);
702
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700703 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
704}
705
706status_t Drm::sign(Vector<uint8_t> const &sessionId,
707 Vector<uint8_t> const &keyId,
708 Vector<uint8_t> const &message,
709 Vector<uint8_t> &signature) {
710 Mutex::Autolock autoLock(mLock);
711
712 if (mInitCheck != OK) {
713 return mInitCheck;
714 }
715
716 if (mPlugin == NULL) {
717 return -EINVAL;
718 }
719
Ronghua Wu5c3da202015-02-22 08:45:28 -0800720 DrmSessionManager::Instance()->useSession(sessionId);
721
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700722 return mPlugin->sign(sessionId, keyId, message, signature);
723}
724
725status_t Drm::verify(Vector<uint8_t> const &sessionId,
726 Vector<uint8_t> const &keyId,
727 Vector<uint8_t> const &message,
728 Vector<uint8_t> const &signature,
729 bool &match) {
730 Mutex::Autolock autoLock(mLock);
731
732 if (mInitCheck != OK) {
733 return mInitCheck;
734 }
735
736 if (mPlugin == NULL) {
737 return -EINVAL;
738 }
739
Ronghua Wu5c3da202015-02-22 08:45:28 -0800740 DrmSessionManager::Instance()->useSession(sessionId);
741
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700742 return mPlugin->verify(sessionId, keyId, message, signature, match);
743}
744
Jeff Tinker68d9d712014-03-04 13:21:31 -0800745status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
746 String8 const &algorithm,
747 Vector<uint8_t> const &message,
748 Vector<uint8_t> const &wrappedKey,
749 Vector<uint8_t> &signature) {
750 Mutex::Autolock autoLock(mLock);
751
752 if (mInitCheck != OK) {
753 return mInitCheck;
754 }
755
756 if (mPlugin == NULL) {
757 return -EINVAL;
758 }
759
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700760 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
761 return -EPERM;
762 }
763
Ronghua Wu5c3da202015-02-22 08:45:28 -0800764 DrmSessionManager::Instance()->useSession(sessionId);
765
Jeff Tinker68d9d712014-03-04 13:21:31 -0800766 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
767}
768
Lajos Molnar6d339f12015-04-17 16:15:53 -0700769void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700770{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800771 mEventLock.lock();
772 mListener.clear();
773 mEventLock.unlock();
774
775 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700776 delete mPlugin;
777 mPlugin = NULL;
778 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700779}
780
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700781void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
782{
783 if (array && array->size()) {
784 obj.writeInt32(array->size());
785 obj.write(array->array(), array->size());
786 } else {
787 obj.writeInt32(0);
788 }
789}
790
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800791} // namespace android