• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #define LOG_TAG "clearkey-DrmPlugin"
17 
18 #include <aidl/android/hardware/drm/DrmMetric.h>
19 #include <utils/Log.h>
20 
21 #include <inttypes.h>
22 #include <stdio.h>
23 #include <chrono>
24 #include <set>
25 
26 #include "AidlUtils.h"
27 #include "ClearKeyDrmProperties.h"
28 #include "DrmPlugin.h"
29 #include "Session.h"
30 #include "Utils.h"
31 #include "AidlClearKeryProperties.h"
32 
33 namespace {
34 const std::string kKeySetIdPrefix("ckid");
35 const int kKeySetIdLength = 16;
36 const int kSecureStopIdStart = 100;
37 const std::string kOfflineLicense("\"type\":\"persistent-license\"");
38 const std::string kStreaming("Streaming");
39 const std::string kTemporaryLicense("\"type\":\"temporary\"");
40 const std::string kTrue("True");
41 
42 const std::string kQueryKeyLicenseType("LicenseType");
43 // Value: "Streaming" or "Offline"
44 const std::string kQueryKeyPlayAllowed("PlayAllowed");
45 // Value: "True" or "False"
46 const std::string kQueryKeyRenewAllowed("RenewAllowed");
47 // Value: "True" or "False"
48 
49 const int kSecureStopIdSize = 10;
50 
uint32ToVector(uint32_t value)51 std::vector<uint8_t> uint32ToVector(uint32_t value) {
52     // 10 bytes to display max value 4294967295 + one byte null terminator
53     char buffer[kSecureStopIdSize];
54     memset(buffer, 0, kSecureStopIdSize);
55     snprintf(buffer, kSecureStopIdSize, "%" PRIu32, value);
56     return std::vector<uint8_t>(buffer, buffer + sizeof(buffer));
57 }
58 
59 };  // unnamed namespace
60 
61 namespace aidl {
62 namespace android {
63 namespace hardware {
64 namespace drm {
65 namespace clearkey {
66 
67 using ::android::Mutex;
68 
DrmPlugin(SessionLibrary * sessionLibrary)69 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
70     : mSessionLibrary(sessionLibrary),
71       mOpenSessionOkCount(0),
72       mCloseSessionOkCount(0),
73       mCloseSessionNotOpenedCount(0),
74       mNextSecureStopId(kSecureStopIdStart),
75       mMockError(Status::OK) {
76     mPlayPolicy.clear();
77     initProperties();
78     mSecureStops.clear();
79     mReleaseKeysMap.clear();
80     std::srand(std::time(nullptr));
81 }
82 
initProperties()83 void DrmPlugin::initProperties() {
84     mStringProperties.clear();
85     mStringProperties[kVendorKey] = kAidlVendorValue;
86     mStringProperties[kVersionKey] = kAidlVersionValue;
87     mStringProperties[kPluginDescriptionKey] = kAidlPluginDescriptionValue;
88     mStringProperties[kAlgorithmsKey] = kAidlAlgorithmsValue;
89     mStringProperties[kListenerTestSupportKey] = kAidlListenerTestSupportValue;
90     mStringProperties[kDrmErrorTestKey] = kAidlDrmErrorTestValue;
91     mStringProperties[kAidlVersionKey] = kAidlVersionValue;
92 
93     std::vector<uint8_t> valueVector;
94     valueVector.clear();
95     valueVector.insert(valueVector.end(), kTestDeviceIdData,
96                        kTestDeviceIdData + sizeof(kTestDeviceIdData) / sizeof(uint8_t));
97     mByteArrayProperties[kDeviceIdKey] = valueVector;
98 
99     valueVector.clear();
100     valueVector.insert(valueVector.end(), kMetricsData,
101                        kMetricsData + sizeof(kMetricsData) / sizeof(uint8_t));
102     mByteArrayProperties[kMetricsKey] = valueVector;
103 }
104 
105 // The secure stop in ClearKey implementation is not installed securely.
106 // This function merely creates a test environment for testing secure stops APIs.
107 // The content in this secure stop is implementation dependent, the clearkey
108 // secureStop does not serve as a reference implementation.
installSecureStop(const std::vector<uint8_t> & sessionId)109 void DrmPlugin::installSecureStop(const std::vector<uint8_t>& sessionId) {
110     ::android::Mutex::Autolock lock(mSecureStopLock);
111 
112     ClearkeySecureStop clearkeySecureStop;
113     clearkeySecureStop.id = uint32ToVector(++mNextSecureStopId);
114     clearkeySecureStop.data.assign(sessionId.begin(), sessionId.end());
115 
116     mSecureStops.insert(std::pair<std::vector<uint8_t>, ClearkeySecureStop>(clearkeySecureStop.id,
117                                                                             clearkeySecureStop));
118 }
119 
closeSession(const std::vector<uint8_t> & in_sessionId)120 ::ndk::ScopedAStatus DrmPlugin::closeSession(const std::vector<uint8_t>& in_sessionId) {
121     if (in_sessionId.size() == 0) {
122         return toNdkScopedAStatus(Status::BAD_VALUE);
123     }
124 
125     ::android::sp<Session> session = mSessionLibrary->findSession(in_sessionId);
126     if (session.get()) {
127         mSessionLibrary->destroySession(session);
128         if (session->getMockError() != clearkeydrm::OK) {
129             sendSessionLostState(in_sessionId);
130             return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE);
131         }
132         mCloseSessionOkCount++;
133         return toNdkScopedAStatus(Status::OK);
134     }
135     mCloseSessionNotOpenedCount++;
136     return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
137 }
138 
decrypt(const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_keyId,const std::vector<uint8_t> & in_input,const std::vector<uint8_t> & in_iv,std::vector<uint8_t> * _aidl_return)139 ::ndk::ScopedAStatus DrmPlugin::decrypt(const std::vector<uint8_t>& in_sessionId,
140                                         const std::vector<uint8_t>& in_keyId,
141                                         const std::vector<uint8_t>& in_input,
142                                         const std::vector<uint8_t>& in_iv,
143                                         std::vector<uint8_t>* _aidl_return) {
144     *_aidl_return = {};
145     if (in_sessionId.size() == 0 || in_keyId.size() == 0 || in_input.size() == 0 ||
146         in_iv.size() == 0) {
147         return toNdkScopedAStatus(Status::BAD_VALUE);
148     }
149     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
150 }
151 
encrypt(const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_keyId,const std::vector<uint8_t> & in_input,const std::vector<uint8_t> & in_iv,std::vector<uint8_t> * _aidl_return)152 ::ndk::ScopedAStatus DrmPlugin::encrypt(const std::vector<uint8_t>& in_sessionId,
153                                         const std::vector<uint8_t>& in_keyId,
154                                         const std::vector<uint8_t>& in_input,
155                                         const std::vector<uint8_t>& in_iv,
156                                         std::vector<uint8_t>* _aidl_return) {
157     *_aidl_return = {};
158     if (in_sessionId.size() == 0 || in_keyId.size() == 0 || in_input.size() == 0 ||
159         in_iv.size() == 0) {
160         return toNdkScopedAStatus(Status::BAD_VALUE);
161     }
162     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
163 }
164 
getHdcpLevels(::aidl::android::hardware::drm::HdcpLevels * _aidl_return)165 ::ndk::ScopedAStatus DrmPlugin::getHdcpLevels(
166         ::aidl::android::hardware::drm::HdcpLevels* _aidl_return) {
167     _aidl_return->connectedLevel = HdcpLevel::HDCP_NONE;
168     _aidl_return->maxLevel = HdcpLevel::HDCP_NO_OUTPUT;
169     return toNdkScopedAStatus(Status::OK);
170 }
171 
getKeyRequest(const std::vector<uint8_t> & in_scope,const std::vector<uint8_t> & in_initData,const std::string & in_mimeType,::aidl::android::hardware::drm::KeyType in_keyType,const std::vector<::aidl::android::hardware::drm::KeyValue> & in_optionalParameters,::aidl::android::hardware::drm::KeyRequest * _aidl_return)172 ::ndk::ScopedAStatus DrmPlugin::getKeyRequest(
173         const std::vector<uint8_t>& in_scope, const std::vector<uint8_t>& in_initData,
174         const std::string& in_mimeType, ::aidl::android::hardware::drm::KeyType in_keyType,
175         const std::vector<::aidl::android::hardware::drm::KeyValue>& in_optionalParameters,
176         ::aidl::android::hardware::drm::KeyRequest* _aidl_return) {
177     UNUSED(in_optionalParameters);
178 
179     KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
180     std::string defaultUrl("https://default.url");
181 
182     _aidl_return->request = {};
183     _aidl_return->requestType = keyRequestType;
184     _aidl_return->defaultUrl = defaultUrl;
185 
186     if (in_scope.size() == 0 ||
187         (in_keyType != KeyType::STREAMING && in_keyType != KeyType::OFFLINE &&
188          in_keyType != KeyType::RELEASE)) {
189         return toNdkScopedAStatus(Status::BAD_VALUE);
190     }
191 
192     const std::vector<uint8_t> scopeId = in_scope;
193     ::android::sp<Session> session;
194     std::set<KeyType> init_types{KeyType::STREAMING, KeyType::OFFLINE};
195     if (init_types.count(in_keyType)) {
196         std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
197         session = mSessionLibrary->findSession(sessionId);
198         if (!session.get()) {
199             return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
200         } else if (session->getMockError() != clearkeydrm::OK) {
201             return toNdkScopedAStatus(session->getMockError());
202         }
203         keyRequestType = KeyRequestType::INITIAL;
204     }
205 
206     std::vector<uint8_t> request = {};
207     auto keyType = static_cast<CdmKeyType>(in_keyType);
208     auto status = session->getKeyRequest(in_initData, in_mimeType, keyType, &request);
209 
210     if (in_keyType == KeyType::RELEASE) {
211         std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
212         std::string requestString(request.begin(), request.end());
213         if (requestString.find(kOfflineLicense) != std::string::npos) {
214             std::string emptyResponse;
215             std::string keySetIdString(keySetId.begin(), keySetId.end());
216             if (!mFileHandle.StoreLicense(keySetIdString, DeviceFiles::kLicenseStateReleasing,
217                                           emptyResponse)) {
218                 ALOGE("Problem releasing offline license");
219                 return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
220             }
221             if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
222                 ::android::sp<Session> session = mSessionLibrary->createSession();
223                 mReleaseKeysMap[keySetIdString] = session->sessionId();
224             } else {
225                 ALOGI("key is in use, ignore release request");
226             }
227         } else {
228             ALOGE("Offline license not found, nothing to release");
229         }
230         keyRequestType = KeyRequestType::RELEASE;
231     }
232     _aidl_return->request = request;
233     _aidl_return->requestType = keyRequestType;
234     _aidl_return->defaultUrl = defaultUrl;
235     return toNdkScopedAStatus(status);
236 }
237 
getLogMessages(std::vector<::aidl::android::hardware::drm::LogMessage> * _aidl_return)238 ::ndk::ScopedAStatus DrmPlugin::getLogMessages(
239         std::vector<::aidl::android::hardware::drm::LogMessage>* _aidl_return) {
240     using std::chrono::duration_cast;
241     using std::chrono::milliseconds;
242     using std::chrono::system_clock;
243 
244     auto timeMillis = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
245 
246     std::vector<::aidl::android::hardware::drm::LogMessage> logs = {
247             {timeMillis, ::aidl::android::hardware::drm::LogPriority::ERROR,
248              std::string("Not implemented")}};
249     *_aidl_return = logs;
250     return toNdkScopedAStatus(Status::OK);
251 }
252 
getMetrics(std::vector<::aidl::android::hardware::drm::DrmMetricGroup> * _aidl_return)253 ::ndk::ScopedAStatus DrmPlugin::getMetrics(
254         std::vector<::aidl::android::hardware::drm::DrmMetricGroup>* _aidl_return) {
255     // Set the open session count metric.
256     DrmMetricNamedValue openSessionOkAttribute = {"status", static_cast<int64_t>(Status::OK)};
257     DrmMetricNamedValue openSessionMetricValue = {"count", mOpenSessionOkCount};
258     DrmMetric openSessionMetric = {
259             "open_session", {openSessionOkAttribute}, {openSessionMetricValue}};
260 
261     // Set the close session count metric.
262     DrmMetricNamedValue closeSessionOkAttribute = {"status", static_cast<int64_t>(Status::OK)};
263     DrmMetricNamedValue closeSessionMetricValue = {"count", mCloseSessionOkCount};
264     DrmMetric closeSessionMetric = {
265             "close_session", {closeSessionOkAttribute}, {closeSessionMetricValue}};
266 
267     // Set the close session, not opened metric.
268     DrmMetricNamedValue closeSessionNotOpenedAttribute = {"status",
269             static_cast<int64_t>(Status::ERROR_DRM_SESSION_NOT_OPENED)};
270     DrmMetricNamedValue closeSessionNotOpenedMetricValue = {"count", mCloseSessionNotOpenedCount};
271     DrmMetric closeSessionNotOpenedMetric = {
272             "close_session", {closeSessionNotOpenedAttribute}, {closeSessionNotOpenedMetricValue}};
273 
274     // Set the setPlaybackId metric.
275     std::vector<DrmMetricNamedValue> sids = {};
276     std::vector<DrmMetricNamedValue> playbackIds = {};
277     for (const auto& [key, value] : mPlaybackId) {
278         std::string sid(key.begin(), key.end());
279         DrmMetricNamedValue sessionIdAttribute = {"sid", sid};
280         sids.push_back(sessionIdAttribute);
281 
282         DrmMetricNamedValue playbackIdMetricValue = {"playbackId", value};
283         playbackIds.push_back(playbackIdMetricValue);
284     }
285     DrmMetric setPlaybackIdMetric = {"set_playback_id", sids, playbackIds};
286 
287     DrmMetricGroup metrics = {{openSessionMetric, closeSessionMetric, closeSessionNotOpenedMetric,
288             setPlaybackIdMetric}};
289 
290     *_aidl_return = {metrics};
291     return toNdkScopedAStatus(Status::OK);
292 }
293 
getNumberOfSessions(::aidl::android::hardware::drm::NumberOfSessions * _aidl_return)294 ::ndk::ScopedAStatus DrmPlugin::getNumberOfSessions(
295         ::aidl::android::hardware::drm::NumberOfSessions* _aidl_return) {
296     _aidl_return->currentSessions = mSessionLibrary->numOpenSessions();
297     _aidl_return->maxSessions = 10;
298     return toNdkScopedAStatus(Status::OK);
299 }
300 
getOfflineLicenseKeySetIds(std::vector<::aidl::android::hardware::drm::KeySetId> * _aidl_return)301 ::ndk::ScopedAStatus DrmPlugin::getOfflineLicenseKeySetIds(
302         std::vector<::aidl::android::hardware::drm::KeySetId>* _aidl_return) {
303     std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
304     std::vector<KeySetId> keySetIds = {};
305     if (mMockError != Status::OK) {
306         *_aidl_return = keySetIds;
307         return toNdkScopedAStatus(toMockStatus(mMockError));
308     }
309     for (const auto& name : licenseNames) {
310         std::vector<uint8_t> keySetId(name.begin(), name.end());
311         KeySetId id = {};
312         id.keySetId = keySetId;
313         keySetIds.push_back(id);
314     }
315     *_aidl_return = keySetIds;
316     return toNdkScopedAStatus(Status::OK);
317 }
318 
getOfflineLicenseState(const::aidl::android::hardware::drm::KeySetId & in_keySetId,::aidl::android::hardware::drm::OfflineLicenseState * _aidl_return)319 ::ndk::ScopedAStatus DrmPlugin::getOfflineLicenseState(
320         const ::aidl::android::hardware::drm::KeySetId& in_keySetId,
321         ::aidl::android::hardware::drm::OfflineLicenseState* _aidl_return) {
322     std::string licenseName(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end());
323     DeviceFiles::LicenseState state;
324     std::string license;
325     OfflineLicenseState licenseState = OfflineLicenseState::UNKNOWN;
326     Status status = Status::OK;
327     if (mMockError != Status::OK) {
328         *_aidl_return = licenseState;
329         return toNdkScopedAStatus(toMockStatus(mMockError));
330     } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
331         switch (state) {
332             case DeviceFiles::kLicenseStateActive:
333                 licenseState = OfflineLicenseState::USABLE;
334                 break;
335             case DeviceFiles::kLicenseStateReleasing:
336                 licenseState = OfflineLicenseState::INACTIVE;
337                 break;
338             case DeviceFiles::kLicenseStateUnknown:
339                 licenseState = OfflineLicenseState::UNKNOWN;
340                 break;
341         }
342     } else {
343         status = Status::BAD_VALUE;
344     }
345     *_aidl_return = licenseState;
346     return toNdkScopedAStatus(status);
347 }
348 
getPropertyByteArray(const std::string & in_propertyName,std::vector<uint8_t> * _aidl_return)349 ::ndk::ScopedAStatus DrmPlugin::getPropertyByteArray(const std::string& in_propertyName,
350                                                      std::vector<uint8_t>* _aidl_return) {
351     std::map<std::string, std::vector<uint8_t>>::iterator itr =
352             mByteArrayProperties.find(std::string(in_propertyName.c_str()));
353     Status status = Status::OK;
354     if (itr != mByteArrayProperties.end()) {
355         *_aidl_return = itr->second;
356     } else {
357         ALOGE("App requested unknown property: %s", in_propertyName.c_str());
358         status = Status::BAD_VALUE;
359         *_aidl_return = {};
360     }
361     return toNdkScopedAStatus(status);
362 }
363 
getPropertyString(const std::string & in_propertyName,std::string * _aidl_return)364 ::ndk::ScopedAStatus DrmPlugin::getPropertyString(const std::string& in_propertyName,
365                                                   std::string* _aidl_return) {
366     std::string name(in_propertyName.c_str());
367     std::string value;
368     Status status = Status::OK;
369 
370     if (name == kVendorKey) {
371         value = mStringProperties[kVendorKey];
372     } else if (name == kVersionKey) {
373         value = mStringProperties[kVersionKey];
374     } else if (name == kPluginDescriptionKey) {
375         value = mStringProperties[kPluginDescriptionKey];
376     } else if (name == kAlgorithmsKey) {
377         value = mStringProperties[kAlgorithmsKey];
378     } else if (name == kListenerTestSupportKey) {
379         value = mStringProperties[kListenerTestSupportKey];
380     } else if (name == kDrmErrorTestKey) {
381         value = mStringProperties[kDrmErrorTestKey];
382     } else if (name == kAidlVersionKey) {
383         value = mStringProperties[kAidlVersionKey];
384     } else {
385         ALOGE("App requested unknown string property %s", name.c_str());
386         status = Status::ERROR_DRM_CANNOT_HANDLE;
387     }
388     *_aidl_return = value;
389     return toNdkScopedAStatus(status);
390 }
391 
getProvisionRequest(const std::string & in_certificateType,const std::string & in_certificateAuthority,::aidl::android::hardware::drm::ProvisionRequest * _aidl_return)392 ::ndk::ScopedAStatus DrmPlugin::getProvisionRequest(
393         const std::string& in_certificateType, const std::string& in_certificateAuthority,
394         ::aidl::android::hardware::drm::ProvisionRequest* _aidl_return) {
395     UNUSED(in_certificateType);
396     UNUSED(in_certificateAuthority);
397     _aidl_return->request = {};
398     _aidl_return->defaultUrl = {};
399     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
400 }
401 
getSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId,::aidl::android::hardware::drm::SecureStop * _aidl_return)402 ::ndk::ScopedAStatus DrmPlugin::getSecureStop(
403         const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId,
404         ::aidl::android::hardware::drm::SecureStop* _aidl_return) {
405     std::vector<uint8_t> stop = {};
406 
407     mSecureStopLock.lock();
408     auto itr = mSecureStops.find(in_secureStopId.secureStopId);
409     if (itr != mSecureStops.end()) {
410         ClearkeySecureStop clearkeyStop = itr->second;
411         stop.insert(stop.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
412         stop.insert(stop.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
413     }
414     mSecureStopLock.unlock();
415 
416     SecureStop secureStop = {};
417     Status status = Status::OK;
418     if (!stop.empty()) {
419         secureStop.opaqueData = stop;
420     } else {
421         status = Status::BAD_VALUE;
422     }
423     *_aidl_return = secureStop;
424     return toNdkScopedAStatus(status);
425 }
426 
getSecureStopIds(std::vector<::aidl::android::hardware::drm::SecureStopId> * _aidl_return)427 ::ndk::ScopedAStatus DrmPlugin::getSecureStopIds(
428         std::vector<::aidl::android::hardware::drm::SecureStopId>* _aidl_return) {
429     mSecureStopLock.lock();
430     std::vector<::aidl::android::hardware::drm::SecureStopId> ids;
431     for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
432         SecureStopId id;
433         id.secureStopId = itr->first;
434         ids.push_back(id);
435     }
436     mSecureStopLock.unlock();
437 
438     *_aidl_return = ids;
439     return toNdkScopedAStatus(Status::OK);
440 }
441 
getSecureStops(std::vector<::aidl::android::hardware::drm::SecureStop> * _aidl_return)442 ::ndk::ScopedAStatus DrmPlugin::getSecureStops(
443         std::vector<::aidl::android::hardware::drm::SecureStop>* _aidl_return) {
444     mSecureStopLock.lock();
445     std::vector<::aidl::android::hardware::drm::SecureStop> stops;
446     for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
447         ClearkeySecureStop clearkeyStop = itr->second;
448         std::vector<uint8_t> stop{};
449         stop.insert(stop.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
450         stop.insert(stop.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
451 
452         SecureStop secureStop;
453         secureStop.opaqueData = stop;
454         stops.push_back(secureStop);
455     }
456     mSecureStopLock.unlock();
457 
458     *_aidl_return = stops;
459     return toNdkScopedAStatus(Status::OK);
460 }
461 
getSecurityLevel(const std::vector<uint8_t> & in_sessionId,::aidl::android::hardware::drm::SecurityLevel * _aidl_return)462 ::ndk::ScopedAStatus DrmPlugin::getSecurityLevel(
463         const std::vector<uint8_t>& in_sessionId,
464         ::aidl::android::hardware::drm::SecurityLevel* _aidl_return) {
465     if (in_sessionId.size() == 0) {
466         *_aidl_return = ::aidl::android::hardware::drm::SecurityLevel::UNKNOWN;
467         return toNdkScopedAStatus(Status::BAD_VALUE);
468     }
469 
470     std::vector<uint8_t> sid = in_sessionId;
471     ::android::sp<Session> session = mSessionLibrary->findSession(sid);
472     if (!session.get()) {
473         *_aidl_return = SecurityLevel::UNKNOWN;
474         return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
475     }
476 
477     std::map<std::vector<uint8_t>, ::aidl::android::hardware::drm::SecurityLevel>::iterator itr =
478             mSecurityLevel.find(sid);
479     if (itr == mSecurityLevel.end()) {
480         ALOGE("Session id not found");
481         *_aidl_return = SecurityLevel::UNKNOWN;
482         return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE);
483     }
484 
485     *_aidl_return = SecurityLevel::SW_SECURE_CRYPTO;
486     return toNdkScopedAStatus(Status::OK);
487 }
488 
openSession(::aidl::android::hardware::drm::SecurityLevel in_securityLevel,std::vector<uint8_t> * _aidl_return)489 ::ndk::ScopedAStatus DrmPlugin::openSession(
490         ::aidl::android::hardware::drm::SecurityLevel in_securityLevel,
491         std::vector<uint8_t>* _aidl_return) {
492     ::android::sp<Session> session = mSessionLibrary->createSession();
493     processMockError(session);
494     std::vector<uint8_t> sessionId = session->sessionId();
495 
496     Status status = setSecurityLevel(sessionId, in_securityLevel);
497     if (status == Status::OK) {
498         mOpenSessionOkCount++;
499     } else {
500         mSessionLibrary->destroySession(session);
501         sessionId.clear();
502     }
503     *_aidl_return = sessionId;
504     return toNdkScopedAStatus(status);
505 }
506 
provideKeyResponse(const std::vector<uint8_t> & in_scope,const std::vector<uint8_t> & in_response,::aidl::android::hardware::drm::KeySetId * _aidl_return)507 ::ndk::ScopedAStatus DrmPlugin::provideKeyResponse(
508         const std::vector<uint8_t>& in_scope, const std::vector<uint8_t>& in_response,
509         ::aidl::android::hardware::drm::KeySetId* _aidl_return) {
510     if (in_scope.size() == 0 || in_response.size() == 0) {
511         // Returns empty keySetId
512         *_aidl_return = {};
513         return toNdkScopedAStatus(Status::BAD_VALUE);
514     }
515 
516     std::string responseString(reinterpret_cast<const char*>(in_response.data()),
517                                in_response.size());
518     const std::vector<uint8_t> scopeId = in_scope;
519     std::vector<uint8_t> sessionId = {};
520     std::string keySetId;
521 
522     bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
523     if (scopeId.size() < kKeySetIdPrefix.size()) {
524         android_errorWriteLog(0x534e4554, "144507096");
525         *_aidl_return = {};
526         return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
527     }
528     bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
529     if (isRelease) {
530         keySetId.assign(scopeId.begin(), scopeId.end());
531 
532         auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
533         if (iter != mReleaseKeysMap.end()) {
534             sessionId.assign(iter->second.begin(), iter->second.end());
535         }
536     } else {
537         sessionId.assign(scopeId.begin(), scopeId.end());
538         // non offline license returns empty keySetId
539         keySetId.clear();
540     }
541 
542     ::android::sp<Session> session = mSessionLibrary->findSession(sessionId);
543     if (!session.get()) {
544         *_aidl_return = {};
545         return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
546     }
547     setPlayPolicy();
548 
549     auto res = session->provideKeyResponse(in_response);
550     if (res == clearkeydrm::OK) {
551         if (isOfflineLicense) {
552             if (isRelease) {
553                 mFileHandle.DeleteLicense(keySetId);
554                 mSessionLibrary->destroySession(session);
555             } else {
556                 if (!makeKeySetId(&keySetId)) {
557                     *_aidl_return = {};
558                     return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
559                 }
560 
561                 bool ok = mFileHandle.StoreLicense(
562                         keySetId, DeviceFiles::kLicenseStateActive,
563                         std::string(in_response.begin(), in_response.end()));
564                 if (!ok) {
565                     ALOGE("Failed to store offline license");
566                 }
567             }
568         }
569 
570         // Test calling AMediaDrm listeners.
571         sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
572 
573         sendExpirationUpdate(sessionId, 100);
574 
575         std::vector<KeyStatus> keysStatus = {};
576         KeyStatus keyStatus;
577 
578         std::vector<uint8_t> keyId1 = {0xA, 0xB, 0xC};
579         keyStatus.keyId = keyId1;
580         keyStatus.type = KeyStatusType::USABLE;
581         keysStatus.push_back(keyStatus);
582 
583         std::vector<uint8_t> keyId2 = {0xD, 0xE, 0xF};
584         keyStatus.keyId = keyId2;
585         keyStatus.type = KeyStatusType::EXPIRED;
586         keysStatus.push_back(keyStatus);
587 
588         std::vector<uint8_t> keyId3 = {0x0, 0x1, 0x2};
589         keyStatus.keyId = keyId3;
590         keyStatus.type = KeyStatusType::USABLE_IN_FUTURE;
591         keysStatus.push_back(keyStatus);
592 
593         sendKeysChange(sessionId, keysStatus, true);
594 
595         installSecureStop(sessionId);
596     } else {
597         ALOGE("provideKeyResponse returns error=%d", res);
598     }
599 
600     std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
601     _aidl_return->keySetId = keySetIdVec;
602     return toNdkScopedAStatus(res);
603 }
604 
provideProvisionResponse(const std::vector<uint8_t> & in_response,::aidl::android::hardware::drm::ProvideProvisionResponseResult * _aidl_return)605 ::ndk::ScopedAStatus DrmPlugin::provideProvisionResponse(
606         const std::vector<uint8_t>& in_response,
607         ::aidl::android::hardware::drm::ProvideProvisionResponseResult* _aidl_return) {
608     Status status = Status::ERROR_DRM_CANNOT_HANDLE;
609     _aidl_return->certificate = {};
610     _aidl_return->wrappedKey = {};
611     if (in_response.size() == 0) {
612         status = Status::BAD_VALUE;
613     }
614     return toNdkScopedAStatus(status);
615 }
616 
queryKeyStatus(const std::vector<uint8_t> & in_sessionId,std::vector<::aidl::android::hardware::drm::KeyValue> * _aidl_return)617 ::ndk::ScopedAStatus DrmPlugin::queryKeyStatus(
618         const std::vector<uint8_t>& in_sessionId,
619         std::vector<::aidl::android::hardware::drm::KeyValue>* _aidl_return) {
620     if (in_sessionId.size() == 0) {
621         // Returns empty key status KeyValue pair
622         *_aidl_return = {};
623         return toNdkScopedAStatus(Status::BAD_VALUE);
624     }
625 
626     std::vector<KeyValue> infoMap = {};
627     mPlayPolicyLock.lock();
628     KeyValue keyValuePair;
629     for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
630         keyValuePair.key = mPlayPolicy[i].key;
631         keyValuePair.value = mPlayPolicy[i].value;
632         infoMap.push_back(keyValuePair);
633     }
634     mPlayPolicyLock.unlock();
635     *_aidl_return = infoMap;
636     return toNdkScopedAStatus(Status::OK);
637 }
638 
releaseAllSecureStops()639 ::ndk::ScopedAStatus DrmPlugin::releaseAllSecureStops() {
640     Status status = Status::OK;
641     const auto res = removeAllSecureStops();
642     if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
643         status = static_cast<Status>(res.getServiceSpecificError());
644     }
645     return toNdkScopedAStatus(status);
646 }
647 
releaseSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId)648 ::ndk::ScopedAStatus DrmPlugin::releaseSecureStop(
649         const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId) {
650     Status status = Status::OK;
651     const auto res = removeSecureStop(in_secureStopId);
652     if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
653         status = static_cast<Status>(res.getServiceSpecificError());
654     }
655     return toNdkScopedAStatus(status);
656 }
657 
releaseSecureStops(const::aidl::android::hardware::drm::OpaqueData & in_ssRelease)658 ::ndk::ScopedAStatus DrmPlugin::releaseSecureStops(
659         const ::aidl::android::hardware::drm::OpaqueData& in_ssRelease) {
660     // OpaqueData starts with 4 byte decimal integer string
661     const size_t kFourBytesOffset = 4;
662     if (in_ssRelease.opaqueData.size() < kFourBytesOffset) {
663         ALOGE("Invalid secureStopRelease length");
664         return toNdkScopedAStatus(Status::BAD_VALUE);
665     }
666 
667     Status status = Status::OK;
668     std::vector<uint8_t> input = in_ssRelease.opaqueData;
669 
670     if (input.size() < kSecureStopIdSize + kFourBytesOffset) {
671         // The minimum size of secure stop has to contain
672         // a 4 bytes count and one secureStop id
673         ALOGE("Total size of secureStops is too short");
674         return toNdkScopedAStatus(Status::BAD_VALUE);
675     }
676 
677     // The format of opaqueData is shared between the server
678     // and the drm service. The clearkey implementation consists of:
679     //    count - number of secure stops
680     //    list of fixed length secure stops
681     size_t countBufferSize = sizeof(uint32_t);
682     if (input.size() < countBufferSize) {
683         // SafetyNet logging
684         android_errorWriteLog(0x534e4554, "144766455");
685         return toNdkScopedAStatus(Status::BAD_VALUE);
686     }
687     uint32_t count = 0;
688     sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
689 
690     // Avoid divide by 0 below.
691     if (count == 0) {
692         ALOGE("Invalid 0 secureStop count");
693         return toNdkScopedAStatus(Status::BAD_VALUE);
694     }
695 
696     // Computes the fixed length secureStop size
697     size_t secureStopSize = (input.size() - kFourBytesOffset) / count;
698     if (secureStopSize < kSecureStopIdSize) {
699         // A valid secureStop contains the id plus data
700         ALOGE("Invalid secureStop size");
701         return toNdkScopedAStatus(Status::BAD_VALUE);
702     }
703     uint8_t* buffer = new uint8_t[secureStopSize];
704     size_t offset = kFourBytesOffset;  // skip the count
705     for (size_t i = 0; i < count; ++i, offset += secureStopSize) {
706         memcpy(buffer, input.data() + offset, secureStopSize);
707 
708         // A secureStop contains id+data, we only use the id for removal
709         std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize);
710         ::aidl::android::hardware::drm::SecureStopId secureStopId{id};
711         const auto res = removeSecureStop(secureStopId);
712         if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
713             status = static_cast<Status>(res.getServiceSpecificError());
714         }
715         if (Status::OK != status) break;
716     }
717 
718     delete[] buffer;
719     return toNdkScopedAStatus(status);
720 }
721 
removeAllSecureStops()722 ::ndk::ScopedAStatus DrmPlugin::removeAllSecureStops() {
723     Mutex::Autolock lock(mSecureStopLock);
724 
725     mSecureStops.clear();
726     mNextSecureStopId = kSecureStopIdStart;
727     return toNdkScopedAStatus(Status::OK);
728 }
729 
removeKeys(const std::vector<uint8_t> & in_sessionId)730 ::ndk::ScopedAStatus DrmPlugin::removeKeys(const std::vector<uint8_t>& in_sessionId) {
731     Status status = Status::ERROR_DRM_CANNOT_HANDLE;
732     if (in_sessionId.size() == 0) {
733         status = Status::BAD_VALUE;
734     }
735     return toNdkScopedAStatus(status);
736 }
737 
removeOfflineLicense(const::aidl::android::hardware::drm::KeySetId & in_keySetId)738 ::ndk::ScopedAStatus DrmPlugin::removeOfflineLicense(
739         const ::aidl::android::hardware::drm::KeySetId& in_keySetId) {
740     if (mMockError != Status::OK) {
741         return toNdkScopedAStatus(toMockStatus(mMockError));
742     }
743     Status status = Status::BAD_VALUE;
744     std::string licenseName(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end());
745     if (mFileHandle.DeleteLicense(licenseName)) {
746         status = Status::OK;
747     }
748     return toNdkScopedAStatus(status);
749 }
750 
removeSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId)751 ::ndk::ScopedAStatus DrmPlugin::removeSecureStop(
752         const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId) {
753     Mutex::Autolock lock(mSecureStopLock);
754 
755     Status status = Status::OK;
756     if (1 != mSecureStops.erase(in_secureStopId.secureStopId)) {
757         status = Status::BAD_VALUE;
758     }
759     return toNdkScopedAStatus(status);
760 }
761 
requiresSecureDecoder(const std::string & in_mime,::aidl::android::hardware::drm::SecurityLevel in_level,bool * _aidl_return)762 ::ndk::ScopedAStatus DrmPlugin::requiresSecureDecoder(
763         const std::string& in_mime, ::aidl::android::hardware::drm::SecurityLevel in_level,
764         bool* _aidl_return) {
765     UNUSED(in_mime);
766     UNUSED(in_level);
767     *_aidl_return = false;
768     return ::ndk::ScopedAStatus::ok();
769 }
770 
restoreKeys(const std::vector<uint8_t> & in_sessionId,const::aidl::android::hardware::drm::KeySetId & in_keySetId)771 ::ndk::ScopedAStatus DrmPlugin::restoreKeys(
772         const std::vector<uint8_t>& in_sessionId,
773         const ::aidl::android::hardware::drm::KeySetId& in_keySetId) {
774     if (in_sessionId.size() == 0 || in_keySetId.keySetId.size() == 0) {
775         return toNdkScopedAStatus(Status::BAD_VALUE);
776     }
777 
778     DeviceFiles::LicenseState licenseState;
779     std::string offlineLicense;
780     if (!mFileHandle.RetrieveLicense(
781                 std::string(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end()),
782                 &licenseState, &offlineLicense)) {
783         ALOGE("Failed to restore offline license");
784         return toNdkScopedAStatus(Status::ERROR_DRM_NO_LICENSE);
785     }
786 
787     if (DeviceFiles::kLicenseStateUnknown == licenseState ||
788         DeviceFiles::kLicenseStateReleasing == licenseState) {
789         ALOGE("Invalid license state=%d", licenseState);
790         return toNdkScopedAStatus(Status::ERROR_DRM_NO_LICENSE);
791     }
792 
793     ::android::sp<Session> session = mSessionLibrary->findSession(in_sessionId);
794     if (!session.get()) {
795         return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
796     }
797     auto res = session->provideKeyResponse(
798             std::vector<uint8_t>(offlineLicense.begin(), offlineLicense.end()));
799     if (res != clearkeydrm::OK) {
800         ALOGE("Failed to restore keys");
801     }
802     return toNdkScopedAStatus(res);
803 }
804 
sendEvent(::aidl::android::hardware::drm::EventType in_eventType,const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_data)805 void DrmPlugin::sendEvent(::aidl::android::hardware::drm::EventType in_eventType,
806                                           const std::vector<uint8_t>& in_sessionId,
807                                           const std::vector<uint8_t>& in_data) {
808     if (mListener != nullptr) {
809         mListener->onEvent(in_eventType, in_sessionId, in_data);
810     } else {
811         ALOGE("Null event listener, event not sent");
812     }
813     return;
814 }
815 
sendExpirationUpdate(const std::vector<uint8_t> & in_sessionId,int64_t in_expiryTimeInMS)816 void DrmPlugin::sendExpirationUpdate(const std::vector<uint8_t>& in_sessionId,
817                                                      int64_t in_expiryTimeInMS) {
818     if (mListener != nullptr) {
819         mListener->onExpirationUpdate(in_sessionId, in_expiryTimeInMS);
820     } else {
821         ALOGE("Null event listener, event not sent");
822     }
823     return;
824 }
825 
sendKeysChange(const std::vector<uint8_t> & in_sessionId,const std::vector<::aidl::android::hardware::drm::KeyStatus> & in_keyStatusList,bool in_hasNewUsableKey)826 void DrmPlugin::sendKeysChange(
827         const std::vector<uint8_t>& in_sessionId,
828         const std::vector<::aidl::android::hardware::drm::KeyStatus>& in_keyStatusList,
829         bool in_hasNewUsableKey) {
830     if (mListener != nullptr) {
831         mListener->onKeysChange(in_sessionId, in_keyStatusList, in_hasNewUsableKey);
832     } else {
833         ALOGE("Null event listener, event not sent");
834     }
835     return;
836 }
837 
sendSessionLostState(const std::vector<uint8_t> & in_sessionId)838 void DrmPlugin::sendSessionLostState(const std::vector<uint8_t>& in_sessionId) {
839     if (mListener != nullptr) {
840         mListener->onSessionLostState(in_sessionId);
841     }
842     return;
843 }
844 
setCipherAlgorithm(const std::vector<uint8_t> &,const std::string &)845 ::ndk::ScopedAStatus DrmPlugin::setCipherAlgorithm(const std::vector<uint8_t>& /*in_sessionId*/,
846                                                    const std::string& /*in_algorithm*/) {
847     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
848 }
849 
setListener(const std::shared_ptr<::aidl::android::hardware::drm::IDrmPluginListener> & in_listener)850 ::ndk::ScopedAStatus DrmPlugin::setListener(
851         const std::shared_ptr<
852                 ::aidl::android::hardware::drm::IDrmPluginListener>& in_listener) {
853     mListener = in_listener;
854     return toNdkScopedAStatus(Status::OK);
855 }
856 
setMacAlgorithm(const std::vector<uint8_t> &,const std::string &)857 ::ndk::ScopedAStatus DrmPlugin::setMacAlgorithm(const std::vector<uint8_t>& /*in_sessionId*/,
858                                                 const std::string& /*in_algorithm*/) {
859     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
860 }
861 
setPlaybackId(const std::vector<uint8_t> & in_sessionId,const std::string & in_playbackId)862 ::ndk::ScopedAStatus DrmPlugin::setPlaybackId(const std::vector<uint8_t>& in_sessionId,
863                                               const std::string& in_playbackId) {
864     if (in_sessionId.size() == 0) {
865         ALOGE("Invalid empty session id");
866         return toNdkScopedAStatus(Status::BAD_VALUE);
867     }
868 
869     std::vector<uint8_t> sid = in_sessionId;
870     mPlaybackId[sid] = in_playbackId;
871     return toNdkScopedAStatus(Status::OK);
872 }
873 
setPropertyByteArray(const std::string & in_propertyName,const std::vector<uint8_t> & in_value)874 ::ndk::ScopedAStatus DrmPlugin::setPropertyByteArray(const std::string& in_propertyName,
875                                                      const std::vector<uint8_t>& in_value) {
876     if (in_propertyName == kDeviceIdKey) {
877         ALOGD("Cannot set immutable property: %s", in_propertyName.c_str());
878         return toNdkScopedAStatus(Status::BAD_VALUE);
879     } else if (in_propertyName == kClientIdKey) {
880         mByteArrayProperties[kClientIdKey] = in_value;
881         return toNdkScopedAStatus(Status::OK);
882     }
883 
884     // Setting of undefined properties is not supported
885     ALOGE("Failed to set property byte array, key=%s", in_propertyName.c_str());
886     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
887 }
888 
setPropertyString(const std::string & in_propertyName,const std::string & in_value)889 ::ndk::ScopedAStatus DrmPlugin::setPropertyString(const std::string& in_propertyName,
890                                                   const std::string& in_value) {
891     std::string immutableKeys;
892     immutableKeys.append(kAlgorithmsKey + ",");
893     immutableKeys.append(kPluginDescriptionKey + ",");
894     immutableKeys.append(kVendorKey + ",");
895     immutableKeys.append(kVersionKey + ",");
896 
897     std::string key = std::string(in_propertyName.c_str());
898     if (immutableKeys.find(key) != std::string::npos) {
899         ALOGD("Cannot set immutable property: %s", key.c_str());
900         return toNdkScopedAStatus(Status::BAD_VALUE);
901     }
902 
903     std::map<std::string, std::string>::iterator itr = mStringProperties.find(key);
904     if (itr == mStringProperties.end()) {
905         ALOGE("Cannot set undefined property string, key=%s", key.c_str());
906         return toNdkScopedAStatus(Status::BAD_VALUE);
907     }
908 
909     if (in_propertyName == kDrmErrorTestKey) {
910         if (in_value == kResourceContentionValue) {
911             mMockError = Status::ERROR_DRM_RESOURCE_CONTENTION;
912         } else if (in_value == kLostStateValue) {
913             mMockError = Status::ERROR_DRM_SESSION_LOST_STATE;
914         } else if (in_value == kFrameTooLargeValue) {
915             mMockError = Status::ERROR_DRM_FRAME_TOO_LARGE;
916         } else if (in_value == kInvalidStateValue) {
917             mMockError = Status::ERROR_DRM_INVALID_STATE;
918         } else {
919             mMockError = Status::ERROR_DRM_UNKNOWN;
920         }
921     }
922 
923     mStringProperties[key] = std::string(in_value.c_str());
924     return toNdkScopedAStatus(Status::OK);
925 }
926 
sign(const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,std::vector<uint8_t> * _aidl_return)927 ::ndk::ScopedAStatus DrmPlugin::sign(const std::vector<uint8_t>& /*in_sessionId*/,
928                                      const std::vector<uint8_t>& /*in_keyId*/,
929                                      const std::vector<uint8_t>& /*in_message*/,
930                                      std::vector<uint8_t>* _aidl_return) {
931     *_aidl_return = {};
932     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
933 }
934 
signRSA(const std::vector<uint8_t> &,const std::string &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,std::vector<uint8_t> * _aidl_return)935 ::ndk::ScopedAStatus DrmPlugin::signRSA(const std::vector<uint8_t>& /*in_sessionId*/,
936                                         const std::string& /*in_algorithm*/,
937                                         const std::vector<uint8_t>& /*in_message*/,
938                                         const std::vector<uint8_t>& /*in_wrappedkey*/,
939                                         std::vector<uint8_t>* _aidl_return) {
940     *_aidl_return = {};
941     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
942 }
943 
verify(const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,bool * _aidl_return)944 ::ndk::ScopedAStatus DrmPlugin::verify(const std::vector<uint8_t>& /*in_sessionId*/,
945                                        const std::vector<uint8_t>& /*in_keyId*/,
946                                        const std::vector<uint8_t>& /*in_message*/,
947                                        const std::vector<uint8_t>& /*in_signature*/,
948                                        bool* _aidl_return) {
949     *_aidl_return = false;
950     return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
951 }
952 
953 // Private methods below.
setPlayPolicy()954 void DrmPlugin::setPlayPolicy() {
955     ::android::Mutex::Autolock lock(mPlayPolicyLock);
956     mPlayPolicy.clear();
957 
958     KeyValue policy;
959     policy.key = kQueryKeyLicenseType;
960     policy.value = kStreaming;
961     mPlayPolicy.push_back(policy);
962 
963     policy.key = kQueryKeyPlayAllowed;
964     policy.value = kTrue;
965     mPlayPolicy.push_back(policy);
966 
967     policy.key = kQueryKeyRenewAllowed;
968     mPlayPolicy.push_back(policy);
969 }
970 
makeKeySetId(std::string * keySetId)971 bool DrmPlugin::makeKeySetId(std::string* keySetId) {
972     if (!keySetId) {
973         ALOGE("keySetId destination not provided");
974         return false;
975     }
976     std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
977     ksid.resize(kKeySetIdLength);
978     std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
979 
980     while (keySetId->empty()) {
981         for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
982             *itr = std::rand() % 0xff;
983         }
984         auto id = reinterpret_cast<const uint8_t*>(randomData.data());
985         *keySetId = kKeySetIdPrefix + ::android::ByteArrayToHexString(id, randomData.size());
986         if (mFileHandle.LicenseExists(*keySetId)) {
987             // collision, regenerate
988             ALOGV("Retry generating KeySetId");
989             keySetId->clear();
990         }
991     }
992     return true;
993 }
994 
setSecurityLevel(const std::vector<uint8_t> & sessionId,SecurityLevel level)995 Status DrmPlugin::setSecurityLevel(const std::vector<uint8_t>& sessionId, SecurityLevel level) {
996     if (sessionId.size() == 0) {
997         ALOGE("Invalid empty session id");
998         return Status::BAD_VALUE;
999     }
1000 
1001     if (level != SecurityLevel::DEFAULT && level != SecurityLevel::SW_SECURE_CRYPTO) {
1002         ALOGE("Cannot set security level > max");
1003         return Status::ERROR_DRM_CANNOT_HANDLE;
1004     }
1005 
1006     std::vector<uint8_t> sid = sessionId;
1007     ::android::sp<Session> session = mSessionLibrary->findSession(sid);
1008     if (!session.get()) {
1009         return Status::ERROR_DRM_SESSION_NOT_OPENED;
1010     }
1011 
1012     std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr = mSecurityLevel.find(sid);
1013     if (itr != mSecurityLevel.end()) {
1014         mSecurityLevel[sid] = level;
1015     } else {
1016         if (!mSecurityLevel.insert(std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level))
1017                      .second) {
1018             ALOGE("Failed to set security level");
1019             return Status::ERROR_DRM_INVALID_STATE;
1020         }
1021     }
1022     return Status::OK;
1023 }
1024 
1025 }  // namespace clearkey
1026 }  // namespace drm
1027 }  // namespace hardware
1028 }  // namespace android
1029 }  // namespace aidl
1030