xref: /aosp_15_r20/frameworks/av/media/ndk/NdkMediaDrm.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2014 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 "NdkMediaDrm"
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <unistd.h>
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include <iostream>
24*ec779b8eSAndroid Build Coastguard Worker #include <fstream>
25*ec779b8eSAndroid Build Coastguard Worker #include <string>
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaDrm.h>
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <gui/Surface.h>
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker #include <android-base/properties.h>
35*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmUtils.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/IDrm.h>
37*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/IDrmClient.h>
38*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaCrypto.h>
40*ec779b8eSAndroid Build Coastguard Worker 
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker using namespace android;
43*ec779b8eSAndroid Build Coastguard Worker 
44*ec779b8eSAndroid Build Coastguard Worker typedef Vector<uint8_t> idvec_t;
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker struct DrmListener: virtual public IDrmClient
47*ec779b8eSAndroid Build Coastguard Worker {
48*ec779b8eSAndroid Build Coastguard Worker private:
49*ec779b8eSAndroid Build Coastguard Worker     AMediaDrm *mObj;
50*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmEventListener mEventListener;
51*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmExpirationUpdateListener mExpirationUpdateListener;
52*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmKeysChangeListener mKeysChangeListener;
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker public:
DrmListenerDrmListener55*ec779b8eSAndroid Build Coastguard Worker     DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj),
56*ec779b8eSAndroid Build Coastguard Worker             mEventListener(listener), mExpirationUpdateListener(NULL), mKeysChangeListener(NULL) {}
57*ec779b8eSAndroid Build Coastguard Worker 
DrmListenerDrmListener58*ec779b8eSAndroid Build Coastguard Worker     DrmListener(AMediaDrm *obj, AMediaDrmExpirationUpdateListener listener) : mObj(obj),
59*ec779b8eSAndroid Build Coastguard Worker             mEventListener(NULL), mExpirationUpdateListener(listener), mKeysChangeListener(NULL) {}
60*ec779b8eSAndroid Build Coastguard Worker 
DrmListenerDrmListener61*ec779b8eSAndroid Build Coastguard Worker     DrmListener(AMediaDrm *obj, AMediaDrmKeysChangeListener listener) : mObj(obj),
62*ec779b8eSAndroid Build Coastguard Worker             mEventListener(NULL), mExpirationUpdateListener(NULL), mKeysChangeListener(listener) {}
63*ec779b8eSAndroid Build Coastguard Worker 
setEventListenerDrmListener64*ec779b8eSAndroid Build Coastguard Worker     void setEventListener(AMediaDrmEventListener listener) {
65*ec779b8eSAndroid Build Coastguard Worker         mEventListener = listener;
66*ec779b8eSAndroid Build Coastguard Worker     }
67*ec779b8eSAndroid Build Coastguard Worker 
setExpirationUpdateListenerDrmListener68*ec779b8eSAndroid Build Coastguard Worker     void setExpirationUpdateListener(AMediaDrmExpirationUpdateListener listener) {
69*ec779b8eSAndroid Build Coastguard Worker         mExpirationUpdateListener = listener;
70*ec779b8eSAndroid Build Coastguard Worker     }
71*ec779b8eSAndroid Build Coastguard Worker 
setKeysChangeListenerDrmListener72*ec779b8eSAndroid Build Coastguard Worker     void setKeysChangeListener(AMediaDrmKeysChangeListener listener) {
73*ec779b8eSAndroid Build Coastguard Worker         mKeysChangeListener = listener;
74*ec779b8eSAndroid Build Coastguard Worker     }
75*ec779b8eSAndroid Build Coastguard Worker 
76*ec779b8eSAndroid Build Coastguard Worker     void sendEvent(
77*ec779b8eSAndroid Build Coastguard Worker             DrmPlugin::EventType eventType,
78*ec779b8eSAndroid Build Coastguard Worker             const hardware::hidl_vec<uint8_t> &sessionId,
79*ec779b8eSAndroid Build Coastguard Worker             const hardware::hidl_vec<uint8_t> &data) override;
80*ec779b8eSAndroid Build Coastguard Worker 
81*ec779b8eSAndroid Build Coastguard Worker     void sendExpirationUpdate(
82*ec779b8eSAndroid Build Coastguard Worker             const hardware::hidl_vec<uint8_t> &sessionId,
83*ec779b8eSAndroid Build Coastguard Worker             int64_t expiryTimeInMS) override;
84*ec779b8eSAndroid Build Coastguard Worker 
85*ec779b8eSAndroid Build Coastguard Worker     void sendKeysChange(
86*ec779b8eSAndroid Build Coastguard Worker             const hardware::hidl_vec<uint8_t> &sessionId,
87*ec779b8eSAndroid Build Coastguard Worker             const std::vector<DrmKeyStatus> &keyStatusList,
88*ec779b8eSAndroid Build Coastguard Worker             bool hasNewUsableKey) override;
89*ec779b8eSAndroid Build Coastguard Worker 
sendSessionLostStateDrmListener90*ec779b8eSAndroid Build Coastguard Worker     void sendSessionLostState(
91*ec779b8eSAndroid Build Coastguard Worker             const hardware::hidl_vec<uint8_t> &) override {}
92*ec779b8eSAndroid Build Coastguard Worker 
93*ec779b8eSAndroid Build Coastguard Worker };
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker struct AMediaDrm {
96*ec779b8eSAndroid Build Coastguard Worker     sp<IDrm> mDrm;
97*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t> mIds;
98*ec779b8eSAndroid Build Coastguard Worker     KeyedVector<String8, String8> mQueryResults;
99*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mKeyRequest;
100*ec779b8eSAndroid Build Coastguard Worker     String8 mDefaultUrl;
101*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmKeyRequestType mkeyRequestType;
102*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mProvisionRequest;
103*ec779b8eSAndroid Build Coastguard Worker     String8 mProvisionUrl;
104*ec779b8eSAndroid Build Coastguard Worker     String8 mPropertyString;
105*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mPropertyByteArray;
106*ec779b8eSAndroid Build Coastguard Worker     List<Vector<uint8_t> > mSecureStops;
107*ec779b8eSAndroid Build Coastguard Worker     sp<DrmListener> mListener;
108*ec779b8eSAndroid Build Coastguard Worker };
109*ec779b8eSAndroid Build Coastguard Worker 
sendExpirationUpdate(const hardware::hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)110*ec779b8eSAndroid Build Coastguard Worker void DrmListener::sendExpirationUpdate(
111*ec779b8eSAndroid Build Coastguard Worker         const hardware::hidl_vec<uint8_t> &sessionId,
112*ec779b8eSAndroid Build Coastguard Worker         int64_t expiryTimeInMS) {
113*ec779b8eSAndroid Build Coastguard Worker     if (!mExpirationUpdateListener) {
114*ec779b8eSAndroid Build Coastguard Worker         ALOGE("No ExpirationUpdateListener specified");
115*ec779b8eSAndroid Build Coastguard Worker         return;
116*ec779b8eSAndroid Build Coastguard Worker     }
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker     if (expiryTimeInMS >= 0) {
119*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
120*ec779b8eSAndroid Build Coastguard Worker         (*mExpirationUpdateListener)(mObj, &asid, expiryTimeInMS);
121*ec779b8eSAndroid Build Coastguard Worker     } else {
122*ec779b8eSAndroid Build Coastguard Worker         ALOGE("expiry time negative, status=%" PRId64 "", expiryTimeInMS);
123*ec779b8eSAndroid Build Coastguard Worker     }
124*ec779b8eSAndroid Build Coastguard Worker }
125*ec779b8eSAndroid Build Coastguard Worker 
sendKeysChange(const hardware::hidl_vec<uint8_t> & sessionId,const std::vector<DrmKeyStatus> & keyStatusList,bool hasNewUsableKey)126*ec779b8eSAndroid Build Coastguard Worker void DrmListener::sendKeysChange(
127*ec779b8eSAndroid Build Coastguard Worker         const hardware::hidl_vec<uint8_t> &sessionId,
128*ec779b8eSAndroid Build Coastguard Worker         const std::vector<DrmKeyStatus> &keyStatusList,
129*ec779b8eSAndroid Build Coastguard Worker         bool hasNewUsableKey) {
130*ec779b8eSAndroid Build Coastguard Worker     if (!mKeysChangeListener) {
131*ec779b8eSAndroid Build Coastguard Worker         ALOGE("No KeysChangeListener specified");
132*ec779b8eSAndroid Build Coastguard Worker         return;
133*ec779b8eSAndroid Build Coastguard Worker     }
134*ec779b8eSAndroid Build Coastguard Worker 
135*ec779b8eSAndroid Build Coastguard Worker     Vector<AMediaDrmKeyStatus> keysStatus;
136*ec779b8eSAndroid Build Coastguard Worker     for (const auto &drmKeyStatus : keyStatusList) {
137*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmKeyStatus keyStatus;
138*ec779b8eSAndroid Build Coastguard Worker         keyStatus.keyId.ptr = drmKeyStatus.keyId.data();
139*ec779b8eSAndroid Build Coastguard Worker         keyStatus.keyId.length = drmKeyStatus.keyId.size();
140*ec779b8eSAndroid Build Coastguard Worker         keyStatus.keyType = static_cast<AMediaDrmKeyStatusType>(drmKeyStatus.type);
141*ec779b8eSAndroid Build Coastguard Worker         keysStatus.push(keyStatus);
142*ec779b8eSAndroid Build Coastguard Worker     }
143*ec779b8eSAndroid Build Coastguard Worker 
144*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
145*ec779b8eSAndroid Build Coastguard Worker     int32_t numKeys = keyStatusList.size();
146*ec779b8eSAndroid Build Coastguard Worker     (*mKeysChangeListener)(mObj, &asid, keysStatus.array(), numKeys, hasNewUsableKey);
147*ec779b8eSAndroid Build Coastguard Worker     return;
148*ec779b8eSAndroid Build Coastguard Worker }
149*ec779b8eSAndroid Build Coastguard Worker 
sendEvent(DrmPlugin::EventType eventType,const hardware::hidl_vec<uint8_t> & sessionId,const hardware::hidl_vec<uint8_t> & data)150*ec779b8eSAndroid Build Coastguard Worker void DrmListener::sendEvent(
151*ec779b8eSAndroid Build Coastguard Worker         DrmPlugin::EventType eventType,
152*ec779b8eSAndroid Build Coastguard Worker         const hardware::hidl_vec<uint8_t> &sessionId,
153*ec779b8eSAndroid Build Coastguard Worker         const hardware::hidl_vec<uint8_t> &data) {
154*ec779b8eSAndroid Build Coastguard Worker     if (!mEventListener) {
155*ec779b8eSAndroid Build Coastguard Worker         ALOGE("No EventListener specified");
156*ec779b8eSAndroid Build Coastguard Worker         return;
157*ec779b8eSAndroid Build Coastguard Worker     }
158*ec779b8eSAndroid Build Coastguard Worker 
159*ec779b8eSAndroid Build Coastguard Worker     // Handles AMediaDrmEventListener below:
160*ec779b8eSAndroid Build Coastguard Worker     //  translates DrmPlugin event types into their NDK equivalents
161*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmEventType ndkEventType;
162*ec779b8eSAndroid Build Coastguard Worker     switch(eventType) {
163*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kDrmPluginEventProvisionRequired:
164*ec779b8eSAndroid Build Coastguard Worker             ndkEventType = EVENT_PROVISION_REQUIRED;
165*ec779b8eSAndroid Build Coastguard Worker             break;
166*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kDrmPluginEventKeyNeeded:
167*ec779b8eSAndroid Build Coastguard Worker             ndkEventType = EVENT_KEY_REQUIRED;
168*ec779b8eSAndroid Build Coastguard Worker             break;
169*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kDrmPluginEventKeyExpired:
170*ec779b8eSAndroid Build Coastguard Worker             ndkEventType = EVENT_KEY_EXPIRED;
171*ec779b8eSAndroid Build Coastguard Worker             break;
172*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kDrmPluginEventVendorDefined:
173*ec779b8eSAndroid Build Coastguard Worker             ndkEventType = EVENT_VENDOR_DEFINED;
174*ec779b8eSAndroid Build Coastguard Worker             break;
175*ec779b8eSAndroid Build Coastguard Worker         case DrmPlugin::kDrmPluginEventSessionReclaimed:
176*ec779b8eSAndroid Build Coastguard Worker             ndkEventType = EVENT_SESSION_RECLAIMED;
177*ec779b8eSAndroid Build Coastguard Worker             break;
178*ec779b8eSAndroid Build Coastguard Worker         default:
179*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Invalid event DrmPlugin::EventType %d, ignored", eventType);
180*ec779b8eSAndroid Build Coastguard Worker             return;
181*ec779b8eSAndroid Build Coastguard Worker     }
182*ec779b8eSAndroid Build Coastguard Worker 
183*ec779b8eSAndroid Build Coastguard Worker     AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
184*ec779b8eSAndroid Build Coastguard Worker     int32_t dataSize = data.size();
185*ec779b8eSAndroid Build Coastguard Worker     const uint8_t *dataPtr = data.data();
186*ec779b8eSAndroid Build Coastguard Worker     if (dataSize >= 0) {
187*ec779b8eSAndroid Build Coastguard Worker         (*mEventListener)(mObj, &asid, ndkEventType, 0, dataPtr, dataSize);
188*ec779b8eSAndroid Build Coastguard Worker     } else {
189*ec779b8eSAndroid Build Coastguard Worker         ALOGE("invalid event data size=%d", dataSize);
190*ec779b8eSAndroid Build Coastguard Worker     }
191*ec779b8eSAndroid Build Coastguard Worker }
192*ec779b8eSAndroid Build Coastguard Worker 
193*ec779b8eSAndroid Build Coastguard Worker extern "C" {
194*ec779b8eSAndroid Build Coastguard Worker 
translateStatus(status_t status)195*ec779b8eSAndroid Build Coastguard Worker static media_status_t translateStatus(status_t status) {
196*ec779b8eSAndroid Build Coastguard Worker     media_status_t result = AMEDIA_ERROR_UNKNOWN;
197*ec779b8eSAndroid Build Coastguard Worker     switch (status) {
198*ec779b8eSAndroid Build Coastguard Worker         case OK:
199*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_OK;
200*ec779b8eSAndroid Build Coastguard Worker             break;
201*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_NOT_PROVISIONED:
202*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_NOT_PROVISIONED;
203*ec779b8eSAndroid Build Coastguard Worker             break;
204*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_RESOURCE_BUSY:
205*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_RESOURCE_BUSY;
206*ec779b8eSAndroid Build Coastguard Worker             break;
207*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_DEVICE_REVOKED:
208*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_DEVICE_REVOKED;
209*ec779b8eSAndroid Build Coastguard Worker             break;
210*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_CANNOT_HANDLE:
211*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_ERROR_INVALID_PARAMETER;
212*ec779b8eSAndroid Build Coastguard Worker             break;
213*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_TAMPER_DETECTED:
214*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_TAMPER_DETECTED;
215*ec779b8eSAndroid Build Coastguard Worker             break;
216*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_SESSION_NOT_OPENED:
217*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_SESSION_NOT_OPENED;
218*ec779b8eSAndroid Build Coastguard Worker             break;
219*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_NO_LICENSE:
220*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_NEED_KEY;
221*ec779b8eSAndroid Build Coastguard Worker             break;
222*ec779b8eSAndroid Build Coastguard Worker         case android::ERROR_DRM_LICENSE_EXPIRED:
223*ec779b8eSAndroid Build Coastguard Worker             result = AMEDIA_DRM_LICENSE_EXPIRED;
224*ec779b8eSAndroid Build Coastguard Worker             break;
225*ec779b8eSAndroid Build Coastguard Worker         default:
226*ec779b8eSAndroid Build Coastguard Worker             break;
227*ec779b8eSAndroid Build Coastguard Worker     }
228*ec779b8eSAndroid Build Coastguard Worker     return result;
229*ec779b8eSAndroid Build Coastguard Worker }
230*ec779b8eSAndroid Build Coastguard Worker 
ShouldGetAppPackageName(void)231*ec779b8eSAndroid Build Coastguard Worker static bool ShouldGetAppPackageName(void) {
232*ec779b8eSAndroid Build Coastguard Worker     // Check what this device's first API level was.
233*ec779b8eSAndroid Build Coastguard Worker     int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
234*ec779b8eSAndroid Build Coastguard Worker     if (firstApiLevel == 0) {
235*ec779b8eSAndroid Build Coastguard Worker         // First API Level is 0 on factory ROMs, but we can assume the current SDK
236*ec779b8eSAndroid Build Coastguard Worker         // version is the first if it's a factory ROM.
237*ec779b8eSAndroid Build Coastguard Worker         firstApiLevel = android::base::GetIntProperty<int32_t>("ro.build.version.sdk", 0);
238*ec779b8eSAndroid Build Coastguard Worker     }
239*ec779b8eSAndroid Build Coastguard Worker     return firstApiLevel >= 29;  // Android Q
240*ec779b8eSAndroid Build Coastguard Worker }
241*ec779b8eSAndroid Build Coastguard Worker 
GetAppPackageName(String8 * packageName)242*ec779b8eSAndroid Build Coastguard Worker static status_t GetAppPackageName(String8 *packageName) {
243*ec779b8eSAndroid Build Coastguard Worker     // todo(robertshih): use refactored/renamed libneuralnetworks_packageinfo which is stable
244*ec779b8eSAndroid Build Coastguard Worker     std::string appName;
245*ec779b8eSAndroid Build Coastguard Worker     std::ifstream cmdline("/proc/self/cmdline");
246*ec779b8eSAndroid Build Coastguard Worker     std::getline(cmdline, appName);
247*ec779b8eSAndroid Build Coastguard Worker     cmdline.close();
248*ec779b8eSAndroid Build Coastguard Worker     if (appName.empty()) {
249*ec779b8eSAndroid Build Coastguard Worker         return UNKNOWN_ERROR;
250*ec779b8eSAndroid Build Coastguard Worker     }
251*ec779b8eSAndroid Build Coastguard Worker     *packageName = String8(appName.c_str());
252*ec779b8eSAndroid Build Coastguard Worker     return OK;
253*ec779b8eSAndroid Build Coastguard Worker }
254*ec779b8eSAndroid Build Coastguard Worker 
CreateDrm()255*ec779b8eSAndroid Build Coastguard Worker static sp<IDrm> CreateDrm() {
256*ec779b8eSAndroid Build Coastguard Worker     return DrmUtils::MakeDrm(IDRM_NDK);
257*ec779b8eSAndroid Build Coastguard Worker }
258*ec779b8eSAndroid Build Coastguard Worker 
259*ec779b8eSAndroid Build Coastguard Worker 
CreateDrmFromUUID(const AMediaUUID uuid)260*ec779b8eSAndroid Build Coastguard Worker static sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) {
261*ec779b8eSAndroid Build Coastguard Worker     sp<IDrm> drm = CreateDrm();
262*ec779b8eSAndroid Build Coastguard Worker 
263*ec779b8eSAndroid Build Coastguard Worker     if (drm == NULL) {
264*ec779b8eSAndroid Build Coastguard Worker         return NULL;
265*ec779b8eSAndroid Build Coastguard Worker     }
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker     String8 packageName;
268*ec779b8eSAndroid Build Coastguard Worker     if (ShouldGetAppPackageName()) {
269*ec779b8eSAndroid Build Coastguard Worker         status_t err = GetAppPackageName(&packageName);
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker         if (err != OK) {
272*ec779b8eSAndroid Build Coastguard Worker             return NULL;
273*ec779b8eSAndroid Build Coastguard Worker         }
274*ec779b8eSAndroid Build Coastguard Worker     }
275*ec779b8eSAndroid Build Coastguard Worker 
276*ec779b8eSAndroid Build Coastguard Worker     status_t err = drm->createPlugin(uuid, packageName);
277*ec779b8eSAndroid Build Coastguard Worker 
278*ec779b8eSAndroid Build Coastguard Worker     if (err != OK) {
279*ec779b8eSAndroid Build Coastguard Worker         return NULL;
280*ec779b8eSAndroid Build Coastguard Worker     }
281*ec779b8eSAndroid Build Coastguard Worker 
282*ec779b8eSAndroid Build Coastguard Worker     return drm;
283*ec779b8eSAndroid Build Coastguard Worker }
284*ec779b8eSAndroid Build Coastguard Worker 
285*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid,const char * mimeType)286*ec779b8eSAndroid Build Coastguard Worker bool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) {
287*ec779b8eSAndroid Build Coastguard Worker     sp<IDrm> drm = CreateDrm();
288*ec779b8eSAndroid Build Coastguard Worker 
289*ec779b8eSAndroid Build Coastguard Worker     if (drm == NULL) {
290*ec779b8eSAndroid Build Coastguard Worker         return false;
291*ec779b8eSAndroid Build Coastguard Worker     }
292*ec779b8eSAndroid Build Coastguard Worker 
293*ec779b8eSAndroid Build Coastguard Worker     String8 mimeStr = mimeType ? String8(mimeType) : String8("");
294*ec779b8eSAndroid Build Coastguard Worker     bool isSupported = false;
295*ec779b8eSAndroid Build Coastguard Worker     status_t status = drm->isCryptoSchemeSupported(uuid, mimeStr,
296*ec779b8eSAndroid Build Coastguard Worker             DrmPlugin::kSecurityLevelUnknown, &isSupported);
297*ec779b8eSAndroid Build Coastguard Worker     return (status == OK) && isSupported;
298*ec779b8eSAndroid Build Coastguard Worker }
299*ec779b8eSAndroid Build Coastguard Worker 
300*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_createByUUID(const AMediaUUID uuid)301*ec779b8eSAndroid Build Coastguard Worker AMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
302*ec779b8eSAndroid Build Coastguard Worker     AMediaDrm *mObj = new AMediaDrm();
303*ec779b8eSAndroid Build Coastguard Worker     mObj->mDrm = CreateDrmFromUUID(uuid);
304*ec779b8eSAndroid Build Coastguard Worker 
305*ec779b8eSAndroid Build Coastguard Worker     mObj->mListener.clear();
306*ec779b8eSAndroid Build Coastguard Worker     return mObj;
307*ec779b8eSAndroid Build Coastguard Worker }
308*ec779b8eSAndroid Build Coastguard Worker 
309*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_release(AMediaDrm * mObj)310*ec779b8eSAndroid Build Coastguard Worker void AMediaDrm_release(AMediaDrm *mObj) {
311*ec779b8eSAndroid Build Coastguard Worker     if (mObj->mDrm != NULL) {
312*ec779b8eSAndroid Build Coastguard Worker         mObj->mDrm->setListener(NULL);
313*ec779b8eSAndroid Build Coastguard Worker         mObj->mDrm->destroyPlugin();
314*ec779b8eSAndroid Build Coastguard Worker         mObj->mDrm.clear();
315*ec779b8eSAndroid Build Coastguard Worker     }
316*ec779b8eSAndroid Build Coastguard Worker     delete mObj;
317*ec779b8eSAndroid Build Coastguard Worker }
318*ec779b8eSAndroid Build Coastguard Worker 
319*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_setOnEventListener(AMediaDrm * mObj,AMediaDrmEventListener listener)320*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) {
321*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
322*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
323*ec779b8eSAndroid Build Coastguard Worker     }
324*ec779b8eSAndroid Build Coastguard Worker 
325*ec779b8eSAndroid Build Coastguard Worker     if (mObj->mListener.get()) {
326*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener->setEventListener(listener);
327*ec779b8eSAndroid Build Coastguard Worker     } else {
328*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener = new DrmListener(mObj, listener);
329*ec779b8eSAndroid Build Coastguard Worker     }
330*ec779b8eSAndroid Build Coastguard Worker     mObj->mDrm->setListener(mObj->mListener);
331*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
332*ec779b8eSAndroid Build Coastguard Worker }
333*ec779b8eSAndroid Build Coastguard Worker 
334*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_setOnExpirationUpdateListener(AMediaDrm * mObj,AMediaDrmExpirationUpdateListener listener)335*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *mObj,
336*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmExpirationUpdateListener listener) {
337*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
338*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
339*ec779b8eSAndroid Build Coastguard Worker     }
340*ec779b8eSAndroid Build Coastguard Worker 
341*ec779b8eSAndroid Build Coastguard Worker     if (mObj->mListener.get()) {
342*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener->setExpirationUpdateListener(listener);
343*ec779b8eSAndroid Build Coastguard Worker     } else {
344*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener = new DrmListener(mObj, listener);
345*ec779b8eSAndroid Build Coastguard Worker     }
346*ec779b8eSAndroid Build Coastguard Worker     mObj->mDrm->setListener(mObj->mListener);
347*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
348*ec779b8eSAndroid Build Coastguard Worker }
349*ec779b8eSAndroid Build Coastguard Worker 
350*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_setOnKeysChangeListener(AMediaDrm * mObj,AMediaDrmKeysChangeListener listener)351*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *mObj,
352*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmKeysChangeListener listener) {
353*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
354*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
355*ec779b8eSAndroid Build Coastguard Worker     }
356*ec779b8eSAndroid Build Coastguard Worker 
357*ec779b8eSAndroid Build Coastguard Worker     if (mObj->mListener.get()) {
358*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener->setKeysChangeListener(listener);
359*ec779b8eSAndroid Build Coastguard Worker     } else {
360*ec779b8eSAndroid Build Coastguard Worker         mObj->mListener = new DrmListener(mObj, listener);
361*ec779b8eSAndroid Build Coastguard Worker     }
362*ec779b8eSAndroid Build Coastguard Worker     mObj->mDrm->setListener(mObj->mListener);
363*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
364*ec779b8eSAndroid Build Coastguard Worker }
365*ec779b8eSAndroid Build Coastguard Worker 
findId(AMediaDrm * mObj,const AMediaDrmByteArray & id,List<idvec_t>::iterator & iter)366*ec779b8eSAndroid Build Coastguard Worker static bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
367*ec779b8eSAndroid Build Coastguard Worker     for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) {
368*ec779b8eSAndroid Build Coastguard Worker         if (id.length == iter->size() && memcmp(iter->array(), id.ptr, iter->size()) == 0) {
369*ec779b8eSAndroid Build Coastguard Worker             return true;
370*ec779b8eSAndroid Build Coastguard Worker         }
371*ec779b8eSAndroid Build Coastguard Worker     }
372*ec779b8eSAndroid Build Coastguard Worker     return false;
373*ec779b8eSAndroid Build Coastguard Worker }
374*ec779b8eSAndroid Build Coastguard Worker 
375*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_openSession(AMediaDrm * mObj,AMediaDrmSessionId * sessionId)376*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
377*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
378*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
379*ec779b8eSAndroid Build Coastguard Worker     }
380*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
381*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
382*ec779b8eSAndroid Build Coastguard Worker     }
383*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> session;
384*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->openSession(DrmPlugin::kSecurityLevelMax, session);
385*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
386*ec779b8eSAndroid Build Coastguard Worker         sessionId->ptr = NULL;
387*ec779b8eSAndroid Build Coastguard Worker         sessionId->length = 0;
388*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
389*ec779b8eSAndroid Build Coastguard Worker     }
390*ec779b8eSAndroid Build Coastguard Worker     mObj->mIds.push_front(session);
391*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter = mObj->mIds.begin();
392*ec779b8eSAndroid Build Coastguard Worker     sessionId->ptr = iter->array();
393*ec779b8eSAndroid Build Coastguard Worker     sessionId->length = iter->size();
394*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
395*ec779b8eSAndroid Build Coastguard Worker }
396*ec779b8eSAndroid Build Coastguard Worker 
397*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_closeSession(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId)398*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
399*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
400*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
401*ec779b8eSAndroid Build Coastguard Worker     }
402*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
403*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
404*ec779b8eSAndroid Build Coastguard Worker     }
405*ec779b8eSAndroid Build Coastguard Worker 
406*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
407*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *sessionId, iter)) {
408*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
409*ec779b8eSAndroid Build Coastguard Worker     }
410*ec779b8eSAndroid Build Coastguard Worker     mObj->mDrm->closeSession(*iter);
411*ec779b8eSAndroid Build Coastguard Worker     mObj->mIds.erase(iter);
412*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker 
415*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getKeyRequest(AMediaDrm * mObj,const AMediaDrmScope * scope,const uint8_t * init,size_t initSize,const char * mimeType,AMediaDrmKeyType keyType,const AMediaDrmKeyValue * optionalParameters,size_t numOptionalParameters,const uint8_t ** keyRequest,size_t * keyRequestSize)416*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
417*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
418*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
419*ec779b8eSAndroid Build Coastguard Worker         const uint8_t **keyRequest, size_t *keyRequestSize) {
420*ec779b8eSAndroid Build Coastguard Worker 
421*ec779b8eSAndroid Build Coastguard Worker     return AMediaDrm_getKeyRequestWithDefaultUrlAndType(mObj,
422*ec779b8eSAndroid Build Coastguard Worker         scope, init, initSize, mimeType, keyType, optionalParameters,
423*ec779b8eSAndroid Build Coastguard Worker         numOptionalParameters, keyRequest,
424*ec779b8eSAndroid Build Coastguard Worker         keyRequestSize, NULL, NULL);
425*ec779b8eSAndroid Build Coastguard Worker }
426*ec779b8eSAndroid Build Coastguard Worker 
427*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getKeyRequestWithDefaultUrlAndType(AMediaDrm * mObj,const AMediaDrmScope * scope,const uint8_t * init,size_t initSize,const char * mimeType,AMediaDrmKeyType keyType,const AMediaDrmKeyValue * optionalParameters,size_t numOptionalParameters,const uint8_t ** keyRequest,size_t * keyRequestSize,const char ** defaultUrl,AMediaDrmKeyRequestType * keyRequestType)428*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getKeyRequestWithDefaultUrlAndType(AMediaDrm *mObj,
429*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmScope *scope, const uint8_t *init, size_t initSize,
430*ec779b8eSAndroid Build Coastguard Worker         const char *mimeType, AMediaDrmKeyType keyType,
431*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmKeyValue *optionalParameters,
432*ec779b8eSAndroid Build Coastguard Worker         size_t numOptionalParameters, const uint8_t **keyRequest,
433*ec779b8eSAndroid Build Coastguard Worker         size_t *keyRequestSize, const char **defaultUrl,
434*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmKeyRequestType *keyRequestType) {
435*ec779b8eSAndroid Build Coastguard Worker 
436*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
437*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
438*ec779b8eSAndroid Build Coastguard Worker     }
439*ec779b8eSAndroid Build Coastguard Worker     if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
440*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
441*ec779b8eSAndroid Build Coastguard Worker     }
442*ec779b8eSAndroid Build Coastguard Worker 
443*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
444*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *scope, iter)) {
445*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
446*ec779b8eSAndroid Build Coastguard Worker     }
447*ec779b8eSAndroid Build Coastguard Worker 
448*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mdInit;
449*ec779b8eSAndroid Build Coastguard Worker     mdInit.appendArray(init, initSize);
450*ec779b8eSAndroid Build Coastguard Worker     DrmPlugin::KeyType mdKeyType;
451*ec779b8eSAndroid Build Coastguard Worker     switch (keyType) {
452*ec779b8eSAndroid Build Coastguard Worker         case KEY_TYPE_STREAMING:
453*ec779b8eSAndroid Build Coastguard Worker             mdKeyType = DrmPlugin::kKeyType_Streaming;
454*ec779b8eSAndroid Build Coastguard Worker             break;
455*ec779b8eSAndroid Build Coastguard Worker         case KEY_TYPE_OFFLINE:
456*ec779b8eSAndroid Build Coastguard Worker             mdKeyType = DrmPlugin::kKeyType_Offline;
457*ec779b8eSAndroid Build Coastguard Worker             break;
458*ec779b8eSAndroid Build Coastguard Worker         case KEY_TYPE_RELEASE:
459*ec779b8eSAndroid Build Coastguard Worker             mdKeyType = DrmPlugin::kKeyType_Release;
460*ec779b8eSAndroid Build Coastguard Worker             break;
461*ec779b8eSAndroid Build Coastguard Worker         default:
462*ec779b8eSAndroid Build Coastguard Worker             return AMEDIA_ERROR_INVALID_PARAMETER;
463*ec779b8eSAndroid Build Coastguard Worker     }
464*ec779b8eSAndroid Build Coastguard Worker     KeyedVector<String8, String8> mdOptionalParameters;
465*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < numOptionalParameters; i++) {
466*ec779b8eSAndroid Build Coastguard Worker         mdOptionalParameters.add(String8(optionalParameters[i].mKey),
467*ec779b8eSAndroid Build Coastguard Worker                 String8(optionalParameters[i].mValue));
468*ec779b8eSAndroid Build Coastguard Worker     }
469*ec779b8eSAndroid Build Coastguard Worker 
470*ec779b8eSAndroid Build Coastguard Worker     DrmPlugin::KeyRequestType requestType;
471*ec779b8eSAndroid Build Coastguard Worker     mObj->mKeyRequest.clear();
472*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
473*ec779b8eSAndroid Build Coastguard Worker             mdKeyType, mdOptionalParameters, mObj->mKeyRequest, mObj->mDefaultUrl,
474*ec779b8eSAndroid Build Coastguard Worker             &requestType);
475*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
476*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
477*ec779b8eSAndroid Build Coastguard Worker     } else {
478*ec779b8eSAndroid Build Coastguard Worker         *keyRequest = mObj->mKeyRequest.array();
479*ec779b8eSAndroid Build Coastguard Worker         *keyRequestSize = mObj->mKeyRequest.size();
480*ec779b8eSAndroid Build Coastguard Worker         if (defaultUrl != NULL)
481*ec779b8eSAndroid Build Coastguard Worker             *defaultUrl = mObj->mDefaultUrl.c_str();
482*ec779b8eSAndroid Build Coastguard Worker         switch(requestType) {
483*ec779b8eSAndroid Build Coastguard Worker             case DrmPlugin::kKeyRequestType_Initial:
484*ec779b8eSAndroid Build Coastguard Worker                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_INITIAL;
485*ec779b8eSAndroid Build Coastguard Worker                 break;
486*ec779b8eSAndroid Build Coastguard Worker             case DrmPlugin::kKeyRequestType_Renewal:
487*ec779b8eSAndroid Build Coastguard Worker                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_RENEWAL;
488*ec779b8eSAndroid Build Coastguard Worker                 break;
489*ec779b8eSAndroid Build Coastguard Worker             case DrmPlugin::kKeyRequestType_Release:
490*ec779b8eSAndroid Build Coastguard Worker                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_RELEASE;
491*ec779b8eSAndroid Build Coastguard Worker                 break;
492*ec779b8eSAndroid Build Coastguard Worker             case DrmPlugin::kKeyRequestType_None:
493*ec779b8eSAndroid Build Coastguard Worker                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_NONE;
494*ec779b8eSAndroid Build Coastguard Worker                 break;
495*ec779b8eSAndroid Build Coastguard Worker             case DrmPlugin::kKeyRequestType_Update:
496*ec779b8eSAndroid Build Coastguard Worker                 mObj->mkeyRequestType = KEY_REQUEST_TYPE_UPDATE;
497*ec779b8eSAndroid Build Coastguard Worker                 break;
498*ec779b8eSAndroid Build Coastguard Worker             default:
499*ec779b8eSAndroid Build Coastguard Worker                 return AMEDIA_ERROR_UNKNOWN;
500*ec779b8eSAndroid Build Coastguard Worker         }
501*ec779b8eSAndroid Build Coastguard Worker 
502*ec779b8eSAndroid Build Coastguard Worker         if (keyRequestType != NULL)
503*ec779b8eSAndroid Build Coastguard Worker             *keyRequestType = mObj->mkeyRequestType;
504*ec779b8eSAndroid Build Coastguard Worker     }
505*ec779b8eSAndroid Build Coastguard Worker 
506*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
507*ec779b8eSAndroid Build Coastguard Worker }
508*ec779b8eSAndroid Build Coastguard Worker 
509*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_provideKeyResponse(AMediaDrm * mObj,const AMediaDrmScope * scope,const uint8_t * response,size_t responseSize,AMediaDrmKeySetId * keySetId)510*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
511*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
512*ec779b8eSAndroid Build Coastguard Worker 
513*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
514*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
515*ec779b8eSAndroid Build Coastguard Worker     }
516*ec779b8eSAndroid Build Coastguard Worker     if (!scope || !response || !responseSize || !keySetId) {
517*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
518*ec779b8eSAndroid Build Coastguard Worker     }
519*ec779b8eSAndroid Build Coastguard Worker 
520*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
521*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *scope, iter)) {
522*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
523*ec779b8eSAndroid Build Coastguard Worker     }
524*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mdResponse;
525*ec779b8eSAndroid Build Coastguard Worker     mdResponse.appendArray(response, responseSize);
526*ec779b8eSAndroid Build Coastguard Worker 
527*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mdKeySetId;
528*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId);
529*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
530*ec779b8eSAndroid Build Coastguard Worker         mObj->mIds.push_front(mdKeySetId);
531*ec779b8eSAndroid Build Coastguard Worker         List<idvec_t>::iterator iter = mObj->mIds.begin();
532*ec779b8eSAndroid Build Coastguard Worker         keySetId->ptr = iter->array();
533*ec779b8eSAndroid Build Coastguard Worker         keySetId->length = iter->size();
534*ec779b8eSAndroid Build Coastguard Worker     } else {
535*ec779b8eSAndroid Build Coastguard Worker         keySetId->ptr = NULL;
536*ec779b8eSAndroid Build Coastguard Worker         keySetId->length = 0;
537*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
538*ec779b8eSAndroid Build Coastguard Worker     }
539*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
540*ec779b8eSAndroid Build Coastguard Worker }
541*ec779b8eSAndroid Build Coastguard Worker 
542*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_restoreKeys(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,const AMediaDrmKeySetId * keySetId)543*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
544*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmKeySetId *keySetId) {
545*ec779b8eSAndroid Build Coastguard Worker 
546*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
547*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
548*ec779b8eSAndroid Build Coastguard Worker     }
549*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId || !keySetId) {
550*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
551*ec779b8eSAndroid Build Coastguard Worker     }
552*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
553*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *sessionId, iter)) {
554*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
555*ec779b8eSAndroid Build Coastguard Worker     }
556*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> keySet;
557*ec779b8eSAndroid Build Coastguard Worker     keySet.appendArray(keySetId->ptr, keySetId->length);
558*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
559*ec779b8eSAndroid Build Coastguard Worker }
560*ec779b8eSAndroid Build Coastguard Worker 
561*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_removeKeys(AMediaDrm * mObj,const AMediaDrmSessionId * keySetId)562*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
563*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
564*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
565*ec779b8eSAndroid Build Coastguard Worker     }
566*ec779b8eSAndroid Build Coastguard Worker     if (!keySetId) {
567*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
568*ec779b8eSAndroid Build Coastguard Worker     }
569*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
570*ec779b8eSAndroid Build Coastguard Worker     status_t status;
571*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *keySetId, iter)) {
572*ec779b8eSAndroid Build Coastguard Worker         Vector<uint8_t> keySet;
573*ec779b8eSAndroid Build Coastguard Worker         keySet.appendArray(keySetId->ptr, keySetId->length);
574*ec779b8eSAndroid Build Coastguard Worker         status = mObj->mDrm->removeKeys(keySet);
575*ec779b8eSAndroid Build Coastguard Worker     } else {
576*ec779b8eSAndroid Build Coastguard Worker         status = mObj->mDrm->removeKeys(*iter);
577*ec779b8eSAndroid Build Coastguard Worker         mObj->mIds.erase(iter);
578*ec779b8eSAndroid Build Coastguard Worker     }
579*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
580*ec779b8eSAndroid Build Coastguard Worker }
581*ec779b8eSAndroid Build Coastguard Worker 
582*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_queryKeyStatus(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,AMediaDrmKeyValue * keyValuePairs,size_t * numPairs)583*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
584*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
585*ec779b8eSAndroid Build Coastguard Worker 
586*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
587*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
588*ec779b8eSAndroid Build Coastguard Worker     }
589*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId || !numPairs) {
590*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
591*ec779b8eSAndroid Build Coastguard Worker     }
592*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
593*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *sessionId, iter)) {
594*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
595*ec779b8eSAndroid Build Coastguard Worker     }
596*ec779b8eSAndroid Build Coastguard Worker 
597*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
598*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
599*ec779b8eSAndroid Build Coastguard Worker         *numPairs = 0;
600*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
601*ec779b8eSAndroid Build Coastguard Worker     }
602*ec779b8eSAndroid Build Coastguard Worker 
603*ec779b8eSAndroid Build Coastguard Worker     if (mObj->mQueryResults.size() > *numPairs) {
604*ec779b8eSAndroid Build Coastguard Worker         *numPairs = mObj->mQueryResults.size();
605*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SHORT_BUFFER;
606*ec779b8eSAndroid Build Coastguard Worker     }
607*ec779b8eSAndroid Build Coastguard Worker 
608*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
609*ec779b8eSAndroid Build Coastguard Worker         keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).c_str();
610*ec779b8eSAndroid Build Coastguard Worker         keyValuePairs[i].mValue = mObj->mQueryResults.valueAt(i).c_str();
611*ec779b8eSAndroid Build Coastguard Worker     }
612*ec779b8eSAndroid Build Coastguard Worker     *numPairs = mObj->mQueryResults.size();
613*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
614*ec779b8eSAndroid Build Coastguard Worker }
615*ec779b8eSAndroid Build Coastguard Worker 
616*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getProvisionRequest(AMediaDrm * mObj,const uint8_t ** provisionRequest,size_t * provisionRequestSize,const char ** serverUrl)617*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
618*ec779b8eSAndroid Build Coastguard Worker         size_t *provisionRequestSize, const char **serverUrl) {
619*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
620*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
621*ec779b8eSAndroid Build Coastguard Worker     }
622*ec779b8eSAndroid Build Coastguard Worker     if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
623*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
624*ec779b8eSAndroid Build Coastguard Worker     }
625*ec779b8eSAndroid Build Coastguard Worker 
626*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""),
627*ec779b8eSAndroid Build Coastguard Worker             mObj->mProvisionRequest, mObj->mProvisionUrl);
628*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
629*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
630*ec779b8eSAndroid Build Coastguard Worker     } else {
631*ec779b8eSAndroid Build Coastguard Worker         *provisionRequest = mObj->mProvisionRequest.array();
632*ec779b8eSAndroid Build Coastguard Worker         *provisionRequestSize = mObj->mProvisionRequest.size();
633*ec779b8eSAndroid Build Coastguard Worker         *serverUrl = mObj->mProvisionUrl.c_str();
634*ec779b8eSAndroid Build Coastguard Worker     }
635*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
636*ec779b8eSAndroid Build Coastguard Worker }
637*ec779b8eSAndroid Build Coastguard Worker 
638*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_provideProvisionResponse(AMediaDrm * mObj,const uint8_t * response,size_t responseSize)639*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
640*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *response, size_t responseSize) {
641*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
642*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
643*ec779b8eSAndroid Build Coastguard Worker     }
644*ec779b8eSAndroid Build Coastguard Worker     if (!response || !responseSize) {
645*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
646*ec779b8eSAndroid Build Coastguard Worker     }
647*ec779b8eSAndroid Build Coastguard Worker 
648*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> mdResponse;
649*ec779b8eSAndroid Build Coastguard Worker     mdResponse.appendArray(response, responseSize);
650*ec779b8eSAndroid Build Coastguard Worker 
651*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> unused;
652*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused));
653*ec779b8eSAndroid Build Coastguard Worker }
654*ec779b8eSAndroid Build Coastguard Worker 
655*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getSecureStops(AMediaDrm * mObj,AMediaDrmSecureStop * secureStops,size_t * numSecureStops)656*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
657*ec779b8eSAndroid Build Coastguard Worker         AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
658*ec779b8eSAndroid Build Coastguard Worker 
659*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
660*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
661*ec779b8eSAndroid Build Coastguard Worker     }
662*ec779b8eSAndroid Build Coastguard Worker     if (!numSecureStops) {
663*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
664*ec779b8eSAndroid Build Coastguard Worker     }
665*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
666*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
667*ec779b8eSAndroid Build Coastguard Worker         *numSecureStops = 0;
668*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
669*ec779b8eSAndroid Build Coastguard Worker     }
670*ec779b8eSAndroid Build Coastguard Worker     if (*numSecureStops < mObj->mSecureStops.size()) {
671*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SHORT_BUFFER;
672*ec779b8eSAndroid Build Coastguard Worker     }
673*ec779b8eSAndroid Build Coastguard Worker     List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
674*ec779b8eSAndroid Build Coastguard Worker     size_t i = 0;
675*ec779b8eSAndroid Build Coastguard Worker     while (iter != mObj->mSecureStops.end()) {
676*ec779b8eSAndroid Build Coastguard Worker         secureStops[i].ptr = iter->array();
677*ec779b8eSAndroid Build Coastguard Worker         secureStops[i].length = iter->size();
678*ec779b8eSAndroid Build Coastguard Worker         ++iter;
679*ec779b8eSAndroid Build Coastguard Worker         ++i;
680*ec779b8eSAndroid Build Coastguard Worker     }
681*ec779b8eSAndroid Build Coastguard Worker     *numSecureStops = mObj->mSecureStops.size();
682*ec779b8eSAndroid Build Coastguard Worker     return AMEDIA_OK;
683*ec779b8eSAndroid Build Coastguard Worker }
684*ec779b8eSAndroid Build Coastguard Worker 
685*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_releaseSecureStops(AMediaDrm * mObj,const AMediaDrmSecureStop * ssRelease)686*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
687*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmSecureStop *ssRelease) {
688*ec779b8eSAndroid Build Coastguard Worker 
689*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
690*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
691*ec779b8eSAndroid Build Coastguard Worker     }
692*ec779b8eSAndroid Build Coastguard Worker     if (!ssRelease) {
693*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
694*ec779b8eSAndroid Build Coastguard Worker     }
695*ec779b8eSAndroid Build Coastguard Worker 
696*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> release;
697*ec779b8eSAndroid Build Coastguard Worker     release.appendArray(ssRelease->ptr, ssRelease->length);
698*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(mObj->mDrm->releaseSecureStops(release));
699*ec779b8eSAndroid Build Coastguard Worker }
700*ec779b8eSAndroid Build Coastguard Worker 
701*ec779b8eSAndroid Build Coastguard Worker 
702*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getPropertyString(AMediaDrm * mObj,const char * propertyName,const char ** propertyValue)703*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
704*ec779b8eSAndroid Build Coastguard Worker         const char **propertyValue) {
705*ec779b8eSAndroid Build Coastguard Worker 
706*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
707*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
708*ec779b8eSAndroid Build Coastguard Worker     }
709*ec779b8eSAndroid Build Coastguard Worker     if (!propertyName || !propertyValue) {
710*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
711*ec779b8eSAndroid Build Coastguard Worker     }
712*ec779b8eSAndroid Build Coastguard Worker 
713*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
714*ec779b8eSAndroid Build Coastguard Worker             mObj->mPropertyString);
715*ec779b8eSAndroid Build Coastguard Worker 
716*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
717*ec779b8eSAndroid Build Coastguard Worker         *propertyValue = mObj->mPropertyString.c_str();
718*ec779b8eSAndroid Build Coastguard Worker     } else {
719*ec779b8eSAndroid Build Coastguard Worker         *propertyValue = NULL;
720*ec779b8eSAndroid Build Coastguard Worker     }
721*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
722*ec779b8eSAndroid Build Coastguard Worker }
723*ec779b8eSAndroid Build Coastguard Worker 
724*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_getPropertyByteArray(AMediaDrm * mObj,const char * propertyName,AMediaDrmByteArray * propertyValue)725*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
726*ec779b8eSAndroid Build Coastguard Worker         const char *propertyName, AMediaDrmByteArray *propertyValue) {
727*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
728*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
729*ec779b8eSAndroid Build Coastguard Worker     }
730*ec779b8eSAndroid Build Coastguard Worker     if (!propertyName || !propertyValue) {
731*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
732*ec779b8eSAndroid Build Coastguard Worker     }
733*ec779b8eSAndroid Build Coastguard Worker 
734*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
735*ec779b8eSAndroid Build Coastguard Worker             mObj->mPropertyByteArray);
736*ec779b8eSAndroid Build Coastguard Worker 
737*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
738*ec779b8eSAndroid Build Coastguard Worker         propertyValue->ptr = mObj->mPropertyByteArray.array();
739*ec779b8eSAndroid Build Coastguard Worker         propertyValue->length = mObj->mPropertyByteArray.size();
740*ec779b8eSAndroid Build Coastguard Worker     } else {
741*ec779b8eSAndroid Build Coastguard Worker         propertyValue->ptr = NULL;
742*ec779b8eSAndroid Build Coastguard Worker         propertyValue->length = 0;
743*ec779b8eSAndroid Build Coastguard Worker     }
744*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
745*ec779b8eSAndroid Build Coastguard Worker }
746*ec779b8eSAndroid Build Coastguard Worker 
747*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_setPropertyString(AMediaDrm * mObj,const char * propertyName,const char * value)748*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj,
749*ec779b8eSAndroid Build Coastguard Worker         const char *propertyName, const char *value) {
750*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
751*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
752*ec779b8eSAndroid Build Coastguard Worker     }
753*ec779b8eSAndroid Build Coastguard Worker 
754*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName),
755*ec779b8eSAndroid Build Coastguard Worker                     String8(value)));
756*ec779b8eSAndroid Build Coastguard Worker }
757*ec779b8eSAndroid Build Coastguard Worker 
758*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_setPropertyByteArray(AMediaDrm * mObj,const char * propertyName,const uint8_t * value,size_t valueSize)759*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
760*ec779b8eSAndroid Build Coastguard Worker         const char *propertyName, const uint8_t *value, size_t valueSize) {
761*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
762*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
763*ec779b8eSAndroid Build Coastguard Worker     }
764*ec779b8eSAndroid Build Coastguard Worker 
765*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> byteArray;
766*ec779b8eSAndroid Build Coastguard Worker     byteArray.appendArray(value, valueSize);
767*ec779b8eSAndroid Build Coastguard Worker 
768*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(mObj->mDrm->setPropertyByteArray(String8(propertyName),
769*ec779b8eSAndroid Build Coastguard Worker                     byteArray));
770*ec779b8eSAndroid Build Coastguard Worker }
771*ec779b8eSAndroid Build Coastguard Worker 
772*ec779b8eSAndroid Build Coastguard Worker 
encrypt_decrypt_common(AMediaDrm * mObj,const AMediaDrmSessionId & sessionId,const char * cipherAlgorithm,uint8_t * keyId,uint8_t * iv,const uint8_t * input,uint8_t * output,size_t dataSize,bool encrypt)773*ec779b8eSAndroid Build Coastguard Worker static media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
774*ec779b8eSAndroid Build Coastguard Worker         const AMediaDrmSessionId &sessionId,
775*ec779b8eSAndroid Build Coastguard Worker         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
776*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) {
777*ec779b8eSAndroid Build Coastguard Worker 
778*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
779*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
780*ec779b8eSAndroid Build Coastguard Worker     }
781*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
782*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, sessionId, iter)) {
783*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
784*ec779b8eSAndroid Build Coastguard Worker     }
785*ec779b8eSAndroid Build Coastguard Worker 
786*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm));
787*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
788*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
789*ec779b8eSAndroid Build Coastguard Worker     }
790*ec779b8eSAndroid Build Coastguard Worker 
791*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> keyIdVec;
792*ec779b8eSAndroid Build Coastguard Worker     const size_t kKeyIdSize = 16;
793*ec779b8eSAndroid Build Coastguard Worker     keyIdVec.appendArray(keyId, kKeyIdSize);
794*ec779b8eSAndroid Build Coastguard Worker 
795*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> inputVec;
796*ec779b8eSAndroid Build Coastguard Worker     inputVec.appendArray(input, dataSize);
797*ec779b8eSAndroid Build Coastguard Worker 
798*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> ivVec;
799*ec779b8eSAndroid Build Coastguard Worker     const size_t kIvSize = 16;
800*ec779b8eSAndroid Build Coastguard Worker     ivVec.appendArray(iv, kIvSize);
801*ec779b8eSAndroid Build Coastguard Worker 
802*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> outputVec;
803*ec779b8eSAndroid Build Coastguard Worker     if (encrypt) {
804*ec779b8eSAndroid Build Coastguard Worker         status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
805*ec779b8eSAndroid Build Coastguard Worker     } else {
806*ec779b8eSAndroid Build Coastguard Worker         status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
807*ec779b8eSAndroid Build Coastguard Worker     }
808*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
809*ec779b8eSAndroid Build Coastguard Worker         memcpy(output, outputVec.array(), outputVec.size());
810*ec779b8eSAndroid Build Coastguard Worker     }
811*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
812*ec779b8eSAndroid Build Coastguard Worker }
813*ec779b8eSAndroid Build Coastguard Worker 
814*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_encrypt(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,const char * cipherAlgorithm,uint8_t * keyId,uint8_t * iv,const uint8_t * input,uint8_t * output,size_t dataSize)815*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
816*ec779b8eSAndroid Build Coastguard Worker         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
817*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *input, uint8_t *output, size_t dataSize) {
818*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
819*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
820*ec779b8eSAndroid Build Coastguard Worker     }
821*ec779b8eSAndroid Build Coastguard Worker     return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
822*ec779b8eSAndroid Build Coastguard Worker             input, output, dataSize, true);
823*ec779b8eSAndroid Build Coastguard Worker }
824*ec779b8eSAndroid Build Coastguard Worker 
825*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_decrypt(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,const char * cipherAlgorithm,uint8_t * keyId,uint8_t * iv,const uint8_t * input,uint8_t * output,size_t dataSize)826*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
827*ec779b8eSAndroid Build Coastguard Worker         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
828*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *input, uint8_t *output, size_t dataSize) {
829*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
830*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
831*ec779b8eSAndroid Build Coastguard Worker     }
832*ec779b8eSAndroid Build Coastguard Worker     return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
833*ec779b8eSAndroid Build Coastguard Worker             input, output, dataSize, false);
834*ec779b8eSAndroid Build Coastguard Worker }
835*ec779b8eSAndroid Build Coastguard Worker 
836*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_sign(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,const char * macAlgorithm,uint8_t * keyId,uint8_t * message,size_t messageSize,uint8_t * signature,size_t * signatureSize)837*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
838*ec779b8eSAndroid Build Coastguard Worker         const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
839*ec779b8eSAndroid Build Coastguard Worker         uint8_t *signature, size_t *signatureSize) {
840*ec779b8eSAndroid Build Coastguard Worker 
841*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
842*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
843*ec779b8eSAndroid Build Coastguard Worker     }
844*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
845*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
846*ec779b8eSAndroid Build Coastguard Worker     }
847*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
848*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *sessionId, iter)) {
849*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
850*ec779b8eSAndroid Build Coastguard Worker     }
851*ec779b8eSAndroid Build Coastguard Worker 
852*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
853*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
854*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
855*ec779b8eSAndroid Build Coastguard Worker     }
856*ec779b8eSAndroid Build Coastguard Worker 
857*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> keyIdVec;
858*ec779b8eSAndroid Build Coastguard Worker     const size_t kKeyIdSize = 16;
859*ec779b8eSAndroid Build Coastguard Worker     keyIdVec.appendArray(keyId, kKeyIdSize);
860*ec779b8eSAndroid Build Coastguard Worker 
861*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> messageVec;
862*ec779b8eSAndroid Build Coastguard Worker     messageVec.appendArray(message, messageSize);
863*ec779b8eSAndroid Build Coastguard Worker 
864*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> signatureVec;
865*ec779b8eSAndroid Build Coastguard Worker     status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec);
866*ec779b8eSAndroid Build Coastguard Worker     if (signatureVec.size() > *signatureSize) {
867*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SHORT_BUFFER;
868*ec779b8eSAndroid Build Coastguard Worker     }
869*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
870*ec779b8eSAndroid Build Coastguard Worker         memcpy(signature, signatureVec.array(), signatureVec.size());
871*ec779b8eSAndroid Build Coastguard Worker     }
872*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
873*ec779b8eSAndroid Build Coastguard Worker }
874*ec779b8eSAndroid Build Coastguard Worker 
875*ec779b8eSAndroid Build Coastguard Worker EXPORT
AMediaDrm_verify(AMediaDrm * mObj,const AMediaDrmSessionId * sessionId,const char * macAlgorithm,uint8_t * keyId,const uint8_t * message,size_t messageSize,const uint8_t * signature,size_t signatureSize)876*ec779b8eSAndroid Build Coastguard Worker media_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
877*ec779b8eSAndroid Build Coastguard Worker         const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
878*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *signature, size_t signatureSize) {
879*ec779b8eSAndroid Build Coastguard Worker 
880*ec779b8eSAndroid Build Coastguard Worker     if (!mObj || mObj->mDrm == NULL) {
881*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_OBJECT;
882*ec779b8eSAndroid Build Coastguard Worker     }
883*ec779b8eSAndroid Build Coastguard Worker     if (!sessionId) {
884*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_ERROR_INVALID_PARAMETER;
885*ec779b8eSAndroid Build Coastguard Worker     }
886*ec779b8eSAndroid Build Coastguard Worker     List<idvec_t>::iterator iter;
887*ec779b8eSAndroid Build Coastguard Worker     if (!findId(mObj, *sessionId, iter)) {
888*ec779b8eSAndroid Build Coastguard Worker         return AMEDIA_DRM_SESSION_NOT_OPENED;
889*ec779b8eSAndroid Build Coastguard Worker     }
890*ec779b8eSAndroid Build Coastguard Worker 
891*ec779b8eSAndroid Build Coastguard Worker     status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
892*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
893*ec779b8eSAndroid Build Coastguard Worker         return translateStatus(status);
894*ec779b8eSAndroid Build Coastguard Worker     }
895*ec779b8eSAndroid Build Coastguard Worker 
896*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> keyIdVec;
897*ec779b8eSAndroid Build Coastguard Worker     const size_t kKeyIdSize = 16;
898*ec779b8eSAndroid Build Coastguard Worker     keyIdVec.appendArray(keyId, kKeyIdSize);
899*ec779b8eSAndroid Build Coastguard Worker 
900*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> messageVec;
901*ec779b8eSAndroid Build Coastguard Worker     messageVec.appendArray(message, messageSize);
902*ec779b8eSAndroid Build Coastguard Worker 
903*ec779b8eSAndroid Build Coastguard Worker     Vector<uint8_t> signatureVec;
904*ec779b8eSAndroid Build Coastguard Worker     signatureVec.appendArray(signature, signatureSize);
905*ec779b8eSAndroid Build Coastguard Worker 
906*ec779b8eSAndroid Build Coastguard Worker     bool match;
907*ec779b8eSAndroid Build Coastguard Worker     status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match);
908*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
909*ec779b8eSAndroid Build Coastguard Worker         return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED;
910*ec779b8eSAndroid Build Coastguard Worker     }
911*ec779b8eSAndroid Build Coastguard Worker     return translateStatus(status);
912*ec779b8eSAndroid Build Coastguard Worker }
913*ec779b8eSAndroid Build Coastguard Worker 
914*ec779b8eSAndroid Build Coastguard Worker } // extern "C"
915