Merge "Better buffer status management and verification in OMXCodec."
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index b7e1a2a..e285847 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -47,3 +47,32 @@
 
 endif
 
+ifeq ($(HOST_OS),linux)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=                                       \
+                  MtpClient.cpp                         \
+                  MtpDataPacket.cpp                     \
+                  MtpDebug.cpp                          \
+                  MtpDevice.cpp                         \
+                  MtpEventPacket.cpp                    \
+                  MtpDeviceInfo.cpp                     \
+                  MtpObjectInfo.cpp                     \
+                  MtpPacket.cpp                         \
+                  MtpProperty.cpp                       \
+                  MtpRequestPacket.cpp                  \
+                  MtpResponsePacket.cpp                 \
+                  MtpStorageInfo.cpp                    \
+                  MtpStringBuffer.cpp                   \
+                  MtpStorage.cpp                        \
+                  MtpUtils.cpp                          \
+                  PtpCursor.cpp                         \
+
+LOCAL_MODULE:= libmtp
+
+LOCAL_CFLAGS := -DMTP_HOST
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+endif
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 416ebfe..8ad39dc 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -63,17 +63,13 @@
     openSession();
     mDeviceInfo = getDeviceInfo();
     if (mDeviceInfo) {
-        mDeviceInfo->print();
-
         if (mDeviceInfo->mDeviceProperties) {
             int count = mDeviceInfo->mDeviceProperties->size();
             for (int i = 0; i < count; i++) {
                 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
                 MtpProperty* property = getDevicePropDesc(propCode);
-                if (property) {
-                    property->print();
+                if (property)
                     mDeviceProperties.push(property);
-                }
             }
         }
     }
@@ -87,6 +83,45 @@
     }
 }
 
+void MtpDevice::print() {
+    if (mDeviceInfo) {
+        mDeviceInfo->print();
+
+        if (mDeviceInfo->mDeviceProperties) {
+            LOGI("***** DEVICE PROPERTIES *****\n");
+            int count = mDeviceInfo->mDeviceProperties->size();
+            for (int i = 0; i < count; i++) {
+                MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
+                MtpProperty* property = getDevicePropDesc(propCode);
+                if (property) {
+                    property->print();
+                }
+            }
+        }
+    }
+
+    if (mDeviceInfo->mPlaybackFormats) {
+            LOGI("***** OBJECT PROPERTIES *****\n");
+        int count = mDeviceInfo->mPlaybackFormats->size();
+        for (int i = 0; i < count; i++) {
+            MtpObjectFormat format = (*mDeviceInfo->mPlaybackFormats)[i];
+            LOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
+            MtpObjectPropertyList* props = getObjectPropsSupported(format);
+            if (props) {
+                for (int j = 0; j < props->size(); j++) {
+                    MtpObjectProperty prop = (*props)[j];
+                    MtpProperty* property = getObjectPropDesc(prop, format);
+                    if (property)
+                        property->print();
+                    else
+                        LOGE("could not fetch property: %s",
+                                MtpDebug::getObjectPropCodeName(prop));
+                }
+            }
+        }
+    }
+}
+
 const char* MtpDevice::getDeviceName() {
     if (mDevice)
         return usb_device_get_name(mDevice);
@@ -330,6 +365,23 @@
         return -1;
 }
 
+MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
+    Mutex::Autolock autoLock(mMutex);
+
+    mRequest.reset();
+    mRequest.setParameter(1, format);
+    if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED))
+        return NULL;
+    if (!readData())
+        return NULL;
+    MtpResponseCode ret = readResponse();
+    if (ret == MTP_RESPONSE_OK) {
+        return mData.getAUInt16();
+    }
+    return NULL;
+
+}
+
 MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
     Mutex::Autolock autoLock(mMutex);
 
@@ -348,6 +400,25 @@
     return NULL;
 }
 
+MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
+    Mutex::Autolock autoLock(mMutex);
+
+    mRequest.reset();
+    mRequest.setParameter(1, code);
+    mRequest.setParameter(2, format);
+    if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROP_DESC))
+        return NULL;
+    if (!readData())
+        return NULL;
+    MtpResponseCode ret = readResponse();
+    if (ret == MTP_RESPONSE_OK) {
+        MtpProperty* property = new MtpProperty;
+        property->read(mData);
+        return property;
+    }
+    return NULL;
+}
+
 // reads the object's data and writes it to the specified file path
 bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
     LOGD("readObject: %s", destPath);
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 21c85d5..6ffbd24 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -67,6 +67,7 @@
 
     void                    initialize();
     void                    close();
+    void                    print();
     const char*             getDeviceName();
 
     bool                    openSession();
@@ -85,7 +86,10 @@
     MtpObjectHandle         getParent(MtpObjectHandle handle);
     MtpObjectHandle         getStorageID(MtpObjectHandle handle);
 
+    MtpObjectPropertyList*  getObjectPropsSupported(MtpObjectFormat format);
+
     MtpProperty*            getDevicePropDesc(MtpDeviceProperty code);
+    MtpProperty*            getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format);
 
     bool                   readObject(MtpObjectHandle handle, const char* destPath, int group,
                                     int perm);
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 4356a6f..b095ce1 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "MtpProperty"
 
 #include "MtpDataPacket.h"
+#include "MtpDebug.h"
 #include "MtpProperty.h"
 #include "MtpStringBuffer.h"
 #include "MtpUtils.h"
@@ -121,9 +122,8 @@
 }
 
 void MtpProperty::read(MtpDataPacket& packet) {
-    bool deviceProp = isDeviceProperty();
-
     mCode = packet.getUInt16();
+    bool deviceProp = isDeviceProperty();
     mType = packet.getUInt16();
     mWriteable = (packet.getUInt8() == 1);
     switch (mType) {
@@ -317,9 +317,93 @@
 }
 
 void MtpProperty::print() {
-    LOGV("MtpProperty %04X\n", mCode);
-    LOGV("    type %04X\n", mType);
-    LOGV("    writeable %s\n", (mWriteable ? "true" : "false"));
+    MtpString buffer;
+    bool deviceProp = isDeviceProperty();
+    if (deviceProp)
+        LOGI("    %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
+    else
+        LOGI("    %s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
+    LOGI("    type %04X", mType);
+    LOGI("    writeable %s", (mWriteable ? "true" : "false"));
+    buffer = "    default value: ";
+    print(mDefaultValue, buffer);
+    LOGI("%s", (const char *)buffer);
+    if (deviceProp) {
+        buffer = "    current value: ";
+        print(mCurrentValue, buffer);
+        LOGI("%s", (const char *)buffer);
+    }
+    switch (mFormFlag) {
+        case kFormNone:
+            break;
+        case kFormRange:
+            buffer = "    Range (";
+            print(mMinimumValue, buffer);
+            buffer += ", ";
+            print(mMaximumValue, buffer);
+            buffer += ", ";
+            print(mStepSize, buffer);
+            LOGI("%s", (const char *)buffer);
+            break;
+        case kFormEnum:
+            buffer = "    Enum { ";
+            for (int i = 0; i < mEnumLength; i++) {
+                print(mEnumValues[i], buffer);
+                buffer += " ";
+            }
+            buffer += "}";
+            LOGI("%s", (const char *)buffer);
+            break;
+        case kFormDateTime:
+            LOGI("    DateTime\n");
+            break;
+        default:
+            LOGI("    form %d\n", mFormFlag);
+            break;
+    }
+}
+
+void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+    switch (mType) {
+        case MTP_TYPE_INT8:
+            buffer.appendFormat("%d", value.u.i8);
+            break;
+        case MTP_TYPE_UINT8:
+            buffer.appendFormat("%d", value.u.u8);
+            break;
+        case MTP_TYPE_INT16:
+            buffer.appendFormat("%d", value.u.i16);
+            break;
+        case MTP_TYPE_UINT16:
+            buffer.appendFormat("%d", value.u.u16);
+            break;
+        case MTP_TYPE_INT32:
+            buffer.appendFormat("%d", value.u.i32);
+            break;
+        case MTP_TYPE_UINT32:
+            buffer.appendFormat("%d", value.u.u32);
+            break;
+        case MTP_TYPE_INT64:
+            buffer.appendFormat("%lld", value.u.i64);
+            break;
+        case MTP_TYPE_UINT64:
+            buffer.appendFormat("%lld", value.u.u64);
+            break;
+        case MTP_TYPE_INT128:
+            buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
+                    value.u.i128[2], value.u.i128[3]);
+            break;
+        case MTP_TYPE_UINT128:
+            buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
+                    value.u.u128[2], value.u.u128[3]);
+            break;
+        case MTP_TYPE_STR:
+            buffer.appendFormat("%s", value.str);
+            break;
+        default:
+            LOGE("unsupported type for MtpProperty::print\n");
+            break;
+    }
 }
 
 void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index f783a87..06ca56e 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -94,6 +94,7 @@
     void                setFormDateTime();
 
     void                print();
+    void                print(MtpPropertyValue& value, MtpString& buffer);
 
     inline bool         isDeviceProperty() const {
                             return (   ((mCode & 0xF000) == 0x5000)
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index de6cbac..5c1e02a 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -423,7 +423,7 @@
     if (!mSessionOpen)
         return MTP_RESPONSE_SESSION_NOT_OPEN;
     MtpObjectFormat format = mRequest.getParameter(1);
-    MtpDevicePropertyList* properties = mDatabase->getSupportedObjectProperties(format);
+    MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format);
     mData.putAUInt16(properties);
     delete properties;
     return MTP_RESPONSE_OK;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 535f07f..f1fa0ff 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1015,7 +1015,10 @@
 
     sp<Client> client = getClientFromCookie(user);
     if (client == 0) return;
-    if (!client->lockIfMessageWanted(msgType)) return;
+    if (!client->lockIfMessageWanted(msgType)) {
+        client->releaseRecordingFrame(dataPtr);
+        return;
+    }
 
     if (dataPtr == 0) {
         LOGE("Null data returned in data with timestamp callback");