Merge "Enhancement for OnInfo callback on DRM Framework" into klp-dev
diff --git a/drm/common/DrmInfoEvent.cpp b/drm/common/DrmInfoEvent.cpp
index 27a5a2d..2315aa9 100644
--- a/drm/common/DrmInfoEvent.cpp
+++ b/drm/common/DrmInfoEvent.cpp
@@ -16,16 +16,29 @@
 
 #include <utils/String8.h>
 #include <drm/DrmInfoEvent.h>
+#include <stdlib.h>
 
 using namespace android;
 
 DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8 message)
     : mUniqueId(uniqueId),
       mInfoType(infoType),
-      mMessage(message) {
+      mMessage(message),
+      mDrmBuffer() {
 
 }
 
+DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8 message,
+        const DrmBuffer& drmBuffer)
+        : mUniqueId(uniqueId), mInfoType(infoType), mMessage(message), mDrmBuffer() {
+    setData(drmBuffer);
+}
+
+DrmInfoEvent::~DrmInfoEvent() {
+    delete [] mDrmBuffer.data;
+}
+
+
 int DrmInfoEvent::getUniqueId() const {
     return mUniqueId;
 }
@@ -38,3 +51,80 @@
     return mMessage;
 }
 
+int DrmInfoEvent::getCount() const {
+    return mAttributes.size();
+}
+
+status_t DrmInfoEvent::put(const String8& key, String8& value) {
+        mAttributes.add(key, value);
+    return DRM_NO_ERROR;
+}
+
+const String8 DrmInfoEvent::get(const String8& key) const {
+    if (mAttributes.indexOfKey(key) != NAME_NOT_FOUND) {
+        return mAttributes.valueFor(key);
+    }
+    return String8("");
+}
+
+const DrmBuffer& DrmInfoEvent::getData() const {
+    return mDrmBuffer;
+}
+
+void DrmInfoEvent::setData(const DrmBuffer& drmBuffer) {
+    delete [] mDrmBuffer.data;
+    mDrmBuffer.data = new char[drmBuffer.length];;
+    mDrmBuffer.length = drmBuffer.length;
+    memcpy(mDrmBuffer.data, drmBuffer.data, drmBuffer.length);
+}
+
+DrmInfoEvent::KeyIterator DrmInfoEvent::keyIterator() const {
+    return KeyIterator(this);
+}
+
+DrmInfoEvent::Iterator DrmInfoEvent::iterator() const {
+    return Iterator(this);
+}
+
+// KeyIterator implementation
+DrmInfoEvent::KeyIterator::KeyIterator(const DrmInfoEvent::KeyIterator& keyIterator)
+        : mDrmInfoEvent(keyIterator.mDrmInfoEvent), mIndex(keyIterator.mIndex) {
+}
+
+bool DrmInfoEvent::KeyIterator::hasNext() {
+    return (mIndex < mDrmInfoEvent->mAttributes.size());
+}
+
+const String8& DrmInfoEvent::KeyIterator::next() {
+    const String8& key = mDrmInfoEvent->mAttributes.keyAt(mIndex);
+    mIndex++;
+    return key;
+}
+
+DrmInfoEvent::KeyIterator& DrmInfoEvent::KeyIterator::operator=(
+        const DrmInfoEvent::KeyIterator& keyIterator) {
+    mDrmInfoEvent = keyIterator.mDrmInfoEvent;
+    mIndex = keyIterator.mIndex;
+    return *this;
+}
+
+// Iterator implementation
+DrmInfoEvent::Iterator::Iterator(const DrmInfoEvent::Iterator& iterator)
+        : mDrmInfoEvent(iterator.mDrmInfoEvent), mIndex(iterator.mIndex) {
+}
+
+DrmInfoEvent::Iterator& DrmInfoEvent::Iterator::operator=(const DrmInfoEvent::Iterator& iterator) {
+    mDrmInfoEvent = iterator.mDrmInfoEvent;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmInfoEvent::Iterator::hasNext() {
+    return mIndex < mDrmInfoEvent->mAttributes.size();
+}
+
+const String8& DrmInfoEvent::Iterator::next() {
+    const String8& value = mDrmInfoEvent->mAttributes.editValueAt(mIndex);
+    mIndex++;
+    return value;
+}
diff --git a/drm/common/IDrmServiceListener.cpp b/drm/common/IDrmServiceListener.cpp
index 6eeea40..d825afb 100644
--- a/drm/common/IDrmServiceListener.cpp
+++ b/drm/common/IDrmServiceListener.cpp
@@ -32,6 +32,19 @@
     data.writeInt32(event.getType());
     data.writeString8(event.getMessage());
 
+    data.writeInt32(event.getCount());
+    DrmInfoEvent::KeyIterator keyIt = event.keyIterator();
+    while (keyIt.hasNext()) {
+        String8 key = keyIt.next();
+        data.writeString8(key);
+        data.writeString8(event.get(key));
+    }
+    const DrmBuffer& value = event.getData();
+    data.writeInt32(value.length);
+    if (value.length > 0) {
+        data.write(value.data, value.length);
+    }
+
     remote()->transact(NOTIFY, data, &reply);
     return reply.readInt32();
 }
@@ -49,7 +62,24 @@
         int type = data.readInt32();
         const String8& message = data.readString8();
 
-        status_t status = notify(DrmInfoEvent(uniqueId, type, message));
+        DrmInfoEvent event(uniqueId, type, message);
+        int size = data.readInt32();
+        for (int index = 0; index < size; index++) {
+            String8 key(data.readString8());
+            String8 value(data.readString8());
+            event.put(key, value);
+        }
+        int valueSize = data.readInt32();
+        if (valueSize > 0) {
+            char* valueData = new char[valueSize];
+            data.read(valueData, valueSize);
+            DrmBuffer drmBuffer(valueData, valueSize);
+            event.setData(drmBuffer);
+            delete[] valueData;
+        }
+
+        status_t status = notify(event);
+
         reply->writeInt32(status);
 
         return DRM_NO_ERROR;
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index dfca228..23b2950 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -17,6 +17,8 @@
 #ifndef __DRM_INFO_EVENT_H__
 #define __DRM_INFO_EVENT_H__
 
+#include "drm_framework_common.h"
+
 namespace android {
 
 class String8;
@@ -71,18 +73,70 @@
 
 public:
     /**
-     * Constructor for DrmInfoEvent
+     * Constructor for DrmInfoEvent.
+     * Data in drmBuffer are copied to newly allocated buffer.
      *
      * @param[in] uniqueId Unique session identifier
      * @param[in] infoType Type of information
      * @param[in] message Message description
+     * @param[in] drmBuffer Binary information
      */
     DrmInfoEvent(int uniqueId, int infoType, const String8 message);
+    DrmInfoEvent(int uniqueId, int infoType, const String8 message, const DrmBuffer& drmBuffer);
 
     /**
      * Destructor for DrmInfoEvent
      */
-    virtual ~DrmInfoEvent() {}
+    ~DrmInfoEvent();
+
+public:
+    /**
+     * Iterator for key
+     */
+    class KeyIterator {
+        friend class DrmInfoEvent;
+
+    private:
+        KeyIterator(const DrmInfoEvent* drmInfoEvent)
+                : mDrmInfoEvent(const_cast <DrmInfoEvent*> (drmInfoEvent)), mIndex(0) {}
+
+    public:
+        KeyIterator(const KeyIterator& keyIterator);
+        KeyIterator& operator=(const KeyIterator& keyIterator);
+        virtual ~KeyIterator() {}
+
+    public:
+        bool hasNext();
+        const String8& next();
+
+    private:
+        DrmInfoEvent* mDrmInfoEvent;
+        unsigned int mIndex;
+    };
+
+    /**
+     * Iterator
+     */
+    class Iterator {
+        friend class DrmInfoEvent;
+
+    private:
+        Iterator(const DrmInfoEvent* drmInfoEvent)
+                : mDrmInfoEvent(const_cast <DrmInfoEvent*> (drmInfoEvent)), mIndex(0) {}
+
+    public:
+        Iterator(const Iterator& iterator);
+        Iterator& operator=(const Iterator& iterator);
+        virtual ~Iterator() {}
+
+    public:
+        bool hasNext();
+        const String8& next();
+
+    private:
+        DrmInfoEvent* mDrmInfoEvent;
+        unsigned int mIndex;
+    };
 
 public:
     /**
@@ -106,10 +160,69 @@
      */
     const String8 getMessage() const;
 
+    /**
+     * Returns the number of attributes contained in this instance
+     *
+     * @return Number of attributes
+     */
+    int getCount() const;
+
+    /**
+     * Adds optional information as <key, value> pair to this instance
+     *
+     * @param[in] key Key to add
+     * @param[in] value Value to add
+     * @return Returns the error code
+     */
+    status_t put(const String8& key, String8& value);
+
+    /**
+     * Retrieves the value of given key
+     *
+     * @param key Key whose value to be retrieved
+     * @return The value
+     */
+    const String8 get(const String8& key) const;
+
+    /**
+     * Returns KeyIterator object to walk through the keys associated with this instance
+     *
+     * @return KeyIterator object
+     */
+    KeyIterator keyIterator() const;
+
+    /**
+     * Returns Iterator object to walk through the values associated with this instance
+     *
+     * @return Iterator object
+     */
+    Iterator iterator() const;
+
+    /**
+     * Returns the Binary information associated with this instance
+     *
+     * @return Binary information
+     */
+    const DrmBuffer& getData() const;
+
+    /**
+     * Sets the Binary information associated with this instance.
+     * Data in drmBuffer are copied to newly allocated buffer.
+     *
+     * @param[in] drmBuffer Binary information associated with this instance
+     */
+    void setData(const DrmBuffer& drmBuffer);
+
+private:
+    DrmInfoEvent(const DrmInfoEvent& ref);
+    const DrmInfoEvent& operator=(const DrmInfoEvent& ref);
+
 private:
     int mUniqueId;
     int mInfoType;
     const String8 mMessage;
+    KeyedVector<String8, String8> mAttributes;
+    DrmBuffer mDrmBuffer;
 };
 
 };