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

Commit 279dcd89 authored by Andreas Huber's avatar Andreas Huber
Browse files

Plumbing to reflect minor changes in the HDCP module API that allow for

support of _decryption_ modules in addition to what we already supported.

Change-Id: Ic37b87dc170ba8def3817991d25df798f21e950b
parent 150a516c
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -45,18 +45,34 @@ struct IHDCP : public IInterface {
    // Request to shutdown the active HDCP session.
    virtual status_t shutdownAsync() = 0;

    // Encrypt a data according to the HDCP spec. The data is to be
    // encrypted in-place, only size bytes of data should be read/write,
    // even if the size is not a multiple of 128 bit (16 bytes).
    // ENCRYPTION only:
    // Encrypt data according to the HDCP spec. "size" bytes of data are
    // available at "inData" (virtual address), "size" may not be a multiple
    // of 128 bits (16 bytes). An equal number of encrypted bytes should be
    // written to the buffer at "outData" (virtual address).
    // This operation is to be synchronous, i.e. this call does not return
    // until outData contains size bytes of encrypted data.
    // streamCTR will be assigned by the caller (to 0 for the first PES stream,
    // 1 for the second and so on)
    // inputCTR will be maintained by the callee for each PES stream.
    // inputCTR _will_be_maintained_by_the_callee_ for each PES stream.
    virtual status_t encrypt(
            const void *inData, size_t size, uint32_t streamCTR,
            uint64_t *outInputCTR, void *outData) = 0;

    // DECRYPTION only:
    // Decrypt data according to the HDCP spec.
    // "size" bytes of encrypted data are available at "inData"
    // (virtual address), "size" may not be a multiple of 128 bits (16 bytes).
    // An equal number of decrypted bytes should be written to the buffer
    // at "outData" (virtual address).
    // This operation is to be synchronous, i.e. this call does not return
    // until outData contains size bytes of decrypted data.
    // Both streamCTR and inputCTR will be provided by the caller.
    virtual status_t decrypt(
            const void *inData, size_t size,
            uint32_t streamCTR, uint64_t inputCTR,
            void *outData) = 0;

private:
    DISALLOW_EVIL_CONSTRUCTORS(IHDCP);
};
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ public:
    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<ICrypto>         makeCrypto() = 0;
    virtual sp<IHDCP>           makeHDCP() = 0;
    virtual sp<IHDCP>           makeHDCP(bool createEncryptionModule) = 0;

    // Connects to a remote display.
    // 'iface' specifies the address of the local interface on which to listen for
+49 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ enum {
    HDCP_INIT_ASYNC,
    HDCP_SHUTDOWN_ASYNC,
    HDCP_ENCRYPT,
    HDCP_DECRYPT,
};

struct BpHDCPObserver : public BpInterface<IHDCPObserver> {
@@ -106,6 +107,29 @@ struct BpHDCP : public BpInterface<IHDCP> {

        return err;
    }

    virtual status_t decrypt(
            const void *inData, size_t size,
            uint32_t streamCTR, uint64_t inputCTR,
            void *outData) {
        Parcel data, reply;
        data.writeInterfaceToken(IHDCP::getInterfaceDescriptor());
        data.writeInt32(size);
        data.write(inData, size);
        data.writeInt32(streamCTR);
        data.writeInt64(inputCTR);
        remote()->transact(HDCP_DECRYPT, data, &reply);

        status_t err = reply.readInt32();

        if (err != OK) {
            return err;
        }

        reply.read(outData, size);

        return err;
    }
};

IMPLEMENT_META_INTERFACE(HDCP, "android.hardware.IHDCP");
@@ -198,6 +222,31 @@ status_t BnHDCP::onTransact(
            return OK;
        }

        case HDCP_DECRYPT:
        {
            size_t size = data.readInt32();

            void *inData = malloc(2 * size);
            void *outData = (uint8_t *)inData + size;

            data.read(inData, size);

            uint32_t streamCTR = data.readInt32();
            uint64_t inputCTR = data.readInt64();
            status_t err = decrypt(inData, size, streamCTR, inputCTR, outData);

            reply->writeInt32(err);

            if (err == OK) {
                reply->write(outData, size);
            }

            free(inData);
            inData = outData = NULL;

            return OK;
        }

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+4 −2
Original line number Diff line number Diff line
@@ -123,9 +123,10 @@ public:
        return interface_cast<ICrypto>(reply.readStrongBinder());
    }

    virtual sp<IHDCP> makeHDCP() {
    virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeInt32(createEncryptionModule);
        remote()->transact(MAKE_HDCP, data, &reply);
        return interface_cast<IHDCP>(reply.readStrongBinder());
    }
@@ -226,7 +227,8 @@ status_t BnMediaPlayerService::onTransact(
        } break;
        case MAKE_HDCP: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IHDCP> hdcp = makeHDCP();
            bool createEncryptionModule = data.readInt32();
            sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);
            reply->writeStrongBinder(hdcp->asBinder());
            return NO_ERROR;
        } break;
+23 −3
Original line number Diff line number Diff line
@@ -26,8 +26,9 @@

namespace android {

HDCP::HDCP()
    : mLibHandle(NULL),
HDCP::HDCP(bool createEncryptionModule)
    : mIsEncryptionModule(createEncryptionModule),
      mLibHandle(NULL),
      mHDCPModule(NULL) {
    mLibHandle = dlopen("libstagefright_hdcp.so", RTLD_NOW);

@@ -40,7 +41,10 @@ HDCP::HDCP()
            void *, HDCPModule::ObserverFunc);

    CreateHDCPModuleFunc createHDCPModule =
        (CreateHDCPModuleFunc)dlsym(mLibHandle, "createHDCPModule");
        mIsEncryptionModule
            ? (CreateHDCPModuleFunc)dlsym(mLibHandle, "createHDCPModule")
            : (CreateHDCPModuleFunc)dlsym(
                    mLibHandle, "createHDCPModuleForDecryption");

    if (createHDCPModule == NULL) {
        ALOGE("Unable to find symbol 'createHDCPModule'.");
@@ -101,6 +105,8 @@ status_t HDCP::encrypt(
        uint64_t *outInputCTR, void *outData) {
    Mutex::Autolock autoLock(mLock);

    CHECK(mIsEncryptionModule);

    if (mHDCPModule == NULL) {
        *outInputCTR = 0;

@@ -110,6 +116,20 @@ status_t HDCP::encrypt(
    return mHDCPModule->encrypt(inData, size, streamCTR, outInputCTR, outData);
}

status_t HDCP::decrypt(
        const void *inData, size_t size,
        uint32_t streamCTR, uint64_t outInputCTR, void *outData) {
    Mutex::Autolock autoLock(mLock);

    CHECK(!mIsEncryptionModule);

    if (mHDCPModule == NULL) {
        return NO_INIT;
    }

    return mHDCPModule->decrypt(inData, size, streamCTR, outInputCTR, outData);
}

// static
void HDCP::ObserveWrapper(void *me, int msg, int ext1, int ext2) {
    static_cast<HDCP *>(me)->observe(msg, ext1, ext2);
Loading