1cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker/*
2cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * Copyright (C) 2013 The Android Open Source Project
3cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *
4cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
5cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * you may not use this file except in compliance with the License.
6cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * You may obtain a copy of the License at
7cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *
8cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
9cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *
10cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * Unless required by applicable law or agreed to in writing, software
11cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
12cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * See the License for the specific language governing permissions and
14cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * limitations under the License.
15cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker */
16cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
17cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker//#define LOG_NDEBUG 0
18cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#define LOG_TAG "Drm"
19cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <utils/Log.h>
20cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
21cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <dirent.h>
22cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <dlfcn.h>
23cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
24cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include "Drm.h"
25cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
26cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <media/drm/DrmAPI.h>
27cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <media/stagefright/foundation/ADebug.h>
28cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <media/stagefright/foundation/AString.h>
29cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <media/stagefright/foundation/hexdump.h>
30cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker#include <media/stagefright/MediaErrors.h>
3181e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker#include <binder/IServiceManager.h>
3281e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker#include <binder/IPCThreadState.h>
33cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
34cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkernamespace android {
35cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3681e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinkerstatic bool checkPermission(const char* permissionString) {
3781e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker#ifndef HAVE_ANDROID_OS
3881e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    return true;
3981e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker#endif
4081e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
4181e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    bool ok = checkCallingPermission(String16(permissionString));
4281e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    if (!ok) ALOGE("Request requires %s", permissionString);
4381e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    return ok;
4481e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker}
4581e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker
46cc82dc6d500023eba6048616301a4b12682458dbJeff TinkerKeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
47cc82dc6d500023eba6048616301a4b12682458dbJeff TinkerKeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
48cc82dc6d500023eba6048616301a4b12682458dbJeff TinkerMutex Drm::mMapLock;
49cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
50cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatic bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
51cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (lhs.size() < rhs.size()) {
52cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return true;
53cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    } else if (lhs.size() > rhs.size()) {
54cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return false;
55cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
56cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
57cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
58cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
59cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
60cc82dc6d500023eba6048616301a4b12682458dbJeff TinkerDrm::Drm()
61cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    : mInitCheck(NO_INIT),
620cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker      mListener(NULL),
63cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker      mFactory(NULL),
64cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker      mPlugin(NULL) {
65cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
66cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
67cc82dc6d500023eba6048616301a4b12682458dbJeff TinkerDrm::~Drm() {
68cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    delete mPlugin;
69cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    mPlugin = NULL;
70cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    closeFactory();
71cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
72cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
73cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkervoid Drm::closeFactory() {
74cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    delete mFactory;
75cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    mFactory = NULL;
76cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    mLibrary.clear();
77cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
78cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
79cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::initCheck() const {
80cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mInitCheck;
81cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
82cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
830cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinkerstatus_t Drm::setListener(const sp<IDrmClient>& listener)
840cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker{
850cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    Mutex::Autolock lock(mEventLock);
863d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    if (mListener != NULL){
873d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker        mListener->asBinder()->unlinkToDeath(this);
883d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    }
893d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    if (listener != NULL) {
903d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker        listener->asBinder()->linkToDeath(this);
913d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    }
920cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    mListener = listener;
930cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    return NO_ERROR;
940cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker}
950cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker
960cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinkervoid Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
970cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker                    Vector<uint8_t> const *sessionId,
980cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker                    Vector<uint8_t> const *data)
990cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker{
1000cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    mEventLock.lock();
1010cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    sp<IDrmClient> listener = mListener;
1020cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    mEventLock.unlock();
1030cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker
1040cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    if (listener != NULL) {
1050cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        Parcel obj;
1060cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        if (sessionId && sessionId->size()) {
1070cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.writeInt32(sessionId->size());
1080cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.write(sessionId->array(), sessionId->size());
1090cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        } else {
1100cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.writeInt32(0);
1110cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        }
1120cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker
1130cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        if (data && data->size()) {
1140cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.writeInt32(data->size());
1150cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.write(data->array(), data->size());
1160cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        } else {
1170cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker            obj.writeInt32(0);
1180cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        }
1190cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker
1200cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
1210cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker        listener->notify(eventType, extra, &obj);
1220cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    }
1230cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker}
124cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
125cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker/*
126cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * Search the plugins directory for a plugin that supports the scheme
127cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * specified by uuid
128cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *
129cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * If found:
130cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *    mLibrary holds a strong pointer to the dlopen'd library
131cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *    mFactory is set to the library's factory method
132cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *    mInitCheck is set to OK
133cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *
134cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker * If not found:
135cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *    mLibrary is cleared and mFactory are set to NULL
136cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker *    mInitCheck is set to an error (!OK)
137cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker */
138cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkervoid Drm::findFactoryForScheme(const uint8_t uuid[16]) {
139cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
140cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    closeFactory();
141cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
142cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    // lock static maps
143cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mMapLock);
144cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
145cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    // first check cache
146cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Vector<uint8_t> uuidVector;
147cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    uuidVector.appendArray(uuid, sizeof(uuid));
148cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
149cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (index >= 0) {
150cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
151cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            mInitCheck = OK;
152cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            return;
153cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        } else {
154cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            ALOGE("Failed to load from cached library path!");
155cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            mInitCheck = ERROR_UNSUPPORTED;
156cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            return;
157cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        }
158cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
159cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
160cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    // no luck, have to search
161cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    String8 dirPath("/vendor/lib/mediadrm");
162cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    DIR* pDir = opendir(dirPath.string());
163cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
164cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (pDir == NULL) {
165cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
166cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        ALOGE("Failed to open plugin directory %s", dirPath.string());
167cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return;
168cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
169cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
170cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
171cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    struct dirent* pEntry;
172cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    while ((pEntry = readdir(pDir))) {
173cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
174cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        String8 pluginPath = dirPath + "/" + pEntry->d_name;
175cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
176cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        if (pluginPath.getPathExtension() == ".so") {
177cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
178cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            if (loadLibraryForScheme(pluginPath, uuid)) {
179cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker                mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
180cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker                mInitCheck = OK;
181cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker                closedir(pDir);
182cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker                return;
183cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            }
184cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        }
185cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
186cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
187cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    closedir(pDir);
188cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
189cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    ALOGE("Failed to find drm plugin");
190cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    mInitCheck = ERROR_UNSUPPORTED;
191cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
192cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
193cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerbool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
194cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
195cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    // get strong pointer to open shared library
196cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
197cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (index >= 0) {
198cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
199cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    } else {
200cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        index = mLibraryPathToOpenLibraryMap.add(path, NULL);
201cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
202cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
203cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (!mLibrary.get()) {
204cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        mLibrary = new SharedLibrary(path);
205cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        if (!*mLibrary) {
206cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker            return false;
207cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        }
208cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
209cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
210cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
211cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
212cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    typedef DrmFactory *(*CreateDrmFactoryFunc)();
213cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
214cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    CreateDrmFactoryFunc createDrmFactory =
215cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
216cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
217cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (createDrmFactory == NULL ||
218cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        (mFactory = createDrmFactory()) == NULL ||
219cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        !mFactory->isCryptoSchemeSupported(uuid)) {
220cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        closeFactory();
221cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return false;
222cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
223cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return true;
224cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
225cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
2269cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinkerbool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
2279cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker
228cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
229cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
2309cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker    if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
2319cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker        findFactoryForScheme(uuid);
2329cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker        if (mInitCheck != OK) {
2339cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker            return false;
2349cf69e0fc110f17c28e988ed0f9bf91abfaf710dJeff Tinker        }
235cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
236cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
237ee7e77d55d510725a314d8ed36dc730c21af6173Jeff Tinker    if (mimeType != "") {
238ee7e77d55d510725a314d8ed36dc730c21af6173Jeff Tinker        return mFactory->isContentTypeSupported(mimeType);
239ee7e77d55d510725a314d8ed36dc730c21af6173Jeff Tinker    }
240ee7e77d55d510725a314d8ed36dc730c21af6173Jeff Tinker
241ee7e77d55d510725a314d8ed36dc730c21af6173Jeff Tinker    return true;
242cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
243cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
244cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::createPlugin(const uint8_t uuid[16]) {
245cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
246cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
247cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin != NULL) {
248cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
249cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
250cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
251cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
252cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        findFactoryForScheme(uuid);
253cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
254cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
255cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
256cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
257cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
258cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
2590cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
2600cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    mPlugin->setListener(this);
2610cb126a34fe32f81c830858102471e7be2ce85b1Jeff Tinker    return result;
262cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
263cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
264cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::destroyPlugin() {
265cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
266cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
267cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
268cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
269cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
270cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
271cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
272cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
273cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
274cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
275cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    delete mPlugin;
276cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    mPlugin = NULL;
277cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
278cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return OK;
279cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
280cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
281cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::openSession(Vector<uint8_t> &sessionId) {
282cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
283cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
284cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
285cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
286cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
287cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
288cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
289cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
290cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
291cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
292cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->openSession(sessionId);
293cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
294cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
295cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
296cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
297cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
298cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
299cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
300cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
301cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
302cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
303cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
304cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
305cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
306cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->closeSession(sessionId);
307cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
308cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3098856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
3108856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                            Vector<uint8_t> const &initData,
3118856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                            String8 const &mimeType, DrmPlugin::KeyType keyType,
3128856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                            KeyedVector<String8, String8> const &optionalParameters,
3138856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                            Vector<uint8_t> &request, String8 &defaultUrl) {
314cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
315cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
316cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
317cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
318cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
319cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
320cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
321cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
322cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
323cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3248856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
3258856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                                  optionalParameters, request, defaultUrl);
326cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
327cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3288856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
3298856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                                 Vector<uint8_t> const &response,
3308856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                                 Vector<uint8_t> &keySetId) {
331cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
332cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
333cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
334cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
335cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
336cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
337cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
338cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
339cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
340cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3418856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->provideKeyResponse(sessionId, response, keySetId);
342cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
343cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3448856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
345cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
346cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
347cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
348cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
349cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
350cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
351cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
352cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
353cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
354cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3558856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->removeKeys(keySetId);
356cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
357cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3588856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
3598856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                          Vector<uint8_t> const &keySetId) {
360cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
361cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
362cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
363cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
364cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
365cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
366cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
367cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
368cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
369cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
3708856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->restoreKeys(sessionId, keySetId);
3718856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
3728856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
3738856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
3748856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                             KeyedVector<String8, String8> &infoMap) const {
3758856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
3768856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
3778856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
3788856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
3798856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
3808856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
3818856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
3828856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
3838856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
3848856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
3858856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->queryKeyStatus(sessionId, infoMap);
386cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
387cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
38868d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinkerstatus_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
38968d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                                  Vector<uint8_t> &request, String8 &defaultUrl) {
390cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
391cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
392cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
393cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
394cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
395cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
396cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
397cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
398cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
399cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
40068d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    return mPlugin->getProvisionRequest(certType, certAuthority,
40168d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                                        request, defaultUrl);
402cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
403cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
40468d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinkerstatus_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
40568d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                                       Vector<uint8_t> &certificate,
40668d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                                       Vector<uint8_t> &wrappedKey) {
407cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
408cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
409cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
410cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
411cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
412cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
413cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
414cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
415cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
416cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
41768d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
418cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
419cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
42068b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinkerstatus_t Drm::unprovisionDevice() {
42168b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    Mutex::Autolock autoLock(mLock);
42268b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker
42368b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    if (mInitCheck != OK) {
42468b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker        return mInitCheck;
42568b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    }
42668b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker
42768b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    if (mPlugin == NULL) {
42868b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker        return -EINVAL;
42968b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    }
43068b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker
43168b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
43268b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker        return -EPERM;
43368b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    }
43468b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker
43568b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker    return mPlugin->unprovisionDevice();
43668b15554f6dca3b056eac517fe5fa2fd4ee80a33Jeff Tinker}
437cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
438cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
439cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
440cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
441cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
442cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
443cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
444cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
445cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
446cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
447cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
448cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
449cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->getSecureStops(secureStops);
450cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
451cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
4523c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinkerstatus_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
4533c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    Mutex::Autolock autoLock(mLock);
4543c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4553c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    if (mInitCheck != OK) {
4563c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker        return mInitCheck;
4573c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    }
4583c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4593c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    if (mPlugin == NULL) {
4603c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker        return -EINVAL;
4613c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    }
4623c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4633c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    return mPlugin->getSecureStop(ssid, secureStop);
4643c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker}
4653c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
466cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
467cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
468cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
469cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
470cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
471cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
472cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
473cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
474cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
475cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
476cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
477cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->releaseSecureStops(ssRelease);
478cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
479cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
4803c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinkerstatus_t Drm::releaseAllSecureStops() {
4813c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    Mutex::Autolock autoLock(mLock);
4823c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4833c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    if (mInitCheck != OK) {
4843c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker        return mInitCheck;
4853c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    }
4863c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4873c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    if (mPlugin == NULL) {
4883c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker        return -EINVAL;
4893c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    }
4903c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
4913c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker    return mPlugin->releaseAllSecureStops();
4923c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker}
4933c1285e8f86bd497e14c14fb6df7b42072ef52bdJeff Tinker
494cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
495cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
496cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
497cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
498cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
499cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
500cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
501cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
502cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
503cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
504cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
505cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->getPropertyString(name, value);
506cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
507cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
508cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
509cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
510cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
511cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
512cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
513cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
514cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
515cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
516cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
517cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
518cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
519cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->getPropertyByteArray(name, value);
520cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
521cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
522cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
523cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
524cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
525cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
526cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
527cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
528cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
529cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
530cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
531cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
532cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
533cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->setPropertyString(name, value);
534cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
535cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
536cc82dc6d500023eba6048616301a4b12682458dbJeff Tinkerstatus_t Drm::setPropertyByteArray(String8 const &name,
537cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker                                   Vector<uint8_t> const &value ) const {
538cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    Mutex::Autolock autoLock(mLock);
539cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
540cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mInitCheck != OK) {
541cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return mInitCheck;
542cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
543cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
544cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    if (mPlugin == NULL) {
545cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker        return -EINVAL;
546cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    }
547cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
548cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker    return mPlugin->setPropertyByteArray(name, value);
549cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}
550cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker
5518856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5528856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
5538856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                                 String8 const &algorithm) {
5548856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
5558856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5568856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
5578856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
5588856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5598856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5608856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
5618856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
5628856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5638856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5648856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->setCipherAlgorithm(sessionId, algorithm);
5658856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
5668856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5678856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
5688856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                              String8 const &algorithm) {
5698856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
5708856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5718856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
5728856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
5738856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5748856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5758856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
5768856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
5778856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5788856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5798856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->setMacAlgorithm(sessionId, algorithm);
5808856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
5818856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5828856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::encrypt(Vector<uint8_t> const &sessionId,
5838856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &keyId,
5848856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &input,
5858856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &iv,
5868856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> &output) {
5878856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
5888856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5898856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
5908856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
5918856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5928856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5938856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
5948856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
5958856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
5968856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
5978856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->encrypt(sessionId, keyId, input, iv, output);
5988856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
5998856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6008856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::decrypt(Vector<uint8_t> const &sessionId,
6018856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &keyId,
6028856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &input,
6038856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> const &iv,
6048856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                      Vector<uint8_t> &output) {
6058856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
6068856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6078856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
6088856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
6098856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6108856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6118856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
6128856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
6138856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6148856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6158856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->decrypt(sessionId, keyId, input, iv, output);
6168856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
6178856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6188856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::sign(Vector<uint8_t> const &sessionId,
6198856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                   Vector<uint8_t> const &keyId,
6208856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                   Vector<uint8_t> const &message,
6218856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                   Vector<uint8_t> &signature) {
6228856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
6238856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6248856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
6258856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
6268856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6278856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6288856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
6298856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
6308856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6318856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6328856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->sign(sessionId, keyId, message, signature);
6338856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
6348856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6358856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinkerstatus_t Drm::verify(Vector<uint8_t> const &sessionId,
6368856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                     Vector<uint8_t> const &keyId,
6378856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                     Vector<uint8_t> const &message,
6388856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                     Vector<uint8_t> const &signature,
6398856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker                     bool &match) {
6408856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    Mutex::Autolock autoLock(mLock);
6418856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6428856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mInitCheck != OK) {
6438856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return mInitCheck;
6448856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6458856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6468856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    if (mPlugin == NULL) {
6478856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker        return -EINVAL;
6488856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    }
6498856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
6508856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker    return mPlugin->verify(sessionId, keyId, message, signature, match);
6518856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker}
6528856c8b8777d0e0de11b2de863a336b001024e29Jeff Tinker
65368d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinkerstatus_t Drm::signRSA(Vector<uint8_t> const &sessionId,
65468d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                      String8 const &algorithm,
65568d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                      Vector<uint8_t> const &message,
65668d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                      Vector<uint8_t> const &wrappedKey,
65768d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker                      Vector<uint8_t> &signature) {
65868d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    Mutex::Autolock autoLock(mLock);
65968d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker
66068d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    if (mInitCheck != OK) {
66168d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker        return mInitCheck;
66268d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    }
66368d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker
66468d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    if (mPlugin == NULL) {
66568d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker        return -EINVAL;
66668d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    }
66768d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker
66881e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
66981e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker        return -EPERM;
67081e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker    }
67181e0bd44a10e90778ab5b0a3babd4fc52cadedd8Jeff Tinker
67268d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker    return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
67368d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker}
67468d9d71a792deed75d32fe13febc07c9c12c8449Jeff Tinker
6753d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinkervoid Drm::binderDied(const wp<IBinder> &the_late_who)
6763d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker{
6774dbc8cc68a2674110ac1dce9e475ac30b1baa7c5Jeff Tinker    mEventLock.lock();
6784dbc8cc68a2674110ac1dce9e475ac30b1baa7c5Jeff Tinker    mListener.clear();
6794dbc8cc68a2674110ac1dce9e475ac30b1baa7c5Jeff Tinker    mEventLock.unlock();
6804dbc8cc68a2674110ac1dce9e475ac30b1baa7c5Jeff Tinker
6814dbc8cc68a2674110ac1dce9e475ac30b1baa7c5Jeff Tinker    Mutex::Autolock autoLock(mLock);
6823d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    delete mPlugin;
6833d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    mPlugin = NULL;
6843d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker    closeFactory();
6853d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker}
6863d3f67f3afa45e6b49d85b20942ee8184a33c1a4Jeff Tinker
687cc82dc6d500023eba6048616301a4b12682458dbJeff Tinker}  // namespace android
688