blob: 1004eb8b150e2c3b1884e8a3f96c8e5087c306bb [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
John W. Brucee9fec542017-03-13 16:29:28 -070024#include <media/DrmPluginPath.h>
Jeff Tinker30038072016-04-25 13:41:35 -070025#include <media/DrmSessionClientInterface.h>
26#include <media/DrmSessionManager.h>
27#include <media/Drm.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) {
Jeff Tinker81e0bd42014-04-02 16:41:38 -070043 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
44 bool ok = checkCallingPermission(String16(permissionString));
45 if (!ok) ALOGE("Request requires %s", permissionString);
46 return ok;
47}
48
Jeff Tinkercc82dc62013-02-08 10:18:35 -080049KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
50KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
51Mutex Drm::mMapLock;
Jeff Tinker2fb561a2015-04-22 15:58:16 -070052Mutex Drm::mLock;
Jeff Tinkercc82dc62013-02-08 10:18:35 -080053
54static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
55 if (lhs.size() < rhs.size()) {
56 return true;
57 } else if (lhs.size() > rhs.size()) {
58 return false;
59 }
60
61 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
62}
63
Ronghua Wu5c3da202015-02-22 08:45:28 -080064struct DrmSessionClient : public DrmSessionClientInterface {
Chih-Hung Hsieh64a28702016-05-03 09:52:51 -070065 explicit DrmSessionClient(Drm* drm) : mDrm(drm) {}
Ronghua Wu5c3da202015-02-22 08:45:28 -080066
67 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
68 sp<Drm> drm = mDrm.promote();
69 if (drm == NULL) {
70 return true;
71 }
72 status_t err = drm->closeSession(sessionId);
73 if (err != OK) {
74 return false;
75 }
76 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
77 return true;
78 }
79
80protected:
81 virtual ~DrmSessionClient() {}
82
83private:
84 wp<Drm> mDrm;
85
86 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
87};
88
Jeff Tinkercc82dc62013-02-08 10:18:35 -080089Drm::Drm()
90 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080091 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070092 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080093 mFactory(NULL),
94 mPlugin(NULL) {
95}
96
97Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -080098 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -080099 delete mPlugin;
100 mPlugin = NULL;
101 closeFactory();
102}
103
104void Drm::closeFactory() {
105 delete mFactory;
106 mFactory = NULL;
107 mLibrary.clear();
108}
109
110status_t Drm::initCheck() const {
111 return mInitCheck;
112}
113
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700114status_t Drm::setListener(const sp<IDrmClient>& listener)
115{
116 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700117 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800118 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700119 }
120 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800121 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700122 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700123 mListener = listener;
124 return NO_ERROR;
125}
126
127void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
128 Vector<uint8_t> const *sessionId,
129 Vector<uint8_t> const *data)
130{
131 mEventLock.lock();
132 sp<IDrmClient> listener = mListener;
133 mEventLock.unlock();
134
135 if (listener != NULL) {
136 Parcel obj;
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700137 writeByteArray(obj, sessionId);
138 writeByteArray(obj, data);
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700139
140 Mutex::Autolock lock(mNotifyLock);
141 listener->notify(eventType, extra, &obj);
142 }
143}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800144
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700145void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
146 int64_t expiryTimeInMS)
147{
148 mEventLock.lock();
149 sp<IDrmClient> listener = mListener;
150 mEventLock.unlock();
151
152 if (listener != NULL) {
153 Parcel obj;
154 writeByteArray(obj, sessionId);
155 obj.writeInt64(expiryTimeInMS);
156
157 Mutex::Autolock lock(mNotifyLock);
158 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
159 }
160}
161
162void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
163 Vector<DrmPlugin::KeyStatus> const *keyStatusList,
164 bool hasNewUsableKey)
165{
166 mEventLock.lock();
167 sp<IDrmClient> listener = mListener;
168 mEventLock.unlock();
169
170 if (listener != NULL) {
171 Parcel obj;
172 writeByteArray(obj, sessionId);
173
174 size_t nkeys = keyStatusList->size();
175 obj.writeInt32(keyStatusList->size());
176 for (size_t i = 0; i < nkeys; ++i) {
177 const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
178 writeByteArray(obj, &keyStatus->mKeyId);
179 obj.writeInt32(keyStatus->mType);
180 }
181 obj.writeInt32(hasNewUsableKey);
182
183 Mutex::Autolock lock(mNotifyLock);
184 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
185 }
186}
187
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800188/*
189 * Search the plugins directory for a plugin that supports the scheme
190 * specified by uuid
191 *
192 * If found:
193 * mLibrary holds a strong pointer to the dlopen'd library
194 * mFactory is set to the library's factory method
195 * mInitCheck is set to OK
196 *
197 * If not found:
198 * mLibrary is cleared and mFactory are set to NULL
199 * mInitCheck is set to an error (!OK)
200 */
201void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
202
203 closeFactory();
204
205 // lock static maps
206 Mutex::Autolock autoLock(mMapLock);
207
208 // first check cache
209 Vector<uint8_t> uuidVector;
Lajos Molnar6d339f12015-04-17 16:15:53 -0700210 uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800211 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
212 if (index >= 0) {
213 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
214 mInitCheck = OK;
215 return;
216 } else {
217 ALOGE("Failed to load from cached library path!");
218 mInitCheck = ERROR_UNSUPPORTED;
219 return;
220 }
221 }
222
223 // no luck, have to search
John W. Brucee9fec542017-03-13 16:29:28 -0700224 String8 dirPath(getDrmPluginPath());
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800225 DIR* pDir = opendir(dirPath.string());
226
227 if (pDir == NULL) {
228 mInitCheck = ERROR_UNSUPPORTED;
229 ALOGE("Failed to open plugin directory %s", dirPath.string());
230 return;
231 }
232
233
234 struct dirent* pEntry;
235 while ((pEntry = readdir(pDir))) {
236
237 String8 pluginPath = dirPath + "/" + pEntry->d_name;
238
239 if (pluginPath.getPathExtension() == ".so") {
240
241 if (loadLibraryForScheme(pluginPath, uuid)) {
242 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
243 mInitCheck = OK;
244 closedir(pDir);
245 return;
246 }
247 }
248 }
249
250 closedir(pDir);
251
252 ALOGE("Failed to find drm plugin");
253 mInitCheck = ERROR_UNSUPPORTED;
254}
255
256bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
257
258 // get strong pointer to open shared library
259 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
260 if (index >= 0) {
261 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
262 } else {
263 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
264 }
265
266 if (!mLibrary.get()) {
267 mLibrary = new SharedLibrary(path);
268 if (!*mLibrary) {
269 return false;
270 }
271
272 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
273 }
274
275 typedef DrmFactory *(*CreateDrmFactoryFunc)();
276
277 CreateDrmFactoryFunc createDrmFactory =
278 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
279
280 if (createDrmFactory == NULL ||
281 (mFactory = createDrmFactory()) == NULL ||
282 !mFactory->isCryptoSchemeSupported(uuid)) {
283 closeFactory();
284 return false;
285 }
286 return true;
287}
288
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700289bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
290
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800291 Mutex::Autolock autoLock(mLock);
292
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700293 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
294 findFactoryForScheme(uuid);
295 if (mInitCheck != OK) {
296 return false;
297 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800298 }
299
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700300 if (mimeType != "") {
301 return mFactory->isContentTypeSupported(mimeType);
302 }
303
304 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800305}
306
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800307status_t Drm::createPlugin(const uint8_t uuid[16],
308 const String8& /* appPackageName */) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800309 Mutex::Autolock autoLock(mLock);
310
311 if (mPlugin != NULL) {
312 return -EINVAL;
313 }
314
315 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
316 findFactoryForScheme(uuid);
317 }
318
319 if (mInitCheck != OK) {
320 return mInitCheck;
321 }
322
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700323 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800324 if (mPlugin) {
325 mPlugin->setListener(this);
326 } else {
327 ALOGE("Failed to create plugin");
328 return UNEXPECTED_NULL;
329 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700330 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800331}
332
333status_t Drm::destroyPlugin() {
334 Mutex::Autolock autoLock(mLock);
335
336 if (mInitCheck != OK) {
337 return mInitCheck;
338 }
339
340 if (mPlugin == NULL) {
341 return -EINVAL;
342 }
343
Jeff Tinker9e27bc62016-10-19 18:20:47 -0700344 setListener(NULL);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800345 delete mPlugin;
346 mPlugin = NULL;
347
348 return OK;
349}
350
351status_t Drm::openSession(Vector<uint8_t> &sessionId) {
352 Mutex::Autolock autoLock(mLock);
353
354 if (mInitCheck != OK) {
355 return mInitCheck;
356 }
357
358 if (mPlugin == NULL) {
359 return -EINVAL;
360 }
361
Ronghua Wu5c3da202015-02-22 08:45:28 -0800362 status_t err = mPlugin->openSession(sessionId);
363 if (err == ERROR_DRM_RESOURCE_BUSY) {
364 bool retry = false;
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700365 mLock.unlock();
366 // reclaimSession may call back to closeSession, since mLock is shared between Drm
367 // instances, we should unlock here to avoid deadlock.
Ronghua Wu5c3da202015-02-22 08:45:28 -0800368 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
Ronghua Wuf35f6be2015-05-13 10:33:21 -0700369 mLock.lock();
370 if (mInitCheck != OK) {
371 return mInitCheck;
372 }
373
374 if (mPlugin == NULL) {
375 return -EINVAL;
376 }
Ronghua Wu5c3da202015-02-22 08:45:28 -0800377 if (retry) {
378 err = mPlugin->openSession(sessionId);
379 }
380 }
381 if (err == OK) {
382 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
383 }
384 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800385}
386
387status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
388 Mutex::Autolock autoLock(mLock);
389
390 if (mInitCheck != OK) {
391 return mInitCheck;
392 }
393
394 if (mPlugin == NULL) {
395 return -EINVAL;
396 }
397
Ronghua Wu5c3da202015-02-22 08:45:28 -0800398 status_t err = mPlugin->closeSession(sessionId);
399 if (err == OK) {
400 DrmSessionManager::Instance()->removeSession(sessionId);
401 }
402 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800403}
404
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700405status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
406 Vector<uint8_t> const &initData,
407 String8 const &mimeType, DrmPlugin::KeyType keyType,
408 KeyedVector<String8, String8> const &optionalParameters,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700409 Vector<uint8_t> &request, String8 &defaultUrl,
410 DrmPlugin::KeyRequestType *keyRequestType) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800411 Mutex::Autolock autoLock(mLock);
412
413 if (mInitCheck != OK) {
414 return mInitCheck;
415 }
416
417 if (mPlugin == NULL) {
418 return -EINVAL;
419 }
420
Ronghua Wu5c3da202015-02-22 08:45:28 -0800421 DrmSessionManager::Instance()->useSession(sessionId);
422
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700423 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
Jeff Tinkerd072c902015-03-16 13:39:29 -0700424 optionalParameters, request, defaultUrl,
425 keyRequestType);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800426}
427
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700428status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
429 Vector<uint8_t> const &response,
430 Vector<uint8_t> &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
Ronghua Wu5c3da202015-02-22 08:45:28 -0800441 DrmSessionManager::Instance()->useSession(sessionId);
442
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700443 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800444}
445
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700446status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800447 Mutex::Autolock autoLock(mLock);
448
449 if (mInitCheck != OK) {
450 return mInitCheck;
451 }
452
453 if (mPlugin == NULL) {
454 return -EINVAL;
455 }
456
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700457 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800458}
459
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700460status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
461 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800462 Mutex::Autolock autoLock(mLock);
463
464 if (mInitCheck != OK) {
465 return mInitCheck;
466 }
467
468 if (mPlugin == NULL) {
469 return -EINVAL;
470 }
471
Ronghua Wu5c3da202015-02-22 08:45:28 -0800472 DrmSessionManager::Instance()->useSession(sessionId);
473
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700474 return mPlugin->restoreKeys(sessionId, keySetId);
475}
476
477status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
478 KeyedVector<String8, String8> &infoMap) const {
479 Mutex::Autolock autoLock(mLock);
480
481 if (mInitCheck != OK) {
482 return mInitCheck;
483 }
484
485 if (mPlugin == NULL) {
486 return -EINVAL;
487 }
488
Ronghua Wu5c3da202015-02-22 08:45:28 -0800489 DrmSessionManager::Instance()->useSession(sessionId);
490
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700491 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800492}
493
Jeff Tinker68d9d712014-03-04 13:21:31 -0800494status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
495 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800496 Mutex::Autolock autoLock(mLock);
497
498 if (mInitCheck != OK) {
499 return mInitCheck;
500 }
501
502 if (mPlugin == NULL) {
503 return -EINVAL;
504 }
505
Jeff Tinker68d9d712014-03-04 13:21:31 -0800506 return mPlugin->getProvisionRequest(certType, certAuthority,
507 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800508}
509
Jeff Tinker68d9d712014-03-04 13:21:31 -0800510status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
511 Vector<uint8_t> &certificate,
512 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800513 Mutex::Autolock autoLock(mLock);
514
515 if (mInitCheck != OK) {
516 return mInitCheck;
517 }
518
519 if (mPlugin == NULL) {
520 return -EINVAL;
521 }
522
Jeff Tinker68d9d712014-03-04 13:21:31 -0800523 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800524}
525
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800526status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
527 Mutex::Autolock autoLock(mLock);
528
529 if (mInitCheck != OK) {
530 return mInitCheck;
531 }
532
533 if (mPlugin == NULL) {
534 return -EINVAL;
535 }
536
537 return mPlugin->getSecureStops(secureStops);
538}
539
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700540status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
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->getSecureStop(ssid, secureStop);
552}
553
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800554status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
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->releaseSecureStops(ssRelease);
566}
567
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700568status_t Drm::releaseAllSecureStops() {
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->releaseAllSecureStops();
580}
581
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800582status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
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->getPropertyString(name, value);
594}
595
596status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &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->getPropertyByteArray(name, value);
608}
609
610status_t Drm::setPropertyString(String8 const &name, String8 const &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->setPropertyString(name, value);
622}
623
624status_t Drm::setPropertyByteArray(String8 const &name,
625 Vector<uint8_t> const &value ) const {
626 Mutex::Autolock autoLock(mLock);
627
628 if (mInitCheck != OK) {
629 return mInitCheck;
630 }
631
632 if (mPlugin == NULL) {
633 return -EINVAL;
634 }
635
636 return mPlugin->setPropertyByteArray(name, value);
637}
638
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700639
640status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
641 String8 const &algorithm) {
642 Mutex::Autolock autoLock(mLock);
643
644 if (mInitCheck != OK) {
645 return mInitCheck;
646 }
647
648 if (mPlugin == NULL) {
649 return -EINVAL;
650 }
651
Ronghua Wu5c3da202015-02-22 08:45:28 -0800652 DrmSessionManager::Instance()->useSession(sessionId);
653
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700654 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
655}
656
657status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
658 String8 const &algorithm) {
659 Mutex::Autolock autoLock(mLock);
660
661 if (mInitCheck != OK) {
662 return mInitCheck;
663 }
664
665 if (mPlugin == NULL) {
666 return -EINVAL;
667 }
668
Ronghua Wu5c3da202015-02-22 08:45:28 -0800669 DrmSessionManager::Instance()->useSession(sessionId);
670
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700671 return mPlugin->setMacAlgorithm(sessionId, algorithm);
672}
673
674status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
675 Vector<uint8_t> const &keyId,
676 Vector<uint8_t> const &input,
677 Vector<uint8_t> const &iv,
678 Vector<uint8_t> &output) {
679 Mutex::Autolock autoLock(mLock);
680
681 if (mInitCheck != OK) {
682 return mInitCheck;
683 }
684
685 if (mPlugin == NULL) {
686 return -EINVAL;
687 }
688
Ronghua Wu5c3da202015-02-22 08:45:28 -0800689 DrmSessionManager::Instance()->useSession(sessionId);
690
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700691 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
692}
693
694status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
695 Vector<uint8_t> const &keyId,
696 Vector<uint8_t> const &input,
697 Vector<uint8_t> const &iv,
698 Vector<uint8_t> &output) {
699 Mutex::Autolock autoLock(mLock);
700
701 if (mInitCheck != OK) {
702 return mInitCheck;
703 }
704
705 if (mPlugin == NULL) {
706 return -EINVAL;
707 }
708
Ronghua Wu5c3da202015-02-22 08:45:28 -0800709 DrmSessionManager::Instance()->useSession(sessionId);
710
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700711 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
712}
713
714status_t Drm::sign(Vector<uint8_t> const &sessionId,
715 Vector<uint8_t> const &keyId,
716 Vector<uint8_t> const &message,
717 Vector<uint8_t> &signature) {
718 Mutex::Autolock autoLock(mLock);
719
720 if (mInitCheck != OK) {
721 return mInitCheck;
722 }
723
724 if (mPlugin == NULL) {
725 return -EINVAL;
726 }
727
Ronghua Wu5c3da202015-02-22 08:45:28 -0800728 DrmSessionManager::Instance()->useSession(sessionId);
729
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700730 return mPlugin->sign(sessionId, keyId, message, signature);
731}
732
733status_t Drm::verify(Vector<uint8_t> const &sessionId,
734 Vector<uint8_t> const &keyId,
735 Vector<uint8_t> const &message,
736 Vector<uint8_t> const &signature,
737 bool &match) {
738 Mutex::Autolock autoLock(mLock);
739
740 if (mInitCheck != OK) {
741 return mInitCheck;
742 }
743
744 if (mPlugin == NULL) {
745 return -EINVAL;
746 }
747
Ronghua Wu5c3da202015-02-22 08:45:28 -0800748 DrmSessionManager::Instance()->useSession(sessionId);
749
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700750 return mPlugin->verify(sessionId, keyId, message, signature, match);
751}
752
Jeff Tinker68d9d712014-03-04 13:21:31 -0800753status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
754 String8 const &algorithm,
755 Vector<uint8_t> const &message,
756 Vector<uint8_t> const &wrappedKey,
757 Vector<uint8_t> &signature) {
758 Mutex::Autolock autoLock(mLock);
759
760 if (mInitCheck != OK) {
761 return mInitCheck;
762 }
763
764 if (mPlugin == NULL) {
765 return -EINVAL;
766 }
767
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700768 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
769 return -EPERM;
770 }
771
Ronghua Wu5c3da202015-02-22 08:45:28 -0800772 DrmSessionManager::Instance()->useSession(sessionId);
773
Jeff Tinker68d9d712014-03-04 13:21:31 -0800774 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
775}
776
Lajos Molnar6d339f12015-04-17 16:15:53 -0700777void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700778{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800779 mEventLock.lock();
780 mListener.clear();
781 mEventLock.unlock();
782
783 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700784 delete mPlugin;
785 mPlugin = NULL;
786 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700787}
788
Jeff Tinker2fb25c82015-03-31 15:40:16 -0700789void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
790{
791 if (array && array->size()) {
792 obj.writeInt32(array->size());
793 obj.write(array->array(), array->size());
794 } else {
795 obj.writeInt32(0);
796 }
797}
798
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800799} // namespace android