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);
102b636524376b7620926fdb64751bfa9b28e362593Greg Kaiser            goto cleanup;
1033305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
1043305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
10518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
1063305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
107b636524376b7620926fdb64751bfa9b28e362593Greg Kaiser cleanup:
1083305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] sessionId.ptr;
1093305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    delete [] data;
1103305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker}
1113305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
1123305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker
113497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerextern "C" {
114497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
115e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translateStatus(status_t status) {
116e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    media_status_t result = AMEDIA_ERROR_UNKNOWN;
117497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (status) {
118497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case OK:
119e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_OK;
120497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
121497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NOT_PROVISIONED:
122e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NOT_PROVISIONED;
123497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
124497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_RESOURCE_BUSY:
125e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_RESOURCE_BUSY;
126497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
127497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_DEVICE_REVOKED:
128e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_DEVICE_REVOKED;
129497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
130497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_CANNOT_HANDLE:
131e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_ERROR_INVALID_PARAMETER;
132497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
133497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_TAMPER_DETECTED:
134e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_TAMPER_DETECTED;
135497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
136497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_SESSION_NOT_OPENED:
137e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_SESSION_NOT_OPENED;
138497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
139497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_NO_LICENSE:
140e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_NEED_KEY;
141497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
142497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case android::ERROR_DRM_LICENSE_EXPIRED:
143e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            result = AMEDIA_DRM_LICENSE_EXPIRED;
144497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
145497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
146497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
147497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
148497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return result;
149497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
150497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
151497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrm() {
152497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
1533003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IBinder> binder = sm->getService(String16("media.drm"));
1543003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker
1553003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
1563003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    if (service == NULL) {
1573003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker        return NULL;
158497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
159497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1603003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker    sp<IDrm> drm = service->makeDrm();
161497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
162497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
163497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
164497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
165497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
166497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
167497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
168497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) {
169497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
170497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
171497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
172497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
173497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
174497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
17568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong    String8 nullPackageName;
17668b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong    status_t err = drm->createPlugin(uuid, nullPackageName);
177497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
178497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (err != OK) {
179497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return NULL;
180497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
181497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
182497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm;
183497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
184497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1853425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
186497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerbool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) {
187497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    sp<IDrm> drm = CreateDrm();
188497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
189497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (drm == NULL) {
190497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return false;
191497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
192497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
193497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 mimeStr = mimeType ? String8(mimeType) : String8("");
194497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return drm->isCryptoSchemeSupported(uuid, mimeStr);
195497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
196497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
1973425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
198497ca097bf373ac69405131bd257915c97b31dc0Jeff TinkerAMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) {
199497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    AMediaDrm *mObj = new AMediaDrm();
200497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm = CreateDrmFromUUID(uuid);
201497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return mObj;
202497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
203497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2043425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
205497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_release(AMediaDrm *mObj) {
206497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (mObj->mDrm != NULL) {
207497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->setListener(NULL);
208497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm->destroyPlugin();
209497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mDrm.clear();
210497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
211497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    delete mObj;
212497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
213497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2143305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff TinkerEXPORT
2157c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissenmedia_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) {
2163305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
2177c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
2183305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    }
2193305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mListener = new DrmListener(mObj, listener);
2203305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker    mObj->mDrm->setListener(mObj->mListener);
2217c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen    return AMEDIA_OK;
222497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
223497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
224497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
225497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
2262103044be5c8fefbd97da410bbca47239fd3348dEdwin Wong    for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) {
227497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        if (iter->array() == id.ptr && iter->size() == id.length) {
228497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            return true;
229497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        }
230497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
231497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return false;
232497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
233497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2343425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
23518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
236497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
237e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
238497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
23918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
24018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
24118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
242497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> session;
243497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->openSession(session);
244497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
245497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(session);
246497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
24718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->ptr = iter->array();
24818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        sessionId->length = iter->size();
249497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
250e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
251497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
252497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2533425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
25418a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
255497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
256e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
257497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
25818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
25918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
26018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
261497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
262497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
26318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
264e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
265497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
266497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mDrm->closeSession(*iter);
267497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mObj->mIds.erase(iter);
268e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
269497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
270497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
2713425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
27218a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
273497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
274497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
27518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t **keyRequest, size_t *keyRequestSize) {
276497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
277497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
278e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
279497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
28018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
281e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
282497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
283497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
284497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
28518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
286e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
287497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
288497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
289497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdInit;
290497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdInit.appendArray(init, initSize);
291497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    DrmPlugin::KeyType mdKeyType;
292497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    switch (keyType) {
293497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_STREAMING:
294497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Streaming;
295497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
296497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_OFFLINE:
297497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Offline;
298497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
299497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        case KEY_TYPE_RELEASE:
300497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mdKeyType = DrmPlugin::kKeyType_Release;
301497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            break;
302497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        default:
303e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen            return AMEDIA_ERROR_INVALID_PARAMETER;
304497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
305497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    KeyedVector<String8, String8> mdOptionalParameters;
306497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < numOptionalParameters; i++) {
307497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mdOptionalParameters.add(String8(optionalParameters[i].mKey),
308497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                String8(optionalParameters[i].mValue));
309497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
310497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    String8 defaultUrl;
311d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker    DrmPlugin::KeyRequestType keyRequestType;
312497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType),
313d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl,
314d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker            &keyRequestType);
315497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
316497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
317497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
31818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequest = mObj->mKeyRequest.array();
31918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *keyRequestSize = mObj->mKeyRequest.size();
320497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
321e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
322497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
323497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3243425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
32518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
32618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
327497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
328497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
329e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
330497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
33118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!scope || !response || !responseSize || !keySetId) {
332e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
333497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
334497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
335497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
33618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *scope, iter)) {
337e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
338497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
339497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
340497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
341497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
342497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdKeySetId;
343497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId);
344497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
345497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.push_front(mdKeySetId);
346497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        List<idvec_t>::iterator iter = mObj->mIds.begin();
34718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = iter->array();
34818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = iter->size();
349497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
35018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->ptr = NULL;
35118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySetId->length = 0;
352497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
353e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
354497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
355497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3563425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
35718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
35818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmKeySetId *keySetId) {
359497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
360497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
361e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
362497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
36318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !keySetId) {
36418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
36518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
366497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
36718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
368e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
369497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
370497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keySet;
37118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    keySet.appendArray(keySetId->ptr, keySetId->length);
372497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
373497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
374497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3753425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
37618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
377497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
378e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
379497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
38018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!keySetId) {
38118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
38218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
383497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
384497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status;
38518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *keySetId, iter)) {
386497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        Vector<uint8_t> keySet;
38718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        keySet.appendArray(keySetId->ptr, keySetId->length);
388497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(keySet);
389497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
390497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        status = mObj->mDrm->removeKeys(*iter);
391497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        mObj->mIds.erase(iter);
392497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
393497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
394497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
395497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
3963425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
39718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
39818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
399497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
400497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
401e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
402497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
40318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId || !numPairs) {
40418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
40518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
406497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
40718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
408e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
409497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
410497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
411497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
412497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
41318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = 0;
414497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
415497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
416497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
41718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (mObj->mQueryResults.size() > *numPairs) {
41818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numPairs = mObj->mQueryResults.size();
419e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
420497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
421497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
422497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    for (size_t i = 0; i < mObj->mQueryResults.size(); i++) {
423497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
424497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string();
425497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
42618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numPairs = mObj->mQueryResults.size();
427e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
428497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
429497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4303425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
43118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
43218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        size_t *provisionRequestSize, const char **serverUrl) {
433497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
434e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
435497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
43618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
437e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
438497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
439497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
440497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""),
441497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mProvisionRequest, mObj->mProvisionUrl);
442497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
443497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
444497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
44518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequest = mObj->mProvisionRequest.array();
44618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *provisionRequestSize = mObj->mProvisionRequest.size();
44718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *serverUrl = mObj->mProvisionUrl.string();
448497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
449e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
450497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
451497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4523425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
453e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
454497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *response, size_t responseSize) {
455497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
456e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
457497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
458497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!response || !responseSize) {
459e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
460497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
461497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
462497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> mdResponse;
463497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    mdResponse.appendArray(response, responseSize);
464497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
465497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> unused;
466497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused));
467497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
468497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4693425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
470e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
47118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
472497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
473497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
474e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
475497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
47618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!numSecureStops) {
47718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
47818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
479497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
480497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
48118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *numSecureStops = 0;
482497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
483497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
48418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (*numSecureStops < mObj->mSecureStops.size()) {
485e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
486497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
487497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
488497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    size_t i = 0;
489497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    while (iter != mObj->mSecureStops.end()) {
490497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].ptr = iter->array();
491497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        secureStops[i].length = iter->size();
492497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++iter;
493497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        ++i;
494497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
49518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    *numSecureStops = mObj->mSecureStops.size();
496e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen    return AMEDIA_OK;
497497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
498497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
4993425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
500e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
50118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const AMediaDrmSecureStop *ssRelease) {
502497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
503497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
504e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
505497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
50618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!ssRelease) {
50718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
50818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
509497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
510497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> release;
51118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    release.appendArray(ssRelease->ptr, ssRelease->length);
512497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->releaseSecureStops(release));
513497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
514497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
515497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5163425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
517e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
51818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char **propertyValue) {
519497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
520497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
521e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
522497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
52318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
52418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
52518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
526497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
527497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
528497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyString);
529497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
530497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
53118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = mObj->mPropertyString.string();
532497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
53318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        *propertyValue = NULL;
534497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
535497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
536497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
537497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5383425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
539e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
54018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        const char *propertyName, AMediaDrmByteArray *propertyValue) {
541497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
542e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
543497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
54418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!propertyName || !propertyValue) {
54518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
54618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
547497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
548497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
549497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            mObj->mPropertyByteArray);
550497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
551497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
55218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = mObj->mPropertyByteArray.array();
55318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = mObj->mPropertyByteArray.size();
554497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
55518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->ptr = NULL;
55618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        propertyValue->length = 0;
557497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
558497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
559497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
560497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5613425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
562e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj,
563497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const char *value) {
564497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
565e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
566497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
567497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
568497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName),
569497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    String8(value)));
570497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
571497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
5723425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
573e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
574497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *propertyName, const uint8_t *value, size_t valueSize) {
575497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
576497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> byteArray;
577497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    byteArray.appendArray(value, valueSize);
578497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
579497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName),
580497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker                    byteArray));
581497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
582497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
583497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
584e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
585497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const AMediaDrmSessionId &sessionId,
586497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
587497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) {
588497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
589497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
590e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
591497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
592497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
593497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!findId(mObj, sessionId, iter)) {
594e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
595497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
596497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
597497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm));
598497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
599497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
600497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
601497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
602497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
603497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
604497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
605497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
606497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> inputVec;
607497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    inputVec.appendArray(input, dataSize);
608497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
609497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> ivVec;
610497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kIvSize = 16;
611497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    ivVec.appendArray(iv, kIvSize);
612497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
613497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> outputVec;
614497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (encrypt) {
615214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas        status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
616497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    } else {
617214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas        status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec);
618497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
619497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
620497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(output, outputVec.array(), outputVec.size());
621497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
622497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
623497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
624497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6253425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
62618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
627497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
628497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
62918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
63018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
63118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
63218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
633497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, true);
634497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
635497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6363425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
63718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
638497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
639497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *input, uint8_t *output, size_t dataSize) {
64018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
64118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
64218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
64318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
644497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker            input, output, dataSize, false);
645497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
646497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6473425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
64818a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
649497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
650497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        uint8_t *signature, size_t *signatureSize) {
651497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
652497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
653e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
654497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
65518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
65618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
65718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
658497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
65918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
660e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
661497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
662497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
663497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
664497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
665497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
666497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
667497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
668497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
669497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
670497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
671497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
672497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
673497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
674497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
675497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
676497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec);
677497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (signatureVec.size() > *signatureSize) {
678e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SHORT_BUFFER;
679497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
680497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
681497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        memcpy(signature, signatureVec.array(), signatureVec.size());
682497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
683497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
684497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
685497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
6863425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT
68718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
688497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
689497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        const uint8_t *signature, size_t signatureSize) {
690497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
691497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (!mObj || mObj->mDrm == NULL) {
692e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_ERROR_INVALID_OBJECT;
693497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
69418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!sessionId) {
69518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen        return AMEDIA_ERROR_INVALID_PARAMETER;
69618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    }
697497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    List<idvec_t>::iterator iter;
69818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen    if (!findId(mObj, *sessionId, iter)) {
699e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return AMEDIA_DRM_SESSION_NOT_OPENED;
700497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
701497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
702497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm));
703497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status != OK) {
704497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker        return translateStatus(status);
705497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
706497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
707497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> keyIdVec;
708497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    const size_t kKeyIdSize = 16;
709497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    keyIdVec.appendArray(keyId, kKeyIdSize);
710497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
711497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> messageVec;
712497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    messageVec.appendArray(message, messageSize);
713497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
714497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    Vector<uint8_t> signatureVec;
715497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    signatureVec.appendArray(signature, signatureSize);
716497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
717497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    bool match;
718497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match);
719497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    if (status == OK) {
720e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen        return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED;
721497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    }
722497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker    return translateStatus(status);
723497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}
724497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker
725497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} // extern "C"
726