1497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker/* 2497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Copyright (C) 2014 The Android Open Source Project 3497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * 4497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License"); 5497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * you may not use this file except in compliance with the License. 6497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * You may obtain a copy of the License at 7497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * 8497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * http://www.apache.org/licenses/LICENSE-2.0 9497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * 10497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * Unless required by applicable law or agreed to in writing, software 11497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS, 12497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * See the License for the specific language governing permissions and 14497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker * limitations under the License. 15497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker */ 16497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 17c7a11b2208aa8f1e6a39eb70a136fbc0dafd3260Marco Nelissen//#define LOG_NDEBUG 0 18497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#define LOG_TAG "NdkMediaDrm" 19497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 20497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include "NdkMediaDrm.h" 21497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 22a69729dc76b97c44387088d351480d5d0701517eJeff Tinker#include <cutils/properties.h> 23497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/Log.h> 24497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <utils/StrongPointer.h> 25497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <gui/Surface.h> 26497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 27497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrm.h> 28497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/IDrmClient.h> 29497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <media/stagefright/MediaErrors.h> 30497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <binder/IServiceManager.h> 31a69729dc76b97c44387088d351480d5d0701517eJeff Tinker#include <media/IMediaDrmService.h> 32497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#include <ndk/NdkMediaCrypto.h> 33497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 34497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 35497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerusing namespace android; 36497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 37497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkertypedef Vector<uint8_t> idvec_t; 38497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 393305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerstruct DrmListener: virtual public BnDrmClient 403305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker{ 413305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerprivate: 423305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker AMediaDrm *mObj; 433305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker AMediaDrmEventListener mListener; 443305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 453305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkerpublic: 463305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker DrmListener(AMediaDrm *obj, AMediaDrmEventListener listener) : mObj(obj), mListener(listener) {} 473305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj); 483305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker}; 493305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 50497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstruct AMediaDrm { 51497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> mDrm; 52497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrmClient> mDrmClient; 53497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t> mIds; 54497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker KeyedVector<String8, String8> mQueryResults; 55497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mKeyRequest; 56497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mProvisionRequest; 57497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mProvisionUrl; 58497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mPropertyString; 59497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mPropertyByteArray; 60497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<Vector<uint8_t> > mSecureStops; 613305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker sp<DrmListener> mListener; 62497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}; 63497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 643305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinkervoid DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) { 653305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker if (!mListener) { 663305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker return; 673305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker } 683305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 693305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker AMediaDrmSessionId sessionId = {NULL, 0}; 703305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker int32_t sessionIdSize = obj->readInt32(); 713305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker if (sessionIdSize) { 723305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker uint8_t *sessionIdData = new uint8_t[sessionIdSize]; 733305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker sessionId.ptr = sessionIdData; 743305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker sessionId.length = sessionIdSize; 753305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker obj->read(sessionIdData, sessionId.length); 763305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker } 773305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 783305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker int32_t dataSize = obj->readInt32(); 793305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker uint8_t *data = NULL; 803305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker if (dataSize) { 813305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker data = new uint8_t[dataSize]; 823305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker obj->read(data, dataSize); 833305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker } 843305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 853305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker // translate DrmPlugin event types into their NDK equivalents 863305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker AMediaDrmEventType ndkEventType; 873305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker switch(eventType) { 883305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker case DrmPlugin::kDrmPluginEventProvisionRequired: 893305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker ndkEventType = EVENT_PROVISION_REQUIRED; 903305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker break; 913305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker case DrmPlugin::kDrmPluginEventKeyNeeded: 923305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker ndkEventType = EVENT_KEY_REQUIRED; 933305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker break; 943305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker case DrmPlugin::kDrmPluginEventKeyExpired: 953305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker ndkEventType = EVENT_KEY_EXPIRED; 963305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker break; 973305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker case DrmPlugin::kDrmPluginEventVendorDefined: 983305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker ndkEventType = EVENT_VENDOR_DEFINED; 993305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker break; 1003305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker default: 1013305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType); 102b636524376b7620926fdb64751bfa9b28e362593Greg Kaiser goto cleanup; 1033305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker } 1043305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 10518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize); 1063305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 107b636524376b7620926fdb64751bfa9b28e362593Greg Kaiser cleanup: 1083305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker delete [] sessionId.ptr; 1093305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker delete [] data; 1103305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker} 1113305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 1123305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker 113497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerextern "C" { 114497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 115e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translateStatus(status_t status) { 116e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen media_status_t result = AMEDIA_ERROR_UNKNOWN; 117497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker switch (status) { 118497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case OK: 119e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_OK; 120497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 121497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_NOT_PROVISIONED: 122e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_NOT_PROVISIONED; 123497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 124497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_RESOURCE_BUSY: 125e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_RESOURCE_BUSY; 126497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 127497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_DEVICE_REVOKED: 128e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_DEVICE_REVOKED; 129497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 130497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_CANNOT_HANDLE: 131e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_ERROR_INVALID_PARAMETER; 132497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 133497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_TAMPER_DETECTED: 134e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_TAMPER_DETECTED; 135497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 136497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_SESSION_NOT_OPENED: 137e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_SESSION_NOT_OPENED; 138497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 139497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_NO_LICENSE: 140e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_NEED_KEY; 141497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 142497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_LICENSE_EXPIRED: 143e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_LICENSE_EXPIRED; 144497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 145497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker default: 146497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 147497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 148497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return result; 149497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 150497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 151497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrm() { 152497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IServiceManager> sm = defaultServiceManager(); 1533003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker sp<IBinder> binder = sm->getService(String16("media.drm")); 1543003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker 1553003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder); 1563003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker if (service == NULL) { 1573003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker return NULL; 158497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 159497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1603003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker sp<IDrm> drm = service->makeDrm(); 161497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) { 162497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 163497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 164497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm; 165497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 166497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 167497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 168497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) { 169497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> drm = CreateDrm(); 170497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 171497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL) { 172497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 173497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 174497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 17568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong String8 nullPackageName; 17668b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong status_t err = drm->createPlugin(uuid, nullPackageName); 177497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 178497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (err != OK) { 179497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 180497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 181497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 182497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm; 183497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 184497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1853425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 186497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerbool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) { 187497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> drm = CreateDrm(); 188497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 189497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL) { 190497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return false; 191497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 192497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 193497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mimeStr = mimeType ? String8(mimeType) : String8(""); 194497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm->isCryptoSchemeSupported(uuid, mimeStr); 195497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 196497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1973425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 198497ca097bf373ac69405131bd257915c97b31dc0Jeff TinkerAMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) { 199497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker AMediaDrm *mObj = new AMediaDrm(); 200497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm = CreateDrmFromUUID(uuid); 201497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return mObj; 202497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 203497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2043425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 205497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_release(AMediaDrm *mObj) { 206497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (mObj->mDrm != NULL) { 207497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->setListener(NULL); 208497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->destroyPlugin(); 209497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm.clear(); 210497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 211497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker delete mObj; 212497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 213497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2143305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff TinkerEXPORT 2157c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissenmedia_status_t AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) { 2163305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 2177c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 2183305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker } 2193305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker mObj->mListener = new DrmListener(mObj, listener); 2203305b99ec3804c740aecd2ab6d1edd5c6137b7c6Jeff Tinker mObj->mDrm->setListener(mObj->mListener); 2217c96d53a65085f42ac2b6d416cbc16fd36ed72ffMarco Nelissen return AMEDIA_OK; 222497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 223497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 224497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 225497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) { 2262103044be5c8fefbd97da410bbca47239fd3348dEdwin Wong for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) { 227497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (iter->array() == id.ptr && iter->size() == id.length) { 228497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return true; 229497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 230497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 231497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return false; 232497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 233497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2343425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 23518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) { 236497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 237e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 238497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 23918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 24018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 24118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 242497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> session; 243497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->openSession(session); 244497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 245497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.push_front(session); 246497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter = mObj->mIds.begin(); 24718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen sessionId->ptr = iter->array(); 24818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen sessionId->length = iter->size(); 249497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 250e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 251497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 252497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2533425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 25418a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) { 255497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 256e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 257497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 25818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 25918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 26018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 261497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 262497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 26318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *sessionId, iter)) { 264e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 265497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 266497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->closeSession(*iter); 267497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.erase(iter); 268e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 269497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 270497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2713425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 27218a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope, 273497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType, 274497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters, 27518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const uint8_t **keyRequest, size_t *keyRequestSize) { 276497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 277497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 278e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 279497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 28018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!mimeType || !scope || !keyRequest || !keyRequestSize) { 281e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 282497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 283497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 284497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 28518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *scope, iter)) { 286e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 287497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 288497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 289497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdInit; 290497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdInit.appendArray(init, initSize); 291497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker DrmPlugin::KeyType mdKeyType; 292497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker switch (keyType) { 293497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_STREAMING: 294497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Streaming; 295497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 296497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_OFFLINE: 297497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Offline; 298497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 299497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_RELEASE: 300497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Release; 301497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 302497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker default: 303e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 304497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 305497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker KeyedVector<String8, String8> mdOptionalParameters; 306497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker for (size_t i = 0; i < numOptionalParameters; i++) { 307497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdOptionalParameters.add(String8(optionalParameters[i].mKey), 308497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8(optionalParameters[i].mValue)); 309497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 310497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 defaultUrl; 311d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker DrmPlugin::KeyRequestType keyRequestType; 312497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType), 313d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl, 314d072c909d87f8150433860f6de4c11df6e09e2f9Jeff Tinker &keyRequestType); 315497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 316497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 317497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 31818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *keyRequest = mObj->mKeyRequest.array(); 31918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *keyRequestSize = mObj->mKeyRequest.size(); 320497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 321e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 322497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 323497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3243425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 32518a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope, 32618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) { 327497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 328497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 329e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 330497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 33118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!scope || !response || !responseSize || !keySetId) { 332e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 333497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 334497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 335497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 33618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *scope, iter)) { 337e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 338497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 339497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdResponse; 340497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdResponse.appendArray(response, responseSize); 341497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 342497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdKeySetId; 343497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId); 344497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 345497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.push_front(mdKeySetId); 346497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter = mObj->mIds.begin(); 34718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySetId->ptr = iter->array(); 34818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySetId->length = iter->size(); 349497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 35018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySetId->ptr = NULL; 35118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySetId->length = 0; 352497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 353e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 354497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 355497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3563425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 35718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 35818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const AMediaDrmKeySetId *keySetId) { 359497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 360497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 361e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 362497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 36318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId || !keySetId) { 36418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 36518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 366497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 36718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *sessionId, iter)) { 368e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 369497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 370497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keySet; 37118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySet.appendArray(keySetId->ptr, keySetId->length); 372497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet)); 373497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 374497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3753425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 37618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) { 377497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 378e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 379497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 38018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!keySetId) { 38118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 38218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 383497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 384497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status; 38518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *keySetId, iter)) { 386497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keySet; 38718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen keySet.appendArray(keySetId->ptr, keySetId->length); 388497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->removeKeys(keySet); 389497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 390497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->removeKeys(*iter); 391497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.erase(iter); 392497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 393497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 394497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 395497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3963425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 39718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 39818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) { 399497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 400497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 401e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 402497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 40318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId || !numPairs) { 40418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 40518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 406497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 40718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *sessionId, iter)) { 408e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 409497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 410497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 411497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults); 412497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 41318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *numPairs = 0; 414497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 415497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 416497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 41718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (mObj->mQueryResults.size() > *numPairs) { 41818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *numPairs = mObj->mQueryResults.size(); 419e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 420497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 421497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 422497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker for (size_t i = 0; i < mObj->mQueryResults.size(); i++) { 423497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string(); 424497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string(); 425497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 42618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *numPairs = mObj->mQueryResults.size(); 427e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 428497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 429497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4303425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 43118a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest, 43218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen size_t *provisionRequestSize, const char **serverUrl) { 433497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 434e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 435497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 43618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) { 437e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 438497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 439497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 440497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""), 441497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mProvisionRequest, mObj->mProvisionUrl); 442497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 443497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 444497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 44518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *provisionRequest = mObj->mProvisionRequest.array(); 44618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *provisionRequestSize = mObj->mProvisionRequest.size(); 44718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *serverUrl = mObj->mProvisionUrl.string(); 448497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 449e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 450497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 451497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4523425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 453e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj, 454497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *response, size_t responseSize) { 455497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 456e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 457497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 458497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!response || !responseSize) { 459e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 460497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 461497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 462497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdResponse; 463497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdResponse.appendArray(response, responseSize); 464497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 465497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> unused; 466497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused)); 467497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 468497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4693425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 470e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj, 47118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen AMediaDrmSecureStop *secureStops, size_t *numSecureStops) { 472497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 473497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 474e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 475497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 47618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!numSecureStops) { 47718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 47818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 479497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops); 480497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 48118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *numSecureStops = 0; 482497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 483497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 48418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (*numSecureStops < mObj->mSecureStops.size()) { 485e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 486497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 487497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin(); 488497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker size_t i = 0; 489497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker while (iter != mObj->mSecureStops.end()) { 490497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker secureStops[i].ptr = iter->array(); 491497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker secureStops[i].length = iter->size(); 492497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ++iter; 493497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ++i; 494497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 49518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *numSecureStops = mObj->mSecureStops.size(); 496e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 497497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 498497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4993425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 500e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj, 50118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const AMediaDrmSecureStop *ssRelease) { 502497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 503497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 504e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 505497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 50618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!ssRelease) { 50718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 50818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 509497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 510497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> release; 51118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen release.appendArray(ssRelease->ptr, ssRelease->length); 512497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->releaseSecureStops(release)); 513497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 514497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 515497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5163425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 517e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName, 51818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const char **propertyValue) { 519497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 520497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 521e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 522497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 52318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!propertyName || !propertyValue) { 52418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 52518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 526497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 527497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getPropertyString(String8(propertyName), 528497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mPropertyString); 529497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 530497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 53118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *propertyValue = mObj->mPropertyString.string(); 532497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 53318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen *propertyValue = NULL; 534497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 535497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 536497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 537497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5383425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 539e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj, 54018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen const char *propertyName, AMediaDrmByteArray *propertyValue) { 541497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 542e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 543497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 54418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!propertyName || !propertyValue) { 54518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 54618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 547497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 548497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName), 549497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mPropertyByteArray); 550497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 551497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 55218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen propertyValue->ptr = mObj->mPropertyByteArray.array(); 55318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen propertyValue->length = mObj->mPropertyByteArray.size(); 554497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 55518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen propertyValue->ptr = NULL; 55618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen propertyValue->length = 0; 557497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 558497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 559497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 560497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5613425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 562e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj, 563497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *propertyName, const char *value) { 564497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 565e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 566497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 567497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 568497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName), 569497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8(value))); 570497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 571497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5723425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 573e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj, 574497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *propertyName, const uint8_t *value, size_t valueSize) { 575497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 576497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> byteArray; 577497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker byteArray.appendArray(value, valueSize); 578497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 579497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName), 580497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker byteArray)); 581497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 582497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 583497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 584e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t encrypt_decrypt_common(AMediaDrm *mObj, 585497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmSessionId &sessionId, 586497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 587497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) { 588497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 589497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 590e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 591497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 592497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 593497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 594e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 595497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 596497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 597497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm)); 598497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 599497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 600497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 601497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 602497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 603497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 604497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 605497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 606497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> inputVec; 607497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker inputVec.appendArray(input, dataSize); 608497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 609497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> ivVec; 610497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kIvSize = 16; 611497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ivVec.appendArray(iv, kIvSize); 612497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 613497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> outputVec; 614497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (encrypt) { 615214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec); 616497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 617214c833fcde68833691cc54d2a4cd995d7eb0e16Aurimas Liutikas status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec); 618497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 619497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 620497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker memcpy(output, outputVec.array(), outputVec.size()); 621497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 622497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 623497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 624497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 6253425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 62618a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 627497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 628497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize) { 62918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 63018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 63118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 63218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv, 633497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker input, output, dataSize, true); 634497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 635497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 6363425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 63718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 638497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 639497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize) { 64018a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 64118a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 64218a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 64318a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv, 644497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker input, output, dataSize, false); 645497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 646497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 6473425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 64818a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 649497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize, 650497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker uint8_t *signature, size_t *signatureSize) { 651497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 652497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 653e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 654497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 65518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 65618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 65718a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 658497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 65918a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *sessionId, iter)) { 660e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 661497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 662497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 663497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm)); 664497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 665497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 666497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 667497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 668497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 669497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 670497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 671497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 672497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> messageVec; 673497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker messageVec.appendArray(message, messageSize); 674497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 675497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> signatureVec; 676497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec); 677497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (signatureVec.size() > *signatureSize) { 678e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 679497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 680497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 681497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker memcpy(signature, signatureVec.array(), signatureVec.size()); 682497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 683497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 684497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 685497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 6863425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 68718a1b5904b352cedef29b95169a1226140d38576Marco Nelissenmedia_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId, 688497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize, 689497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *signature, size_t signatureSize) { 690497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 691497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 692e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 693497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 69418a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!sessionId) { 69518a1b5904b352cedef29b95169a1226140d38576Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 69618a1b5904b352cedef29b95169a1226140d38576Marco Nelissen } 697497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 69818a1b5904b352cedef29b95169a1226140d38576Marco Nelissen if (!findId(mObj, *sessionId, iter)) { 699e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 700497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 701497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 702497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm)); 703497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 704497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 705497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 706497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 707497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 708497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 709497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 710497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 711497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> messageVec; 712497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker messageVec.appendArray(message, messageSize); 713497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 714497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> signatureVec; 715497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker signatureVec.appendArray(signature, signatureSize); 716497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 717497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker bool match; 718497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match); 719497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 720e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED; 721497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 722497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 723497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 724497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 725497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} // extern "C" 726