MTP: Partial implementation of the GetObjectPropList command

In this initial implementation we only support fetching one property at a time.
Support depth = 0 (single object) or depth = 1 (all objects in a directory)
Reimplemented GetObjectPropValue on top of GetObjectPropList, since the former
is a special case of the latter.

Change-Id: Ia76ee61741d6ee3902b5c5d9fc094cf86dfaf650
Signed-off-by: Mike Lockwood <lockwood@google.com>
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index c8cb016..fafd221 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -75,6 +75,12 @@
 
     virtual MtpResponseCode         resetDeviceProperty(MtpDeviceProperty property) = 0;
 
+    virtual MtpResponseCode         getObjectPropertyList(MtpObjectHandle handle,
+                                            MtpObjectFormat format,
+                                            MtpObjectProperty property,
+                                            int groupCode, int depth,
+                                            MtpDataPacket& packet) = 0;
+
     virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
                                             MtpDataPacket& packet) = 0;
 
diff --git a/media/mtp/MtpDebug.cpp b/media/mtp/MtpDebug.cpp
index 3416807..1668ecf 100644
--- a/media/mtp/MtpDebug.cpp
+++ b/media/mtp/MtpDebug.cpp
@@ -56,6 +56,10 @@
     { "MTP_OPERATION_GET_OBJECT_PROP_DESC",         0x9802 },
     { "MTP_OPERATION_GET_OBJECT_PROP_VALUE",        0x9803 },
     { "MTP_OPERATION_SET_OBJECT_PROP_VALUE",        0x9804 },
+    { "MTP_OPERATION_GET_OBJECT_PROP_LIST",         0x9805 },
+    { "MTP_OPERATION_SET_OBJECT_PROP_LIST",         0x9806 },
+    { "MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC", 0x9807 },
+    { "MTP_OPERATION_SEND_OBJECT_PROP_LIST",        0x9808 },
     { "MTP_OPERATION_GET_OBJECT_REFERENCES",        0x9810 },
     { "MTP_OPERATION_SET_OBJECT_REFERENCES",        0x9811 },
     { "MTP_OPERATION_SKIP",                         0x9820 },
@@ -371,15 +375,21 @@
     return getCodeName(code, sOperationCodes);
 }
 
-const char* MtpDebug::getFormatCodeName(MtpOperationCode code) {
+const char* MtpDebug::getFormatCodeName(MtpObjectFormat code) {
+    if (code == 0)
+        return "NONE";
     return getCodeName(code, sFormatCodes);
 }
 
 const char* MtpDebug::getObjectPropCodeName(MtpPropertyCode code) {
+    if (code == 0)
+        return "NONE";
     return getCodeName(code, sObjectPropCodes);
 }
 
 const char* MtpDebug::getDevicePropCodeName(MtpPropertyCode code) {
+    if (code == 0)
+        return "NONE";
     return getCodeName(code, sDevicePropCodes);
 }
 
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index f7c12d6..86889c3 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -53,7 +53,7 @@
         mDefaultArrayValues(NULL),
         mCurrentArrayLength(0),
         mCurrentArrayValues(NULL),
-        mGroupCode(0),
+        mGroupCode(-1), // disable multiple properties in GetObjectPropList for now
         mFormFlag(kFormNone),
         mEnumLength(0),
         mEnumValues(NULL)
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 5ba6be9..6cf70ec 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -72,6 +72,10 @@
     MTP_OPERATION_GET_OBJECT_PROP_DESC,
     MTP_OPERATION_GET_OBJECT_PROP_VALUE,
     MTP_OPERATION_SET_OBJECT_PROP_VALUE,
+    MTP_OPERATION_GET_OBJECT_PROP_LIST,
+//    MTP_OPERATION_SET_OBJECT_PROP_LIST,
+//    MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC,
+//    MTP_OPERATION_SEND_OBJECT_PROP_LIST,
     MTP_OPERATION_GET_OBJECT_REFERENCES,
     MTP_OPERATION_SET_OBJECT_REFERENCES,
 //    MTP_OPERATION_SKIP,
@@ -276,6 +280,9 @@
         case MTP_OPERATION_RESET_DEVICE_PROP_VALUE:
             response = doResetDevicePropValue();
             break;
+        case MTP_OPERATION_GET_OBJECT_PROP_LIST:
+            response = doGetObjectPropList();
+            break;
         case MTP_OPERATION_GET_OBJECT_INFO:
             response = doGetObjectInfo();
             break;
@@ -523,6 +530,20 @@
     return mDatabase->resetDeviceProperty(property);
 }
 
+MtpResponseCode MtpServer::doGetObjectPropList() {
+
+    MtpObjectHandle handle = mRequest.getParameter(1);
+    MtpObjectFormat format = mRequest.getParameter(2);
+    MtpDeviceProperty property = mRequest.getParameter(3);
+    int groupCode = mRequest.getParameter(4);
+    int depth = mRequest.getParameter(4);
+   LOGD("GetObjectPropList %d format: %s property: %s group: %d depth: %d\n",
+            handle, MtpDebug::getFormatCodeName(format),
+            MtpDebug::getObjectPropCodeName(property), groupCode, depth);
+
+    return mDatabase->getObjectPropertyList(handle, format, property, groupCode, depth, mData);
+}
+
 MtpResponseCode MtpServer::doGetObjectInfo() {
     MtpObjectHandle handle = mRequest.getParameter(1);
     return mDatabase->getObjectInfo(handle, mData);
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 68a6564..e65ddb0 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -93,6 +93,7 @@
     MtpResponseCode     doGetDevicePropValue();
     MtpResponseCode     doSetDevicePropValue();
     MtpResponseCode     doResetDevicePropValue();
+    MtpResponseCode     doGetObjectPropList();
     MtpResponseCode     doGetObjectInfo();
     MtpResponseCode     doGetObject();
     MtpResponseCode     doSendObjectInfo();
diff --git a/media/mtp/mtp.h b/media/mtp/mtp.h
index b7afa66..8bc2e22 100644
--- a/media/mtp/mtp.h
+++ b/media/mtp/mtp.h
@@ -37,7 +37,7 @@
 #define MTP_CONTAINER_PARAMETER_OFFSET          12
 #define MTP_CONTAINER_HEADER_SIZE               12
 
-// MTP Types
+// MTP Data Types
 #define MTP_TYPE_UNDEFINED      0x0000          // Undefined
 #define MTP_TYPE_INT8           0x0001          // Signed 8-bit integer
 #define MTP_TYPE_UINT8          0x0002          // Unsigned 8-bit integer
@@ -383,6 +383,10 @@
 #define MTP_OPERATION_GET_OBJECT_PROP_DESC                  0x9802
 #define MTP_OPERATION_GET_OBJECT_PROP_VALUE                 0x9803
 #define MTP_OPERATION_SET_OBJECT_PROP_VALUE                 0x9804
+#define MTP_OPERATION_GET_OBJECT_PROP_LIST                  0x9805
+#define MTP_OPERATION_SET_OBJECT_PROP_LIST                  0x9806
+#define MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC          0x9807
+#define MTP_OPERATION_SEND_OBJECT_PROP_LIST                 0x9808
 #define MTP_OPERATION_GET_OBJECT_REFERENCES                 0x9810
 #define MTP_OPERATION_SET_OBJECT_REFERENCES                 0x9811
 #define MTP_OPERATION_SKIP                                  0x9820