MTP: Include current property value in GetDevicePropDesc

Change-Id: I05125c79ad58b6f75734fcedcc8af9b689fa9ff3
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 995f589..bbd0237 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -36,10 +36,10 @@
         mEnumLength(0),
         mEnumValues(NULL)
 {
-    mDefaultValue.str = NULL;
-    mCurrentValue.str = NULL;
-    mMinimumValue.str = NULL;
-    mMaximumValue.str = NULL;
+    memset(&mDefaultValue, 0, sizeof(mDefaultValue));
+    memset(&mCurrentValue, 0, sizeof(mCurrentValue));
+    memset(&mMinimumValue, 0, sizeof(mMinimumValue));
+    memset(&mMaximumValue, 0, sizeof(mMaximumValue));
 }
 
 MtpProperty::MtpProperty(MtpPropertyCode propCode,
@@ -66,28 +66,28 @@
     if (defaultValue) {
         switch (type) {
             case MTP_TYPE_INT8:
-                mDefaultValue.i8 = defaultValue;
+                mDefaultValue.u.i8 = defaultValue;
                 break;
             case MTP_TYPE_UINT8:
-                mDefaultValue.u8 = defaultValue;
+                mDefaultValue.u.u8 = defaultValue;
                 break;
             case MTP_TYPE_INT16:
-                mDefaultValue.i16 = defaultValue;
+                mDefaultValue.u.i16 = defaultValue;
                 break;
             case MTP_TYPE_UINT16:
-                mDefaultValue.u16 = defaultValue;
+                mDefaultValue.u.u16 = defaultValue;
                 break;
             case MTP_TYPE_INT32:
-                mDefaultValue.i32 = defaultValue;
+                mDefaultValue.u.i32 = defaultValue;
                 break;
             case MTP_TYPE_UINT32:
-                mDefaultValue.u32 = defaultValue;
+                mDefaultValue.u.u32 = defaultValue;
                 break;
             case MTP_TYPE_INT64:
-                mDefaultValue.i64 = defaultValue;
+                mDefaultValue.u.i64 = defaultValue;
                 break;
             case MTP_TYPE_UINT64:
-                mDefaultValue.u64 = defaultValue;
+                mDefaultValue.u.u64 = defaultValue;
                 break;
             default:
                 LOGE("unknown type %04X in MtpProperty::MtpProperty", type);
@@ -203,6 +203,26 @@
     }
 }
 
+void MtpProperty::setDefaultValue(const uint16_t* string) {
+    free(mDefaultValue.str);
+    if (string) {
+        MtpStringBuffer buffer(string);
+        mDefaultValue.str = strdup(buffer);
+    }
+    else
+        mDefaultValue.str = NULL;
+}
+
+void MtpProperty::setCurrentValue(const uint16_t* string) {
+    free(mCurrentValue.str);
+    if (string) {
+        MtpStringBuffer buffer(string);
+        mCurrentValue.str = strdup(buffer);
+    }
+    else
+        mCurrentValue.str = NULL;
+}
+
 void MtpProperty::print() {
     LOGV("MtpProperty %04X\n", mCode);
     LOGV("    type %04X\n", mType);
@@ -215,43 +235,43 @@
     switch (mType) {
         case MTP_TYPE_INT8:
         case MTP_TYPE_AINT8:
-            value.i8 = packet.getInt8();
+            value.u.i8 = packet.getInt8();
             break;
         case MTP_TYPE_UINT8:
         case MTP_TYPE_AUINT8:
-            value.u8 = packet.getUInt8();
+            value.u.u8 = packet.getUInt8();
             break;
         case MTP_TYPE_INT16:
         case MTP_TYPE_AINT16:
-            value.i16 = packet.getInt16();
+            value.u.i16 = packet.getInt16();
             break;
         case MTP_TYPE_UINT16:
         case MTP_TYPE_AUINT16:
-            value.u16 = packet.getUInt16();
+            value.u.u16 = packet.getUInt16();
             break;
         case MTP_TYPE_INT32:
         case MTP_TYPE_AINT32:
-            value.i32 = packet.getInt32();
+            value.u.i32 = packet.getInt32();
             break;
         case MTP_TYPE_UINT32:
         case MTP_TYPE_AUINT32:
-            value.u32 = packet.getUInt32();
+            value.u.u32 = packet.getUInt32();
             break;
         case MTP_TYPE_INT64:
         case MTP_TYPE_AINT64:
-            value.i64 = packet.getInt64();
+            value.u.i64 = packet.getInt64();
             break;
         case MTP_TYPE_UINT64:
         case MTP_TYPE_AUINT64:
-            value.u64 = packet.getUInt64();
+            value.u.u64 = packet.getUInt64();
             break;
         case MTP_TYPE_INT128:
         case MTP_TYPE_AINT128:
-            packet.getInt128(value.i128);
+            packet.getInt128(value.u.i128);
             break;
         case MTP_TYPE_UINT128:
         case MTP_TYPE_AUINT128:
-            packet.getUInt128(value.u128);
+            packet.getUInt128(value.u.u128);
             break;
         case MTP_TYPE_STR:
             packet.getString(stringBuffer);
@@ -268,43 +288,43 @@
     switch (mType) {
         case MTP_TYPE_INT8:
         case MTP_TYPE_AINT8:
-            packet.putInt8(value.i8);
+            packet.putInt8(value.u.i8);
             break;
         case MTP_TYPE_UINT8:
         case MTP_TYPE_AUINT8:
-            packet.putUInt8(value.u8);
+            packet.putUInt8(value.u.u8);
             break;
         case MTP_TYPE_INT16:
         case MTP_TYPE_AINT16:
-            packet.putInt16(value.i16);
+            packet.putInt16(value.u.i16);
             break;
         case MTP_TYPE_UINT16:
         case MTP_TYPE_AUINT16:
-            packet.putUInt16(value.u16);
+            packet.putUInt16(value.u.u16);
             break;
         case MTP_TYPE_INT32:
         case MTP_TYPE_AINT32:
-            packet.putInt32(value.i32);
+            packet.putInt32(value.u.i32);
             break;
         case MTP_TYPE_UINT32:
         case MTP_TYPE_AUINT32:
-            packet.putUInt32(value.u32);
+            packet.putUInt32(value.u.u32);
             break;
         case MTP_TYPE_INT64:
         case MTP_TYPE_AINT64:
-            packet.putInt64(value.i64);
+            packet.putInt64(value.u.i64);
             break;
         case MTP_TYPE_UINT64:
         case MTP_TYPE_AUINT64:
-            packet.putUInt64(value.u64);
+            packet.putUInt64(value.u.u64);
             break;
         case MTP_TYPE_INT128:
         case MTP_TYPE_AINT128:
-            packet.putInt128(value.i128);
+            packet.putInt128(value.u.i128);
             break;
         case MTP_TYPE_UINT128:
         case MTP_TYPE_AUINT128:
-            packet.putUInt128(value.u128);
+            packet.putUInt128(value.u.u128);
             break;
         case MTP_TYPE_STR:
             if (value.str)
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index 64cfb93..98b465a 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -23,6 +23,23 @@
 
 class MtpDataPacket;
 
+struct MtpPropertyValue {
+    union {
+        int8_t          i8;
+        uint8_t         u8;
+        int16_t         i16;
+        uint16_t        u16;
+        int32_t         i32;
+        uint32_t        u32;
+        int64_t         i64;
+        uint64_t        u64;
+        int128_t        i128;
+        uint128_t       u128;
+    } u;
+    // string in UTF8 format
+    char*               str;
+};
+
 class MtpProperty {
 public:
     MtpPropertyCode     mCode;
@@ -68,6 +85,9 @@
     void                read(MtpDataPacket& packet);
     void                write(MtpDataPacket& packet);
 
+    void                setDefaultValue(const uint16_t* string);
+    void                setCurrentValue(const uint16_t* string);
+
     void                print();
 
     inline bool         isDeviceProperty() const {
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index 8bf6731..fe8cf04 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -37,6 +37,13 @@
     set(src);
 }
 
+MtpStringBuffer::MtpStringBuffer(const uint16_t* src)
+    :   mCharCount(0),
+        mByteCount(1)
+{
+    set(src);
+}
+
 MtpStringBuffer::MtpStringBuffer(const MtpStringBuffer& src)
     :   mCharCount(src.mCharCount),
         mByteCount(src.mByteCount)
@@ -88,6 +95,29 @@
     mCharCount = count;
 }
 
+void MtpStringBuffer::set(const uint16_t* src) {
+    int count = 0;
+    uint16_t ch;
+    uint8_t* dest = mBuffer;
+
+    while ((ch = *src++) != 0 && count < 255) {
+        if (ch >= 0x0800) {
+            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
+            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
+            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
+        } else if (ch >= 0x80) {
+            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
+            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
+        } else {
+            *dest++ = ch;
+        }
+        count++;
+    }
+    *dest++ = 0;
+    mCharCount = count;
+    mByteCount = dest - mBuffer;
+}
+
 void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
     int count = packet->getUInt8();
     uint8_t* dest = mBuffer;
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index 4641c3f..cbc8307 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -27,6 +27,7 @@
 class MtpStringBuffer {
 
 private:
+    // mBuffer contains string in UTF8 format
     // maximum 3 bytes/character, with 1 extra for zero termination
     uint8_t         mBuffer[255 * 3 + 1];
     int             mCharCount;
@@ -35,10 +36,12 @@
 public:
                     MtpStringBuffer();
                     MtpStringBuffer(const char* src);
+                    MtpStringBuffer(const uint16_t* src);
                     MtpStringBuffer(const MtpStringBuffer& src);
     virtual         ~MtpStringBuffer();
 
     void            set(const char* src);
+    void            set(const uint16_t* src);
 
     void            readFromPacket(MtpDataPacket* packet);
     void            writeToPacket(MtpDataPacket* packet) const;
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index 7e3c009..720c854 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -43,20 +43,6 @@
 // values 0x00000000 and 0xFFFFFFFF are reserved for special purposes.
 typedef uint32_t MtpObjectHandle;
 
-union MtpPropertyValue {
-    int8_t          i8;
-    uint8_t         u8;
-    int16_t         i16;
-    uint16_t        u16;
-    int32_t         i32;
-    uint32_t        u32;
-    int64_t         i64;
-    uint64_t        u64;
-    int128_t        i128;
-    uint128_t       u128;
-    char*           str;
-};
-
 // Special values
 #define MTP_PARENT_ROOT         0xFFFFFFFF       // parent is root of the storage
 #define kInvalidObjectHandle    0xFFFFFFFF