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