1497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker/*
2497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Copyright (C) 2014 The Android Open Source Project
3497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker *
4497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
5497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * you may not use this file except in compliance with the License.
6497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * You may obtain a copy of the License at
7497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker *
8497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
9497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker *
10497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Unless required by applicable law or agreed to in writing, software
11497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
12497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * See the License for the specific language governing permissions and
14497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * limitations under the License.
15497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker */
16497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
17c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260Marco Nelissen//#define LOG_NDEBUG 0
18497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#define LOG_TAG "NdkMediaDrm"
19497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
20497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include "NdkMediaDrm.h"
21497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
22497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/Log.h>
23497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/StrongPointer.h>
24497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <gui/Surface.h>
25497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
26497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrm.h>
27497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrmClient.h>
28497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/stagefright/MediaErrors.h>
29497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <binder/IServiceManager.h>
30497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IMediaPlayerService.h>
31497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <ndk/NdkMediaCrypto.h>
32497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
33497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
34497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerusing namespace android;
35497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
36497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkertypedef Vector<uint8_t> idvec_t;
37497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
383305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerstruct DrmListener: virtual public BnDrmClient
393305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker{
403305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerprivate:
413305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrm *mObj;
423305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmEventListener mListener;
433305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
443305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerpublic:
453305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj), mListener(listener) {}
463305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj);
473305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker};
483305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
49497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstruct AMediaDrm {
50497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> mDrm;
51497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrmClient> mDrmClient;
52497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t> mIds;
53497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    KeyedVector<String8, String8> mQueryResults;
54497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mKeyRequest;
55497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mProvisionRequest;
56497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mProvisionUrl;
57497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mPropertyString;
58497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mPropertyByteArray;
59497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<Vector<uint8_t> > mSecureStops;
603305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    sp<DrmListener> mListener;
61497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker};
62497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
633305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkervoid DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
643305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (!mListener) {
653305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        return;
663305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
673305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
683305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmSessionId sessionId = {NULL, 0};
693305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    int32_t sessionIdSize = obj->readInt32();
703305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (sessionIdSize) {
713305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        uint8_t *sessionIdData = new uint8_t[sessionIdSize];
723305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        sessionId.ptr = sessionIdData;
733305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        sessionId.length = sessionIdSize;
743305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        obj->read(sessionIdData, sessionId.length);
753305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
763305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
773305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    int32_t dataSize = obj->readInt32();
783305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    uint8_t *data = NULL;
793305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (dataSize) {
803305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        data = new uint8_t[dataSize];
813305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        obj->read(data, dataSize);
823305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
833305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
843305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    // translate DrmPlugin event types into their NDK equivalents
853305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmEventType ndkEventType;
863305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    switch(eventType) {
873305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventProvisionRequired:
883305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_PROVISION_REQUIRED;
893305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
903305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyNeeded:
913305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_KEY_REQUIRED;
923305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
933305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyExpired:
943305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_KEY_EXPIRED;
953305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
963305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventVendorDefined:
973305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_VENDOR_DEFINED;
983305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
993305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        default:
1003305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
1013305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            return;
1023305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
1033305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
10418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
1053305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
1063305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] sessionId.ptr;
1073305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] data;
1083305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker}
1093305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
1103305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
111497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerextern "C" {
112497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
113e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translateStatus(status_t status) {
114e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    media_status_t result = AMEDIA_ERROR_UNKNOWN;
115497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (status) {
116497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case OK:
117e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_OK;
118497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
119497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NOT_PROVISIONED:
120e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NOT_PROVISIONED;
121497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
122497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_RESOURCE_BUSY:
123e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_RESOURCE_BUSY;
124497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
125497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_DEVICE_REVOKED:
126e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_DEVICE_REVOKED;
127497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
128497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_CANNOT_HANDLE:
129e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_ERROR_INVALID_PARAMETER;
130497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
131497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_TAMPER_DETECTED:
132e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_TAMPER_DETECTED;
133497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
134497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_SESSION_NOT_OPENED:
135e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_SESSION_NOT_OPENED;
136497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
137497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NO_LICENSE:
138e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NEED_KEY;
139497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
140497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_LICENSE_EXPIRED:
141e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_LICENSE_EXPIRED;
142497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
143497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
144497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
145497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
146497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return result;
147497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
148497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
149497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrm() {
150497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
151497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
152497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IBinder> binder =
153497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        sm->getService(String16("media.player"));
154497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
155497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IMediaPlayerService> service =
156497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        interface_cast<IMediaPlayerService>(binder);
157497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
158497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (service == NULL) {
159497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
160497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
161497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
162497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = service->makeDrm();
163497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
164497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
165497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
166497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
167497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
168497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
169497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
170497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
171497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
172497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) {
173497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
174497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
175497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
176497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
177497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
178497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
179497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t err = drm->createPlugin(uuid);
180497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
181497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (err != OK) {
182497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
183497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
184497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
185497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
186497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
187497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1883425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
189497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerbool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) {
190497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
191497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
192497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
193497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return false;
194497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
195497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
196497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mimeStr = mimeType ? String8(mimeType) : String8("");
197497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm->isCryptoSchemeSupported(uuid, mimeStr);
198497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
199497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2003425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
201497ca097bf373ac69405131bd257915c97b31dc0Jeff TinkerAMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
202497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    AMediaDrm *mObj = new AMediaDrm();
203497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm = CreateDrmFromUUID(uuid);
204497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return mObj;
205497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
206497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2073425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
208497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_release(AMediaDrm *mObj) {
209497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (mObj->mDrm != NULL) {
210497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->setListener(NULL);
211497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->destroyPlugin();
212497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm.clear();
213497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
214497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    delete mObj;
215497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
216497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2173305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff TinkerEXPORT
2187c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissenmedia_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) {
2193305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
2207c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
2213305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
2223305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mListener = new DrmListener(mObj, listener);
2233305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mDrm->setListener(mObj->mListener);
2247c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen    return AMEDIA_OK;
225497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
226497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
227497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
228497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
229497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    iter = mObj->mIds.begin();
230497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    while (iter != mObj->mIds.end()) {
231497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        if (iter->array() == id.ptr && iter->size() == id.length) {
232497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            return true;
233497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        }
234497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
235497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return false;
236497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
237497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2383425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
23918a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
240497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
241e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
242497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
24318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
24418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
24518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
246497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> session;
247497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->openSession(session);
248497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
249497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(session);
250497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
25118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->ptr = iter->array();
25218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->length = iter->size();
253497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
254e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
255497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
256497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2573425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
25818a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
259497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
260e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
261497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
26218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
26318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
26418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
265497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
266497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
26718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
268e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
269497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
270497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm->closeSession(*iter);
271497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mIds.erase(iter);
272e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
273497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
274497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2753425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
27618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
277497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
278497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
27918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t **keyRequest, size_t *keyRequestSize) {
280497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
281497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
282e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
283497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
28418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
285e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
286497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
287497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
288497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
28918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
290e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
291497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
292497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
293497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdInit;
294497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdInit.appendArray(init, initSize);
295497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    DrmPlugin::KeyType mdKeyType;
296497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (keyType) {
297497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_STREAMING:
298497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Streaming;
299497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
300497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_OFFLINE:
301497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Offline;
302497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
303497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_RELEASE:
304497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Release;
305497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
306497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
307e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            return AMEDIA_ERROR_INVALID_PARAMETER;
308497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
309497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    KeyedVector<String8, String8> mdOptionalParameters;
310497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < numOptionalParameters; i++) {
311497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mdOptionalParameters.add(String8(optionalParameters[i].mKey),
312497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                String8(optionalParameters[i].mValue));
313497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
314497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 defaultUrl;
315d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker    DrmPlugin::KeyRequestType keyRequestType;
316497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
317d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl,
318d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            &keyRequestType);
319497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
320497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
321497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
32218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequest = mObj->mKeyRequest.array();
32318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequestSize = mObj->mKeyRequest.size();
324497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
325e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
326497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
327497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3283425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
32918a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
33018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
331497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
332497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
333e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
334497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
33518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!scope || !response || !responseSize || !keySetId) {
336e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
337497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
338497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
339497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
34018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
341e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
342497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
343497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
344497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
345497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
346497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdKeySetId;
347497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId);
348497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
349497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(mdKeySetId);
350497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
35118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = iter->array();
35218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = iter->size();
353497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
35418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = NULL;
35518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = 0;
356497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
357e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
358497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
359497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3603425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
36118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
36218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmKeySetId *keySetId) {
363497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
364497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
365e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
366497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
36718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !keySetId) {
36818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
36918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
370497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
37118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
372e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
373497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
374497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keySet;
37518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    keySet.appendArray(keySetId->ptr, keySetId->length);
376497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
377497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
378497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3793425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
38018a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
381497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
382e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
383497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
38418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!keySetId) {
38518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
38618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
387497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
388497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status;
38918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *keySetId, iter)) {
390497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        Vector<uint8_t> keySet;
39118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySet.appendArray(keySetId->ptr, keySetId->length);
392497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(keySet);
393497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
394497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(*iter);
395497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.erase(iter);
396497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
397497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
398497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
399497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4003425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
40118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
40218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
403497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
404497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
405e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
406497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
40718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !numPairs) {
40818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
40918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
410497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
41118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
412e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
413497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
414497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
415497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
416497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
41718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = 0;
418497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
419497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
420497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
42118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (mObj->mQueryResults.size() > *numPairs) {
42218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = mObj->mQueryResults.size();
423e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
424497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
425497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
426497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
427497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
428497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string();
429497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
43018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numPairs = mObj->mQueryResults.size();
431e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
432497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
433497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4343425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
43518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
43618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        size_t *provisionRequestSize, const char **serverUrl) {
437497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
438e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
439497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
44018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
441e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
442497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
443497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
444497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""),
445497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mProvisionRequest, mObj->mProvisionUrl);
446497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
447497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
448497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
44918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequest = mObj->mProvisionRequest.array();
45018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequestSize = mObj->mProvisionRequest.size();
45118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *serverUrl = mObj->mProvisionUrl.string();
452497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
453e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
454497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
455497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4563425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
457e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
458497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *response, size_t responseSize) {
459497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
460e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
461497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
462497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!response || !responseSize) {
463e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
464497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
465497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
466497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
467497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
468497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
469497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> unused;
470497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused));
471497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
472497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4733425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
474e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
47518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
476497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
477497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
478e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
479497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
48018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!numSecureStops) {
48118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
48218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
483497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
484497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
48518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numSecureStops = 0;
486497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
487497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
48818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (*numSecureStops < mObj->mSecureStops.size()) {
489e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
490497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
491497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
492497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    size_t i = 0;
493497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    while (iter != mObj->mSecureStops.end()) {
494497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].ptr = iter->array();
495497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].length = iter->size();
496497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++iter;
497497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++i;
498497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
49918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numSecureStops = mObj->mSecureStops.size();
500e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
501497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
502497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5033425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
504e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
50518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmSecureStop *ssRelease) {
506497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
507497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
508e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
509497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
51018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!ssRelease) {
51118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
51218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
513497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
514497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> release;
51518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    release.appendArray(ssRelease->ptr, ssRelease->length);
516497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->releaseSecureStops(release));
517497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
518497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
519497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5203425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
521e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
52218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char **propertyValue) {
523497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
524497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
525e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
526497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
52718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
52818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
52918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
530497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
531497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
532497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyString);
533497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
534497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
53518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = mObj->mPropertyString.string();
536497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
53718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = NULL;
538497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
539497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
540497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
541497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5423425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
543e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
54418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char *propertyName, AMediaDrmByteArray *propertyValue) {
545497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
546e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
547497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
54818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
54918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
55018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
551497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
552497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
553497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyByteArray);
554497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
555497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
55618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = mObj->mPropertyByteArray.array();
55718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = mObj->mPropertyByteArray.size();
558497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
55918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = NULL;
56018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = 0;
561497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
562497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
563497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
564497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5653425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
566e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj,
567497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const char *value) {
568497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
569e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
570497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
571497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
572497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName),
573497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    String8(value)));
574497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
575497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5763425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
577e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
578497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const uint8_t *value, size_t valueSize) {
579497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
580497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> byteArray;
581497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    byteArray.appendArray(value, valueSize);
582497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
583497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName),
584497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    byteArray));
585497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
586497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
587497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
588e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
589497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmSessionId &sessionId,
590497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
591497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) {
592497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
593497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
594e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
595497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
596497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
597497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!findId(mObj, sessionId, iter)) {
598e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
599497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
600497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
601497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm));
602497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
603497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
604497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
605497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
606497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
607497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
608497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
609497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
610497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> inputVec;
611497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    inputVec.appendArray(input, dataSize);
612497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
613497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> ivVec;
614497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kIvSize = 16;
615497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    ivVec.appendArray(iv, kIvSize);
616497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
617497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> outputVec;
618497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (encrypt) {
619497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status_t status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
620497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
621497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status_t status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
622497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
623497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
624497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(output, outputVec.array(), outputVec.size());
625497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
626497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
627497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
628497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6293425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
63018a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
631497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
632497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
63318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
63418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
63518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
63618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
637497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, true);
638497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
639497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6403425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
64118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
642497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
643497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
64418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
64518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
64618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
64718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
648497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, false);
649497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
650497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6513425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
65218a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
653497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
654497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        uint8_t *signature, size_t *signatureSize) {
655497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
656497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
657e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
658497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
65918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
66018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
66118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
662497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
66318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
664e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
665497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
666497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
667497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
668497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
669497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
670497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
671497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
672497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
673497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
674497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
675497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
676497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
677497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
678497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
679497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
680497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec);
681497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (signatureVec.size() > *signatureSize) {
682e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
683497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
684497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
685497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(signature, signatureVec.array(), signatureVec.size());
686497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
687497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
688497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
689497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6903425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
69118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
692497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
693497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *signature, size_t signatureSize) {
694497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
695497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
696e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
697497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
69818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
69918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
70018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
701497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
70218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
703e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
704497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
705497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
706497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
707497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
708497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
709497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
710497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
711497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
712497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
713497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
714497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
715497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
716497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
717497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
718497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
719497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    signatureVec.appendArray(signature, signatureSize);
720497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
721497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    bool match;
722497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match);
723497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
724e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED;
725497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
726497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
727497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
728497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
729497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} // extern "C"
730