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