NdkMediaDrm.cpp revision e419d7cd5c62b4b5866a45d59c5770bb470193c1
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 17497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#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 38497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstruct AMediaDrm { 39497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> mDrm; 40497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrmClient> mDrmClient; 41497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker AMediaDrmEventListener mListener; 42497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t> mIds; 43497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker KeyedVector<String8, String8> mQueryResults; 44497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mKeyRequest; 45497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mProvisionRequest; 46497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mProvisionUrl; 47497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mPropertyString; 48497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mPropertyByteArray; 49497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<Vector<uint8_t> > mSecureStops; 50497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker}; 51497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 52497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerextern "C" { 53497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 54e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t translateStatus(status_t status) { 55e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen media_status_t result = AMEDIA_ERROR_UNKNOWN; 56497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker switch (status) { 57497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case OK: 58e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_OK; 59497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 60497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_NOT_PROVISIONED: 61e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_NOT_PROVISIONED; 62497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 63497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_RESOURCE_BUSY: 64e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_RESOURCE_BUSY; 65497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 66497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_DEVICE_REVOKED: 67e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_DEVICE_REVOKED; 68497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 69497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_CANNOT_HANDLE: 70e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_ERROR_INVALID_PARAMETER; 71497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 72497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_TAMPER_DETECTED: 73e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_TAMPER_DETECTED; 74497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 75497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_SESSION_NOT_OPENED: 76e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_SESSION_NOT_OPENED; 77497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 78497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_NO_LICENSE: 79e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_NEED_KEY; 80497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 81497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case android::ERROR_DRM_LICENSE_EXPIRED: 82e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen result = AMEDIA_DRM_LICENSE_EXPIRED; 83497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 84497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker default: 85497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 86497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 87497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return result; 88497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 89497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 90497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrm() { 91497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IServiceManager> sm = defaultServiceManager(); 92497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 93497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IBinder> binder = 94497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sm->getService(String16("media.player")); 95497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 96497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IMediaPlayerService> service = 97497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker interface_cast<IMediaPlayerService>(binder); 98497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 99497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (service == NULL) { 100497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 101497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 102497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 103497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> drm = service->makeDrm(); 104497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 105497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) { 106497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 107497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 108497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 109497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm; 110497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 111497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 112497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 113497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic sp<IDrm> CreateDrmFromUUID(const AMediaUUID uuid) { 114497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> drm = CreateDrm(); 115497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 116497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL) { 117497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 118497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 119497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 120497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t err = drm->createPlugin(uuid); 121497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 122497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (err != OK) { 123497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return NULL; 124497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 125497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 126497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm; 127497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 128497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1293425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 130497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerbool AMediaDrm_isCryptoSchemeSupported(const AMediaUUID uuid, const char *mimeType) { 131497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sp<IDrm> drm = CreateDrm(); 132497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 133497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (drm == NULL) { 134497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return false; 135497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 136497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 137497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 mimeStr = mimeType ? String8(mimeType) : String8(""); 138497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return drm->isCryptoSchemeSupported(uuid, mimeStr); 139497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 140497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1413425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 142497ca097bf373ac69405131bd257915c97b31dc0Jeff TinkerAMediaDrm* AMediaDrm_createByUUID(const AMediaUUID uuid) { 143497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker AMediaDrm *mObj = new AMediaDrm(); 144497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm = CreateDrmFromUUID(uuid); 145497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return mObj; 146497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 147497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1483425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 149497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_release(AMediaDrm *mObj) { 150497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (mObj->mDrm != NULL) { 151497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->setListener(NULL); 152497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->destroyPlugin(); 153497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm.clear(); 154497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 155497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker delete mObj; 156497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 157497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 158497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#if 0 159497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkervoid AMediaDrm_setOnEventListener(AMediaDrm *mObj, AMediaDrmEventListener listener) { 160497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mListener = listener; 161497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 162497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker#endif 163497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 164497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 165497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinkerstatic bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) { 166497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker iter = mObj->mIds.begin(); 167497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker while (iter != mObj->mIds.end()) { 168497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (iter->array() == id.ptr && iter->size() == id.length) { 169497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return true; 170497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 171497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 172497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return false; 173497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 174497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1753425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 176e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId &sessionId) { 177497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 178e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 179497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 180497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> session; 181497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->openSession(session); 182497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 183497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.push_front(session); 184497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter = mObj->mIds.begin(); 185497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sessionId.ptr = iter->array(); 186497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker sessionId.length = iter->size(); 187497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 188e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 189497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 190497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 1913425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 192e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId) { 193497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 194e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 195497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 196497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 197497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 198497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 199e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 200497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 201497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mDrm->closeSession(*iter); 202497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.erase(iter); 203e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 204497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 205497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2063425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 207e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope &scope, 208497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType, 209497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters, 210497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *&keyRequest, size_t &keyRequestSize) { 211497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 212497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 213e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 214497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 215497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mimeType) { 216e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 217497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 218497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 219497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 220497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, scope, iter)) { 221e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 222497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 223497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 224497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdInit; 225497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdInit.appendArray(init, initSize); 226497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker DrmPlugin::KeyType mdKeyType; 227497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker switch (keyType) { 228497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_STREAMING: 229497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Streaming; 230497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 231497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_OFFLINE: 232497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Offline; 233497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 234497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker case KEY_TYPE_RELEASE: 235497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType = DrmPlugin::kKeyType_Release; 236497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker break; 237497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker default: 238e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 239497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 240497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker KeyedVector<String8, String8> mdOptionalParameters; 241497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker for (size_t i = 0; i < numOptionalParameters; i++) { 242497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdOptionalParameters.add(String8(optionalParameters[i].mKey), 243497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8(optionalParameters[i].mValue)); 244497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 245497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8 defaultUrl; 246497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getKeyRequest(*iter, mdInit, String8(mimeType), 247497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdKeyType, mdOptionalParameters, mObj->mKeyRequest, defaultUrl); 248497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 249497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 250497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 251497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyRequest = mObj->mKeyRequest.array(); 252497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyRequestSize = mObj->mKeyRequest.size(); 253497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 254e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 255497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 256497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2573425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 258e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope &scope, 259497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *response, size_t responseSize, AMediaDrmKeySetId &keySetId) { 260497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 261497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 262e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 263497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 264497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!response || !responseSize) { 265e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 266497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 267497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 268497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 269497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, scope, iter)) { 270e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 271497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 272497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdResponse; 273497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdResponse.appendArray(response, responseSize); 274497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 275497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdKeySetId; 276497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->provideKeyResponse(*iter, mdResponse, mdKeySetId); 277497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 278497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.push_front(mdKeySetId); 279497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter = mObj->mIds.begin(); 280497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySetId.ptr = iter->array(); 281497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySetId.length = iter->size(); 282497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 283497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySetId.ptr = NULL; 284497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySetId.length = 0; 285497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 286e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 287497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 288497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 2893425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 290e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 291497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmKeySetId &keySetId) { 292497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 293497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 294e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 295497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 296497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 297497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 298e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 299497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 300497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keySet; 301497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySet.appendArray(keySetId.ptr, keySetId.length); 302497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet)); 303497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 304497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3053425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 306e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId &keySetId) { 307497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 308e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 309497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 310497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 311497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status; 312497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, keySetId, iter)) { 313497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keySet; 314497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keySet.appendArray(keySetId.ptr, keySetId.length); 315497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->removeKeys(keySet); 316497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 317497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->removeKeys(*iter); 318497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mIds.erase(iter); 319497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 320497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 321497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 322497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3233425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 324e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 325497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker AMediaDrmKeyValue *keyValuePairs, size_t &numPairs) { 326497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 327497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 328e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 329497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 330497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 331497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 332e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 333497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 334497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 335497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults); 336497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 337497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker numPairs = 0; 338497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 339497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 340497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 341497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (mObj->mQueryResults.size() > numPairs) { 342497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker numPairs = mObj->mQueryResults.size(); 343e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 344497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 345497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 346497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker for (size_t i = 0; i < mObj->mQueryResults.size(); i++) { 347497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string(); 348497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string(); 349497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 350497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker numPairs = mObj->mQueryResults.size(); 351e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 352497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 353497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3543425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 355e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t *&provisionRequest, 356497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker size_t &provisionRequestSize, const char *&serverUrl) { 357497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 358e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 359497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 360497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!provisionRequestSize || !serverUrl) { 361e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 362497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 363497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 364497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getProvisionRequest(String8(""), String8(""), 365497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mProvisionRequest, mObj->mProvisionUrl); 366497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 367497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 368497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 369497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker provisionRequest = mObj->mProvisionRequest.array(); 370497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker provisionRequestSize = mObj->mProvisionRequest.size(); 371497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker serverUrl = mObj->mProvisionUrl.string(); 372497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 373e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 374497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 375497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3763425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 377e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj, 378497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *response, size_t responseSize) { 379497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 380e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 381497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 382497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!response || !responseSize) { 383e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_PARAMETER; 384497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 385497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 386497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> mdResponse; 387497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mdResponse.appendArray(response, responseSize); 388497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 389497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> unused; 390497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->provideProvisionResponse(mdResponse, unused, unused)); 391497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 392497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 3933425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 394e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj, 395497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker AMediaDrmSecureStop *secureStops, size_t &numSecureStops) { 396497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 397497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 398e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 399497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 400497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops); 401497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 402497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker numSecureStops = 0; 403497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 404497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 405497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (numSecureStops < mObj->mSecureStops.size()) { 406e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 407497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 408497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin(); 409497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker size_t i = 0; 410497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker while (iter != mObj->mSecureStops.end()) { 411497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker secureStops[i].ptr = iter->array(); 412497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker secureStops[i].length = iter->size(); 413497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ++iter; 414497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ++i; 415497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 416497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker numSecureStops = mObj->mSecureStops.size(); 417e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_OK; 418497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 419497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4203425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 421e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj, 422497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmSecureStop &ssRelease) { 423497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 424497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 425e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 426497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 427497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 428497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> release; 429497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker release.appendArray(ssRelease.ptr, ssRelease.length); 430497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->releaseSecureStops(release)); 431497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 432497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 433497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4343425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 435e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName, 436497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *&propertyValue) { 437497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 438497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 439e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 440497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 441497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 442497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getPropertyString(String8(propertyName), 443497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mPropertyString); 444497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 445497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 446497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue = mObj->mPropertyString.string(); 447497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 448497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue = NULL; 449497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 450497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 451497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 452497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4533425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 454e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj, 455497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *propertyName, AMediaDrmByteArray &propertyValue) { 456497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 457e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 458497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 459497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 460497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName), 461497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker mObj->mPropertyByteArray); 462497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 463497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 464497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue.ptr = mObj->mPropertyByteArray.array(); 465497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue.length = mObj->mPropertyByteArray.size(); 466497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 467497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue.ptr = NULL; 468497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker propertyValue.length = 0; 469497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 470497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 471497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 472497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4733425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 474e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyString(AMediaDrm *mObj, 475497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *propertyName, const char *value) { 476497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 477e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 478497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 479497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 480497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->setPropertyString(String8(propertyName), 481497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker String8(value))); 482497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 483497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 4843425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 485e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj, 486497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *propertyName, const uint8_t *value, size_t valueSize) { 487497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 488497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> byteArray; 489497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker byteArray.appendArray(value, valueSize); 490497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 491497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(mObj->mDrm->getPropertyByteArray(String8(propertyName), 492497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker byteArray)); 493497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 494497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 495497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 496e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenstatic media_status_t encrypt_decrypt_common(AMediaDrm *mObj, 497497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const AMediaDrmSessionId &sessionId, 498497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 499497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize, bool encrypt) { 500497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 501497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 502e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 503497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 504497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 505497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 506e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 507497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 508497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 509497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setCipherAlgorithm(*iter, String8(cipherAlgorithm)); 510497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 511497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 512497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 513497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 514497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 515497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 516497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 517497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 518497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> inputVec; 519497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker inputVec.appendArray(input, dataSize); 520497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 521497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> ivVec; 522497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kIvSize = 16; 523497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker ivVec.appendArray(iv, kIvSize); 524497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 525497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> outputVec; 526497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (encrypt) { 527497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->encrypt(*iter, keyIdVec, inputVec, ivVec, outputVec); 528497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } else { 529497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->decrypt(*iter, keyIdVec, inputVec, ivVec, outputVec); 530497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 531497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 532497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker memcpy(output, outputVec.array(), outputVec.size()); 533497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 534497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 535497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 536497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5373425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 538e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 539497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 540497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize) { 541497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return encrypt_decrypt_common(mObj, sessionId, cipherAlgorithm, keyId, iv, 542497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker input, output, dataSize, true); 543497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 544497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5453425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 546e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 547497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, 548497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *input, uint8_t *output, size_t dataSize) { 549497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return encrypt_decrypt_common(mObj, sessionId, cipherAlgorithm, keyId, iv, 550497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker input, output, dataSize, false); 551497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 552497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5533425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 554e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 555497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize, 556497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker uint8_t *signature, size_t *signatureSize) { 557497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 558497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 559e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 560497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 561497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 562497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 563e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 564497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 565497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 566497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm)); 567497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 568497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 569497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 570497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 571497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 572497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 573497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 574497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 575497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> messageVec; 576497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker messageVec.appendArray(message, messageSize); 577497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 578497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> signatureVec; 579497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->sign(*iter, keyIdVec, messageVec, signatureVec); 580497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (signatureVec.size() > *signatureSize) { 581e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SHORT_BUFFER; 582497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 583497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 584497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker memcpy(signature, signatureVec.array(), signatureVec.size()); 585497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 586497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 587497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 588497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 5893425fd5a55dd31e261d2f2a9590c762d6d0a6b79Marco NelissenEXPORT 590e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissenmedia_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId, 591497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize, 592497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const uint8_t *signature, size_t signatureSize) { 593497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 594497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!mObj || mObj->mDrm == NULL) { 595e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_ERROR_INVALID_OBJECT; 596497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 597497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker List<idvec_t>::iterator iter; 598497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (!findId(mObj, sessionId, iter)) { 599e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return AMEDIA_DRM_SESSION_NOT_OPENED; 600497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 601497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 602497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status_t status = mObj->mDrm->setMacAlgorithm(*iter, String8(macAlgorithm)); 603497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status != OK) { 604497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 605497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 606497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 607497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> keyIdVec; 608497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker const size_t kKeyIdSize = 16; 609497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker keyIdVec.appendArray(keyId, kKeyIdSize); 610497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 611497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> messageVec; 612497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker messageVec.appendArray(message, messageSize); 613497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 614497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker Vector<uint8_t> signatureVec; 615497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker signatureVec.appendArray(signature, signatureSize); 616497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 617497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker bool match; 618497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker status = mObj->mDrm->verify(*iter, keyIdVec, messageVec, signatureVec, match); 619497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker if (status == OK) { 620e419d7cd5c62b4b5866a45d59c5770bb470193c1Marco Nelissen return match ? AMEDIA_OK : AMEDIA_DRM_VERIFY_FAILED; 621497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker } 622497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker return translateStatus(status); 623497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} 624497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 625497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker} // extern "C" 626497ca097bf373ac69405131bd257915c97b31dc0Jeff Tinker 627