From 413577d8600413bb1dca3730d4ccf20892b929b4 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Tue, 16 Nov 2010 17:38:43 -0500 Subject: [PATCH] MTP: Fixes to allow file transfers > 4 gigabytes BUG: 3198248 Change-Id: I6f11c79a19d7bdd63718a7370939124b1262d221 Signed-off-by: Mike Lockwood --- media/java/android/media/MtpDatabase.java | 14 +++++++++++++- media/jni/android_media_MtpDatabase.cpp | 7 ++++--- media/mtp/MtpDatabase.h | 1 + media/mtp/MtpServer.cpp | 10 +++++++++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java index ab31cd4485091..e48e9e8d59cea 100644 --- a/media/java/android/media/MtpDatabase.java +++ b/media/java/android/media/MtpDatabase.java @@ -164,7 +164,7 @@ public class MtpDatabase { } } - private void endSendObject(String path, int handle, int format, boolean succeeded) { + private void endSendObject(String path, int handle, int format, long actualSize, boolean succeeded) { if (succeeded) { // handle abstract playlists separately // they do not exist in the file system so don't use the media scanner here @@ -192,6 +192,18 @@ public class MtpDatabase { Log.e(TAG, "RemoteException in endSendObject", e); } } else { + if (actualSize >= 0) { + // update size if necessary + ContentValues values = new ContentValues(); + values.put(Files.FileColumns.SIZE, actualSize); + try { + String[] whereArgs = new String[] { Integer.toString(handle) }; + mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in mMediaProvider.update", e); + } + } + mMediaScanner.scanMtpFile(path, mVolumeName, handle, format); } } else { diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp index 5377af6a14c72..4525d1ff88350 100644 --- a/media/jni/android_media_MtpDatabase.cpp +++ b/media/jni/android_media_MtpDatabase.cpp @@ -99,6 +99,7 @@ public: virtual void endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, + int64_t actualSize, bool succeeded); virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID, @@ -235,11 +236,11 @@ MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path, } void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle, - MtpObjectFormat format, bool succeeded) { + MtpObjectFormat format, int64_t actualSize, bool succeeded) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jstring pathStr = env->NewStringUTF(path); env->CallVoidMethod(mDatabase, method_endSendObject, pathStr, - (jint)handle, (jint)format, (jboolean)succeeded); + (jint)handle, (jint)format, (jlong)actualSize, (jboolean)succeeded); if (pathStr) env->DeleteLocalRef(pathStr); @@ -1076,7 +1077,7 @@ int register_android_media_MtpDatabase(JNIEnv *env) LOGE("Can't find beginSendObject"); return -1; } - method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V"); + method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIJZ)V"); if (method_endSendObject == NULL) { LOGE("Can't find endSendObject"); return -1; diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h index fafd22112d90c..900b517d3ba53 100644 --- a/media/mtp/MtpDatabase.h +++ b/media/mtp/MtpDatabase.h @@ -42,6 +42,7 @@ public: virtual void endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, + int64_t size, bool succeeded) = 0; virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID, diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 7edbeb4a0ec56..ca13636469173 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -664,6 +664,7 @@ MtpResponseCode MtpServer::doSendObject() { MtpResponseCode result = MTP_RESPONSE_OK; mode_t mask; int ret; + uint64_t actualSize = -1; if (mSendObjectHandle == kInvalidObjectHandle) { LOGE("Expected SendObjectInfo before SendObject"); @@ -706,11 +707,18 @@ MtpResponseCode MtpServer::doSendObject() { result = MTP_RESPONSE_TRANSACTION_CANCELLED; else result = MTP_RESPONSE_GENERAL_ERROR; + } else if (mSendObjectFileSize == 0xFFFFFFFF) { + // actual size is likely > 4 gig so stat the file to compute actual length + struct stat s; + if (lstat(mSendObjectFilePath, &s) == 0) { + actualSize = s.st_size; + LOGD("actualSize: %lld\n", actualSize); + } } done: mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat, - result == MTP_RESPONSE_OK); + actualSize, result == MTP_RESPONSE_OK); mSendObjectHandle = kInvalidObjectHandle; mSendObjectFormat = 0; return result;