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
22a69729dc76b97c44387088d351480d5d0701517eJeff Tinker#include <cutils/properties.h>
23497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/Log.h>
24497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/StrongPointer.h>
25497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <gui/Surface.h>
26497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
27497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrm.h>
28497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrmClient.h>
29497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/stagefright/MediaErrors.h>
30497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <binder/IServiceManager.h>
31a69729dc76b97c44387088d351480d5d0701517eJeff Tinker#include <media/IMediaDrmService.h>
32497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <ndk/NdkMediaCrypto.h>
33497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
34497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
35497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerusing namespace android;
36497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
37497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkertypedef Vector<uint8_t> idvec_t;
38497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
393305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerstruct DrmListener: virtual public BnDrmClient
403305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker{
413305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerprivate:
423305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrm *mObj;
433305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmEventListener mListener;
443305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
453305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerpublic:
463305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj), mListener(listener) {}
473305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj);
483305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker};
493305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
50497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstruct AMediaDrm {
51497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> mDrm;
52497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrmClient> mDrmClient;
53497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t> mIds;
54497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    KeyedVector<String8, String8> mQueryResults;
55497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mKeyRequest;
56497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mProvisionRequest;
57497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mProvisionUrl;
58497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mPropertyString;
59497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mPropertyByteArray;
60497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<Vector<uint8_t> > mSecureStops;
613305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    sp<DrmListener> mListener;
62497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker};
63497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
643305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkervoid DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
653305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (!mListener) {
663305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        return;
673305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
683305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
693305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmSessionId sessionId = {NULL, 0};
703305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    int32_t sessionIdSize = obj->readInt32();
713305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (sessionIdSize) {
723305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        uint8_t *sessionIdData = new uint8_t[sessionIdSize];
733305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        sessionId.ptr = sessionIdData;
743305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        sessionId.length = sessionIdSize;
753305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        obj->read(sessionIdData, sessionId.length);
763305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
773305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
783305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    int32_t dataSize = obj->readInt32();
793305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    uint8_t *data = NULL;
803305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (dataSize) {
813305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        data = new uint8_t[dataSize];
823305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        obj->read(data, dataSize);
833305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
843305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
853305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    // translate DrmPlugin event types into their NDK equivalents
863305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    AMediaDrmEventType ndkEventType;
873305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    switch(eventType) {
883305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventProvisionRequired:
893305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_PROVISION_REQUIRED;
903305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
913305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyNeeded:
923305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_KEY_REQUIRED;
933305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
943305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyExpired:
953305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_KEY_EXPIRED;
963305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
973305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        case DrmPlugin::kDrmPluginEventVendorDefined:
983305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ndkEventType = EVENT_VENDOR_DEFINED;
993305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            break;
1003305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker        default:
1013305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
1023305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker            return;
1033305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
1043305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
10518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
1063305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
1073305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] sessionId.ptr;
1083305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] data;
1093305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker}
1103305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
1113305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
112497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerextern "C" {
113497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
114e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translateStatus(status_t status) {
115e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    media_status_t result = AMEDIA_ERROR_UNKNOWN;
116497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (status) {
117497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case OK:
118e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_OK;
119497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
120497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NOT_PROVISIONED:
121e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NOT_PROVISIONED;
122497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
123497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_RESOURCE_BUSY:
124e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_RESOURCE_BUSY;
125497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
126497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_DEVICE_REVOKED:
127e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_DEVICE_REVOKED;
128497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
129497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_CANNOT_HANDLE:
130e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_ERROR_INVALID_PARAMETER;
131497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
132497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_TAMPER_DETECTED:
133e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_TAMPER_DETECTED;
134497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
135497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_SESSION_NOT_OPENED:
136e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_SESSION_NOT_OPENED;
137497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
138497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NO_LICENSE:
139e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NEED_KEY;
140497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
141497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_LICENSE_EXPIRED:
142e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_LICENSE_EXPIRED;
143497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
144497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
145497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
146497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
147497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return result;
148497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
149497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
150497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrm() {
151497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
1523003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IBinder> binder = sm->getService(String16("media.drm"));
1533003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker
1543003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
1553003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    if (service == NULL) {
1563003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker        return NULL;
157497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
158497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1593003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IDrm> drm = service->makeDrm();
160497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
161497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
162497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
163497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
164497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
165497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
166497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
167497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) {
168497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
169497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
170497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
171497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
172497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
173497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
174497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t err = drm->createPlugin(uuid);
175497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
176497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (err != OK) {
177497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
178497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
179497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
180497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
181497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
182497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1833425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
184497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerbool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) {
185497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
186497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
187497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
188497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return false;
189497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
190497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
191497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mimeStr = mimeType ? String8(mimeType) : String8("");
192497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm->isCryptoSchemeSupported(uuid, mimeStr);
193497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
194497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1953425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
196497ca097bf373ac69405131bd257915c97b31dc0Jeff TinkerAMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
197497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    AMediaDrm *mObj = new AMediaDrm();
198497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm = CreateDrmFromUUID(uuid);
199497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return mObj;
200497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
201497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2023425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
203497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_release(AMediaDrm *mObj) {
204497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (mObj->mDrm != NULL) {
205497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->setListener(NULL);
206497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->destroyPlugin();
207497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm.clear();
208497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
209497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    delete mObj;
210497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
211497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2123305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff TinkerEXPORT
2137c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissenmedia_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) {
2143305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
2157c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
2163305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
2173305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mListener = new DrmListener(mObj, listener);
2183305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mDrm->setListener(mObj->mListener);
2197c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen    return AMEDIA_OK;
220497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
221497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
222497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
223497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
224497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    iter = mObj->mIds.begin();
225497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    while (iter != mObj->mIds.end()) {
226497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        if (iter->array() == id.ptr && iter->size() == id.length) {
227497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            return true;
228497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        }
229497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
230497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return false;
231497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
232497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2333425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
23418a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
235497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
236e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
237497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
23818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
23918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
24018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
241497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> session;
242497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->openSession(session);
243497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
244497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(session);
245497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
24618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->ptr = iter->array();
24718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->length = iter->size();
248497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
249e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
250497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
251497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2523425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
25318a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
254497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
255e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
256497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
25718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
25818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
25918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
260497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
261497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
26218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
263e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
264497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
265497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm->closeSession(*iter);
266497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mIds.erase(iter);
267e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
268497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
269497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2703425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
27118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
272497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
273497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
27418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t **keyRequest, size_t *keyRequestSize) {
275497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
276497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
277e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
278497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
27918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
280e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
281497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
282497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
283497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
28418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
285e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
286497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
287497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
288497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdInit;
289497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdInit.appendArray(init, initSize);
290497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    DrmPlugin::KeyType mdKeyType;
291497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (keyType) {
292497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_STREAMING:
293497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Streaming;
294497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
295497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_OFFLINE:
296497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Offline;
297497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
298497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_RELEASE:
299497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Release;
300497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
301497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
302e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            return AMEDIA_ERROR_INVALID_PARAMETER;
303497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
304497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    KeyedVector<String8, String8> mdOptionalParameters;
305497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < numOptionalParameters; i++) {
306497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mdOptionalParameters.add(String8(optionalParameters[i].mKey),
307497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                String8(optionalParameters[i].mValue));
308497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
309497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 defaultUrl;
310d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker    DrmPlugin::KeyRequestType keyRequestType;
311497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
312d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl,
313d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            &keyRequestType);
314497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
315497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
316497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
31718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequest = mObj->mKeyRequest.array();
31818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequestSize = mObj->mKeyRequest.size();
319497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
320e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
321497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
322497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3233425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
32418a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
32518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
326497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
327497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
328e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
329497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
33018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!scope || !response || !responseSize || !keySetId) {
331e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
332497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
333497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
334497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
33518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
336e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
337497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
338497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
339497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
340497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
341497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdKeySetId;
342497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId);
343497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
344497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(mdKeySetId);
345497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
34618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = iter->array();
34718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = iter->size();
348497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
34918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = NULL;
35018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = 0;
351497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
352e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
353497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
354497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3553425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
35618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
35718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmKeySetId *keySetId) {
358497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
359497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
360e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
361497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
36218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !keySetId) {
36318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
36418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
365497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
36618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
367e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
368497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
369497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keySet;
37018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    keySet.appendArray(keySetId->ptr, keySetId->length);
371497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
372497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
373497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3743425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
37518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
376497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
377e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
378497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
37918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!keySetId) {
38018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
38118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
382497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
383497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status;
38418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *keySetId, iter)) {
385497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        Vector<uint8_t> keySet;
38618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySet.appendArray(keySetId->ptr, keySetId->length);
387497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(keySet);
388497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
389497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(*iter);
390497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.erase(iter);
391497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
392497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
393497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
394497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3953425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
39618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
39718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
398497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
399497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
400e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
401497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
40218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !numPairs) {
40318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
40418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
405497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
40618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
407e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
408497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
409497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
410497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
411497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
41218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = 0;
413497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
414497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
415497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
41618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (mObj->mQueryResults.size() > *numPairs) {
41718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = mObj->mQueryResults.size();
418e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
419497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
420497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
421497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
422497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
423497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string();
424497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
42518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numPairs = mObj->mQueryResults.size();
426e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
427497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
428497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4293425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
43018a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
43118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        size_t *provisionRequestSize, const char **serverUrl) {
432497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
433e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
434497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
43518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
436e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
437497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
438497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
439497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""),
440497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mProvisionRequest, mObj->mProvisionUrl);
441497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
442497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
443497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
44418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequest = mObj->mProvisionRequest.array();
44518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequestSize = mObj->mProvisionRequest.size();
44618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *serverUrl = mObj->mProvisionUrl.string();
447497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
448e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
449497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
450497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4513425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
452e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
453497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *response, size_t responseSize) {
454497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
455e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
456497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
457497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!response || !responseSize) {
458e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
459497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
460497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
461497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
462497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
463497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
464497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> unused;
465497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused));
466497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
467497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4683425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
469e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
47018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
471497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
472497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
473e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
474497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
47518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!numSecureStops) {
47618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
47718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
478497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
479497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
48018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numSecureStops = 0;
481497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
482497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
48318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (*numSecureStops < mObj->mSecureStops.size()) {
484e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
485497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
486497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
487497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    size_t i = 0;
488497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    while (iter != mObj->mSecureStops.end()) {
489497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].ptr = iter->array();
490497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].length = iter->size();
491497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++iter;
492497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++i;
493497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
49418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numSecureStops = mObj->mSecureStops.size();
495e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
496497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
497497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4983425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
499e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
50018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmSecureStop *ssRelease) {
501497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
502497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
503e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
504497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
50518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!ssRelease) {
50618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
50718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
508497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
509497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> release;
51018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    release.appendArray(ssRelease->ptr, ssRelease->length);
511497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->releaseSecureStops(release));
512497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
513497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
514497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5153425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
516e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
51718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char **propertyValue) {
518497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
519497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
520e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
521497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
52218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
52318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
52418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
525497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
526497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
527497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyString);
528497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
529497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
53018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = mObj->mPropertyString.string();
531497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
53218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = NULL;
533497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
534497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
535497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
536497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5373425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
538e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
53918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char *propertyName, AMediaDrmByteArray *propertyValue) {
540497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
541e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
542497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
54318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
54418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
54518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
546497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
547497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
548497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyByteArray);
549497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
550497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
55118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = mObj->mPropertyByteArray.array();
55218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = mObj->mPropertyByteArray.size();
553497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
55418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = NULL;
55518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = 0;
556497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
557497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
558497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
559497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5603425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
561e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj,
562497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const char *value) {
563497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
564e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
565497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
566497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
567497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName),
568497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    String8(value)));
569497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
570497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5713425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
572e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
573497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const uint8_t *value, size_t valueSize) {
574497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
575497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> byteArray;
576497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    byteArray.appendArray(value, valueSize);
577497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
578497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName),
579497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    byteArray));
580497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
581497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
582497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
583e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
584497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmSessionId &sessionId,
585497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
586497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) {
587497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
588497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
589e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
590497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
591497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
592497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!findId(mObj, sessionId, iter)) {
593e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
594497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
595497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
596497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm));
597497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
598497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
599497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
600497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
601497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
602497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
603497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
604497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
605497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> inputVec;
606497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    inputVec.appendArray(input, dataSize);
607497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
608497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> ivVec;
609497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kIvSize = 16;
610497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    ivVec.appendArray(iv, kIvSize);
611497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
612497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> outputVec;
613497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (encrypt) {
614214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas        status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
615497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
616214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas        status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
617497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
618497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
619497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(output, outputVec.array(), outputVec.size());
620497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
621497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
622497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
623497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6243425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
62518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
626497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
627497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
62818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
62918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
63018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
63118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
632497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, true);
633497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
634497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6353425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
63618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
637497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
638497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
63918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
64018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
64118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
64218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
643497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, false);
644497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
645497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6463425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
64718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
648497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
649497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        uint8_t *signature, size_t *signatureSize) {
650497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
651497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
652e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
653497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
65418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
65518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
65618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
657497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
65818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
659e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
660497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
661497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
662497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
663497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
664497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
665497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
666497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
667497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
668497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
669497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
670497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
671497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
672497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
673497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
674497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
675497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec);
676497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (signatureVec.size() > *signatureSize) {
677e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
678497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
679497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
680497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(signature, signatureVec.array(), signatureVec.size());
681497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
682497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
683497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
684497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6853425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
68618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
687497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
688497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *signature, size_t signatureSize) {
689497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
690497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
691e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
692497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
69318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
69418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
69518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
696497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
69718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
698e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
699497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
700497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
701497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
702497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
703497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
704497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
705497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
706497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
707497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
708497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
709497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
710497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
711497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
712497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
713497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
714497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    signatureVec.appendArray(signature, signatureSize);
715497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
716497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    bool match;
717497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match);
718497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
719e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED;
720497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
721497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
722497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
723497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
724497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} // extern "C"
725