Merge "Support streaming data across binder boundaries."
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3f32f2f..3108e4e 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3898,32 +3898,34 @@
             mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
             mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
 
-            OMX_CONFIG_RECTTYPE rect;
-            status_t err =
-                     mOMX->getConfig(
-                         mNode, OMX_IndexConfigCommonOutputCrop,
-                         &rect, sizeof(rect));
+            if (!mIsEncoder) {
+                OMX_CONFIG_RECTTYPE rect;
+                status_t err =
+                        mOMX->getConfig(
+                            mNode, OMX_IndexConfigCommonOutputCrop,
+                            &rect, sizeof(rect));
 
-            if (err == OK) {
-                CHECK_GE(rect.nLeft, 0);
-                CHECK_GE(rect.nTop, 0);
-                CHECK_GE(rect.nWidth, 0u);
-                CHECK_GE(rect.nHeight, 0u);
-                CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
-                CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
+                if (err == OK) {
+                    CHECK_GE(rect.nLeft, 0);
+                    CHECK_GE(rect.nTop, 0);
+                    CHECK_GE(rect.nWidth, 0u);
+                    CHECK_GE(rect.nHeight, 0u);
+                    CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
+                    CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
 
-                mOutputFormat->setRect(
-                        kKeyCropRect,
-                        rect.nLeft,
-                        rect.nTop,
-                        rect.nLeft + rect.nWidth - 1,
-                        rect.nTop + rect.nHeight - 1);
-            } else {
-                mOutputFormat->setRect(
-                        kKeyCropRect,
-                        0, 0,
-                        video_def->nFrameWidth - 1,
-                        video_def->nFrameHeight - 1);
+                    mOutputFormat->setRect(
+                            kKeyCropRect,
+                            rect.nLeft,
+                            rect.nTop,
+                            rect.nLeft + rect.nWidth - 1,
+                            rect.nTop + rect.nHeight - 1);
+                } else {
+                    mOutputFormat->setRect(
+                            kKeyCropRect,
+                            0, 0,
+                            video_def->nFrameWidth - 1,
+                            video_def->nFrameHeight - 1);
+                }
             }
 
             break;
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index 7502f6e..b7e1a2a 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -22,7 +22,6 @@
 
 LOCAL_SRC_FILES:=                                       \
                   MtpClient.cpp                         \
-                  MtpCursor.cpp                         \
                   MtpDataPacket.cpp                     \
                   MtpDebug.cpp                          \
                   MtpDevice.cpp                         \
@@ -38,6 +37,7 @@
                   MtpStringBuffer.cpp                   \
                   MtpStorage.cpp                        \
                   MtpUtils.cpp                          \
+                  PtpCursor.cpp                         \
 
 LOCAL_MODULE:= libmtp
 
@@ -47,32 +47,3 @@
 
 endif
 
-ifeq ($(HOST_OS),linux)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=                                       \
-                  MtpClient.cpp                         \
-                  MtpCursor.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                          \
-
-LOCAL_MODULE:= libmtp
-
-LOCAL_CFLAGS := -DMTP_HOST
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index 42bf8ba..bd6196f 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -123,7 +123,7 @@
 
 uint32_t MtpPacket::getParameter(int index) const {
     if (index < 1 || index > 5) {
-        LOGE("index %d out of range in MtpRequestPacket::getParameter", index);
+        LOGE("index %d out of range in MtpPacket::getParameter", index);
         return 0;
     }
     return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
@@ -131,7 +131,7 @@
 
 void MtpPacket::setParameter(int index, uint32_t value) {
     if (index < 1 || index > 5) {
-        LOGE("index %d out of range in MtpResponsePacket::setParameter", index);
+        LOGE("index %d out of range in MtpPacket::setParameter", index);
         return;
     }
     int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 86889c3..42945f5 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -312,6 +312,10 @@
     }
 }
 
+void MtpProperty::setFormDateTime() {
+     mFormFlag = kFormDateTime;
+}
+
 void MtpProperty::print() {
     LOGV("MtpProperty %04X\n", mCode);
     LOGV("    type %04X\n", mType);
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index c12399c..f783a87 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -58,6 +58,7 @@
         kFormNone = 0,
         kFormRange = 1,
         kFormEnum = 2,
+        kFormDateTime = 3,
     };
 
     uint32_t            mGroupCode;
@@ -90,6 +91,7 @@
 
     void                setFormRange(int min, int max, int step);
     void                setFormEnum(const int* values, int count);
+    void                setFormDateTime();
 
     void                print();
 
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index ca13636..c3755f3 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -66,7 +66,7 @@
 //    MTP_OPERATION_TERMINATE_OPEN_CAPTURE,
 //    MTP_OPERATION_MOVE_OBJECT,
 //    MTP_OPERATION_COPY_OBJECT,
-//    MTP_OPERATION_GET_PARTIAL_OBJECT,
+    MTP_OPERATION_GET_PARTIAL_OBJECT,
 //    MTP_OPERATION_INITIATE_OPEN_CAPTURE,
     MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED,
     MTP_OPERATION_GET_OBJECT_PROP_DESC,
@@ -289,6 +289,9 @@
         case MTP_OPERATION_GET_OBJECT:
             response = doGetObject();
             break;
+        case MTP_OPERATION_GET_PARTIAL_OBJECT:
+            response = doGetPartialObject();
+            break;
         case MTP_OPERATION_SEND_OBJECT_INFO:
             response = doSendObjectInfo();
             break;
@@ -536,7 +539,7 @@
     MtpObjectFormat format = mRequest.getParameter(2);
     MtpDeviceProperty property = mRequest.getParameter(3);
     int groupCode = mRequest.getParameter(4);
-    int depth = mRequest.getParameter(4);
+    int depth = mRequest.getParameter(5);
    LOGD("GetObjectPropList %d format: %s property: %s group: %d depth: %d\n",
             handle, MtpDebug::getFormatCodeName(format),
             MtpDebug::getObjectPropCodeName(property), groupCode, depth);
@@ -583,6 +586,45 @@
     return MTP_RESPONSE_OK;
 }
 
+MtpResponseCode MtpServer::doGetPartialObject() {
+    MtpObjectHandle handle = mRequest.getParameter(1);
+    uint32_t offset = mRequest.getParameter(2);
+    uint32_t length = mRequest.getParameter(3);
+    MtpString pathBuf;
+    int64_t fileLength;
+    int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+    if (offset + length > fileLength)
+        length = fileLength - offset;
+
+    const char* filePath = (const char *)pathBuf;
+    mtp_file_range  mfr;
+    mfr.fd = open(filePath, O_RDONLY);
+    if (mfr.fd < 0) {
+        return MTP_RESPONSE_GENERAL_ERROR;
+    }
+    mfr.offset = offset;
+    mfr.length = length;
+    mResponse.setParameter(1, length);
+
+    // send data header
+    mData.setOperationCode(mRequest.getOperationCode());
+    mData.setTransactionID(mRequest.getTransactionID());
+    mData.writeDataHeader(mFD, length + MTP_CONTAINER_HEADER_SIZE);
+
+    // then transfer the file
+    int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr);
+    close(mfr.fd);
+    if (ret < 0) {
+        if (errno == ECANCELED)
+            return MTP_RESPONSE_TRANSACTION_CANCELLED;
+        else
+            return MTP_RESPONSE_GENERAL_ERROR;
+    }
+    return MTP_RESPONSE_OK;
+}
+
 MtpResponseCode MtpServer::doSendObjectInfo() {
     MtpString path;
     MtpStorageID storageID = mRequest.getParameter(1);
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index e65ddb0..5aee4ea 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -96,6 +96,7 @@
     MtpResponseCode     doGetObjectPropList();
     MtpResponseCode     doGetObjectInfo();
     MtpResponseCode     doGetObject();
+    MtpResponseCode     doGetPartialObject();
     MtpResponseCode     doSendObjectInfo();
     MtpResponseCode     doSendObject();
     MtpResponseCode     doDeleteObject();
diff --git a/media/mtp/MtpCursor.cpp b/media/mtp/PtpCursor.cpp
similarity index 91%
rename from media/mtp/MtpCursor.cpp
rename to media/mtp/PtpCursor.cpp
index 35d90dc..7294cef 100644
--- a/media/mtp/MtpCursor.cpp
+++ b/media/mtp/PtpCursor.cpp
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "MtpCursor"
+#define LOG_TAG "PtpCursor"
 
 #include "MtpDebug.h"
 #include "MtpClient.h"
-#include "MtpCursor.h"
+#include "PtpCursor.h"
 #include "MtpDevice.h"
 #include "MtpDeviceInfo.h"
 #include "MtpObjectInfo.h"
@@ -30,19 +30,19 @@
 namespace android {
 
 /* Device Column IDs */
-/* These must match the values in MtpCursor.java */
+/* These must match the values in PtpCursor.java */
 #define DEVICE_ROW_ID           1
 #define DEVICE_MANUFACTURER     2
 #define DEVICE_MODEL            3
 
 /* Storage Column IDs */
-/* These must match the values in MtpCursor.java */
+/* These must match the values in PtpCursor.java */
 #define STORAGE_ROW_ID          101
 #define STORAGE_IDENTIFIER      102
 #define STORAGE_DESCRIPTION     103
 
 /* Object Column IDs */
-/* These must match the values in MtpCursor.java */
+/* These must match the values in PtpCursor.java */
 #define OBJECT_ROW_ID               201
 #define OBJECT_STORAGE_ID           202
 #define OBJECT_FORMAT               203
@@ -65,7 +65,7 @@
 #define OBJECT_KEYWORDS             220
 #define OBJECT_THUMB                221
 
-MtpCursor::MtpCursor(MtpClient* client, int queryType, int deviceID,
+PtpCursor::PtpCursor(MtpClient* client, int queryType, int deviceID,
                 MtpStorageID storageID, MtpObjectHandle objectID,
                 int columnCount, int* columns)
         :   mClient(client),
@@ -82,12 +82,12 @@
     }
 }
 
-MtpCursor::~MtpCursor() {
+PtpCursor::~PtpCursor() {
     delete[] mColumns;
 }
 
-int MtpCursor::fillWindow(CursorWindow* window, int startPos) {
-    LOGD("MtpCursor::fillWindow mQueryType: %d\n", mQueryType);
+int PtpCursor::fillWindow(CursorWindow* window, int startPos) {
+    LOGD("PtpCursor::fillWindow mQueryType: %d\n", mQueryType);
 
     switch (mQueryType) {
         case DEVICE:
@@ -107,12 +107,12 @@
         case OBJECT_CHILDREN:
             return fillObjects(window, mQbjectID, startPos);
         default:
-            LOGE("MtpCursor::fillWindow: unknown query type %d\n", mQueryType);
+            LOGE("PtpCursor::fillWindow: unknown query type %d\n", mQueryType);
             return 0;
     }
 }
 
-int MtpCursor::fillDevices(CursorWindow* window, int startPos) {
+int PtpCursor::fillDevices(CursorWindow* window, int startPos) {
     int count = 0;
     MtpDeviceList& deviceList = mClient->getDeviceList();
     for (int i = 0; i < deviceList.size(); i++) {
@@ -127,7 +127,7 @@
     return count;
 }
 
-int MtpCursor::fillDevice(CursorWindow* window, int startPos) {
+int PtpCursor::fillDevice(CursorWindow* window, int startPos) {
     MtpDevice* device = mClient->getDevice(mDeviceID);
     if (device && fillDevice(window, device, startPos))
         return 1;
@@ -135,7 +135,7 @@
         return 0;
 }
 
-int MtpCursor::fillStorages(CursorWindow* window, int startPos) {
+int PtpCursor::fillStorages(CursorWindow* window, int startPos) {
     int count = 0;
     MtpDevice* device = mClient->getDevice(mDeviceID);
     if (!device)
@@ -157,7 +157,7 @@
     return count;
 }
 
-int MtpCursor::fillStorage(CursorWindow* window, int startPos) {
+int PtpCursor::fillStorage(CursorWindow* window, int startPos) {
     MtpDevice* device = mClient->getDevice(mDeviceID);
     if (device && fillStorage(window, device, mStorageID, startPos))
         return 1;
@@ -165,7 +165,7 @@
         return 0;
 }
 
-int MtpCursor::fillObjects(CursorWindow* window, int parent, int startPos) {
+int PtpCursor::fillObjects(CursorWindow* window, int parent, int startPos) {
     int count = 0;
     MtpDevice* device = mClient->getDevice(mDeviceID);
     if (!device)
@@ -187,7 +187,7 @@
     return count;
 }
 
-int MtpCursor::fillObject(CursorWindow* window, int startPos) {
+int PtpCursor::fillObject(CursorWindow* window, int startPos) {
     MtpDevice* device = mClient->getDevice(mDeviceID);
     if (device && fillObject(window, device, mQbjectID, startPos))
         return 1;
@@ -195,7 +195,7 @@
         return 0;
 }
 
-bool MtpCursor::fillDevice(CursorWindow* window, MtpDevice* device, int row) {
+bool PtpCursor::fillDevice(CursorWindow* window, MtpDevice* device, int row) {
     MtpDeviceInfo* deviceInfo = device->getDeviceInfo();
     if (!deviceInfo)
         return false;
@@ -225,7 +225,7 @@
     return true;
 }
 
-bool MtpCursor::fillStorage(CursorWindow* window, MtpDevice* device,
+bool PtpCursor::fillStorage(CursorWindow* window, MtpDevice* device,
         MtpStorageID storageID, int row) {
 
 LOGD("fillStorage %d\n", storageID);
@@ -273,7 +273,7 @@
     return false;
 }
 
-bool MtpCursor::fillObject(CursorWindow* window, MtpDevice* device,
+bool PtpCursor::fillObject(CursorWindow* window, MtpDevice* device,
         MtpObjectHandle objectID, int row) {
 
     MtpObjectInfo* objectInfo = device->getObjectInfo(objectID);
@@ -385,7 +385,7 @@
     return false;
 }
 
-bool MtpCursor::prepareRow(CursorWindow* window) {
+bool PtpCursor::prepareRow(CursorWindow* window) {
     if (!window->setNumColumns(mColumnCount)) {
         LOGE("Failed to change column count from %d to %d", window->getNumColumns(), mColumnCount);
         return false;
@@ -399,7 +399,7 @@
 }
 
 
-bool MtpCursor::putLong(CursorWindow* window, int64_t value, int row, int column) {
+bool PtpCursor::putLong(CursorWindow* window, int64_t value, int row, int column) {
     if (!window->putLong(row, column, value)) {
         window->freeLastRow();
         LOGE("Failed allocating space for a long in column %d", column);
@@ -408,7 +408,7 @@
     return true;
 }
 
-bool MtpCursor::putString(CursorWindow* window, const char* text, int row, int column) {
+bool PtpCursor::putString(CursorWindow* window, const char* text, int row, int column) {
     int size = strlen(text) + 1;
     int offset = window->alloc(size);
     if (!offset) {
@@ -427,7 +427,7 @@
     return true;
 }
 
-bool MtpCursor::putThumbnail(CursorWindow* window, MtpObjectHandle objectID,
+bool PtpCursor::putThumbnail(CursorWindow* window, MtpObjectHandle objectID,
                             MtpObjectFormat format, int row, int column) {
     MtpDevice* device = mClient->getDevice(mDeviceID);
     void* thumbnail;
diff --git a/media/mtp/MtpCursor.h b/media/mtp/PtpCursor.h
similarity index 93%
rename from media/mtp/MtpCursor.h
rename to media/mtp/PtpCursor.h
index 2e03c29..38a1d47 100644
--- a/media/mtp/MtpCursor.h
+++ b/media/mtp/PtpCursor.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _MTP_CURSOR_H
-#define _MTP_CURSOR_H
+#ifndef _PTP_CURSOR_H
+#define _PTP_CURSOR_H
 
 #include "MtpTypes.h"
 
@@ -23,7 +23,7 @@
 
 class CursorWindow;
 
-class MtpCursor {
+class PtpCursor {
 private:
     enum {
         DEVICE              = 1,
@@ -45,10 +45,10 @@
     int*            mColumns;
 
 public:
-                MtpCursor(MtpClient* client, int queryType, int deviceID,
+                PtpCursor(MtpClient* client, int queryType, int deviceID,
                         MtpStorageID storageID, MtpObjectHandle objectID,
                         int columnCount, int* columns);
-    virtual     ~MtpCursor();
+    virtual     ~PtpCursor();
 
     int         fillWindow(CursorWindow* window, int startPos);
 
@@ -75,4 +75,4 @@
 
 }; // namespace android
 
-#endif // _MTP_CURSOR_H
+#endif // _PTP_CURSOR_H