1ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber/*
2ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Copyright (C) 2012 The Android Open Source Project
3ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber *
4ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * you may not use this file except in compliance with the License.
6ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * You may obtain a copy of the License at
7ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber *
8ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber *
10ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Unless required by applicable law or agreed to in writing, software
11ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * See the License for the specific language governing permissions and
14ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * limitations under the License.
15ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber */
16ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber//#define LOG_NDEBUG 0
18ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#define LOG_TAG "ICrypto"
19ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <utils/Log.h>
20ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <binder/Parcel.h>
22c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
23ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/MediaErrors.h>
25ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/ADebug.h>
265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
28ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android {
29ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberenum {
311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    IS_CRYPTO_SUPPORTED,
331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    CREATE_PLUGIN,
341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DESTROY_PLUGIN,
351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    REQUIRES_SECURE_COMPONENT,
361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DECRYPT,
372514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    NOTIFY_RESOLUTION,
381849570240443d1f75775c205fa658f7070849c6Jeff Tinker    SET_MEDIADRM_SESSION,
39d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    SET_HEAP,
40d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    UNSET_HEAP,
41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstruct BpCrypto : public BpInterface<ICrypto> {
44090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BpCrypto(const sp<IBinder> &impl)
45ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        : BpInterface<ICrypto>(impl) {
46ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
47ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t initCheck() const {
49ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(INIT_CHECK, data, &reply);
52ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
53ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
54ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
55ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
56bafb682ec7f51486e751fea954169deb91846063Jeff Tinker    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) {
57ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
58ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
61ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
63ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
64ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t createPlugin(
661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) {
67ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
68ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(opaqueSize);
71705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
72705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        if (opaqueSize > 0) {
73705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            data.write(opaqueData, opaqueSize);
74705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        }
75705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(CREATE_PLUGIN, data, &reply);
77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
78ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
79ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
80ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t destroyPlugin() {
82ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
83ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DESTROY_PLUGIN, data, &reply);
85ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
88ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool requiresSecureDecoderComponent(
901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime) const {
91ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
92ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeCString(mime);
941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
95ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
97ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
98ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
99a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
10018cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker            CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
1016dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            const SourceBuffer &source, size_t offset,
1021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            const DestinationBuffer &destination, AString *errorDetailMsg) {
104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
105ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(mode);
10718cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker        data.writeInt32(pattern.mEncryptBlocks);
10818cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker        data.writeInt32(pattern.mSkipBlocks);
1094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        static const uint8_t kDummy[16] = { 0 };
1114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (key == NULL) {
1134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = kDummy;
1144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (iv == NULL) {
1174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = kDummy;
1184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(key, 16);
1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(iv, 16);
1221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        size_t totalSize = 0;
1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfEncryptedData;
1261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfClearData;
127ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
128ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(totalSize);
1306dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        data.writeStrongBinder(IInterface::asBinder(source.mSharedMemory));
1316dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        data.writeInt32(source.mHeapSeqNum);
132c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker        data.writeInt32(offset);
1331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(numSubSamples);
1351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
137a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        data.writeInt32((int32_t)destination.mType);
138a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (destination.mType == kDestinationTypeNativeHandle) {
139a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            if (destination.mHandle == NULL) {
140a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                return BAD_VALUE;
141a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
142a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            data.writeNativeHandle(destination.mHandle);
1439ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker        } else {
144a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            if (destination.mSharedMemory == NULL) {
145a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                return BAD_VALUE;
146a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
147a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            data.writeStrongBinder(IInterface::asBinder(destination.mSharedMemory));
1481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
149ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DECRYPT, data, &reply);
151ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
152fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = reply.readInt32();
153ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
154ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker        if (isCryptoError(result)) {
1550be134af061566c7d68c0c4f868a677daf85f550Jeff Tinker            AString msg = reply.readCString();
1560be134af061566c7d68c0c4f868a677daf85f550Jeff Tinker            if (errorDetailMsg) {
1570be134af061566c7d68c0c4f868a677daf85f550Jeff Tinker                *errorDetailMsg = msg;
1580be134af061566c7d68c0c4f868a677daf85f550Jeff Tinker            }
159ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
160ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
161fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        return result;
162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
163ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1642514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    virtual void notifyResolution(
1652514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        uint32_t width, uint32_t height) {
1662514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        Parcel data, reply;
1672514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1682514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInt32(width);
1692514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInt32(height);
1702514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        remote()->transact(NOTIFY_RESOLUTION, data, &reply);
1712514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    }
1722514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
1731849570240443d1f75775c205fa658f7070849c6Jeff Tinker    virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) {
1741849570240443d1f75775c205fa658f7070849c6Jeff Tinker        Parcel data, reply;
1751849570240443d1f75775c205fa658f7070849c6Jeff Tinker        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1761849570240443d1f75775c205fa658f7070849c6Jeff Tinker
1771849570240443d1f75775c205fa658f7070849c6Jeff Tinker        writeVector(data, sessionId);
1781849570240443d1f75775c205fa658f7070849c6Jeff Tinker        remote()->transact(SET_MEDIADRM_SESSION, data, &reply);
1791849570240443d1f75775c205fa658f7070849c6Jeff Tinker
1801849570240443d1f75775c205fa658f7070849c6Jeff Tinker        return reply.readInt32();
1811849570240443d1f75775c205fa658f7070849c6Jeff Tinker    }
1821849570240443d1f75775c205fa658f7070849c6Jeff Tinker
1836dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    virtual int32_t setHeap(const sp<IMemoryHeap> &heap) {
184d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        Parcel data, reply;
185d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
186d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        data.writeStrongBinder(IInterface::asBinder(heap));
1876dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        status_t err = remote()->transact(SET_HEAP, data, &reply);
1886dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        if (err != NO_ERROR) {
1896dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            return -1;
1906dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        }
1916dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        int32_t seqNum;
1926dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        if (reply.readInt32(&seqNum) != NO_ERROR) {
1936dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            return -1;
1946dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        }
1956dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        return seqNum;
196d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    }
197d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
1986dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    virtual void unsetHeap(int32_t seqNum) {
199d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        Parcel data, reply;
200d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
2016dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        data.writeInt32(seqNum);
202d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        remote()->transact(UNSET_HEAP, data, &reply);
203d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        return;
204d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    }
205d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
206d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate:
2081849570240443d1f75775c205fa658f7070849c6Jeff Tinker    void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
2091849570240443d1f75775c205fa658f7070849c6Jeff Tinker        uint32_t size = reply.readInt32();
2101849570240443d1f75775c205fa658f7070849c6Jeff Tinker        vector.insertAt((size_t)0, size);
2111849570240443d1f75775c205fa658f7070849c6Jeff Tinker        reply.read(vector.editArray(), size);
2121849570240443d1f75775c205fa658f7070849c6Jeff Tinker    }
2131849570240443d1f75775c205fa658f7070849c6Jeff Tinker
2141849570240443d1f75775c205fa658f7070849c6Jeff Tinker    void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
2151849570240443d1f75775c205fa658f7070849c6Jeff Tinker        data.writeInt32(vector.size());
2161849570240443d1f75775c205fa658f7070849c6Jeff Tinker        data.write(vector.array(), vector.size());
2171849570240443d1f75775c205fa658f7070849c6Jeff Tinker    }
2181849570240443d1f75775c205fa658f7070849c6Jeff Tinker
219ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
223ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber////////////////////////////////////////////////////////////////////////////////
225ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2261849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
2271849570240443d1f75775c205fa658f7070849c6Jeff Tinker    uint32_t size = data.readInt32();
2281849570240443d1f75775c205fa658f7070849c6Jeff Tinker    vector.insertAt((size_t)0, size);
2291849570240443d1f75775c205fa658f7070849c6Jeff Tinker    data.read(vector.editArray(), size);
2301849570240443d1f75775c205fa658f7070849c6Jeff Tinker}
2311849570240443d1f75775c205fa658f7070849c6Jeff Tinker
2321849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
2331849570240443d1f75775c205fa658f7070849c6Jeff Tinker    reply->writeInt32(vector.size());
2341849570240443d1f75775c205fa658f7070849c6Jeff Tinker    reply->write(vector.array(), vector.size());
2351849570240443d1f75775c205fa658f7070849c6Jeff Tinker}
2361849570240443d1f75775c205fa658f7070849c6Jeff Tinker
237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact(
238ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
239ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    switch (code) {
2401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case INIT_CHECK:
241ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
242ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(initCheck());
244ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
245ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
247ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case IS_CRYPTO_SUPPORTED:
249ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
2521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
2531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(isCryptoSchemeSupported(uuid));
254ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
255ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
256ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
257ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case CREATE_PLUGIN:
259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
260ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
261ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
2631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
2641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t opaqueSize = data.readInt32();
266705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            void *opaqueData = NULL;
267705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
2689247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            const size_t kMaxOpaqueSize = 100 * 1024;
2699247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            if (opaqueSize > kMaxOpaqueSize) {
2709247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong                return BAD_VALUE;
2719247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            }
2729247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong
2739247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            opaqueData = malloc(opaqueSize);
2749247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            if (NULL == opaqueData) {
2759247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong                return NO_MEMORY;
276705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
277ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2789247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            data.read(opaqueData, opaqueSize);
2791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
280ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2819247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            free(opaqueData);
2829247e10531fa3128d5263e3ad605a0fecefcd2d0Edwin Wong            opaqueData = NULL;
283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DESTROY_PLUGIN:
288ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
289ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(destroyPlugin());
291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case REQUIRES_SECURE_COMPONENT:
296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime = data.readCString();
3002afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            if (mime == NULL) {
3012afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                reply->writeInt32(BAD_VALUE);
3022afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            } else {
3032afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                reply->writeInt32(requiresSecureDecoderComponent(mime));
3042afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            }
305ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return OK;
3071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
308ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DECRYPT:
3101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        {
3111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
312ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
31418cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker            CryptoPlugin::Pattern pattern;
31518cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker            pattern.mEncryptBlocks = data.readInt32();
31618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker            pattern.mSkipBlocks = data.readInt32();
317ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t key[16];
3191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(key, sizeof(key));
320ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t iv[16];
3221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(iv, sizeof(iv));
323ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t totalSize = data.readInt32();
3256dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
3266dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            SourceBuffer source;
3276dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
3286dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            source.mSharedMemory =
329c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                interface_cast<IMemory>(data.readStrongBinder());
3306dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            if (source.mSharedMemory == NULL) {
3312afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                reply->writeInt32(BAD_VALUE);
3322afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia                return OK;
3332afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia            }
3346dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            source.mHeapSeqNum = data.readInt32();
3356dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
336c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker            int32_t offset = data.readInt32();
337ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            int32_t numSubSamples = data.readInt32();
3394183d539fd9528d79d2c740769d01233b19017a1Jeff Tinker            if (numSubSamples < 0 || numSubSamples > 0xffff) {
3404183d539fd9528d79d2c740769d01233b19017a1Jeff Tinker                reply->writeInt32(BAD_VALUE);
3414183d539fd9528d79d2c740769d01233b19017a1Jeff Tinker                return OK;
3424183d539fd9528d79d2c740769d01233b19017a1Jeff Tinker            }
343ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::SubSample *subSamples =
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    new CryptoPlugin::SubSample[numSubSamples];
346ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            data.read(subSamples,
3481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    sizeof(CryptoPlugin::SubSample) * numSubSamples);
349ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
350a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            DestinationBuffer destination;
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            destination.mType = (DestinationType)data.readInt32();
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            if (destination.mType == kDestinationTypeNativeHandle) {
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                destination.mHandle = data.readNativeHandle();
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (destination.mHandle == NULL) {
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    reply->writeInt32(BAD_VALUE);
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    return OK;
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            } else if (destination.mType == kDestinationTypeSharedMemory) {
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                destination.mSharedMemory =
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        interface_cast<IMemory>(data.readStrongBinder());
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (destination.mSharedMemory == NULL) {
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    reply->writeInt32(BAD_VALUE);
363a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    return OK;
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
366ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            AString errorDetailMsg;
368c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker            ssize_t result;
369c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
370c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker            size_t sumSubsampleSizes = 0;
371c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker            bool overflow = false;
372c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker            for (int32_t i = 0; i < numSubSamples; ++i) {
373c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                CryptoPlugin::SubSample &ss = subSamples[i];
374c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) {
375c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                    sumSubsampleSizes += ss.mNumBytesOfEncryptedData;
376c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                } else {
377c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                    overflow = true;
378c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                }
379c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) {
380c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                    sumSubsampleSizes += ss.mNumBytesOfClearData;
381c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                } else {
382c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                    overflow = true;
383c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                }
384c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker            }
385c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker
386c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker            if (overflow || sumSubsampleSizes != totalSize) {
387c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker                result = -EINVAL;
3886dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            } else if (totalSize > source.mSharedMemory->size()) {
389bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker                result = -EINVAL;
3906dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            } else if ((size_t)offset > source.mSharedMemory->size() - totalSize) {
391c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                result = -EINVAL;
392c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker            } else {
393a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                result = decrypt(key, iv, mode, pattern, source, offset,
394a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        subSamples, numSubSamples, destination, &errorDetailMsg);
395c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker            }
396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
397fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            reply->writeInt32(result);
398ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
399ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker            if (isCryptoError(result)) {
4005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                reply->writeCString(errorDetailMsg.c_str());
4015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            }
4025b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
403a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            if (destination.mType == kDestinationTypeNativeHandle) {
4049ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                int err;
405a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if ((err = native_handle_close(destination.mHandle)) < 0) {
4069ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                    ALOGW("secure buffer native_handle_close failed: %d", err);
4079ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                }
408a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if ((err = native_handle_delete(destination.mHandle)) < 0) {
4099ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                    ALOGW("secure buffer native_handle_delete failed: %d", err);
4109ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                }
411ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
412ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            delete[] subSamples;
4141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            subSamples = NULL;
415ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
416ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
417ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
418ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4192514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        case NOTIFY_RESOLUTION:
4202514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        {
4212514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            CHECK_INTERFACE(ICrypto, data, reply);
4222514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
4232514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            int32_t width = data.readInt32();
4242514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            int32_t height = data.readInt32();
4252514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            notifyResolution(width, height);
4262514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
4272514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            return OK;
4282514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        }
4292514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
4301849570240443d1f75775c205fa658f7070849c6Jeff Tinker        case SET_MEDIADRM_SESSION:
4311849570240443d1f75775c205fa658f7070849c6Jeff Tinker        {
4321849570240443d1f75775c205fa658f7070849c6Jeff Tinker            CHECK_INTERFACE(IDrm, data, reply);
4331849570240443d1f75775c205fa658f7070849c6Jeff Tinker            Vector<uint8_t> sessionId;
4341849570240443d1f75775c205fa658f7070849c6Jeff Tinker            readVector(data, sessionId);
4351849570240443d1f75775c205fa658f7070849c6Jeff Tinker            reply->writeInt32(setMediaDrmSession(sessionId));
4361849570240443d1f75775c205fa658f7070849c6Jeff Tinker            return OK;
4371849570240443d1f75775c205fa658f7070849c6Jeff Tinker        }
4381849570240443d1f75775c205fa658f7070849c6Jeff Tinker
439d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        case SET_HEAP:
440d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        {
441d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang            CHECK_INTERFACE(ICrypto, data, reply);
442d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang            sp<IMemoryHeap> heap =
443d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang                interface_cast<IMemoryHeap>(data.readStrongBinder());
4446dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            reply->writeInt32(setHeap(heap));
445d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang            return OK;
446d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        }
447d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
448d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        case UNSET_HEAP:
449d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        {
450d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang            CHECK_INTERFACE(ICrypto, data, reply);
4516dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            int32_t seqNum = data.readInt32();
4526dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang            unsetHeap(seqNum);
453d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang            return OK;
454d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        }
455d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        default:
457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return BBinder::onTransact(code, data, reply, flags);
458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
460ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}  // namespace android
462