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