• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 "DrmManager(Native)"
19 
20 #include <cutils/properties.h>
21 #include <utils/String8.h>
22 #include <utils/Log.h>
23 
24 #include <binder/IPCThreadState.h>
25 #include <drm/DrmInfo.h>
26 
27 #include <drm/DrmInfoEvent.h>
28 #include <drm/DrmRights.h>
29 #include <drm/DrmConstraints.h>
30 #include <drm/DrmMetadata.h>
31 #include <drm/DrmInfoStatus.h>
32 #include <drm/DrmInfoRequest.h>
33 #include <drm/DrmSupportInfo.h>
34 #include <drm/DrmConvertedStatus.h>
35 #include <media/MediaMetricsItem.h>
36 #include <IDrmEngine.h>
37 
38 #include "DrmManager.h"
39 #include "ReadWriteUtils.h"
40 
41 #include <algorithm>
42 
43 #define DECRYPT_FILE_ERROR (-1)
44 
45 using namespace android;
46 
47 const String8 DrmManager::EMPTY_STRING("");
48 
49 const std::map<const char*, size_t> DrmManager::kMethodIdMap {
50     {"getConstraints"     , DrmManagerMethodId::GET_CONSTRAINTS       },
51     {"getMetadata"        , DrmManagerMethodId::GET_METADATA          },
52     {"canHandle"          , DrmManagerMethodId::CAN_HANDLE            },
53     {"processDrmInfo"     , DrmManagerMethodId::PROCESS_DRM_INFO      },
54     {"acquireDrmInfo"     , DrmManagerMethodId::ACQUIRE_DRM_INFO      },
55     {"saveRights"         , DrmManagerMethodId::SAVE_RIGHTS           },
56     {"getOriginalMimeType", DrmManagerMethodId::GET_ORIGINAL_MIME_TYPE},
57     {"getDrmObjectType"   , DrmManagerMethodId::GET_DRM_OBJECT_TYPE   },
58     {"checkRightsStatus"  , DrmManagerMethodId::CHECK_RIGHTS_STATUS   },
59     {"removeRights"       , DrmManagerMethodId::REMOVE_RIGHTS         },
60     {"removeAllRights"    , DrmManagerMethodId::REMOVE_ALL_RIGHTS     },
61     {"openConvertSession" , DrmManagerMethodId::OPEN_CONVERT_SESSION  },
62     {"openDecryptSession" , DrmManagerMethodId::OPEN_DECRYPT_SESSION  }
63 };
64 
DrmManager()65 DrmManager::DrmManager() :
66     mDecryptSessionId(0),
67     mConvertId(0) {
68     srand(time(NULL));
69     memset(mUniqueIdArray, 0, sizeof(bool) * kMaxNumUniqueIds);
70 }
71 
~DrmManager()72 DrmManager::~DrmManager() {
73     if (mMetricsLooper != NULL) {
74         mMetricsLooper->stop();
75     }
76     flushEngineMetrics();
77 }
78 
initMetricsLooper()79 void DrmManager::initMetricsLooper() {
80     if (mMetricsLooper != NULL) {
81         return;
82     }
83     mMetricsLooper = new ALooper;
84     mMetricsLooper->setName("DrmManagerMetricsLooper");
85     mMetricsLooper->start();
86     mMetricsLooper->registerHandler(this);
87 
88     sp<AMessage> msg = new AMessage(kWhatFlushMetrics, this);
89     msg->post(getMetricsFlushPeriodUs());
90 }
91 
onMessageReceived(const sp<AMessage> & msg)92 void DrmManager::onMessageReceived(const sp<AMessage> &msg) {
93     switch (msg->what()) {
94         case kWhatFlushMetrics:
95         {
96             flushEngineMetrics();
97             msg->post(getMetricsFlushPeriodUs());
98             break;
99         }
100         default:
101         {
102             ALOGW("Unrecognized message type: %u", msg->what());
103         }
104     }
105 }
106 
getMetricsFlushPeriodUs()107 int64_t DrmManager::getMetricsFlushPeriodUs() {
108     return 1000 * 1000 * std::max(1ll, (long long)property_get_int64("drmmanager.metrics.period", 86400));
109 }
110 
recordEngineMetrics(const char func[],const String8 & plugInId8,const String8 & mimeType)111 void DrmManager::recordEngineMetrics(
112         const char func[], const String8& plugInId8, const String8& mimeType) {
113     IDrmEngine& engine = mPlugInManager.getPlugIn(plugInId8);
114     std::unique_ptr<DrmSupportInfo> info(engine.getSupportInfo(0));
115 
116     uid_t callingUid = IPCThreadState::self()->getCallingUid();
117     std::string plugInId(plugInId8.getPathLeaf().getBasePath().c_str());
118     ALOGV("%d calling %s %s", callingUid, plugInId.c_str(), func);
119 
120     Mutex::Autolock _l(mMetricsLock);
121     auto& metrics = mPluginMetrics[std::make_pair(callingUid, plugInId)];
122     if (metrics.mPluginId.empty()) {
123         metrics.mPluginId = plugInId;
124         metrics.mCallingUid = callingUid;
125         if (NULL != info) {
126             metrics.mDescription = info->getDescription().c_str();
127         }
128     }
129 
130     if (!mimeType.isEmpty()) {
131         metrics.mMimeTypes.insert(mimeType.c_str());
132     } else if (NULL != info) {
133         DrmSupportInfo::MimeTypeIterator mimeIter = info->getMimeTypeIterator();
134         while (mimeIter.hasNext()) {
135             metrics.mMimeTypes.insert(mimeIter.next().c_str());
136         }
137     }
138 
139     size_t methodId = kMethodIdMap.at(func);
140     if (methodId < metrics.mMethodCounts.size()) {
141         metrics.mMethodCounts[methodId]++;
142     }
143 }
144 
flushEngineMetrics()145 void DrmManager::flushEngineMetrics() {
146     using namespace std::string_literals;
147     Mutex::Autolock _l(mMetricsLock);
148     for (auto kv : mPluginMetrics) {
149         DrmManagerMetrics& metrics = kv.second;
150         std::unique_ptr<mediametrics::Item> item(mediametrics::Item::create("drmmanager"));
151         item->setUid(metrics.mCallingUid);
152         item->setCString("plugin_id", metrics.mPluginId.c_str());
153         item->setCString("description", metrics.mDescription.c_str());
154 
155         std::vector<std::string> mimeTypes(metrics.mMimeTypes.begin(), metrics.mMimeTypes.end());
156         std::string mimeTypesStr(mimeTypes.empty() ? "" : mimeTypes[0]);
157         for (size_t i = 1; i < mimeTypes.size() ; i++) {
158             mimeTypesStr.append(",").append(mimeTypes[i]);
159         }
160         item->setCString("mime_types", mimeTypesStr.c_str());
161 
162         for (size_t i = 0; i < metrics.mMethodCounts.size() ; i++) {
163             item->setInt64(("method"s + std::to_string(i)).c_str(), metrics.mMethodCounts[i]);
164         }
165 
166         if (!item->selfrecord()) {
167             ALOGE("Failed to record metrics");
168         }
169     }
170     mPluginMetrics.clear();
171 }
172 
addUniqueId(bool isNative)173 int DrmManager::addUniqueId(bool isNative) {
174     Mutex::Autolock _l(mLock);
175 
176     int uniqueId = -1;
177     int random = rand();
178 
179     for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
180         int temp = (random + index) % kMaxNumUniqueIds;
181         if (!mUniqueIdArray[temp]) {
182             uniqueId = temp;
183             mUniqueIdArray[uniqueId] = true;
184 
185             if (isNative) {
186                 // set a flag to differentiate DrmManagerClient
187                 // created from native side and java side
188                 uniqueId |= 0x1000;
189             }
190             break;
191         }
192     }
193 
194     // -1 indicates that no unique id can be allocated.
195     return uniqueId;
196 }
197 
removeUniqueId(int uniqueId)198 void DrmManager::removeUniqueId(int uniqueId) {
199     Mutex::Autolock _l(mLock);
200     if (uniqueId & 0x1000) {
201         // clear the flag for the native side.
202         uniqueId &= ~(0x1000);
203     }
204 
205     if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
206         mUniqueIdArray[uniqueId] = false;
207     }
208 }
209 
loadPlugIns()210 status_t DrmManager::loadPlugIns() {
211 #if __LP64__
212     String8 pluginDirPath("/system/lib64/drm");
213 #else
214     String8 pluginDirPath("/system/lib/drm");
215 #endif
216     loadPlugIns(pluginDirPath);
217     return DRM_NO_ERROR;
218 }
219 
loadPlugIns(const String8 & plugInDirPath)220 status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
221     mPlugInManager.loadPlugIns(plugInDirPath);
222     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
223     for (size_t i = 0; i < plugInPathList.size(); ++i) {
224         String8 plugInPath = plugInPathList[i];
225         DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
226         if (NULL != info) {
227             if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
228                 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
229             }
230             delete info;
231         }
232     }
233     return DRM_NO_ERROR;
234 }
235 
unloadPlugIns()236 status_t DrmManager::unloadPlugIns() {
237     Mutex::Autolock _l(mLock);
238     mConvertSessionMap.clear();
239     mDecryptSessionMap.clear();
240     mPlugInManager.unloadPlugIns();
241     mSupportInfoToPlugInIdMap.clear();
242     return DRM_NO_ERROR;
243 }
244 
setDrmServiceListener(int uniqueId,const sp<IDrmServiceListener> & drmServiceListener)245 status_t DrmManager::setDrmServiceListener(
246             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
247     Mutex::Autolock _l(mListenerLock);
248     if (NULL != drmServiceListener.get()) {
249         mServiceListeners.add(uniqueId, drmServiceListener);
250     } else {
251         mServiceListeners.removeItem(uniqueId);
252     }
253     return DRM_NO_ERROR;
254 }
255 
addClient(int uniqueId)256 void DrmManager::addClient(int uniqueId) {
257     Mutex::Autolock _l(mLock);
258     if (!mSupportInfoToPlugInIdMap.isEmpty()) {
259         Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
260         for (size_t index = 0; index < plugInIdList.size(); index++) {
261             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
262             rDrmEngine.initialize(uniqueId);
263             rDrmEngine.setOnInfoListener(uniqueId, this);
264         }
265     }
266 }
267 
removeClient(int uniqueId)268 void DrmManager::removeClient(int uniqueId) {
269     Mutex::Autolock _l(mLock);
270     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
271     for (size_t index = 0; index < plugInIdList.size(); index++) {
272         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
273         rDrmEngine.terminate(uniqueId);
274     }
275 }
276 
getConstraints(int uniqueId,const String8 * path,const int action)277 DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
278     Mutex::Autolock _l(mLock);
279     DrmConstraints *constraints = NULL;
280     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
281     if (EMPTY_STRING != plugInId) {
282         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
283         constraints = rDrmEngine.getConstraints(uniqueId, path, action);
284     }
285     if (NULL != constraints) {
286         recordEngineMetrics(__func__, plugInId);
287     }
288     return constraints;
289 }
290 
getMetadata(int uniqueId,const String8 * path)291 DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
292     Mutex::Autolock _l(mLock);
293     DrmMetadata *meta = NULL;
294     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
295     if (EMPTY_STRING != plugInId) {
296         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
297         meta = rDrmEngine.getMetadata(uniqueId, path);
298     }
299     if (NULL != meta) {
300         recordEngineMetrics(__func__, plugInId);
301     }
302     return meta;
303 }
304 
canHandle(int uniqueId,const String8 & path,const String8 & mimeType)305 bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
306     Mutex::Autolock _l(mLock);
307     const String8 plugInId = getSupportedPlugInId(mimeType);
308     bool result = (EMPTY_STRING != plugInId) ? true : false;
309 
310     if (result) {
311         recordEngineMetrics(__func__, plugInId, mimeType);
312     }
313 
314     if (0 < path.length()) {
315         if (result) {
316             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
317             result = rDrmEngine.canHandle(uniqueId, path);
318         } else {
319             String8 extension = path.getPathExtension();
320             if (String8("") != extension) {
321                 result = canHandle(uniqueId, path);
322             }
323         }
324     }
325     return result;
326 }
327 
processDrmInfo(int uniqueId,const DrmInfo * drmInfo)328 DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
329     Mutex::Autolock _l(mLock);
330     DrmInfoStatus *infoStatus = NULL;
331     const String8 mimeType = drmInfo->getMimeType();
332     const String8 plugInId = getSupportedPlugInId(mimeType);
333     if (EMPTY_STRING != plugInId) {
334         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
335         infoStatus = rDrmEngine.processDrmInfo(uniqueId, drmInfo);
336     }
337     if (NULL != infoStatus) {
338         recordEngineMetrics(__func__, plugInId, mimeType);
339     }
340     return infoStatus;
341 }
342 
canHandle(int uniqueId,const String8 & path)343 bool DrmManager::canHandle(int uniqueId, const String8& path) {
344     bool result = false;
345     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
346 
347     for (size_t i = 0; i < plugInPathList.size(); ++i) {
348         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
349         result = rDrmEngine.canHandle(uniqueId, path);
350 
351         if (result) {
352             recordEngineMetrics(__func__, plugInPathList[i]);
353             break;
354         }
355     }
356     return result;
357 }
358 
acquireDrmInfo(int uniqueId,const DrmInfoRequest * drmInfoRequest)359 DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
360     Mutex::Autolock _l(mLock);
361     DrmInfo *info = NULL;
362     const String8 mimeType = drmInfoRequest->getMimeType();
363     const String8 plugInId = getSupportedPlugInId(mimeType);
364     if (EMPTY_STRING != plugInId) {
365         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
366         info = rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
367     }
368     if (NULL != info) {
369         recordEngineMetrics(__func__, plugInId, mimeType);
370     }
371     return info;
372 }
373 
saveRights(int uniqueId,const DrmRights & drmRights,const String8 & rightsPath,const String8 & contentPath)374 status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
375             const String8& rightsPath, const String8& contentPath) {
376     Mutex::Autolock _l(mLock);
377     const String8 mimeType = drmRights.getMimeType();
378     const String8 plugInId = getSupportedPlugInId(mimeType);
379     status_t result = DRM_ERROR_UNKNOWN;
380     if (EMPTY_STRING != plugInId) {
381         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
382         result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
383     }
384     if (DRM_NO_ERROR == result) {
385         recordEngineMetrics(__func__, plugInId, mimeType);
386     }
387     return result;
388 }
389 
getOriginalMimeType(int uniqueId,const String8 & path,int fd)390 String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
391     Mutex::Autolock _l(mLock);
392     String8 mimeType(EMPTY_STRING);
393     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
394     if (EMPTY_STRING != plugInId) {
395         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
396         mimeType = rDrmEngine.getOriginalMimeType(uniqueId, path, fd);
397     }
398     if (!mimeType.isEmpty()) {
399         recordEngineMetrics(__func__, plugInId, mimeType);
400     }
401     return mimeType;
402 }
403 
getDrmObjectType(int uniqueId,const String8 & path,const String8 & mimeType)404 int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
405     Mutex::Autolock _l(mLock);
406     int type = DrmObjectType::UNKNOWN;
407     const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
408     if (EMPTY_STRING != plugInId) {
409         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
410         type = rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
411     }
412     if (DrmObjectType::UNKNOWN != type) {
413         recordEngineMetrics(__func__, plugInId, mimeType);
414     }
415     return type;
416 }
417 
checkRightsStatus(int uniqueId,const String8 & path,int action)418 int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
419     Mutex::Autolock _l(mLock);
420     int rightsStatus = RightsStatus::RIGHTS_INVALID;
421     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
422     if (EMPTY_STRING != plugInId) {
423         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
424         rightsStatus = rDrmEngine.checkRightsStatus(uniqueId, path, action);
425     }
426     if (RightsStatus::RIGHTS_INVALID != rightsStatus) {
427         recordEngineMetrics(__func__, plugInId);
428     }
429     return rightsStatus;
430 }
431 
consumeRights(int uniqueId,sp<DecryptHandle> & decryptHandle,int action,bool reserve)432 status_t DrmManager::consumeRights(
433     int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
434     status_t result = DRM_ERROR_UNKNOWN;
435     Mutex::Autolock _l(mDecryptLock);
436     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
437         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
438         result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
439     }
440     return result;
441 }
442 
setPlaybackStatus(int uniqueId,sp<DecryptHandle> & decryptHandle,int playbackStatus,int64_t position)443 status_t DrmManager::setPlaybackStatus(
444     int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
445     status_t result = DRM_ERROR_UNKNOWN;
446     Mutex::Autolock _l(mDecryptLock);
447     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
448         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
449         result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
450     }
451     return result;
452 }
453 
validateAction(int uniqueId,const String8 & path,int action,const ActionDescription & description)454 bool DrmManager::validateAction(
455     int uniqueId, const String8& path, int action, const ActionDescription& description) {
456     Mutex::Autolock _l(mLock);
457     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
458     if (EMPTY_STRING != plugInId) {
459         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
460         return rDrmEngine.validateAction(uniqueId, path, action, description);
461     }
462     return false;
463 }
464 
removeRights(int uniqueId,const String8 & path)465 status_t DrmManager::removeRights(int uniqueId, const String8& path) {
466     Mutex::Autolock _l(mLock);
467     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
468     status_t result = DRM_ERROR_UNKNOWN;
469     if (EMPTY_STRING != plugInId) {
470         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
471         result = rDrmEngine.removeRights(uniqueId, path);
472     }
473     if (DRM_NO_ERROR == result) {
474         recordEngineMetrics(__func__, plugInId);
475     }
476     return result;
477 }
478 
removeAllRights(int uniqueId)479 status_t DrmManager::removeAllRights(int uniqueId) {
480     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
481     status_t result = DRM_ERROR_UNKNOWN;
482     for (size_t index = 0; index < plugInIdList.size(); index++) {
483         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
484         result = rDrmEngine.removeAllRights(uniqueId);
485         if (DRM_NO_ERROR != result) {
486             break;
487         }
488         recordEngineMetrics(__func__, plugInIdList[index]);
489     }
490     return result;
491 }
492 
openConvertSession(int uniqueId,const String8 & mimeType)493 int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
494     Mutex::Autolock _l(mConvertLock);
495     int convertId = -1;
496 
497     const String8 plugInId = getSupportedPlugInId(mimeType);
498     if (EMPTY_STRING != plugInId) {
499         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
500 
501         if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
502             ++mConvertId;
503             convertId = mConvertId;
504             mConvertSessionMap.add(convertId, &rDrmEngine);
505             recordEngineMetrics(__func__, plugInId, mimeType);
506         }
507     }
508     return convertId;
509 }
510 
convertData(int uniqueId,int convertId,const DrmBuffer * inputData)511 DrmConvertedStatus* DrmManager::convertData(
512             int uniqueId, int convertId, const DrmBuffer* inputData) {
513     DrmConvertedStatus *drmConvertedStatus = NULL;
514 
515     Mutex::Autolock _l(mConvertLock);
516     if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
517         IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
518         drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
519     }
520     return drmConvertedStatus;
521 }
522 
closeConvertSession(int uniqueId,int convertId)523 DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
524     Mutex::Autolock _l(mConvertLock);
525     DrmConvertedStatus *drmConvertedStatus = NULL;
526 
527     if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
528         IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
529         drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
530         mConvertSessionMap.removeItem(convertId);
531     }
532     return drmConvertedStatus;
533 }
534 
getAllSupportInfo(int,int * length,DrmSupportInfo ** drmSupportInfoArray)535 status_t DrmManager::getAllSupportInfo(
536                     int /* uniqueId */, int* length, DrmSupportInfo** drmSupportInfoArray) {
537     Mutex::Autolock _l(mLock);
538     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
539     int size = plugInPathList.size();
540     int validPlugins = 0;
541 
542     if (0 < size) {
543         Vector<DrmSupportInfo> drmSupportInfoList;
544 
545         for (int i = 0; i < size; ++i) {
546             String8 plugInPath = plugInPathList[i];
547             DrmSupportInfo* drmSupportInfo
548                 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
549             if (NULL != drmSupportInfo) {
550                 drmSupportInfoList.add(*drmSupportInfo);
551                 delete drmSupportInfo; drmSupportInfo = NULL;
552             }
553         }
554 
555         validPlugins = drmSupportInfoList.size();
556         if (0 < validPlugins) {
557             *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
558             for (int i = 0; i < validPlugins; ++i) {
559                 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
560             }
561         }
562     }
563     *length = validPlugins;
564     return DRM_NO_ERROR;
565 }
566 
openDecryptSession(int uniqueId,int fd,off64_t offset,off64_t length,const char * mime)567 sp<DecryptHandle> DrmManager::openDecryptSession(
568         int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
569 
570     Mutex::Autolock _l(mDecryptLock);
571     status_t result = DRM_ERROR_CANNOT_HANDLE;
572     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
573 
574     sp<DecryptHandle> handle = new DecryptHandle();
575     if (NULL != handle.get()) {
576         handle->decryptId = mDecryptSessionId + 1;
577 
578         for (size_t index = 0; index < plugInIdList.size(); index++) {
579             const String8& plugInId = plugInIdList.itemAt(index);
580             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
581             result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
582 
583             if (DRM_NO_ERROR == result) {
584                 ++mDecryptSessionId;
585                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
586                 recordEngineMetrics(__func__, plugInId, String8(mime));
587                 break;
588             }
589         }
590     }
591     if (DRM_NO_ERROR != result) {
592         handle.clear();
593     }
594     return handle;
595 }
596 
openDecryptSession(int uniqueId,const char * uri,const char * mime)597 sp<DecryptHandle> DrmManager::openDecryptSession(
598         int uniqueId, const char* uri, const char* mime) {
599     Mutex::Autolock _l(mDecryptLock);
600     status_t result = DRM_ERROR_CANNOT_HANDLE;
601     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
602 
603     sp<DecryptHandle> handle = new DecryptHandle();
604     if (NULL != handle.get()) {
605         handle->decryptId = mDecryptSessionId + 1;
606 
607         for (size_t index = 0; index < plugInIdList.size(); index++) {
608             const String8& plugInId = plugInIdList.itemAt(index);
609             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
610             result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
611 
612             if (DRM_NO_ERROR == result) {
613                 ++mDecryptSessionId;
614                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
615                 recordEngineMetrics(__func__, plugInId, String8(mime));
616                 break;
617             }
618         }
619     }
620     if (DRM_NO_ERROR != result) {
621         handle.clear();
622         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
623     }
624     return handle;
625 }
626 
openDecryptSession(int uniqueId,const DrmBuffer & buf,const String8 & mimeType)627 sp<DecryptHandle> DrmManager::openDecryptSession(
628         int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
629     Mutex::Autolock _l(mDecryptLock);
630     status_t result = DRM_ERROR_CANNOT_HANDLE;
631     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
632 
633     sp<DecryptHandle> handle = new DecryptHandle();
634     if (NULL != handle.get()) {
635         handle->decryptId = mDecryptSessionId + 1;
636 
637         for (size_t index = 0; index < plugInIdList.size(); index++) {
638             const String8& plugInId = plugInIdList.itemAt(index);
639             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
640             result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
641 
642             if (DRM_NO_ERROR == result) {
643                 ++mDecryptSessionId;
644                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
645                 recordEngineMetrics(__func__, plugInId, mimeType);
646                 break;
647             }
648         }
649     }
650     if (DRM_NO_ERROR != result) {
651         handle.clear();
652         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
653     }
654     return handle;
655 }
656 
closeDecryptSession(int uniqueId,sp<DecryptHandle> & decryptHandle)657 status_t DrmManager::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
658     Mutex::Autolock _l(mDecryptLock);
659     status_t result = DRM_ERROR_UNKNOWN;
660     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
661         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
662         result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
663         if (DRM_NO_ERROR == result && NULL != decryptHandle.get()) {
664             mDecryptSessionMap.removeItem(decryptHandle->decryptId);
665         }
666     }
667     return result;
668 }
669 
initializeDecryptUnit(int uniqueId,sp<DecryptHandle> & decryptHandle,int decryptUnitId,const DrmBuffer * headerInfo)670 status_t DrmManager::initializeDecryptUnit(
671         int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
672         const DrmBuffer* headerInfo) {
673     status_t result = DRM_ERROR_UNKNOWN;
674     Mutex::Autolock _l(mDecryptLock);
675     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
676         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
677         result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
678     }
679     return result;
680 }
681 
decrypt(int uniqueId,sp<DecryptHandle> & decryptHandle,int decryptUnitId,const DrmBuffer * encBuffer,DrmBuffer ** decBuffer,DrmBuffer * IV)682 status_t DrmManager::decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
683             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
684     status_t result = DRM_ERROR_UNKNOWN;
685 
686     Mutex::Autolock _l(mDecryptLock);
687     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
688         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
689         result = drmEngine->decrypt(
690                 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
691     }
692     return result;
693 }
694 
finalizeDecryptUnit(int uniqueId,sp<DecryptHandle> & decryptHandle,int decryptUnitId)695 status_t DrmManager::finalizeDecryptUnit(
696             int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
697     status_t result = DRM_ERROR_UNKNOWN;
698     Mutex::Autolock _l(mDecryptLock);
699     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
700         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
701         result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
702     }
703     return result;
704 }
705 
pread(int uniqueId,sp<DecryptHandle> & decryptHandle,void * buffer,ssize_t numBytes,off64_t offset)706 ssize_t DrmManager::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
707             void* buffer, ssize_t numBytes, off64_t offset) {
708     ssize_t result = DECRYPT_FILE_ERROR;
709 
710     Mutex::Autolock _l(mDecryptLock);
711     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
712         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
713         result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
714     }
715     return result;
716 }
717 
getSupportedPlugInId(int uniqueId,const String8 & path,const String8 & mimeType)718 String8 DrmManager::getSupportedPlugInId(
719             int uniqueId, const String8& path, const String8& mimeType) {
720     String8 plugInId("");
721 
722     if (EMPTY_STRING != mimeType) {
723         plugInId = getSupportedPlugInId(mimeType);
724     } else {
725         plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
726     }
727     return plugInId;
728 }
729 
getSupportedPlugInId(const String8 & mimeType)730 String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
731     String8 plugInId("");
732 
733     if (EMPTY_STRING != mimeType) {
734         for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
735             const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
736 
737             if (drmSupportInfo.isSupportedMimeType(mimeType)) {
738                 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
739                 break;
740             }
741         }
742     }
743     return plugInId;
744 }
745 
getSupportedPlugInIdFromPath(int uniqueId,const String8 & path)746 String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
747     String8 plugInId("");
748     const String8 fileSuffix = path.getPathExtension();
749 
750     for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
751         const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
752 
753         if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
754             String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
755             IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
756 
757             if (drmEngine.canHandle(uniqueId, path)) {
758                 plugInId = key;
759                 break;
760             }
761         }
762     }
763     return plugInId;
764 }
765 
onInfo(const DrmInfoEvent & event)766 void DrmManager::onInfo(const DrmInfoEvent& event) {
767     Mutex::Autolock _l(mListenerLock);
768     for (size_t index = 0; index < mServiceListeners.size(); index++) {
769         int uniqueId = mServiceListeners.keyAt(index);
770 
771         if (uniqueId == event.getUniqueId()) {
772             sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
773             serviceListener->notify(event);
774         }
775     }
776 }
777 
778