diff options
| author | Jeff Tinker <jtinker@google.com> | 2013-04-02 13:08:05 -0700 | 
|---|---|---|
| committer | Jeff Tinker <jtinker@google.com> | 2013-04-03 12:20:53 -0700 | 
| commit | c0d5f1f8405de861ed6f1725f26cd6601e7103ab (patch) | |
| tree | 710d03a7ee6541642c1dc16ac82b4ffea3903968 | |
| parent | 4c63a239c404af1e055e5f9939939ab0fd09d98a (diff) | |
| download | frameworks_av-c0d5f1f8405de861ed6f1725f26cd6601e7103ab.zip frameworks_av-c0d5f1f8405de861ed6f1725f26cd6601e7103ab.tar.gz frameworks_av-c0d5f1f8405de861ed6f1725f26cd6601e7103ab.tar.bz2  | |
Implement async event callout from drm plugin to Java app
Change-Id: I007f147d693664e777b8758be2bb8a4c7ec0236b
| -rw-r--r-- | drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp | 26 | ||||
| -rw-r--r-- | include/media/IDrm.h | 3 | ||||
| -rw-r--r-- | include/media/IDrmClient.h | 48 | ||||
| -rw-r--r-- | media/libmedia/Android.mk | 1 | ||||
| -rw-r--r-- | media/libmedia/IDrm.cpp | 19 | ||||
| -rw-r--r-- | media/libmedia/IDrmClient.cpp | 81 | ||||
| -rw-r--r-- | media/libmediaplayerservice/Drm.cpp | 40 | ||||
| -rw-r--r-- | media/libmediaplayerservice/Drm.h | 14 | 
8 files changed, 228 insertions, 4 deletions
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp index c34690b..00f6de3 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -343,7 +343,31 @@ namespace android {          Mutex::Autolock lock(mLock);          ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",                name.string(), value.string()); -        mStringProperties.add(name, value); + +        if (name == "mock-send-event") { +            unsigned code, extra; +            sscanf(value.string(), "%d %d", &code, &extra); +            DrmPlugin::EventType eventType = (DrmPlugin::EventType)code; + +            Vector<uint8_t> const *pSessionId = NULL; +            ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id")); +            if (index >= 0) { +                pSessionId = &mByteArrayProperties[index]; +            } + +            Vector<uint8_t> const *pData = NULL; +            index = mByteArrayProperties.indexOfKey(String8("mock-event-data")); +            if (index >= 0) { +                pData = &mByteArrayProperties[index]; +            } +            ALOGD("sending event from mock drm plugin: %d %d %s %s", +                  (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}", +                  pData ? vectorToString(*pData) : "{}"); + +            sendEvent(eventType, extra, pSessionId, pData); +        } else { +            mStringProperties.add(name, value); +        }          return OK;      } diff --git a/include/media/IDrm.h b/include/media/IDrm.h index 15d0a75..d630c40 100644 --- a/include/media/IDrm.h +++ b/include/media/IDrm.h @@ -17,6 +17,7 @@  #include <binder/IInterface.h>  #include <media/stagefright/foundation/ABase.h>  #include <media/drm/DrmAPI.h> +#include <media/IDrmClient.h>  #ifndef ANDROID_IDRM_H_ @@ -106,6 +107,8 @@ struct IDrm : public IInterface {                              Vector<uint8_t> const &signature,                              bool &match) = 0; +    virtual status_t setListener(const sp<IDrmClient>& listener) = 0; +  private:      DISALLOW_EVIL_CONSTRUCTORS(IDrm);  }; diff --git a/include/media/IDrmClient.h b/include/media/IDrmClient.h new file mode 100644 index 0000000..3b2fc7c --- /dev/null +++ b/include/media/IDrmClient.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 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. + */ + +#ifndef ANDROID_IDRMCLIENT_H +#define ANDROID_IDRMCLIENT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <media/drm/DrmAPI.h> + +namespace android { + +class IDrmClient: public IInterface +{ +public: +    DECLARE_META_INTERFACE(DrmClient); + +    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnDrmClient: public BnInterface<IDrmClient> +{ +public: +    virtual status_t onTransact(uint32_t code, +                                const Parcel& data, +                                Parcel* reply, +                                uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IDRMCLIENT_H diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 1ada9c3..fbe71ad 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES:= \      IAudioRecord.cpp \      ICrypto.cpp \      IDrm.cpp \ +    IDrmClient.cpp \      IHDCP.cpp \      AudioRecord.cpp \      AudioSystem.cpp \ diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index 1641b56..1578846 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -51,7 +51,8 @@ enum {      ENCRYPT,      DECRYPT,      SIGN, -    VERIFY +    VERIFY, +    SET_LISTENER  };  struct BpDrm : public BpInterface<IDrm> { @@ -384,6 +385,14 @@ struct BpDrm : public BpInterface<IDrm> {          return reply.readInt32();      } +    virtual status_t setListener(const sp<IDrmClient>& listener) { +        Parcel data, reply; +        data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); +        data.writeStrongBinder(listener->asBinder()); +        remote()->transact(SET_LISTENER, data, &reply); +        return reply.readInt32(); +    } +  private:      void readVector(Parcel &reply, Vector<uint8_t> &vector) const {          uint32_t size = reply.readInt32(); @@ -712,6 +721,14 @@ status_t BnDrm::onTransact(              return OK;          } +    case SET_LISTENER: { +        CHECK_INTERFACE(IDrm, data, reply); +        sp<IDrmClient> listener = +            interface_cast<IDrmClient>(data.readStrongBinder()); +        reply->writeInt32(setListener(listener)); +        return NO_ERROR; +    } break; +      default:          return BBinder::onTransact(code, data, reply, flags);      } diff --git a/media/libmedia/IDrmClient.cpp b/media/libmedia/IDrmClient.cpp new file mode 100644 index 0000000..f50715e --- /dev/null +++ b/media/libmedia/IDrmClient.cpp @@ -0,0 +1,81 @@ +/* +** +** Copyright 2013, 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. +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "IDrmClient" +#include <utils/Log.h> + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +#include <media/IMediaPlayerClient.h> +#include <media/IDrmClient.h> + +namespace android { + +enum { +    NOTIFY = IBinder::FIRST_CALL_TRANSACTION, +}; + +class BpDrmClient: public BpInterface<IDrmClient> +{ +public: +    BpDrmClient(const sp<IBinder>& impl) +        : BpInterface<IDrmClient>(impl) +    { +    } + +    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) +    { +        Parcel data, reply; +        data.writeInterfaceToken(IDrmClient::getInterfaceDescriptor()); +        data.writeInt32((int)eventType); +        data.writeInt32(extra); +        if (obj && obj->dataSize() > 0) { +            data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); +        } +        remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); +    } +}; + +IMPLEMENT_META_INTERFACE(DrmClient, "android.media.IDrmClient"); + +// ---------------------------------------------------------------------- + +status_t BnDrmClient::onTransact( +    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ +    switch (code) { +        case NOTIFY: { +            CHECK_INTERFACE(IDrmClient, data, reply); +            int eventType = data.readInt32(); +            int extra = data.readInt32(); +            Parcel obj; +            if (data.dataAvail() > 0) { +                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); +            } + +            notify((DrmPlugin::EventType)eventType, extra, &obj); +            return NO_ERROR; +        } break; +        default: +            return BBinder::onTransact(code, data, reply, flags); +    } +} + +}; // namespace android diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp index 5fdb9f4..1e6cd94 100644 --- a/media/libmediaplayerservice/Drm.cpp +++ b/media/libmediaplayerservice/Drm.cpp @@ -47,6 +47,7 @@ static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {  Drm::Drm()      : mInitCheck(NO_INIT), +      mListener(NULL),        mFactory(NULL),        mPlugin(NULL) {  } @@ -67,6 +68,41 @@ status_t Drm::initCheck() const {      return mInitCheck;  } +status_t Drm::setListener(const sp<IDrmClient>& listener) +{ +    Mutex::Autolock lock(mEventLock); +    mListener = listener; +    return NO_ERROR; +} + +void Drm::sendEvent(DrmPlugin::EventType eventType, int extra, +                    Vector<uint8_t> const *sessionId, +                    Vector<uint8_t> const *data) +{ +    mEventLock.lock(); +    sp<IDrmClient> listener = mListener; +    mEventLock.unlock(); + +    if (listener != NULL) { +        Parcel obj; +        if (sessionId && sessionId->size()) { +            obj.writeInt32(sessionId->size()); +            obj.write(sessionId->array(), sessionId->size()); +        } else { +            obj.writeInt32(0); +        } + +        if (data && data->size()) { +            obj.writeInt32(data->size()); +            obj.write(data->array(), data->size()); +        } else { +            obj.writeInt32(0); +        } + +        Mutex::Autolock lock(mNotifyLock); +        listener->notify(eventType, extra, &obj); +    } +}  /*   * Search the plugins directory for a plugin that supports the scheme @@ -195,7 +231,9 @@ status_t Drm::createPlugin(const uint8_t uuid[16]) {          return mInitCheck;      } -    return mFactory->createDrmPlugin(uuid, &mPlugin); +    status_t result = mFactory->createDrmPlugin(uuid, &mPlugin); +    mPlugin->setListener(this); +    return result;  }  status_t Drm::destroyPlugin() { diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h index f24921e..3da8ad4 100644 --- a/media/libmediaplayerservice/Drm.h +++ b/media/libmediaplayerservice/Drm.h @@ -21,6 +21,7 @@  #include "SharedLibrary.h"  #include <media/IDrm.h> +#include <media/IDrmClient.h>  #include <utils/threads.h>  namespace android { @@ -28,7 +29,7 @@ namespace android {  struct DrmFactory;  struct DrmPlugin; -struct Drm : public BnDrm { +struct Drm : public BnDrm, public DrmPluginListener {      Drm();      virtual ~Drm(); @@ -108,10 +109,21 @@ struct Drm : public BnDrm {                              Vector<uint8_t> const &signature,                              bool &match); +    virtual status_t setListener(const sp<IDrmClient>& listener); + +    virtual void sendEvent(DrmPlugin::EventType eventType, int extra, +                           Vector<uint8_t> const *sessionId, +                           Vector<uint8_t> const *data); +  private:      mutable Mutex mLock;      status_t mInitCheck; + +    sp<IDrmClient> mListener; +    mutable Mutex mEventLock; +    mutable Mutex mNotifyLock; +      sp<SharedLibrary> mLibrary;      DrmFactory *mFactory;      DrmPlugin *mPlugin;  | 
