xref: /aosp_15_r20/frameworks/av/drm/libmediadrm/DrmHalHidl.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "DrmHalHidl"
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/media/BnResourceManagerClient.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <android/binder_manager.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/drm/1.2/types.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/drm/1.3/IDrmFactory.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <android/hidl/manager/1.2/IServiceManager.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/EventMetric.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaMetrics.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/PluginMetricsReporting.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/drm/DrmAPI.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/base64.h>
34*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmHalHidl.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmSessionClientInterface.h>
37*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmSessionManager.h>
38*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmStatus.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmUtils.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/IDrmMetricsConsumer.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker #include <iomanip>
44*ec779b8eSAndroid Build Coastguard Worker #include <vector>
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker using ::android::sp;
47*ec779b8eSAndroid Build Coastguard Worker using ::android::DrmUtils::toStatusT;
48*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_array;
49*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_string;
50*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_vec;
51*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::Return;
52*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::Void;
53*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::drm::V1_1::DrmMetricGroup;
54*ec779b8eSAndroid Build Coastguard Worker using ::android::os::PersistableBundle;
55*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::KeyedVector;
56*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::KeyRequestType;
57*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::KeyType;
58*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::KeyValue;
59*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::SecureStop;
60*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::SecureStopId;
61*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::Status;
62*ec779b8eSAndroid Build Coastguard Worker using drm::V1_1::HdcpLevel;
63*ec779b8eSAndroid Build Coastguard Worker using drm::V1_1::SecureStopRelease;
64*ec779b8eSAndroid Build Coastguard Worker using drm::V1_1::SecurityLevel;
65*ec779b8eSAndroid Build Coastguard Worker using drm::V1_2::KeySetId;
66*ec779b8eSAndroid Build Coastguard Worker using drm::V1_2::KeyStatusType;
67*ec779b8eSAndroid Build Coastguard Worker 
68*ec779b8eSAndroid Build Coastguard Worker typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
69*ec779b8eSAndroid Build Coastguard Worker typedef drm::V1_2::Status Status_V1_2;
70*ec779b8eSAndroid Build Coastguard Worker typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
71*ec779b8eSAndroid Build Coastguard Worker 
72*ec779b8eSAndroid Build Coastguard Worker namespace {
73*ec779b8eSAndroid Build Coastguard Worker 
74*ec779b8eSAndroid Build Coastguard Worker // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
75*ec779b8eSAndroid Build Coastguard Worker // in the MediaDrm API.
76*ec779b8eSAndroid Build Coastguard Worker constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
77*ec779b8eSAndroid Build Coastguard Worker constexpr char kEqualsSign[] = "=";
78*ec779b8eSAndroid Build Coastguard Worker 
79*ec779b8eSAndroid Build Coastguard Worker template <typename T>
toBase64StringNoPad(const T * data,size_t size)80*ec779b8eSAndroid Build Coastguard Worker std::string toBase64StringNoPad(const T* data, size_t size) {
81*ec779b8eSAndroid Build Coastguard Worker     // Note that the base 64 conversion only works with arrays of single-byte
82*ec779b8eSAndroid Build Coastguard Worker     // values. If the source is empty or is not an array of single-byte values,
83*ec779b8eSAndroid Build Coastguard Worker     // return empty string.
84*ec779b8eSAndroid Build Coastguard Worker     if (size == 0 || sizeof(data[0]) != 1) {
85*ec779b8eSAndroid Build Coastguard Worker         return "";
86*ec779b8eSAndroid Build Coastguard Worker     }
87*ec779b8eSAndroid Build Coastguard Worker 
88*ec779b8eSAndroid Build Coastguard Worker     android::AString outputString;
89*ec779b8eSAndroid Build Coastguard Worker     encodeBase64(data, size, &outputString);
90*ec779b8eSAndroid Build Coastguard Worker     // Remove trailing equals padding if it exists.
91*ec779b8eSAndroid Build Coastguard Worker     while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
92*ec779b8eSAndroid Build Coastguard Worker         outputString.erase(outputString.size() - 1, 1);
93*ec779b8eSAndroid Build Coastguard Worker     }
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker     return std::string(outputString.c_str(), outputString.size());
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker 
98*ec779b8eSAndroid Build Coastguard Worker }  // anonymous namespace
99*ec779b8eSAndroid Build Coastguard Worker 
100*ec779b8eSAndroid Build Coastguard Worker namespace android {
101*ec779b8eSAndroid Build Coastguard Worker 
102*ec779b8eSAndroid Build Coastguard Worker #define INIT_CHECK()                             \
103*ec779b8eSAndroid Build Coastguard Worker     {                                            \
104*ec779b8eSAndroid Build Coastguard Worker         if (mInitCheck != OK) return mInitCheck; \
105*ec779b8eSAndroid Build Coastguard Worker     }
106*ec779b8eSAndroid Build Coastguard Worker 
toVector(const hidl_vec<uint8_t> & vec)107*ec779b8eSAndroid Build Coastguard Worker static const Vector<uint8_t> toVector(const hidl_vec<uint8_t>& vec) {
108*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> vector;
109*ec779b8eSAndroid Build Coastguard Worker     vector.appendArray(vec.data(), vec.size());
110*ec779b8eSAndroid Build Coastguard Worker     return *const_cast<const Vector<uint8_t>*>(&vector);
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker 
toHidlVec(const Vector<uint8_t> & vector)113*ec779b8eSAndroid Build Coastguard Worker static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t>& vector) {
114*ec779b8eSAndroid Build Coastguard Worker     hidl_vec<uint8_t> vec;
115*ec779b8eSAndroid Build Coastguard Worker     vec.setToExternal(const_cast<uint8_t*>(vector.array()), vector.size());
116*ec779b8eSAndroid Build Coastguard Worker     return vec;
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker 
toString8(const hidl_string & string)119*ec779b8eSAndroid Build Coastguard Worker static String8 toString8(const hidl_string& string) {
120*ec779b8eSAndroid Build Coastguard Worker     return String8(string.c_str());
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker 
toHidlString(const String8 & string)123*ec779b8eSAndroid Build Coastguard Worker static hidl_string toHidlString(const String8& string) {
124*ec779b8eSAndroid Build Coastguard Worker     return hidl_string(string.c_str());
125*ec779b8eSAndroid Build Coastguard Worker }
126*ec779b8eSAndroid Build Coastguard Worker 
toSecurityLevel(SecurityLevel level)127*ec779b8eSAndroid Build Coastguard Worker static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
128*ec779b8eSAndroid Build Coastguard Worker     switch (level) {
129*ec779b8eSAndroid Build Coastguard Worker         case SecurityLevel::SW_SECURE_CRYPTO:
130*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelSwSecureCrypto;
131*ec779b8eSAndroid Build Coastguard Worker         case SecurityLevel::SW_SECURE_DECODE:
132*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelSwSecureDecode;
133*ec779b8eSAndroid Build Coastguard Worker         case SecurityLevel::HW_SECURE_CRYPTO:
134*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelHwSecureCrypto;
135*ec779b8eSAndroid Build Coastguard Worker         case SecurityLevel::HW_SECURE_DECODE:
136*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelHwSecureDecode;
137*ec779b8eSAndroid Build Coastguard Worker         case SecurityLevel::HW_SECURE_ALL:
138*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelHwSecureAll;
139*ec779b8eSAndroid Build Coastguard Worker         default:
140*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kSecurityLevelUnknown;
141*ec779b8eSAndroid Build Coastguard Worker     }
142*ec779b8eSAndroid Build Coastguard Worker }
143*ec779b8eSAndroid Build Coastguard Worker 
toHidlSecurityLevel(DrmPlugin::SecurityLevel level)144*ec779b8eSAndroid Build Coastguard Worker static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
145*ec779b8eSAndroid Build Coastguard Worker     switch (level) {
146*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kSecurityLevelSwSecureCrypto:
147*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::SW_SECURE_CRYPTO;
148*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kSecurityLevelSwSecureDecode:
149*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::SW_SECURE_DECODE;
150*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kSecurityLevelHwSecureCrypto:
151*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::HW_SECURE_CRYPTO;
152*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kSecurityLevelHwSecureDecode:
153*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::HW_SECURE_DECODE;
154*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kSecurityLevelHwSecureAll:
155*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::HW_SECURE_ALL;
156*ec779b8eSAndroid Build Coastguard Worker         default:
157*ec779b8eSAndroid Build Coastguard Worker             return SecurityLevel::UNKNOWN;
158*ec779b8eSAndroid Build Coastguard Worker     }
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker 
toOfflineLicenseState(OfflineLicenseState licenseState)161*ec779b8eSAndroid Build Coastguard Worker static DrmPlugin::OfflineLicenseState toOfflineLicenseState(OfflineLicenseState licenseState) {
162*ec779b8eSAndroid Build Coastguard Worker     switch (licenseState) {
163*ec779b8eSAndroid Build Coastguard Worker         case OfflineLicenseState::USABLE:
164*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kOfflineLicenseStateUsable;
165*ec779b8eSAndroid Build Coastguard Worker         case OfflineLicenseState::INACTIVE:
166*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kOfflineLicenseStateReleased;
167*ec779b8eSAndroid Build Coastguard Worker         default:
168*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kOfflineLicenseStateUnknown;
169*ec779b8eSAndroid Build Coastguard Worker     }
170*ec779b8eSAndroid Build Coastguard Worker }
171*ec779b8eSAndroid Build Coastguard Worker 
toHdcpLevel(HdcpLevel_V1_2 level)172*ec779b8eSAndroid Build Coastguard Worker static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
173*ec779b8eSAndroid Build Coastguard Worker     switch (level) {
174*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_NONE:
175*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpNone;
176*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_V1:
177*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpV1;
178*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_V2:
179*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpV2;
180*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_V2_1:
181*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpV2_1;
182*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_V2_2:
183*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpV2_2;
184*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_V2_3:
185*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpV2_3;
186*ec779b8eSAndroid Build Coastguard Worker         case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
187*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpNoOutput;
188*ec779b8eSAndroid Build Coastguard Worker         default:
189*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kHdcpLevelUnknown;
190*ec779b8eSAndroid Build Coastguard Worker     }
191*ec779b8eSAndroid Build Coastguard Worker }
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)192*ec779b8eSAndroid Build Coastguard Worker static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>& keyedVector) {
193*ec779b8eSAndroid Build Coastguard Worker     std::vector<KeyValue> stdKeyedVector;
194*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < keyedVector.size(); i++) {
195*ec779b8eSAndroid Build Coastguard Worker         KeyValue keyValue;
196*ec779b8eSAndroid Build Coastguard Worker         keyValue.key = toHidlString(keyedVector.keyAt(i));
197*ec779b8eSAndroid Build Coastguard Worker         keyValue.value = toHidlString(keyedVector.valueAt(i));
198*ec779b8eSAndroid Build Coastguard Worker         stdKeyedVector.push_back(keyValue);
199*ec779b8eSAndroid Build Coastguard Worker     }
200*ec779b8eSAndroid Build Coastguard Worker     return ::KeyedVector(stdKeyedVector);
201*ec779b8eSAndroid Build Coastguard Worker }
202*ec779b8eSAndroid Build Coastguard Worker 
toKeyedVector(const::KeyedVector & hKeyedVector)203*ec779b8eSAndroid Build Coastguard Worker static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector& hKeyedVector) {
204*ec779b8eSAndroid Build Coastguard Worker     KeyedVector<String8, String8> keyedVector;
205*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < hKeyedVector.size(); i++) {
206*ec779b8eSAndroid Build Coastguard Worker         keyedVector.add(toString8(hKeyedVector[i].key), toString8(hKeyedVector[i].value));
207*ec779b8eSAndroid Build Coastguard Worker     }
208*ec779b8eSAndroid Build Coastguard Worker     return keyedVector;
209*ec779b8eSAndroid Build Coastguard Worker }
210*ec779b8eSAndroid Build Coastguard Worker 
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)211*ec779b8eSAndroid Build Coastguard Worker static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>& hSecureStops) {
212*ec779b8eSAndroid Build Coastguard Worker     List<Vector<uint8_t>> secureStops;
213*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < hSecureStops.size(); i++) {
214*ec779b8eSAndroid Build Coastguard Worker         secureStops.push_back(toVector(hSecureStops[i].opaqueData));
215*ec779b8eSAndroid Build Coastguard Worker     }
216*ec779b8eSAndroid Build Coastguard Worker     return secureStops;
217*ec779b8eSAndroid Build Coastguard Worker }
218*ec779b8eSAndroid Build Coastguard Worker 
toSecureStopIds(const hidl_vec<SecureStopId> & hSecureStopIds)219*ec779b8eSAndroid Build Coastguard Worker static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>& hSecureStopIds) {
220*ec779b8eSAndroid Build Coastguard Worker     List<Vector<uint8_t>> secureStopIds;
221*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < hSecureStopIds.size(); i++) {
222*ec779b8eSAndroid Build Coastguard Worker         secureStopIds.push_back(toVector(hSecureStopIds[i]));
223*ec779b8eSAndroid Build Coastguard Worker     }
224*ec779b8eSAndroid Build Coastguard Worker     return secureStopIds;
225*ec779b8eSAndroid Build Coastguard Worker }
226*ec779b8eSAndroid Build Coastguard Worker 
toKeySetIds(const hidl_vec<KeySetId> & hKeySetIds)227*ec779b8eSAndroid Build Coastguard Worker static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>& hKeySetIds) {
228*ec779b8eSAndroid Build Coastguard Worker     List<Vector<uint8_t>> keySetIds;
229*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < hKeySetIds.size(); i++) {
230*ec779b8eSAndroid Build Coastguard Worker         keySetIds.push_back(toVector(hKeySetIds[i]));
231*ec779b8eSAndroid Build Coastguard Worker     }
232*ec779b8eSAndroid Build Coastguard Worker     return keySetIds;
233*ec779b8eSAndroid Build Coastguard Worker }
234*ec779b8eSAndroid Build Coastguard Worker 
235*ec779b8eSAndroid Build Coastguard Worker Mutex DrmHalHidl::mLock;
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker struct DrmHalHidl::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
DrmSessionClientandroid::DrmHalHidl::DrmSessionClient238*ec779b8eSAndroid Build Coastguard Worker     explicit DrmSessionClient(DrmHalHidl* drm, const Vector<uint8_t>& sessionId)
239*ec779b8eSAndroid Build Coastguard Worker         : mSessionId(sessionId), mDrm(drm) {}
240*ec779b8eSAndroid Build Coastguard Worker 
241*ec779b8eSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
242*ec779b8eSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
243*ec779b8eSAndroid Build Coastguard Worker 
244*ec779b8eSAndroid Build Coastguard Worker     const Vector<uint8_t> mSessionId;
245*ec779b8eSAndroid Build Coastguard Worker 
246*ec779b8eSAndroid Build Coastguard Worker     virtual ~DrmSessionClient();
247*ec779b8eSAndroid Build Coastguard Worker 
248*ec779b8eSAndroid Build Coastguard Worker   private:
249*ec779b8eSAndroid Build Coastguard Worker     wp<DrmHalHidl> mDrm;
250*ec779b8eSAndroid Build Coastguard Worker 
251*ec779b8eSAndroid Build Coastguard Worker     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
252*ec779b8eSAndroid Build Coastguard Worker };
253*ec779b8eSAndroid Build Coastguard Worker 
reclaimResource(bool * _aidl_return)254*ec779b8eSAndroid Build Coastguard Worker ::ndk::ScopedAStatus DrmHalHidl::DrmSessionClient::reclaimResource(bool* _aidl_return) {
255*ec779b8eSAndroid Build Coastguard Worker     auto sessionId = mSessionId;
256*ec779b8eSAndroid Build Coastguard Worker     sp<DrmHalHidl> drm = mDrm.promote();
257*ec779b8eSAndroid Build Coastguard Worker     if (drm == NULL) {
258*ec779b8eSAndroid Build Coastguard Worker         *_aidl_return = true;
259*ec779b8eSAndroid Build Coastguard Worker         return ::ndk::ScopedAStatus::ok();
260*ec779b8eSAndroid Build Coastguard Worker     }
261*ec779b8eSAndroid Build Coastguard Worker     status_t err = drm->closeSession(sessionId);
262*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
263*ec779b8eSAndroid Build Coastguard Worker         *_aidl_return = false;
264*ec779b8eSAndroid Build Coastguard Worker         return ::ndk::ScopedAStatus::ok();
265*ec779b8eSAndroid Build Coastguard Worker     }
266*ec779b8eSAndroid Build Coastguard Worker     drm->sendEvent(EventType::SESSION_RECLAIMED, toHidlVec(sessionId), hidl_vec<uint8_t>());
267*ec779b8eSAndroid Build Coastguard Worker     *_aidl_return = true;
268*ec779b8eSAndroid Build Coastguard Worker     return ::ndk::ScopedAStatus::ok();
269*ec779b8eSAndroid Build Coastguard Worker }
270*ec779b8eSAndroid Build Coastguard Worker 
getName(::std::string * _aidl_return)271*ec779b8eSAndroid Build Coastguard Worker ::ndk::ScopedAStatus DrmHalHidl::DrmSessionClient::getName(::std::string* _aidl_return) {
272*ec779b8eSAndroid Build Coastguard Worker     String8 name;
273*ec779b8eSAndroid Build Coastguard Worker     sp<DrmHalHidl> drm = mDrm.promote();
274*ec779b8eSAndroid Build Coastguard Worker     if (drm == NULL) {
275*ec779b8eSAndroid Build Coastguard Worker         name.append("<deleted>");
276*ec779b8eSAndroid Build Coastguard Worker     } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK || name.empty()) {
277*ec779b8eSAndroid Build Coastguard Worker         name.append("<Get vendor failed or is empty>");
278*ec779b8eSAndroid Build Coastguard Worker     }
279*ec779b8eSAndroid Build Coastguard Worker     name.append("[");
280*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mSessionId.size(); ++i) {
281*ec779b8eSAndroid Build Coastguard Worker         name.appendFormat("%02x", mSessionId[i]);
282*ec779b8eSAndroid Build Coastguard Worker     }
283*ec779b8eSAndroid Build Coastguard Worker     name.append("]");
284*ec779b8eSAndroid Build Coastguard Worker     *_aidl_return = name;
285*ec779b8eSAndroid Build Coastguard Worker     return ::ndk::ScopedAStatus::ok();
286*ec779b8eSAndroid Build Coastguard Worker }
287*ec779b8eSAndroid Build Coastguard Worker 
~DrmSessionClient()288*ec779b8eSAndroid Build Coastguard Worker DrmHalHidl::DrmSessionClient::~DrmSessionClient() {
289*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->removeSession(mSessionId);
290*ec779b8eSAndroid Build Coastguard Worker }
291*ec779b8eSAndroid Build Coastguard Worker 
DrmHalHidl()292*ec779b8eSAndroid Build Coastguard Worker DrmHalHidl::DrmHalHidl()
293*ec779b8eSAndroid Build Coastguard Worker     : mFactories(makeDrmFactories()),
294*ec779b8eSAndroid Build Coastguard Worker       mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
295*ec779b8eSAndroid Build Coastguard Worker 
closeOpenSessions()296*ec779b8eSAndroid Build Coastguard Worker void DrmHalHidl::closeOpenSessions() {
297*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
298*ec779b8eSAndroid Build Coastguard Worker     auto openSessions = mOpenSessions;
299*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < openSessions.size(); i++) {
300*ec779b8eSAndroid Build Coastguard Worker         mLock.unlock();
301*ec779b8eSAndroid Build Coastguard Worker         closeSession(openSessions[i]->mSessionId);
302*ec779b8eSAndroid Build Coastguard Worker         mLock.lock();
303*ec779b8eSAndroid Build Coastguard Worker     }
304*ec779b8eSAndroid Build Coastguard Worker     mOpenSessions.clear();
305*ec779b8eSAndroid Build Coastguard Worker }
306*ec779b8eSAndroid Build Coastguard Worker 
~DrmHalHidl()307*ec779b8eSAndroid Build Coastguard Worker DrmHalHidl::~DrmHalHidl() {}
308*ec779b8eSAndroid Build Coastguard Worker 
cleanup()309*ec779b8eSAndroid Build Coastguard Worker void DrmHalHidl::cleanup() {
310*ec779b8eSAndroid Build Coastguard Worker     closeOpenSessions();
311*ec779b8eSAndroid Build Coastguard Worker 
312*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
313*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck == OK) reportFrameworkMetrics(reportPluginMetrics());
314*ec779b8eSAndroid Build Coastguard Worker 
315*ec779b8eSAndroid Build Coastguard Worker     setListener(NULL);
316*ec779b8eSAndroid Build Coastguard Worker     mInitCheck = NO_INIT;
317*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 != NULL) {
318*ec779b8eSAndroid Build Coastguard Worker         if (!mPluginV1_2->setListener(NULL).isOk()) {
319*ec779b8eSAndroid Build Coastguard Worker             mInitCheck = DEAD_OBJECT;
320*ec779b8eSAndroid Build Coastguard Worker         }
321*ec779b8eSAndroid Build Coastguard Worker     } else if (mPlugin != NULL) {
322*ec779b8eSAndroid Build Coastguard Worker         if (!mPlugin->setListener(NULL).isOk()) {
323*ec779b8eSAndroid Build Coastguard Worker             mInitCheck = DEAD_OBJECT;
324*ec779b8eSAndroid Build Coastguard Worker         }
325*ec779b8eSAndroid Build Coastguard Worker     }
326*ec779b8eSAndroid Build Coastguard Worker     mPlugin.clear();
327*ec779b8eSAndroid Build Coastguard Worker     mPluginV1_1.clear();
328*ec779b8eSAndroid Build Coastguard Worker     mPluginV1_2.clear();
329*ec779b8eSAndroid Build Coastguard Worker     mPluginV1_4.clear();
330*ec779b8eSAndroid Build Coastguard Worker }
331*ec779b8eSAndroid Build Coastguard Worker 
makeDrmFactories()332*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<IDrmFactory>> DrmHalHidl::makeDrmFactories() {
333*ec779b8eSAndroid Build Coastguard Worker     static std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
334*ec779b8eSAndroid Build Coastguard Worker     if (factories.size() == 0) {
335*ec779b8eSAndroid Build Coastguard Worker         DrmUtils::LOG2BI("No hidl drm factories found");
336*ec779b8eSAndroid Build Coastguard Worker         // could be in passthrough mode, load the default passthrough service
337*ec779b8eSAndroid Build Coastguard Worker         auto passthrough = IDrmFactory::getService();
338*ec779b8eSAndroid Build Coastguard Worker         if (passthrough != NULL) {
339*ec779b8eSAndroid Build Coastguard Worker             DrmUtils::LOG2BI("makeDrmFactories: using default passthrough drm instance");
340*ec779b8eSAndroid Build Coastguard Worker             factories.push_back(passthrough);
341*ec779b8eSAndroid Build Coastguard Worker         } else {
342*ec779b8eSAndroid Build Coastguard Worker             DrmUtils::LOG2BW("Failed to find passthrough drm factories");
343*ec779b8eSAndroid Build Coastguard Worker         }
344*ec779b8eSAndroid Build Coastguard Worker     }
345*ec779b8eSAndroid Build Coastguard Worker     return factories;
346*ec779b8eSAndroid Build Coastguard Worker }
347*ec779b8eSAndroid Build Coastguard Worker 
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)348*ec779b8eSAndroid Build Coastguard Worker sp<IDrmPlugin> DrmHalHidl::makeDrmPlugin(const sp<IDrmFactory>& factory, const uint8_t uuid[16],
349*ec779b8eSAndroid Build Coastguard Worker                                          const String8& appPackageName) {
350*ec779b8eSAndroid Build Coastguard Worker     mAppPackageName = appPackageName;
351*ec779b8eSAndroid Build Coastguard Worker     mMetrics.SetAppPackageName(appPackageName);
352*ec779b8eSAndroid Build Coastguard Worker     mMetrics.SetAppUid(AIBinder_getCallingUid());
353*ec779b8eSAndroid Build Coastguard Worker 
354*ec779b8eSAndroid Build Coastguard Worker     sp<IDrmPlugin> plugin;
355*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = factory->createPlugin(
356*ec779b8eSAndroid Build Coastguard Worker             uuid, appPackageName.c_str(), [&](Status status, const sp<IDrmPlugin>& hPlugin) {
357*ec779b8eSAndroid Build Coastguard Worker                 if (status != Status::OK) {
358*ec779b8eSAndroid Build Coastguard Worker                     DrmUtils::LOG2BE(uuid, "Failed to make drm plugin: %d", status);
359*ec779b8eSAndroid Build Coastguard Worker                     return;
360*ec779b8eSAndroid Build Coastguard Worker                 }
361*ec779b8eSAndroid Build Coastguard Worker                 plugin = hPlugin;
362*ec779b8eSAndroid Build Coastguard Worker             });
363*ec779b8eSAndroid Build Coastguard Worker 
364*ec779b8eSAndroid Build Coastguard Worker     if (!hResult.isOk()) {
365*ec779b8eSAndroid Build Coastguard Worker         DrmUtils::LOG2BE(uuid, "createPlugin remote call failed: %s",
366*ec779b8eSAndroid Build Coastguard Worker                          hResult.description().c_str());
367*ec779b8eSAndroid Build Coastguard Worker     }
368*ec779b8eSAndroid Build Coastguard Worker 
369*ec779b8eSAndroid Build Coastguard Worker     return plugin;
370*ec779b8eSAndroid Build Coastguard Worker }
371*ec779b8eSAndroid Build Coastguard Worker 
initCheck() const372*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::initCheck() const {
373*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(mInitCheck);
374*ec779b8eSAndroid Build Coastguard Worker }
375*ec779b8eSAndroid Build Coastguard Worker 
setListener(const sp<IDrmClient> & listener)376*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setListener(const sp<IDrmClient>& listener) {
377*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock lock(mEventLock);
378*ec779b8eSAndroid Build Coastguard Worker     mListener = listener;
379*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(NO_ERROR);
380*ec779b8eSAndroid Build Coastguard Worker }
381*ec779b8eSAndroid Build Coastguard Worker 
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)382*ec779b8eSAndroid Build Coastguard Worker Return<void> DrmHalHidl::sendEvent(EventType hEventType, const hidl_vec<uint8_t>& sessionId,
383*ec779b8eSAndroid Build Coastguard Worker                                    const hidl_vec<uint8_t>& data) {
384*ec779b8eSAndroid Build Coastguard Worker     mMetrics.mEventCounter.Increment((uint32_t)hEventType);
385*ec779b8eSAndroid Build Coastguard Worker 
386*ec779b8eSAndroid Build Coastguard Worker     mEventLock.lock();
387*ec779b8eSAndroid Build Coastguard Worker     sp<IDrmClient> listener = mListener;
388*ec779b8eSAndroid Build Coastguard Worker     mEventLock.unlock();
389*ec779b8eSAndroid Build Coastguard Worker 
390*ec779b8eSAndroid Build Coastguard Worker     if (listener != NULL) {
391*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock lock(mNotifyLock);
392*ec779b8eSAndroid Build Coastguard Worker         DrmPlugin::EventType eventType;
393*ec779b8eSAndroid Build Coastguard Worker         switch (hEventType) {
394*ec779b8eSAndroid Build Coastguard Worker             case EventType::PROVISION_REQUIRED:
395*ec779b8eSAndroid Build Coastguard Worker                 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
396*ec779b8eSAndroid Build Coastguard Worker                 break;
397*ec779b8eSAndroid Build Coastguard Worker             case EventType::KEY_NEEDED:
398*ec779b8eSAndroid Build Coastguard Worker                 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
399*ec779b8eSAndroid Build Coastguard Worker                 break;
400*ec779b8eSAndroid Build Coastguard Worker             case EventType::KEY_EXPIRED:
401*ec779b8eSAndroid Build Coastguard Worker                 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
402*ec779b8eSAndroid Build Coastguard Worker                 break;
403*ec779b8eSAndroid Build Coastguard Worker             case EventType::VENDOR_DEFINED:
404*ec779b8eSAndroid Build Coastguard Worker                 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
405*ec779b8eSAndroid Build Coastguard Worker                 break;
406*ec779b8eSAndroid Build Coastguard Worker             case EventType::SESSION_RECLAIMED:
407*ec779b8eSAndroid Build Coastguard Worker                 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
408*ec779b8eSAndroid Build Coastguard Worker                 break;
409*ec779b8eSAndroid Build Coastguard Worker             default:
410*ec779b8eSAndroid Build Coastguard Worker                 return Void();
411*ec779b8eSAndroid Build Coastguard Worker         }
412*ec779b8eSAndroid Build Coastguard Worker         listener->sendEvent(eventType, sessionId, data);
413*ec779b8eSAndroid Build Coastguard Worker     }
414*ec779b8eSAndroid Build Coastguard Worker     return Void();
415*ec779b8eSAndroid Build Coastguard Worker }
416*ec779b8eSAndroid Build Coastguard Worker 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)417*ec779b8eSAndroid Build Coastguard Worker Return<void> DrmHalHidl::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
418*ec779b8eSAndroid Build Coastguard Worker                                               int64_t expiryTimeInMS) {
419*ec779b8eSAndroid Build Coastguard Worker     mEventLock.lock();
420*ec779b8eSAndroid Build Coastguard Worker     sp<IDrmClient> listener = mListener;
421*ec779b8eSAndroid Build Coastguard Worker     mEventLock.unlock();
422*ec779b8eSAndroid Build Coastguard Worker 
423*ec779b8eSAndroid Build Coastguard Worker     if (listener != NULL) {
424*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock lock(mNotifyLock);
425*ec779b8eSAndroid Build Coastguard Worker         listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
426*ec779b8eSAndroid Build Coastguard Worker     }
427*ec779b8eSAndroid Build Coastguard Worker     return Void();
428*ec779b8eSAndroid Build Coastguard Worker }
429*ec779b8eSAndroid Build Coastguard Worker 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus_V1_0> & keyStatusList_V1_0,bool hasNewUsableKey)430*ec779b8eSAndroid Build Coastguard Worker Return<void> DrmHalHidl::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
431*ec779b8eSAndroid Build Coastguard Worker                                         const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0,
432*ec779b8eSAndroid Build Coastguard Worker                                         bool hasNewUsableKey) {
433*ec779b8eSAndroid Build Coastguard Worker     std::vector<KeyStatus> keyStatusVec;
434*ec779b8eSAndroid Build Coastguard Worker     for (const auto& keyStatus_V1_0 : keyStatusList_V1_0) {
435*ec779b8eSAndroid Build Coastguard Worker         keyStatusVec.push_back(
436*ec779b8eSAndroid Build Coastguard Worker                 {keyStatus_V1_0.keyId, static_cast<KeyStatusType>(keyStatus_V1_0.type)});
437*ec779b8eSAndroid Build Coastguard Worker     }
438*ec779b8eSAndroid Build Coastguard Worker     hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
439*ec779b8eSAndroid Build Coastguard Worker     return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
440*ec779b8eSAndroid Build Coastguard Worker }
441*ec779b8eSAndroid Build Coastguard Worker 
sendKeysChange_1_2(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & hKeyStatusList,bool hasNewUsableKey)442*ec779b8eSAndroid Build Coastguard Worker Return<void> DrmHalHidl::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
443*ec779b8eSAndroid Build Coastguard Worker                                             const hidl_vec<KeyStatus>& hKeyStatusList,
444*ec779b8eSAndroid Build Coastguard Worker                                             bool hasNewUsableKey) {
445*ec779b8eSAndroid Build Coastguard Worker     mEventLock.lock();
446*ec779b8eSAndroid Build Coastguard Worker     sp<IDrmClient> listener = mListener;
447*ec779b8eSAndroid Build Coastguard Worker     mEventLock.unlock();
448*ec779b8eSAndroid Build Coastguard Worker 
449*ec779b8eSAndroid Build Coastguard Worker     if (listener != NULL) {
450*ec779b8eSAndroid Build Coastguard Worker         std::vector<DrmKeyStatus> keyStatusList;
451*ec779b8eSAndroid Build Coastguard Worker         size_t nKeys = hKeyStatusList.size();
452*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < nKeys; ++i) {
453*ec779b8eSAndroid Build Coastguard Worker             const KeyStatus& keyStatus = hKeyStatusList[i];
454*ec779b8eSAndroid Build Coastguard Worker             uint32_t type;
455*ec779b8eSAndroid Build Coastguard Worker             switch (keyStatus.type) {
456*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::USABLE:
457*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_Usable;
458*ec779b8eSAndroid Build Coastguard Worker                     break;
459*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::EXPIRED:
460*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_Expired;
461*ec779b8eSAndroid Build Coastguard Worker                     break;
462*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::OUTPUTNOTALLOWED:
463*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
464*ec779b8eSAndroid Build Coastguard Worker                     break;
465*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::STATUSPENDING:
466*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_StatusPending;
467*ec779b8eSAndroid Build Coastguard Worker                     break;
468*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::USABLEINFUTURE:
469*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_UsableInFuture;
470*ec779b8eSAndroid Build Coastguard Worker                     break;
471*ec779b8eSAndroid Build Coastguard Worker                 case KeyStatusType::INTERNALERROR:
472*ec779b8eSAndroid Build Coastguard Worker                 default:
473*ec779b8eSAndroid Build Coastguard Worker                     type = DrmPlugin::kKeyStatusType_InternalError;
474*ec779b8eSAndroid Build Coastguard Worker                     break;
475*ec779b8eSAndroid Build Coastguard Worker             }
476*ec779b8eSAndroid Build Coastguard Worker             keyStatusList.push_back({type, keyStatus.keyId});
477*ec779b8eSAndroid Build Coastguard Worker             mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)keyStatus.type);
478*ec779b8eSAndroid Build Coastguard Worker         }
479*ec779b8eSAndroid Build Coastguard Worker 
480*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock lock(mNotifyLock);
481*ec779b8eSAndroid Build Coastguard Worker         listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
482*ec779b8eSAndroid Build Coastguard Worker     } else {
483*ec779b8eSAndroid Build Coastguard Worker         // There's no listener. But we still want to count the key change
484*ec779b8eSAndroid Build Coastguard Worker         // events.
485*ec779b8eSAndroid Build Coastguard Worker         size_t nKeys = hKeyStatusList.size();
486*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < nKeys; i++) {
487*ec779b8eSAndroid Build Coastguard Worker             mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)hKeyStatusList[i].type);
488*ec779b8eSAndroid Build Coastguard Worker         }
489*ec779b8eSAndroid Build Coastguard Worker     }
490*ec779b8eSAndroid Build Coastguard Worker 
491*ec779b8eSAndroid Build Coastguard Worker     return Void();
492*ec779b8eSAndroid Build Coastguard Worker }
493*ec779b8eSAndroid Build Coastguard Worker 
sendSessionLostState(const hidl_vec<uint8_t> & sessionId)494*ec779b8eSAndroid Build Coastguard Worker Return<void> DrmHalHidl::sendSessionLostState(const hidl_vec<uint8_t>& sessionId) {
495*ec779b8eSAndroid Build Coastguard Worker     mEventLock.lock();
496*ec779b8eSAndroid Build Coastguard Worker     sp<IDrmClient> listener = mListener;
497*ec779b8eSAndroid Build Coastguard Worker     mEventLock.unlock();
498*ec779b8eSAndroid Build Coastguard Worker 
499*ec779b8eSAndroid Build Coastguard Worker     if (listener != NULL) {
500*ec779b8eSAndroid Build Coastguard Worker         Mutex::Autolock lock(mNotifyLock);
501*ec779b8eSAndroid Build Coastguard Worker         listener->sendSessionLostState(sessionId);
502*ec779b8eSAndroid Build Coastguard Worker     }
503*ec779b8eSAndroid Build Coastguard Worker     return Void();
504*ec779b8eSAndroid Build Coastguard Worker }
505*ec779b8eSAndroid Build Coastguard Worker 
matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)506*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory>& factory,
507*ec779b8eSAndroid Build Coastguard Worker                                                     const uint8_t uuid[16], const String8& mimeType,
508*ec779b8eSAndroid Build Coastguard Worker                                                     DrmPlugin::SecurityLevel level,
509*ec779b8eSAndroid Build Coastguard Worker                                                     bool* isSupported) {
510*ec779b8eSAndroid Build Coastguard Worker     *isSupported = false;
511*ec779b8eSAndroid Build Coastguard Worker 
512*ec779b8eSAndroid Build Coastguard Worker     // handle default value cases
513*ec779b8eSAndroid Build Coastguard Worker     if (level == DrmPlugin::kSecurityLevelUnknown) {
514*ec779b8eSAndroid Build Coastguard Worker         if (mimeType == "") {
515*ec779b8eSAndroid Build Coastguard Worker             // isCryptoSchemeSupported(uuid)
516*ec779b8eSAndroid Build Coastguard Worker             *isSupported = true;
517*ec779b8eSAndroid Build Coastguard Worker             return DrmStatus(OK);
518*ec779b8eSAndroid Build Coastguard Worker         }
519*ec779b8eSAndroid Build Coastguard Worker         // isCryptoSchemeSupported(uuid, mimeType)
520*ec779b8eSAndroid Build Coastguard Worker         auto hResult = factory->isContentTypeSupported(mimeType.c_str());
521*ec779b8eSAndroid Build Coastguard Worker         if (!hResult.isOk()) {
522*ec779b8eSAndroid Build Coastguard Worker             return DrmStatus(DEAD_OBJECT);
523*ec779b8eSAndroid Build Coastguard Worker         }
524*ec779b8eSAndroid Build Coastguard Worker         *isSupported = hResult;
525*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(OK);
526*ec779b8eSAndroid Build Coastguard Worker     } else if (mimeType == "") {
527*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(BAD_VALUE);
528*ec779b8eSAndroid Build Coastguard Worker     }
529*ec779b8eSAndroid Build Coastguard Worker 
530*ec779b8eSAndroid Build Coastguard Worker     sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
531*ec779b8eSAndroid Build Coastguard Worker     if (factoryV1_2 == NULL) {
532*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_UNSUPPORTED);
533*ec779b8eSAndroid Build Coastguard Worker     } else {
534*ec779b8eSAndroid Build Coastguard Worker         auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.c_str(),
535*ec779b8eSAndroid Build Coastguard Worker                                                                 toHidlSecurityLevel(level));
536*ec779b8eSAndroid Build Coastguard Worker         if (!hResult.isOk()) {
537*ec779b8eSAndroid Build Coastguard Worker             return DrmStatus(DEAD_OBJECT);
538*ec779b8eSAndroid Build Coastguard Worker         }
539*ec779b8eSAndroid Build Coastguard Worker         *isSupported = hResult;
540*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(OK);
541*ec779b8eSAndroid Build Coastguard Worker     }
542*ec779b8eSAndroid Build Coastguard Worker }
543*ec779b8eSAndroid Build Coastguard Worker 
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)544*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
545*ec779b8eSAndroid Build Coastguard Worker                                               DrmPlugin::SecurityLevel level, bool* isSupported) {
546*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
547*ec779b8eSAndroid Build Coastguard Worker     *isSupported = false;
548*ec779b8eSAndroid Build Coastguard Worker     for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
549*ec779b8eSAndroid Build Coastguard Worker         auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
550*ec779b8eSAndroid Build Coastguard Worker         if (hResult.isOk() && hResult) {
551*ec779b8eSAndroid Build Coastguard Worker             return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
552*ec779b8eSAndroid Build Coastguard Worker         }
553*ec779b8eSAndroid Build Coastguard Worker     }
554*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
555*ec779b8eSAndroid Build Coastguard Worker }
556*ec779b8eSAndroid Build Coastguard Worker 
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)557*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
558*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
559*ec779b8eSAndroid Build Coastguard Worker 
560*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck == ERROR_UNSUPPORTED) return mInitCheck;
561*ec779b8eSAndroid Build Coastguard Worker     for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
562*ec779b8eSAndroid Build Coastguard Worker         auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
563*ec779b8eSAndroid Build Coastguard Worker         if (hResult.isOk() && hResult) {
564*ec779b8eSAndroid Build Coastguard Worker             auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
565*ec779b8eSAndroid Build Coastguard Worker             if (plugin != NULL) {
566*ec779b8eSAndroid Build Coastguard Worker                 mPlugin = plugin;
567*ec779b8eSAndroid Build Coastguard Worker                 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
568*ec779b8eSAndroid Build Coastguard Worker                 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
569*ec779b8eSAndroid Build Coastguard Worker                 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
570*ec779b8eSAndroid Build Coastguard Worker                 break;
571*ec779b8eSAndroid Build Coastguard Worker             }
572*ec779b8eSAndroid Build Coastguard Worker         }
573*ec779b8eSAndroid Build Coastguard Worker     }
574*ec779b8eSAndroid Build Coastguard Worker 
575*ec779b8eSAndroid Build Coastguard Worker     if (mPlugin == NULL) {
576*ec779b8eSAndroid Build Coastguard Worker         DrmUtils::LOG2BE(uuid, "No supported hal instance found");
577*ec779b8eSAndroid Build Coastguard Worker         mInitCheck = ERROR_UNSUPPORTED;
578*ec779b8eSAndroid Build Coastguard Worker     } else {
579*ec779b8eSAndroid Build Coastguard Worker         mInitCheck = OK;
580*ec779b8eSAndroid Build Coastguard Worker         if (mPluginV1_2 != NULL) {
581*ec779b8eSAndroid Build Coastguard Worker             if (!mPluginV1_2->setListener(this).isOk()) {
582*ec779b8eSAndroid Build Coastguard Worker                 mInitCheck = DEAD_OBJECT;
583*ec779b8eSAndroid Build Coastguard Worker             }
584*ec779b8eSAndroid Build Coastguard Worker         } else if (!mPlugin->setListener(this).isOk()) {
585*ec779b8eSAndroid Build Coastguard Worker             mInitCheck = DEAD_OBJECT;
586*ec779b8eSAndroid Build Coastguard Worker         }
587*ec779b8eSAndroid Build Coastguard Worker         if (mInitCheck != OK) {
588*ec779b8eSAndroid Build Coastguard Worker             mPlugin.clear();
589*ec779b8eSAndroid Build Coastguard Worker             mPluginV1_1.clear();
590*ec779b8eSAndroid Build Coastguard Worker             mPluginV1_2.clear();
591*ec779b8eSAndroid Build Coastguard Worker             mPluginV1_4.clear();
592*ec779b8eSAndroid Build Coastguard Worker         }
593*ec779b8eSAndroid Build Coastguard Worker     }
594*ec779b8eSAndroid Build Coastguard Worker 
595*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(mInitCheck);
596*ec779b8eSAndroid Build Coastguard Worker }
597*ec779b8eSAndroid Build Coastguard Worker 
destroyPlugin()598*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::destroyPlugin() {
599*ec779b8eSAndroid Build Coastguard Worker     cleanup();
600*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
601*ec779b8eSAndroid Build Coastguard Worker }
602*ec779b8eSAndroid Build Coastguard Worker 
openSession(DrmPlugin::SecurityLevel level,Vector<uint8_t> & sessionId)603*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
604*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
605*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
606*ec779b8eSAndroid Build Coastguard Worker 
607*ec779b8eSAndroid Build Coastguard Worker     SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
608*ec779b8eSAndroid Build Coastguard Worker     bool setSecurityLevel = true;
609*ec779b8eSAndroid Build Coastguard Worker 
610*ec779b8eSAndroid Build Coastguard Worker     if (level == DrmPlugin::kSecurityLevelMax) {
611*ec779b8eSAndroid Build Coastguard Worker         setSecurityLevel = false;
612*ec779b8eSAndroid Build Coastguard Worker     } else {
613*ec779b8eSAndroid Build Coastguard Worker         if (hSecurityLevel == SecurityLevel::UNKNOWN) {
614*ec779b8eSAndroid Build Coastguard Worker             return ERROR_DRM_CANNOT_HANDLE;
615*ec779b8eSAndroid Build Coastguard Worker         }
616*ec779b8eSAndroid Build Coastguard Worker     }
617*ec779b8eSAndroid Build Coastguard Worker 
618*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
619*ec779b8eSAndroid Build Coastguard Worker     bool retry = true;
620*ec779b8eSAndroid Build Coastguard Worker     do {
621*ec779b8eSAndroid Build Coastguard Worker         hidl_vec<uint8_t> hSessionId;
622*ec779b8eSAndroid Build Coastguard Worker 
623*ec779b8eSAndroid Build Coastguard Worker         Return<void> hResult;
624*ec779b8eSAndroid Build Coastguard Worker         if (mPluginV1_1 == NULL || !setSecurityLevel) {
625*ec779b8eSAndroid Build Coastguard Worker             hResult = mPlugin->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
626*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
627*ec779b8eSAndroid Build Coastguard Worker                     sessionId = toVector(id);
628*ec779b8eSAndroid Build Coastguard Worker                 }
629*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
630*ec779b8eSAndroid Build Coastguard Worker             });
631*ec779b8eSAndroid Build Coastguard Worker         } else {
632*ec779b8eSAndroid Build Coastguard Worker             hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
633*ec779b8eSAndroid Build Coastguard Worker                                                    [&](Status status, const hidl_vec<uint8_t>& id) {
634*ec779b8eSAndroid Build Coastguard Worker                                                        if (status == Status::OK) {
635*ec779b8eSAndroid Build Coastguard Worker                                                            sessionId = toVector(id);
636*ec779b8eSAndroid Build Coastguard Worker                                                        }
637*ec779b8eSAndroid Build Coastguard Worker                                                        err = toStatusT(status);
638*ec779b8eSAndroid Build Coastguard Worker                                                    });
639*ec779b8eSAndroid Build Coastguard Worker         }
640*ec779b8eSAndroid Build Coastguard Worker 
641*ec779b8eSAndroid Build Coastguard Worker         if (!hResult.isOk()) {
642*ec779b8eSAndroid Build Coastguard Worker             err = DEAD_OBJECT;
643*ec779b8eSAndroid Build Coastguard Worker         }
644*ec779b8eSAndroid Build Coastguard Worker 
645*ec779b8eSAndroid Build Coastguard Worker         if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
646*ec779b8eSAndroid Build Coastguard Worker             mLock.unlock();
647*ec779b8eSAndroid Build Coastguard Worker             // reclaimSession may call back to closeSession, since mLock is
648*ec779b8eSAndroid Build Coastguard Worker             // shared between Drm instances, we should unlock here to avoid
649*ec779b8eSAndroid Build Coastguard Worker             // deadlock.
650*ec779b8eSAndroid Build Coastguard Worker             retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
651*ec779b8eSAndroid Build Coastguard Worker             mLock.lock();
652*ec779b8eSAndroid Build Coastguard Worker         } else {
653*ec779b8eSAndroid Build Coastguard Worker             retry = false;
654*ec779b8eSAndroid Build Coastguard Worker         }
655*ec779b8eSAndroid Build Coastguard Worker     } while (retry);
656*ec779b8eSAndroid Build Coastguard Worker 
657*ec779b8eSAndroid Build Coastguard Worker     if (err == OK) {
658*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<DrmSessionClient> client =
659*ec779b8eSAndroid Build Coastguard Worker                 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
660*ec779b8eSAndroid Build Coastguard Worker         DrmSessionManager::Instance()->addSession(
661*ec779b8eSAndroid Build Coastguard Worker                 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
662*ec779b8eSAndroid Build Coastguard Worker                 sessionId);
663*ec779b8eSAndroid Build Coastguard Worker         mOpenSessions.push_back(client);
664*ec779b8eSAndroid Build Coastguard Worker         mMetrics.SetSessionStart(sessionId);
665*ec779b8eSAndroid Build Coastguard Worker     }
666*ec779b8eSAndroid Build Coastguard Worker 
667*ec779b8eSAndroid Build Coastguard Worker     mMetrics.mOpenSessionCounter.Increment(err);
668*ec779b8eSAndroid Build Coastguard Worker     return err;
669*ec779b8eSAndroid Build Coastguard Worker }
670*ec779b8eSAndroid Build Coastguard Worker 
closeSession(Vector<uint8_t> const & sessionId)671*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
672*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
673*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
674*ec779b8eSAndroid Build Coastguard Worker 
675*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
676*ec779b8eSAndroid Build Coastguard Worker     if (status.isOk()) {
677*ec779b8eSAndroid Build Coastguard Worker         if (status == Status::OK) {
678*ec779b8eSAndroid Build Coastguard Worker             DrmSessionManager::Instance()->removeSession(sessionId);
679*ec779b8eSAndroid Build Coastguard Worker             for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
680*ec779b8eSAndroid Build Coastguard Worker                 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
681*ec779b8eSAndroid Build Coastguard Worker                     mOpenSessions.erase(i);
682*ec779b8eSAndroid Build Coastguard Worker                     break;
683*ec779b8eSAndroid Build Coastguard Worker                 }
684*ec779b8eSAndroid Build Coastguard Worker             }
685*ec779b8eSAndroid Build Coastguard Worker         }
686*ec779b8eSAndroid Build Coastguard Worker         DrmStatus response = toStatusT(status);
687*ec779b8eSAndroid Build Coastguard Worker         mMetrics.SetSessionEnd(sessionId);
688*ec779b8eSAndroid Build Coastguard Worker         mMetrics.mCloseSessionCounter.Increment(response);
689*ec779b8eSAndroid Build Coastguard Worker         return response;
690*ec779b8eSAndroid Build Coastguard Worker     }
691*ec779b8eSAndroid Build Coastguard Worker     mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
692*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(DEAD_OBJECT);
693*ec779b8eSAndroid Build Coastguard Worker }
694*ec779b8eSAndroid Build Coastguard Worker 
toKeyRequestType(KeyRequestType keyRequestType)695*ec779b8eSAndroid Build Coastguard Worker static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
696*ec779b8eSAndroid Build Coastguard Worker     switch (keyRequestType) {
697*ec779b8eSAndroid Build Coastguard Worker         case KeyRequestType::INITIAL:
698*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_Initial;
699*ec779b8eSAndroid Build Coastguard Worker             break;
700*ec779b8eSAndroid Build Coastguard Worker         case KeyRequestType::RENEWAL:
701*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_Renewal;
702*ec779b8eSAndroid Build Coastguard Worker             break;
703*ec779b8eSAndroid Build Coastguard Worker         case KeyRequestType::RELEASE:
704*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_Release;
705*ec779b8eSAndroid Build Coastguard Worker             break;
706*ec779b8eSAndroid Build Coastguard Worker         default:
707*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_Unknown;
708*ec779b8eSAndroid Build Coastguard Worker             break;
709*ec779b8eSAndroid Build Coastguard Worker     }
710*ec779b8eSAndroid Build Coastguard Worker }
711*ec779b8eSAndroid Build Coastguard Worker 
toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType)712*ec779b8eSAndroid Build Coastguard Worker static DrmPlugin::KeyRequestType toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType) {
713*ec779b8eSAndroid Build Coastguard Worker     switch (keyRequestType) {
714*ec779b8eSAndroid Build Coastguard Worker         case KeyRequestType_V1_1::NONE:
715*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_None;
716*ec779b8eSAndroid Build Coastguard Worker             break;
717*ec779b8eSAndroid Build Coastguard Worker         case KeyRequestType_V1_1::UPDATE:
718*ec779b8eSAndroid Build Coastguard Worker             return DrmPlugin::kKeyRequestType_Update;
719*ec779b8eSAndroid Build Coastguard Worker             break;
720*ec779b8eSAndroid Build Coastguard Worker         default:
721*ec779b8eSAndroid Build Coastguard Worker             return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
722*ec779b8eSAndroid Build Coastguard Worker             break;
723*ec779b8eSAndroid Build Coastguard Worker     }
724*ec779b8eSAndroid Build Coastguard Worker }
725*ec779b8eSAndroid Build Coastguard Worker 
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,DrmPlugin::KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)726*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
727*ec779b8eSAndroid Build Coastguard Worker                                     Vector<uint8_t> const& initData, String8 const& mimeType,
728*ec779b8eSAndroid Build Coastguard Worker                                     DrmPlugin::KeyType keyType,
729*ec779b8eSAndroid Build Coastguard Worker                                     KeyedVector<String8, String8> const& optionalParameters,
730*ec779b8eSAndroid Build Coastguard Worker                                     Vector<uint8_t>& request, String8& defaultUrl,
731*ec779b8eSAndroid Build Coastguard Worker                                     DrmPlugin::KeyRequestType* keyRequestType) {
732*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
733*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
734*ec779b8eSAndroid Build Coastguard Worker     EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
735*ec779b8eSAndroid Build Coastguard Worker 
736*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
737*ec779b8eSAndroid Build Coastguard Worker 
738*ec779b8eSAndroid Build Coastguard Worker     KeyType hKeyType;
739*ec779b8eSAndroid Build Coastguard Worker     if (keyType == DrmPlugin::kKeyType_Streaming) {
740*ec779b8eSAndroid Build Coastguard Worker         hKeyType = KeyType::STREAMING;
741*ec779b8eSAndroid Build Coastguard Worker     } else if (keyType == DrmPlugin::kKeyType_Offline) {
742*ec779b8eSAndroid Build Coastguard Worker         hKeyType = KeyType::OFFLINE;
743*ec779b8eSAndroid Build Coastguard Worker     } else if (keyType == DrmPlugin::kKeyType_Release) {
744*ec779b8eSAndroid Build Coastguard Worker         hKeyType = KeyType::RELEASE;
745*ec779b8eSAndroid Build Coastguard Worker     } else {
746*ec779b8eSAndroid Build Coastguard Worker         keyRequestTimer.SetAttribute(BAD_VALUE);
747*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
748*ec779b8eSAndroid Build Coastguard Worker     }
749*ec779b8eSAndroid Build Coastguard Worker 
750*ec779b8eSAndroid Build Coastguard Worker     ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
751*ec779b8eSAndroid Build Coastguard Worker 
752*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
753*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult;
754*ec779b8eSAndroid Build Coastguard Worker 
755*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 != NULL) {
756*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_2->getKeyRequest_1_2(
757*ec779b8eSAndroid Build Coastguard Worker                 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
758*ec779b8eSAndroid Build Coastguard Worker                 hOptionalParameters,
759*ec779b8eSAndroid Build Coastguard Worker                 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
760*ec779b8eSAndroid Build Coastguard Worker                     KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
761*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status_V1_2::OK) {
762*ec779b8eSAndroid Build Coastguard Worker                         request = toVector(hRequest);
763*ec779b8eSAndroid Build Coastguard Worker                         defaultUrl = toString8(hDefaultUrl);
764*ec779b8eSAndroid Build Coastguard Worker                         *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
765*ec779b8eSAndroid Build Coastguard Worker                     }
766*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
767*ec779b8eSAndroid Build Coastguard Worker                 });
768*ec779b8eSAndroid Build Coastguard Worker     } else if (mPluginV1_1 != NULL) {
769*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_1->getKeyRequest_1_1(
770*ec779b8eSAndroid Build Coastguard Worker                 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
771*ec779b8eSAndroid Build Coastguard Worker                 hOptionalParameters,
772*ec779b8eSAndroid Build Coastguard Worker                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
773*ec779b8eSAndroid Build Coastguard Worker                     KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
774*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status::OK) {
775*ec779b8eSAndroid Build Coastguard Worker                         request = toVector(hRequest);
776*ec779b8eSAndroid Build Coastguard Worker                         defaultUrl = toString8(hDefaultUrl);
777*ec779b8eSAndroid Build Coastguard Worker                         *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
778*ec779b8eSAndroid Build Coastguard Worker                     }
779*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
780*ec779b8eSAndroid Build Coastguard Worker                 });
781*ec779b8eSAndroid Build Coastguard Worker     } else {
782*ec779b8eSAndroid Build Coastguard Worker         hResult = mPlugin->getKeyRequest(
783*ec779b8eSAndroid Build Coastguard Worker                 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
784*ec779b8eSAndroid Build Coastguard Worker                 hOptionalParameters,
785*ec779b8eSAndroid Build Coastguard Worker                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
786*ec779b8eSAndroid Build Coastguard Worker                     KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
787*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status::OK) {
788*ec779b8eSAndroid Build Coastguard Worker                         request = toVector(hRequest);
789*ec779b8eSAndroid Build Coastguard Worker                         defaultUrl = toString8(hDefaultUrl);
790*ec779b8eSAndroid Build Coastguard Worker                         *keyRequestType = toKeyRequestType(hKeyRequestType);
791*ec779b8eSAndroid Build Coastguard Worker                     }
792*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
793*ec779b8eSAndroid Build Coastguard Worker                 });
794*ec779b8eSAndroid Build Coastguard Worker     }
795*ec779b8eSAndroid Build Coastguard Worker 
796*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
797*ec779b8eSAndroid Build Coastguard Worker     keyRequestTimer.SetAttribute(err);
798*ec779b8eSAndroid Build Coastguard Worker     return err;
799*ec779b8eSAndroid Build Coastguard Worker }
800*ec779b8eSAndroid Build Coastguard Worker 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)801*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
802*ec779b8eSAndroid Build Coastguard Worker                                          Vector<uint8_t> const& response,
803*ec779b8eSAndroid Build Coastguard Worker                                          Vector<uint8_t>& keySetId) {
804*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
805*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
806*ec779b8eSAndroid Build Coastguard Worker     EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
807*ec779b8eSAndroid Build Coastguard Worker 
808*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
809*ec779b8eSAndroid Build Coastguard Worker 
810*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
811*ec779b8eSAndroid Build Coastguard Worker 
812*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
813*ec779b8eSAndroid Build Coastguard Worker             mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
814*ec779b8eSAndroid Build Coastguard Worker                                         [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
815*ec779b8eSAndroid Build Coastguard Worker                                             if (status == Status::OK) {
816*ec779b8eSAndroid Build Coastguard Worker                                                 keySetId = toVector(hKeySetId);
817*ec779b8eSAndroid Build Coastguard Worker                                             }
818*ec779b8eSAndroid Build Coastguard Worker                                             err = toStatusT(status);
819*ec779b8eSAndroid Build Coastguard Worker                                         });
820*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
821*ec779b8eSAndroid Build Coastguard Worker     keyResponseTimer.SetAttribute(err);
822*ec779b8eSAndroid Build Coastguard Worker     return err;
823*ec779b8eSAndroid Build Coastguard Worker }
824*ec779b8eSAndroid Build Coastguard Worker 
removeKeys(Vector<uint8_t> const & keySetId)825*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
826*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
827*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
828*ec779b8eSAndroid Build Coastguard Worker 
829*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
830*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
831*ec779b8eSAndroid Build Coastguard Worker }
832*ec779b8eSAndroid Build Coastguard Worker 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)833*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
834*ec779b8eSAndroid Build Coastguard Worker                                   Vector<uint8_t> const& keySetId) {
835*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
836*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
837*ec779b8eSAndroid Build Coastguard Worker 
838*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
839*ec779b8eSAndroid Build Coastguard Worker 
840*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
841*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
842*ec779b8eSAndroid Build Coastguard Worker }
843*ec779b8eSAndroid Build Coastguard Worker 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const844*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
845*ec779b8eSAndroid Build Coastguard Worker                                      KeyedVector<String8, String8>& infoMap) const {
846*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
847*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
848*ec779b8eSAndroid Build Coastguard Worker 
849*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
850*ec779b8eSAndroid Build Coastguard Worker 
851*ec779b8eSAndroid Build Coastguard Worker     ::KeyedVector hInfoMap;
852*ec779b8eSAndroid Build Coastguard Worker 
853*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
854*ec779b8eSAndroid Build Coastguard Worker 
855*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->queryKeyStatus(
856*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
857*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
858*ec779b8eSAndroid Build Coastguard Worker                     infoMap = toKeyedVector(map);
859*ec779b8eSAndroid Build Coastguard Worker                 }
860*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
861*ec779b8eSAndroid Build Coastguard Worker             });
862*ec779b8eSAndroid Build Coastguard Worker 
863*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? DrmStatus(err) : DrmStatus(DEAD_OBJECT);
864*ec779b8eSAndroid Build Coastguard Worker }
865*ec779b8eSAndroid Build Coastguard Worker 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)866*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
867*ec779b8eSAndroid Build Coastguard Worker                                           Vector<uint8_t>& request, String8& defaultUrl) {
868*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
869*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
870*ec779b8eSAndroid Build Coastguard Worker 
871*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
872*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult;
873*ec779b8eSAndroid Build Coastguard Worker 
874*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 != NULL) {
875*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_2->getProvisionRequest_1_2(
876*ec779b8eSAndroid Build Coastguard Worker                 toHidlString(certType), toHidlString(certAuthority),
877*ec779b8eSAndroid Build Coastguard Worker                 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
878*ec779b8eSAndroid Build Coastguard Worker                     const hidl_string& hDefaultUrl) {
879*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status_V1_2::OK) {
880*ec779b8eSAndroid Build Coastguard Worker                         request = toVector(hRequest);
881*ec779b8eSAndroid Build Coastguard Worker                         defaultUrl = toString8(hDefaultUrl);
882*ec779b8eSAndroid Build Coastguard Worker                     }
883*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
884*ec779b8eSAndroid Build Coastguard Worker                 });
885*ec779b8eSAndroid Build Coastguard Worker     } else {
886*ec779b8eSAndroid Build Coastguard Worker         hResult = mPlugin->getProvisionRequest(toHidlString(certType), toHidlString(certAuthority),
887*ec779b8eSAndroid Build Coastguard Worker                                                [&](Status status, const hidl_vec<uint8_t>& hRequest,
888*ec779b8eSAndroid Build Coastguard Worker                                                    const hidl_string& hDefaultUrl) {
889*ec779b8eSAndroid Build Coastguard Worker                                                    if (status == Status::OK) {
890*ec779b8eSAndroid Build Coastguard Worker                                                        request = toVector(hRequest);
891*ec779b8eSAndroid Build Coastguard Worker                                                        defaultUrl = toString8(hDefaultUrl);
892*ec779b8eSAndroid Build Coastguard Worker                                                    }
893*ec779b8eSAndroid Build Coastguard Worker                                                    err = toStatusT(status);
894*ec779b8eSAndroid Build Coastguard Worker                                                });
895*ec779b8eSAndroid Build Coastguard Worker     }
896*ec779b8eSAndroid Build Coastguard Worker 
897*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
898*ec779b8eSAndroid Build Coastguard Worker     mMetrics.mGetProvisionRequestCounter.Increment(err);
899*ec779b8eSAndroid Build Coastguard Worker     return err;
900*ec779b8eSAndroid Build Coastguard Worker }
901*ec779b8eSAndroid Build Coastguard Worker 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)902*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
903*ec779b8eSAndroid Build Coastguard Worker                                                Vector<uint8_t>& certificate,
904*ec779b8eSAndroid Build Coastguard Worker                                                Vector<uint8_t>& wrappedKey) {
905*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
906*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
907*ec779b8eSAndroid Build Coastguard Worker 
908*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
909*ec779b8eSAndroid Build Coastguard Worker 
910*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->provideProvisionResponse(
911*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
912*ec779b8eSAndroid Build Coastguard Worker                                      const hidl_vec<uint8_t>& hWrappedKey) {
913*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
914*ec779b8eSAndroid Build Coastguard Worker                     certificate = toVector(hCertificate);
915*ec779b8eSAndroid Build Coastguard Worker                     wrappedKey = toVector(hWrappedKey);
916*ec779b8eSAndroid Build Coastguard Worker                 }
917*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
918*ec779b8eSAndroid Build Coastguard Worker             });
919*ec779b8eSAndroid Build Coastguard Worker 
920*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
921*ec779b8eSAndroid Build Coastguard Worker     mMetrics.mProvideProvisionResponseCounter.Increment(err);
922*ec779b8eSAndroid Build Coastguard Worker     return err;
923*ec779b8eSAndroid Build Coastguard Worker }
924*ec779b8eSAndroid Build Coastguard Worker 
getSecureStops(List<Vector<uint8_t>> & secureStops)925*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
926*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
927*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
928*ec779b8eSAndroid Build Coastguard Worker 
929*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
930*ec779b8eSAndroid Build Coastguard Worker 
931*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
932*ec779b8eSAndroid Build Coastguard Worker             mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
933*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
934*ec779b8eSAndroid Build Coastguard Worker                     secureStops = toSecureStops(hSecureStops);
935*ec779b8eSAndroid Build Coastguard Worker                 }
936*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
937*ec779b8eSAndroid Build Coastguard Worker             });
938*ec779b8eSAndroid Build Coastguard Worker 
939*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
940*ec779b8eSAndroid Build Coastguard Worker }
941*ec779b8eSAndroid Build Coastguard Worker 
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)942*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
943*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
944*ec779b8eSAndroid Build Coastguard Worker 
945*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
946*ec779b8eSAndroid Build Coastguard Worker         return mInitCheck;
947*ec779b8eSAndroid Build Coastguard Worker     }
948*ec779b8eSAndroid Build Coastguard Worker 
949*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 == NULL) {
950*ec779b8eSAndroid Build Coastguard Worker         return ERROR_DRM_CANNOT_HANDLE;
951*ec779b8eSAndroid Build Coastguard Worker     }
952*ec779b8eSAndroid Build Coastguard Worker 
953*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
954*ec779b8eSAndroid Build Coastguard Worker 
955*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPluginV1_1->getSecureStopIds(
956*ec779b8eSAndroid Build Coastguard Worker             [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
957*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
958*ec779b8eSAndroid Build Coastguard Worker                     secureStopIds = toSecureStopIds(hSecureStopIds);
959*ec779b8eSAndroid Build Coastguard Worker                 }
960*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
961*ec779b8eSAndroid Build Coastguard Worker             });
962*ec779b8eSAndroid Build Coastguard Worker 
963*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
964*ec779b8eSAndroid Build Coastguard Worker }
965*ec779b8eSAndroid Build Coastguard Worker 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)966*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
967*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
968*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
969*ec779b8eSAndroid Build Coastguard Worker 
970*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
971*ec779b8eSAndroid Build Coastguard Worker 
972*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->getSecureStop(
973*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
974*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
975*ec779b8eSAndroid Build Coastguard Worker                     secureStop = toVector(hSecureStop.opaqueData);
976*ec779b8eSAndroid Build Coastguard Worker                 }
977*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
978*ec779b8eSAndroid Build Coastguard Worker             });
979*ec779b8eSAndroid Build Coastguard Worker 
980*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
981*ec779b8eSAndroid Build Coastguard Worker }
982*ec779b8eSAndroid Build Coastguard Worker 
releaseSecureStops(Vector<uint8_t> const & ssRelease)983*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
984*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
985*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
986*ec779b8eSAndroid Build Coastguard Worker 
987*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status(Status::ERROR_DRM_UNKNOWN);
988*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 != NULL) {
989*ec779b8eSAndroid Build Coastguard Worker         SecureStopRelease secureStopRelease;
990*ec779b8eSAndroid Build Coastguard Worker         secureStopRelease.opaqueData = toHidlVec(ssRelease);
991*ec779b8eSAndroid Build Coastguard Worker         status = mPluginV1_1->releaseSecureStops(secureStopRelease);
992*ec779b8eSAndroid Build Coastguard Worker     } else {
993*ec779b8eSAndroid Build Coastguard Worker         status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
994*ec779b8eSAndroid Build Coastguard Worker     }
995*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
996*ec779b8eSAndroid Build Coastguard Worker }
997*ec779b8eSAndroid Build Coastguard Worker 
removeSecureStop(Vector<uint8_t> const & ssid)998*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
999*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1000*ec779b8eSAndroid Build Coastguard Worker 
1001*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
1002*ec779b8eSAndroid Build Coastguard Worker         return mInitCheck;
1003*ec779b8eSAndroid Build Coastguard Worker     }
1004*ec779b8eSAndroid Build Coastguard Worker 
1005*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 == NULL) {
1006*ec779b8eSAndroid Build Coastguard Worker         return ERROR_DRM_CANNOT_HANDLE;
1007*ec779b8eSAndroid Build Coastguard Worker     }
1008*ec779b8eSAndroid Build Coastguard Worker 
1009*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1010*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1011*ec779b8eSAndroid Build Coastguard Worker }
1012*ec779b8eSAndroid Build Coastguard Worker 
removeAllSecureStops()1013*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::removeAllSecureStops() {
1014*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1015*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1016*ec779b8eSAndroid Build Coastguard Worker 
1017*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1018*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 != NULL) {
1019*ec779b8eSAndroid Build Coastguard Worker         status = mPluginV1_1->removeAllSecureStops();
1020*ec779b8eSAndroid Build Coastguard Worker     } else {
1021*ec779b8eSAndroid Build Coastguard Worker         status = mPlugin->releaseAllSecureStops();
1022*ec779b8eSAndroid Build Coastguard Worker     }
1023*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1024*ec779b8eSAndroid Build Coastguard Worker }
1025*ec779b8eSAndroid Build Coastguard Worker 
getHdcpLevels(DrmPlugin::HdcpLevel * connected,DrmPlugin::HdcpLevel * max) const1026*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
1027*ec779b8eSAndroid Build Coastguard Worker                                     DrmPlugin::HdcpLevel* max) const {
1028*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1029*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1030*ec779b8eSAndroid Build Coastguard Worker 
1031*ec779b8eSAndroid Build Coastguard Worker     if (connected == NULL || max == NULL) {
1032*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1033*ec779b8eSAndroid Build Coastguard Worker     }
1034*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1035*ec779b8eSAndroid Build Coastguard Worker 
1036*ec779b8eSAndroid Build Coastguard Worker     *connected = DrmPlugin::kHdcpLevelUnknown;
1037*ec779b8eSAndroid Build Coastguard Worker     *max = DrmPlugin::kHdcpLevelUnknown;
1038*ec779b8eSAndroid Build Coastguard Worker 
1039*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult;
1040*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 != NULL) {
1041*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_2->getHdcpLevels_1_2([&](Status_V1_2 status,
1042*ec779b8eSAndroid Build Coastguard Worker                                                      const HdcpLevel_V1_2& hConnected,
1043*ec779b8eSAndroid Build Coastguard Worker                                                      const HdcpLevel_V1_2& hMax) {
1044*ec779b8eSAndroid Build Coastguard Worker             if (status == Status_V1_2::OK) {
1045*ec779b8eSAndroid Build Coastguard Worker                 *connected = toHdcpLevel(hConnected);
1046*ec779b8eSAndroid Build Coastguard Worker                 *max = toHdcpLevel(hMax);
1047*ec779b8eSAndroid Build Coastguard Worker             }
1048*ec779b8eSAndroid Build Coastguard Worker             err = toStatusT(status);
1049*ec779b8eSAndroid Build Coastguard Worker         });
1050*ec779b8eSAndroid Build Coastguard Worker     } else if (mPluginV1_1 != NULL) {
1051*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_1->getHdcpLevels(
1052*ec779b8eSAndroid Build Coastguard Worker                 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1053*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status::OK) {
1054*ec779b8eSAndroid Build Coastguard Worker                         *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1055*ec779b8eSAndroid Build Coastguard Worker                         *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1056*ec779b8eSAndroid Build Coastguard Worker                     }
1057*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
1058*ec779b8eSAndroid Build Coastguard Worker                 });
1059*ec779b8eSAndroid Build Coastguard Worker     } else {
1060*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
1061*ec779b8eSAndroid Build Coastguard Worker     }
1062*ec779b8eSAndroid Build Coastguard Worker 
1063*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1064*ec779b8eSAndroid Build Coastguard Worker }
1065*ec779b8eSAndroid Build Coastguard Worker 
getNumberOfSessions(uint32_t * open,uint32_t * max) const1066*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
1067*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1068*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1069*ec779b8eSAndroid Build Coastguard Worker 
1070*ec779b8eSAndroid Build Coastguard Worker     if (open == NULL || max == NULL) {
1071*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1072*ec779b8eSAndroid Build Coastguard Worker     }
1073*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1074*ec779b8eSAndroid Build Coastguard Worker 
1075*ec779b8eSAndroid Build Coastguard Worker     *open = 0;
1076*ec779b8eSAndroid Build Coastguard Worker     *max = 0;
1077*ec779b8eSAndroid Build Coastguard Worker 
1078*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 == NULL) {
1079*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
1080*ec779b8eSAndroid Build Coastguard Worker     }
1081*ec779b8eSAndroid Build Coastguard Worker 
1082*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
1083*ec779b8eSAndroid Build Coastguard Worker             mPluginV1_1->getNumberOfSessions([&](Status status, uint32_t hOpen, uint32_t hMax) {
1084*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1085*ec779b8eSAndroid Build Coastguard Worker                     *open = hOpen;
1086*ec779b8eSAndroid Build Coastguard Worker                     *max = hMax;
1087*ec779b8eSAndroid Build Coastguard Worker                 }
1088*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1089*ec779b8eSAndroid Build Coastguard Worker             });
1090*ec779b8eSAndroid Build Coastguard Worker 
1091*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1092*ec779b8eSAndroid Build Coastguard Worker }
1093*ec779b8eSAndroid Build Coastguard Worker 
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const1094*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
1095*ec779b8eSAndroid Build Coastguard Worker                                        DrmPlugin::SecurityLevel* level) const {
1096*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1097*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1098*ec779b8eSAndroid Build Coastguard Worker 
1099*ec779b8eSAndroid Build Coastguard Worker     if (level == NULL) {
1100*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(BAD_VALUE);
1101*ec779b8eSAndroid Build Coastguard Worker     }
1102*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1103*ec779b8eSAndroid Build Coastguard Worker 
1104*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 == NULL) {
1105*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
1106*ec779b8eSAndroid Build Coastguard Worker     }
1107*ec779b8eSAndroid Build Coastguard Worker 
1108*ec779b8eSAndroid Build Coastguard Worker     *level = DrmPlugin::kSecurityLevelUnknown;
1109*ec779b8eSAndroid Build Coastguard Worker 
1110*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1111*ec779b8eSAndroid Build Coastguard Worker                                                          [&](Status status, SecurityLevel hLevel) {
1112*ec779b8eSAndroid Build Coastguard Worker                                                              if (status == Status::OK) {
1113*ec779b8eSAndroid Build Coastguard Worker                                                                  *level = toSecurityLevel(hLevel);
1114*ec779b8eSAndroid Build Coastguard Worker                                                              }
1115*ec779b8eSAndroid Build Coastguard Worker                                                              err = toStatusT(status);
1116*ec779b8eSAndroid Build Coastguard Worker                                                          });
1117*ec779b8eSAndroid Build Coastguard Worker 
1118*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1119*ec779b8eSAndroid Build Coastguard Worker }
1120*ec779b8eSAndroid Build Coastguard Worker 
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const1121*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
1122*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1123*ec779b8eSAndroid Build Coastguard Worker 
1124*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
1125*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(mInitCheck);
1126*ec779b8eSAndroid Build Coastguard Worker     }
1127*ec779b8eSAndroid Build Coastguard Worker 
1128*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 == NULL) {
1129*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_UNSUPPORTED);
1130*ec779b8eSAndroid Build Coastguard Worker     }
1131*ec779b8eSAndroid Build Coastguard Worker 
1132*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1133*ec779b8eSAndroid Build Coastguard Worker 
1134*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1135*ec779b8eSAndroid Build Coastguard Worker             [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1136*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1137*ec779b8eSAndroid Build Coastguard Worker                     keySetIds = toKeySetIds(hKeySetIds);
1138*ec779b8eSAndroid Build Coastguard Worker                 }
1139*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1140*ec779b8eSAndroid Build Coastguard Worker             });
1141*ec779b8eSAndroid Build Coastguard Worker 
1142*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1143*ec779b8eSAndroid Build Coastguard Worker }
1144*ec779b8eSAndroid Build Coastguard Worker 
removeOfflineLicense(Vector<uint8_t> const & keySetId)1145*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
1146*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1147*ec779b8eSAndroid Build Coastguard Worker 
1148*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
1149*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(mInitCheck);
1150*ec779b8eSAndroid Build Coastguard Worker     }
1151*ec779b8eSAndroid Build Coastguard Worker 
1152*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 == NULL) {
1153*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_UNSUPPORTED);
1154*ec779b8eSAndroid Build Coastguard Worker     }
1155*ec779b8eSAndroid Build Coastguard Worker 
1156*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1157*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1158*ec779b8eSAndroid Build Coastguard Worker }
1159*ec779b8eSAndroid Build Coastguard Worker 
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const1160*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
1161*ec779b8eSAndroid Build Coastguard Worker                                              DrmPlugin::OfflineLicenseState* licenseState) const {
1162*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1163*ec779b8eSAndroid Build Coastguard Worker 
1164*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
1165*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(mInitCheck);
1166*ec779b8eSAndroid Build Coastguard Worker     }
1167*ec779b8eSAndroid Build Coastguard Worker 
1168*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 == NULL) {
1169*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_UNSUPPORTED);
1170*ec779b8eSAndroid Build Coastguard Worker     }
1171*ec779b8eSAndroid Build Coastguard Worker     *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1172*ec779b8eSAndroid Build Coastguard Worker 
1173*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1174*ec779b8eSAndroid Build Coastguard Worker 
1175*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
1176*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
1177*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1178*ec779b8eSAndroid Build Coastguard Worker                     *licenseState = toOfflineLicenseState(hLicenseState);
1179*ec779b8eSAndroid Build Coastguard Worker                 }
1180*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1181*ec779b8eSAndroid Build Coastguard Worker             });
1182*ec779b8eSAndroid Build Coastguard Worker 
1183*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1184*ec779b8eSAndroid Build Coastguard Worker }
1185*ec779b8eSAndroid Build Coastguard Worker 
getPropertyString(String8 const & name,String8 & value) const1186*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
1187*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1188*ec779b8eSAndroid Build Coastguard Worker     return getPropertyStringInternal(name, value);
1189*ec779b8eSAndroid Build Coastguard Worker }
1190*ec779b8eSAndroid Build Coastguard Worker 
getPropertyStringInternal(String8 const & name,String8 & value) const1191*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
1192*ec779b8eSAndroid Build Coastguard Worker     // This function is internal to the class and should only be called while
1193*ec779b8eSAndroid Build Coastguard Worker     // mLock is already held.
1194*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1195*ec779b8eSAndroid Build Coastguard Worker 
1196*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1197*ec779b8eSAndroid Build Coastguard Worker 
1198*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->getPropertyString(
1199*ec779b8eSAndroid Build Coastguard Worker             toHidlString(name), [&](Status status, const hidl_string& hValue) {
1200*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1201*ec779b8eSAndroid Build Coastguard Worker                     value = toString8(hValue);
1202*ec779b8eSAndroid Build Coastguard Worker                 }
1203*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1204*ec779b8eSAndroid Build Coastguard Worker             });
1205*ec779b8eSAndroid Build Coastguard Worker 
1206*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1207*ec779b8eSAndroid Build Coastguard Worker }
1208*ec779b8eSAndroid Build Coastguard Worker 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const1209*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
1210*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1211*ec779b8eSAndroid Build Coastguard Worker     return getPropertyByteArrayInternal(name, value);
1212*ec779b8eSAndroid Build Coastguard Worker }
1213*ec779b8eSAndroid Build Coastguard Worker 
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const1214*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
1215*ec779b8eSAndroid Build Coastguard Worker                                                    Vector<uint8_t>& value) const {
1216*ec779b8eSAndroid Build Coastguard Worker     // This function is internal to the class and should only be called while
1217*ec779b8eSAndroid Build Coastguard Worker     // mLock is already held.
1218*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1219*ec779b8eSAndroid Build Coastguard Worker 
1220*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1221*ec779b8eSAndroid Build Coastguard Worker 
1222*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->getPropertyByteArray(
1223*ec779b8eSAndroid Build Coastguard Worker             toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
1224*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1225*ec779b8eSAndroid Build Coastguard Worker                     value = toVector(hValue);
1226*ec779b8eSAndroid Build Coastguard Worker                 }
1227*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1228*ec779b8eSAndroid Build Coastguard Worker             });
1229*ec779b8eSAndroid Build Coastguard Worker 
1230*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
1231*ec779b8eSAndroid Build Coastguard Worker     if (name == kPropertyDeviceUniqueId) {
1232*ec779b8eSAndroid Build Coastguard Worker         mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1233*ec779b8eSAndroid Build Coastguard Worker     }
1234*ec779b8eSAndroid Build Coastguard Worker     return err;
1235*ec779b8eSAndroid Build Coastguard Worker }
1236*ec779b8eSAndroid Build Coastguard Worker 
setPropertyString(String8 const & name,String8 const & value) const1237*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
1238*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1239*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1240*ec779b8eSAndroid Build Coastguard Worker 
1241*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(value));
1242*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1243*ec779b8eSAndroid Build Coastguard Worker }
1244*ec779b8eSAndroid Build Coastguard Worker 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const1245*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setPropertyByteArray(String8 const& name,
1246*ec779b8eSAndroid Build Coastguard Worker                                            Vector<uint8_t> const& value) const {
1247*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1248*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1249*ec779b8eSAndroid Build Coastguard Worker 
1250*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
1251*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1252*ec779b8eSAndroid Build Coastguard Worker }
1253*ec779b8eSAndroid Build Coastguard Worker 
getMetrics(const sp<IDrmMetricsConsumer> & consumer)1254*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
1255*ec779b8eSAndroid Build Coastguard Worker     if (consumer == nullptr) {
1256*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(UNEXPECTED_NULL);
1257*ec779b8eSAndroid Build Coastguard Worker     }
1258*ec779b8eSAndroid Build Coastguard Worker     consumer->consumeFrameworkMetrics(mMetrics);
1259*ec779b8eSAndroid Build Coastguard Worker 
1260*ec779b8eSAndroid Build Coastguard Worker     // Append vendor metrics if they are supported.
1261*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_1 != NULL) {
1262*ec779b8eSAndroid Build Coastguard Worker         String8 vendor;
1263*ec779b8eSAndroid Build Coastguard Worker         String8 description;
1264*ec779b8eSAndroid Build Coastguard Worker         if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.empty()) {
1265*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Get vendor failed or is empty");
1266*ec779b8eSAndroid Build Coastguard Worker             vendor = "NONE";
1267*ec779b8eSAndroid Build Coastguard Worker         }
1268*ec779b8eSAndroid Build Coastguard Worker         if (getPropertyStringInternal(String8("description"), description) != OK ||
1269*ec779b8eSAndroid Build Coastguard Worker             description.empty()) {
1270*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Get description failed or is empty.");
1271*ec779b8eSAndroid Build Coastguard Worker             description = "NONE";
1272*ec779b8eSAndroid Build Coastguard Worker         }
1273*ec779b8eSAndroid Build Coastguard Worker         vendor += ".";
1274*ec779b8eSAndroid Build Coastguard Worker         vendor += description;
1275*ec779b8eSAndroid Build Coastguard Worker 
1276*ec779b8eSAndroid Build Coastguard Worker         hidl_vec<DrmMetricGroup> pluginMetrics;
1277*ec779b8eSAndroid Build Coastguard Worker         DrmStatus err = UNKNOWN_ERROR;
1278*ec779b8eSAndroid Build Coastguard Worker 
1279*ec779b8eSAndroid Build Coastguard Worker         Return<void> status =
1280*ec779b8eSAndroid Build Coastguard Worker                 mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1281*ec779b8eSAndroid Build Coastguard Worker                     if (status != Status::OK) {
1282*ec779b8eSAndroid Build Coastguard Worker                         ALOGV("Error getting plugin metrics: %d", status);
1283*ec779b8eSAndroid Build Coastguard Worker                     } else {
1284*ec779b8eSAndroid Build Coastguard Worker                         consumer->consumeHidlMetrics(vendor, pluginMetrics);
1285*ec779b8eSAndroid Build Coastguard Worker                     }
1286*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
1287*ec779b8eSAndroid Build Coastguard Worker                 });
1288*ec779b8eSAndroid Build Coastguard Worker         return status.isOk() ? err : DrmStatus(DEAD_OBJECT);
1289*ec779b8eSAndroid Build Coastguard Worker     }
1290*ec779b8eSAndroid Build Coastguard Worker 
1291*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
1292*ec779b8eSAndroid Build Coastguard Worker }
1293*ec779b8eSAndroid Build Coastguard Worker 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1294*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
1295*ec779b8eSAndroid Build Coastguard Worker                                          String8 const& algorithm) {
1296*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1297*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1298*ec779b8eSAndroid Build Coastguard Worker 
1299*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1300*ec779b8eSAndroid Build Coastguard Worker 
1301*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status =
1302*ec779b8eSAndroid Build Coastguard Worker             mPlugin->setCipherAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
1303*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1304*ec779b8eSAndroid Build Coastguard Worker }
1305*ec779b8eSAndroid Build Coastguard Worker 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1306*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
1307*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1308*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1309*ec779b8eSAndroid Build Coastguard Worker 
1310*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1311*ec779b8eSAndroid Build Coastguard Worker 
1312*ec779b8eSAndroid Build Coastguard Worker     Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
1313*ec779b8eSAndroid Build Coastguard Worker     return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
1314*ec779b8eSAndroid Build Coastguard Worker }
1315*ec779b8eSAndroid Build Coastguard Worker 
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)1316*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1317*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1318*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t>& output) {
1319*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1320*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1321*ec779b8eSAndroid Build Coastguard Worker 
1322*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1323*ec779b8eSAndroid Build Coastguard Worker 
1324*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1325*ec779b8eSAndroid Build Coastguard Worker 
1326*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
1327*ec779b8eSAndroid Build Coastguard Worker             mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1328*ec779b8eSAndroid Build Coastguard Worker                              toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1329*ec779b8eSAndroid Build Coastguard Worker                                  if (status == Status::OK) {
1330*ec779b8eSAndroid Build Coastguard Worker                                      output = toVector(hOutput);
1331*ec779b8eSAndroid Build Coastguard Worker                                  }
1332*ec779b8eSAndroid Build Coastguard Worker                                  err = toStatusT(status);
1333*ec779b8eSAndroid Build Coastguard Worker                              });
1334*ec779b8eSAndroid Build Coastguard Worker 
1335*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1336*ec779b8eSAndroid Build Coastguard Worker }
1337*ec779b8eSAndroid Build Coastguard Worker 
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)1338*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1339*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1340*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t>& output) {
1341*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1342*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1343*ec779b8eSAndroid Build Coastguard Worker 
1344*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1345*ec779b8eSAndroid Build Coastguard Worker 
1346*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1347*ec779b8eSAndroid Build Coastguard Worker 
1348*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
1349*ec779b8eSAndroid Build Coastguard Worker             mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1350*ec779b8eSAndroid Build Coastguard Worker                              toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1351*ec779b8eSAndroid Build Coastguard Worker                                  if (status == Status::OK) {
1352*ec779b8eSAndroid Build Coastguard Worker                                      output = toVector(hOutput);
1353*ec779b8eSAndroid Build Coastguard Worker                                  }
1354*ec779b8eSAndroid Build Coastguard Worker                                  err = toStatusT(status);
1355*ec779b8eSAndroid Build Coastguard Worker                              });
1356*ec779b8eSAndroid Build Coastguard Worker 
1357*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1358*ec779b8eSAndroid Build Coastguard Worker }
1359*ec779b8eSAndroid Build Coastguard Worker 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)1360*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1361*ec779b8eSAndroid Build Coastguard Worker                            Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
1362*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1363*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1364*ec779b8eSAndroid Build Coastguard Worker 
1365*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1366*ec779b8eSAndroid Build Coastguard Worker 
1367*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1368*ec779b8eSAndroid Build Coastguard Worker 
1369*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1370*ec779b8eSAndroid Build Coastguard Worker                                          [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1371*ec779b8eSAndroid Build Coastguard Worker                                              if (status == Status::OK) {
1372*ec779b8eSAndroid Build Coastguard Worker                                                  signature = toVector(hSignature);
1373*ec779b8eSAndroid Build Coastguard Worker                                              }
1374*ec779b8eSAndroid Build Coastguard Worker                                              err = toStatusT(status);
1375*ec779b8eSAndroid Build Coastguard Worker                                          });
1376*ec779b8eSAndroid Build Coastguard Worker 
1377*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1378*ec779b8eSAndroid Build Coastguard Worker }
1379*ec779b8eSAndroid Build Coastguard Worker 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)1380*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1381*ec779b8eSAndroid Build Coastguard Worker                              Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1382*ec779b8eSAndroid Build Coastguard Worker                              bool& match) {
1383*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1384*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1385*ec779b8eSAndroid Build Coastguard Worker 
1386*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1387*ec779b8eSAndroid Build Coastguard Worker 
1388*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1389*ec779b8eSAndroid Build Coastguard Worker 
1390*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
1391*ec779b8eSAndroid Build Coastguard Worker             mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1392*ec779b8eSAndroid Build Coastguard Worker                             toHidlVec(signature), [&](Status status, bool hMatch) {
1393*ec779b8eSAndroid Build Coastguard Worker                                 if (status == Status::OK) {
1394*ec779b8eSAndroid Build Coastguard Worker                                     match = hMatch;
1395*ec779b8eSAndroid Build Coastguard Worker                                 } else {
1396*ec779b8eSAndroid Build Coastguard Worker                                     match = false;
1397*ec779b8eSAndroid Build Coastguard Worker                                 }
1398*ec779b8eSAndroid Build Coastguard Worker                                 err = toStatusT(status);
1399*ec779b8eSAndroid Build Coastguard Worker                             });
1400*ec779b8eSAndroid Build Coastguard Worker 
1401*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1402*ec779b8eSAndroid Build Coastguard Worker }
1403*ec779b8eSAndroid Build Coastguard Worker 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)1404*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1405*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1406*ec779b8eSAndroid Build Coastguard Worker                               Vector<uint8_t>& signature) {
1407*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1408*ec779b8eSAndroid Build Coastguard Worker     INIT_CHECK();
1409*ec779b8eSAndroid Build Coastguard Worker 
1410*ec779b8eSAndroid Build Coastguard Worker     DrmSessionManager::Instance()->useSession(sessionId);
1411*ec779b8eSAndroid Build Coastguard Worker 
1412*ec779b8eSAndroid Build Coastguard Worker     DrmStatus err = UNKNOWN_ERROR;
1413*ec779b8eSAndroid Build Coastguard Worker 
1414*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->signRSA(
1415*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
1416*ec779b8eSAndroid Build Coastguard Worker             toHidlVec(wrappedKey), [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1417*ec779b8eSAndroid Build Coastguard Worker                 if (status == Status::OK) {
1418*ec779b8eSAndroid Build Coastguard Worker                     signature = toVector(hSignature);
1419*ec779b8eSAndroid Build Coastguard Worker                 }
1420*ec779b8eSAndroid Build Coastguard Worker                 err = toStatusT(status);
1421*ec779b8eSAndroid Build Coastguard Worker             });
1422*ec779b8eSAndroid Build Coastguard Worker 
1423*ec779b8eSAndroid Build Coastguard Worker     return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
1424*ec779b8eSAndroid Build Coastguard Worker }
1425*ec779b8eSAndroid Build Coastguard Worker 
reportFrameworkMetrics(const std::string & pluginMetrics) const1426*ec779b8eSAndroid Build Coastguard Worker std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1427*ec779b8eSAndroid Build Coastguard Worker     mediametrics_handle_t item(mediametrics_create("mediadrm"));
1428*ec779b8eSAndroid Build Coastguard Worker     mediametrics_setUid(item, mMetrics.GetAppUid());
1429*ec779b8eSAndroid Build Coastguard Worker     String8 vendor;
1430*ec779b8eSAndroid Build Coastguard Worker     String8 description;
1431*ec779b8eSAndroid Build Coastguard Worker     status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1432*ec779b8eSAndroid Build Coastguard Worker     if (result != OK) {
1433*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to get vendor from drm plugin: %d", result);
1434*ec779b8eSAndroid Build Coastguard Worker     } else {
1435*ec779b8eSAndroid Build Coastguard Worker         mediametrics_setCString(item, "vendor", vendor.c_str());
1436*ec779b8eSAndroid Build Coastguard Worker     }
1437*ec779b8eSAndroid Build Coastguard Worker     result = getPropertyStringInternal(String8("description"), description);
1438*ec779b8eSAndroid Build Coastguard Worker     if (result != OK) {
1439*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to get description from drm plugin: %d", result);
1440*ec779b8eSAndroid Build Coastguard Worker     } else {
1441*ec779b8eSAndroid Build Coastguard Worker         mediametrics_setCString(item, "description", description.c_str());
1442*ec779b8eSAndroid Build Coastguard Worker     }
1443*ec779b8eSAndroid Build Coastguard Worker 
1444*ec779b8eSAndroid Build Coastguard Worker     std::string serializedMetrics;
1445*ec779b8eSAndroid Build Coastguard Worker     result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1446*ec779b8eSAndroid Build Coastguard Worker     if (result != OK) {
1447*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to serialize framework metrics: %d", result);
1448*ec779b8eSAndroid Build Coastguard Worker     }
1449*ec779b8eSAndroid Build Coastguard Worker     std::string b64EncodedMetrics =
1450*ec779b8eSAndroid Build Coastguard Worker             toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1451*ec779b8eSAndroid Build Coastguard Worker     if (!b64EncodedMetrics.empty()) {
1452*ec779b8eSAndroid Build Coastguard Worker         mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1453*ec779b8eSAndroid Build Coastguard Worker     }
1454*ec779b8eSAndroid Build Coastguard Worker     if (!pluginMetrics.empty()) {
1455*ec779b8eSAndroid Build Coastguard Worker         mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1456*ec779b8eSAndroid Build Coastguard Worker     }
1457*ec779b8eSAndroid Build Coastguard Worker     if (!mediametrics_selfRecord(item)) {
1458*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to self record framework metrics");
1459*ec779b8eSAndroid Build Coastguard Worker     }
1460*ec779b8eSAndroid Build Coastguard Worker     mediametrics_delete(item);
1461*ec779b8eSAndroid Build Coastguard Worker     return serializedMetrics;
1462*ec779b8eSAndroid Build Coastguard Worker }
1463*ec779b8eSAndroid Build Coastguard Worker 
reportPluginMetrics() const1464*ec779b8eSAndroid Build Coastguard Worker std::string DrmHalHidl::reportPluginMetrics() const {
1465*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> metricsVector;
1466*ec779b8eSAndroid Build Coastguard Worker     String8 vendor;
1467*ec779b8eSAndroid Build Coastguard Worker     String8 description;
1468*ec779b8eSAndroid Build Coastguard Worker     std::string metricsString;
1469*ec779b8eSAndroid Build Coastguard Worker     if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1470*ec779b8eSAndroid Build Coastguard Worker         getPropertyStringInternal(String8("description"), description) == OK &&
1471*ec779b8eSAndroid Build Coastguard Worker         getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1472*ec779b8eSAndroid Build Coastguard Worker         metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1473*ec779b8eSAndroid Build Coastguard Worker         status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1474*ec779b8eSAndroid Build Coastguard Worker                                                        mMetrics.GetAppUid());
1475*ec779b8eSAndroid Build Coastguard Worker         if (res != OK) {
1476*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Metrics were retrieved but could not be reported: %d", res);
1477*ec779b8eSAndroid Build Coastguard Worker         }
1478*ec779b8eSAndroid Build Coastguard Worker     }
1479*ec779b8eSAndroid Build Coastguard Worker     return metricsString;
1480*ec779b8eSAndroid Build Coastguard Worker }
1481*ec779b8eSAndroid Build Coastguard Worker 
requiresSecureDecoder(const char * mime,bool * required) const1482*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
1483*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1484*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_4 == NULL) {
1485*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(false);
1486*ec779b8eSAndroid Build Coastguard Worker     }
1487*ec779b8eSAndroid Build Coastguard Worker     auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1488*ec779b8eSAndroid Build Coastguard Worker     if (!hResult.isOk()) {
1489*ec779b8eSAndroid Build Coastguard Worker         DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
1490*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(DEAD_OBJECT);
1491*ec779b8eSAndroid Build Coastguard Worker     }
1492*ec779b8eSAndroid Build Coastguard Worker     if (required) {
1493*ec779b8eSAndroid Build Coastguard Worker         *required = hResult;
1494*ec779b8eSAndroid Build Coastguard Worker     }
1495*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
1496*ec779b8eSAndroid Build Coastguard Worker }
1497*ec779b8eSAndroid Build Coastguard Worker 
requiresSecureDecoder(const char * mime,DrmPlugin::SecurityLevel securityLevel,bool * required) const1498*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime,
1499*ec779b8eSAndroid Build Coastguard Worker                                             DrmPlugin::SecurityLevel securityLevel,
1500*ec779b8eSAndroid Build Coastguard Worker                                             bool* required) const {
1501*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1502*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_4 == NULL) {
1503*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(false);
1504*ec779b8eSAndroid Build Coastguard Worker     }
1505*ec779b8eSAndroid Build Coastguard Worker     auto hLevel = toHidlSecurityLevel(securityLevel);
1506*ec779b8eSAndroid Build Coastguard Worker     auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1507*ec779b8eSAndroid Build Coastguard Worker     if (!hResult.isOk()) {
1508*ec779b8eSAndroid Build Coastguard Worker         DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
1509*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(DEAD_OBJECT);
1510*ec779b8eSAndroid Build Coastguard Worker     }
1511*ec779b8eSAndroid Build Coastguard Worker     if (required) {
1512*ec779b8eSAndroid Build Coastguard Worker         *required = hResult;
1513*ec779b8eSAndroid Build Coastguard Worker     }
1514*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
1515*ec779b8eSAndroid Build Coastguard Worker }
1516*ec779b8eSAndroid Build Coastguard Worker 
setPlaybackId(Vector<uint8_t> const & sessionId,const char * playbackId)1517*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
1518*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1519*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_4 == NULL) {
1520*ec779b8eSAndroid Build Coastguard Worker         return DrmStatus(ERROR_UNSUPPORTED);
1521*ec779b8eSAndroid Build Coastguard Worker     }
1522*ec779b8eSAndroid Build Coastguard Worker     auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
1523*ec779b8eSAndroid Build Coastguard Worker     return err.isOk() ? DrmStatus(toStatusT(err)) : DrmStatus(DEAD_OBJECT);
1524*ec779b8eSAndroid Build Coastguard Worker }
1525*ec779b8eSAndroid Build Coastguard Worker 
getLogMessages(Vector<drm::V1_4::LogMessage> & logs) const1526*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
1527*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1528*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs));
1529*ec779b8eSAndroid Build Coastguard Worker }
1530*ec779b8eSAndroid Build Coastguard Worker 
getSupportedSchemes(std::vector<uint8_t> & schemes) const1531*ec779b8eSAndroid Build Coastguard Worker DrmStatus DrmHalHidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
1532*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
1533*ec779b8eSAndroid Build Coastguard Worker     for (auto &factory : mFactories) {
1534*ec779b8eSAndroid Build Coastguard Worker         sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
1535*ec779b8eSAndroid Build Coastguard Worker         if (factoryV1_3 == nullptr) {
1536*ec779b8eSAndroid Build Coastguard Worker             continue;
1537*ec779b8eSAndroid Build Coastguard Worker         }
1538*ec779b8eSAndroid Build Coastguard Worker 
1539*ec779b8eSAndroid Build Coastguard Worker         factoryV1_3->getSupportedCryptoSchemes(
1540*ec779b8eSAndroid Build Coastguard Worker             [&](const hardware::hidl_vec<hardware::hidl_array<uint8_t, 16>>& schemes_hidl) {
1541*ec779b8eSAndroid Build Coastguard Worker                 for (const auto &scheme : schemes_hidl) {
1542*ec779b8eSAndroid Build Coastguard Worker                     schemes.insert(schemes.end(), scheme.data(), scheme.data() + scheme.size());
1543*ec779b8eSAndroid Build Coastguard Worker                 }
1544*ec779b8eSAndroid Build Coastguard Worker             });
1545*ec779b8eSAndroid Build Coastguard Worker     }
1546*ec779b8eSAndroid Build Coastguard Worker 
1547*ec779b8eSAndroid Build Coastguard Worker     return DrmStatus(OK);
1548*ec779b8eSAndroid Build Coastguard Worker }
1549*ec779b8eSAndroid Build Coastguard Worker 
1550*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
1551