Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed3e3e04 authored by Andreas Huber's avatar Andreas Huber
Browse files

Provisional support for secure decryption of media streams.

Change-Id: Ib3982a9c960bfdb0cb7e1b174440b141b194cfbe
parent cc1110dc
Loading
Loading
Loading
Loading
+50 −8
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/NuMediaExtractor.h>
#include <media/stagefright/NuMediaExtractor.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceComposerClient.h>
@@ -36,7 +37,9 @@ static void usage(const char *me) {
    fprintf(stderr, "usage: %s [-a] use audio\n"
    fprintf(stderr, "usage: %s [-a] use audio\n"
                    "\t\t[-v] use video\n"
                    "\t\t[-v] use video\n"
                    "\t\t[-p] playback\n"
                    "\t\t[-p] playback\n"
                    "\t\t[-S] allocate buffers from a surface\n", me);
                    "\t\t[-S] allocate buffers from a surface\n"
                    "\t\t[-D] decrypt input buffers\n",
                    me);


    exit(1);
    exit(1);
}
}
@@ -63,7 +66,8 @@ static int decode(
        const char *path,
        const char *path,
        bool useAudio,
        bool useAudio,
        bool useVideo,
        bool useVideo,
        const android::sp<android::Surface> &surface) {
        const android::sp<android::Surface> &surface,
        bool decryptInputBuffers) {
    using namespace android;
    using namespace android;


    static int64_t kTimeout = 500ll;
    static int64_t kTimeout = 500ll;
@@ -109,13 +113,31 @@ static int decode(
        state->mNumBuffersDecoded = 0;
        state->mNumBuffersDecoded = 0;
        state->mIsAudio = isAudio;
        state->mIsAudio = isAudio;


        if (decryptInputBuffers && !isAudio) {
            static const MediaCodecList *list = MediaCodecList::getInstance();

            ssize_t index =
                list->findCodecByType(mime.c_str(), false /* encoder */);

            CHECK_GE(index, 0);

            const char *componentName = list->getCodecName(index);

            AString fullName = componentName;
            fullName.append(".secure");

            state->mCodec = MediaCodec::CreateByComponentName(
                    looper, fullName.c_str());
        } else {
            state->mCodec = MediaCodec::CreateByType(
            state->mCodec = MediaCodec::CreateByType(
                    looper, mime.c_str(), false /* encoder */);
                    looper, mime.c_str(), false /* encoder */);
        }


        CHECK(state->mCodec != NULL);
        CHECK(state->mCodec != NULL);


        err = state->mCodec->configure(
        err = state->mCodec->configure(
                format, isVideo ? surface : NULL, 0 /* flags */);
                format, isVideo ? surface : NULL,
                decryptInputBuffers ? MediaCodec::CONFIGURE_FLAG_SECURE : 0);


        CHECK_EQ(err, (status_t)OK);
        CHECK_EQ(err, (status_t)OK);


@@ -202,12 +224,24 @@ static int decode(
                    err = extractor->getSampleTime(&timeUs);
                    err = extractor->getSampleTime(&timeUs);
                    CHECK_EQ(err, (status_t)OK);
                    CHECK_EQ(err, (status_t)OK);


                    uint32_t bufferFlags = 0;

                    uint32_t sampleFlags;
                    err = extractor->getSampleFlags(&sampleFlags);
                    CHECK_EQ(err, (status_t)OK);

                    if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) {
                        CHECK(decryptInputBuffers);

                        bufferFlags |= MediaCodec::BUFFER_FLAG_ENCRYPTED;
                    }

                    err = state->mCodec->queueInputBuffer(
                    err = state->mCodec->queueInputBuffer(
                            index,
                            index,
                            0 /* offset */,
                            0 /* offset */,
                            buffer->size(),
                            buffer->size(),
                            timeUs,
                            timeUs,
                            0 /* flags */);
                            bufferFlags);


                    CHECK_EQ(err, (status_t)OK);
                    CHECK_EQ(err, (status_t)OK);


@@ -341,9 +375,10 @@ int main(int argc, char **argv) {
    bool useVideo = false;
    bool useVideo = false;
    bool playback = false;
    bool playback = false;
    bool useSurface = false;
    bool useSurface = false;
    bool decryptInputBuffers = false;


    int res;
    int res;
    while ((res = getopt(argc, argv, "havpS")) >= 0) {
    while ((res = getopt(argc, argv, "havpSD")) >= 0) {
        switch (res) {
        switch (res) {
            case 'a':
            case 'a':
            {
            {
@@ -369,6 +404,12 @@ int main(int argc, char **argv) {
                break;
                break;
            }
            }


            case 'D':
            {
                decryptInputBuffers = true;
                break;
            }

            case '?':
            case '?':
            case 'h':
            case 'h':
            default:
            default:
@@ -440,7 +481,8 @@ int main(int argc, char **argv) {
        player->stop();
        player->stop();
        player->reset();
        player->reset();
    } else {
    } else {
        decode(looper, argv[0], useAudio, useVideo, surface);
        decode(looper, argv[0],
               useAudio, useVideo, surface, decryptInputBuffers);
    }
    }


    if (playback || (useSurface && useVideo)) {
    if (playback || (useSurface && useVideo)) {
+5 −0
Original line number Original line Diff line number Diff line
@@ -287,6 +287,11 @@ private:


            msg->setInt32("channel-count", numChannels);
            msg->setInt32("channel-count", numChannels);
            msg->setInt32("sample-rate", sampleRate);
            msg->setInt32("sample-rate", sampleRate);

            int32_t isADTS;
            if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) {
                msg->setInt32("is-adts", true);
            }
        }
        }


        uint32_t type;
        uint32_t type;
+63 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <binder/IInterface.h>
#include <media/stagefright/foundation/ABase.h>

#ifndef ANDROID_ICRYPTO_H_

#define ANDROID_ICRYPTO_H_

namespace android {

struct ICrypto : public IInterface {
    DECLARE_META_INTERFACE(Crypto);

    virtual status_t initialize() = 0;
    virtual status_t terminate() = 0;

    virtual status_t setEntitlementKey(
            const void *key, size_t keyLength) = 0;

    virtual status_t setEntitlementControlMessage(
            const void *msg, size_t msgLength) = 0;

    // "dstData" is in media_server's address space (but inaccessible).
    virtual ssize_t decryptVideo(
            const void *iv, size_t ivLength,
            const void *srcData, size_t srcDataSize,
            void *dstData, size_t dstDataOffset) = 0;

    // "dstData" is in the calling process' address space.
    virtual ssize_t decryptAudio(
            const void *iv, size_t ivLength,
            const void *srcData, size_t srcDataSize,
            void *dstData, size_t dstDataSize) = 0;

private:
    DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
};

struct BnCrypto : public BnInterface<ICrypto> {
    virtual status_t onTransact(
            uint32_t code, const Parcel &data, Parcel *reply,
            uint32_t flags = 0);
};

}  // namespace android

#endif // ANDROID_ICRYPTO_H_
+2 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@


namespace android {
namespace android {


struct ICrypto;
class IMediaRecorder;
class IMediaRecorder;
class IOMX;
class IOMX;
struct IStreamSource;
struct IStreamSource;
@@ -47,6 +48,7 @@ public:
    virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
    virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
    virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
    virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
    virtual sp<IOMX>            getOMX() = 0;
    virtual sp<IOMX>            getOMX() = 0;
    virtual sp<ICrypto>         makeCrypto() = 0;


    // codecs and audio devices usage tracking for the battery app
    // codecs and audio devices usage tracking for the battery app
    enum BatteryDataBits {
    enum BatteryDataBits {
+7 −1
Original line number Original line Diff line number Diff line
@@ -89,6 +89,10 @@ private:
        kPortIndexOutput = 1
        kPortIndexOutput = 1
    };
    };


    enum {
        kFlagIsSecure   = 1,
    };

    struct BufferInfo {
    struct BufferInfo {
        enum Status {
        enum Status {
            OWNED_BY_US,
            OWNED_BY_US,
@@ -118,6 +122,7 @@ private:
    sp<FlushingState> mFlushingState;
    sp<FlushingState> mFlushingState;


    AString mComponentName;
    AString mComponentName;
    uint32_t mFlags;
    uint32_t mQuirks;
    uint32_t mQuirks;
    sp<IOMX> mOMX;
    sp<IOMX> mOMX;
    IOMX::node_id mNode;
    IOMX::node_id mNode;
@@ -176,7 +181,8 @@ private:


    status_t setupAACCodec(
    status_t setupAACCodec(
            bool encoder,
            bool encoder,
            int32_t numChannels, int32_t sampleRate, int32_t bitRate);
            int32_t numChannels, int32_t sampleRate, int32_t bitRate,
            bool isADTS);


    status_t selectAudioPortFormat(
    status_t selectAudioPortFormat(
            OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
            OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
Loading