Skip to content

Commit f6f1661

Browse files
author
Mike Lockwood
committed
MtpDatabase: Use actual file size instead of media database size column
Fixes problems with file transfer from device to host that can occur if the database size value is wrong. Bug: 6954446 Change-Id: I03c3dd4b75267d1f4613f0b588c8899ded9a70be Signed-off-by: Mike Lockwood <lockwood@google.com>
1 parent d428e95 commit f6f1661

File tree

2 files changed

+41
-40
lines changed

2 files changed

+41
-40
lines changed

media/java/android/mtp/MtpDatabase.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,18 @@ public class MtpDatabase {
8484
Files.FileColumns._ID, // 0
8585
Files.FileColumns.DATA, // 1
8686
};
87-
private static final String[] PATH_SIZE_FORMAT_PROJECTION = new String[] {
87+
private static final String[] PATH_FORMAT_PROJECTION = new String[] {
8888
Files.FileColumns._ID, // 0
8989
Files.FileColumns.DATA, // 1
90-
Files.FileColumns.SIZE, // 2
91-
Files.FileColumns.FORMAT, // 3
90+
Files.FileColumns.FORMAT, // 2
9291
};
9392
private static final String[] OBJECT_INFO_PROJECTION = new String[] {
9493
Files.FileColumns._ID, // 0
9594
Files.FileColumns.STORAGE_ID, // 1
9695
Files.FileColumns.FORMAT, // 2
9796
Files.FileColumns.PARENT, // 3
9897
Files.FileColumns.DATA, // 4
99-
Files.FileColumns.SIZE, // 5
100-
Files.FileColumns.DATE_MODIFIED, // 6
98+
Files.FileColumns.DATE_MODIFIED, // 5
10199
};
102100
private static final String ID_WHERE = Files.FileColumns._ID + "=?";
103101
private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
@@ -834,7 +832,7 @@ private int setDeviceProperty(int property, long intValue, String stringValue) {
834832
}
835833

836834
private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
837-
char[] outName, long[] outSizeModified) {
835+
char[] outName, long[] outModified) {
838836
Cursor c = null;
839837
try {
840838
c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
@@ -855,8 +853,7 @@ private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
855853
path.getChars(start, end, outName, 0);
856854
outName[end - start] = 0;
857855

858-
outSizeModified[0] = c.getLong(5);
859-
outSizeModified[1] = c.getLong(6);
856+
outModified[0] = c.getLong(5);
860857
return true;
861858
}
862859
} catch (RemoteException e) {
@@ -880,14 +877,16 @@ private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLeng
880877
}
881878
Cursor c = null;
882879
try {
883-
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
880+
c = mMediaProvider.query(mObjectsUri, PATH_FORMAT_PROJECTION,
884881
ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
885882
if (c != null && c.moveToNext()) {
886883
String path = c.getString(1);
887884
path.getChars(0, path.length(), outFilePath, 0);
888885
outFilePath[path.length()] = 0;
889-
outFileLengthFormat[0] = c.getLong(2);
890-
outFileLengthFormat[1] = c.getLong(3);
886+
// File transfers from device to host will likely fail if the size is incorrect.
887+
// So to be safe, use the actual file size here.
888+
outFileLengthFormat[0] = new File(path).length();
889+
outFileLengthFormat[1] = c.getLong(2);
891890
return MtpConstants.RESPONSE_OK;
892891
} else {
893892
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
@@ -909,13 +908,13 @@ private int deleteFile(int handle) {
909908

910909
Cursor c = null;
911910
try {
912-
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
911+
c = mMediaProvider.query(mObjectsUri, PATH_FORMAT_PROJECTION,
913912
ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
914913
if (c != null && c.moveToNext()) {
915914
// don't convert to media path here, since we will be matching
916915
// against paths in the database matching /data/media
917916
path = c.getString(1);
918-
format = c.getInt(3);
917+
format = c.getInt(2);
919918
} else {
920919
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
921920
}

media/jni/android_mtp_MtpDatabase.cpp

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,22 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
751751

752752
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
753753
MtpObjectInfo& info) {
754-
char date[20];
754+
char date[20];
755+
MtpString path;
756+
int64_t length;
757+
MtpObjectFormat format;
758+
759+
MtpResponseCode result = getObjectFilePath(handle, path, length, format);
760+
if (result != MTP_RESPONSE_OK) {
761+
return result;
762+
}
763+
info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
755764

756765
JNIEnv* env = AndroidRuntime::getJNIEnv();
757-
jboolean result = env->CallBooleanMethod(mDatabase, method_getObjectInfo,
758-
(jint)handle, mIntBuffer, mStringBuffer, mLongBuffer);
759-
if (!result)
766+
if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
767+
(jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
760768
return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
769+
}
761770

762771
jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
763772
info.mStorageID = intValues[0];
@@ -766,9 +775,7 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
766775
env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
767776

768777
jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
769-
uint64_t size = longValues[0];
770-
info.mCompressedSize = (size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size);
771-
info.mDateModified = longValues[1];
778+
info.mDateModified = longValues[0];
772779
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
773780

774781
// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
@@ -783,28 +790,23 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
783790

784791
// read EXIF data for thumbnail information
785792
if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
786-
MtpString path;
787-
int64_t length;
788-
MtpObjectFormat format;
789-
if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
790-
ResetJpgfile();
791-
// Start with an empty image information structure.
792-
memset(&ImageInfo, 0, sizeof(ImageInfo));
793-
ImageInfo.FlashUsed = -1;
794-
ImageInfo.MeteringMode = -1;
795-
ImageInfo.Whitebalance = -1;
796-
strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
797-
if (ReadJpegFile((const char*)path, READ_METADATA)) {
798-
Section_t* section = FindSection(M_EXIF);
799-
if (section) {
800-
info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
801-
info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
802-
info.mImagePixWidth = ImageInfo.Width;
803-
info.mImagePixHeight = ImageInfo.Height;
804-
}
793+
ResetJpgfile();
794+
// Start with an empty image information structure.
795+
memset(&ImageInfo, 0, sizeof(ImageInfo));
796+
ImageInfo.FlashUsed = -1;
797+
ImageInfo.MeteringMode = -1;
798+
ImageInfo.Whitebalance = -1;
799+
strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
800+
if (ReadJpegFile((const char*)path, READ_METADATA)) {
801+
Section_t* section = FindSection(M_EXIF);
802+
if (section) {
803+
info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
804+
info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
805+
info.mImagePixWidth = ImageInfo.Width;
806+
info.mImagePixHeight = ImageInfo.Height;
805807
}
806-
DiscardData();
807808
}
809+
DiscardData();
808810
}
809811

810812
checkAndClearExceptionFromCallback(env, __FUNCTION__);

0 commit comments

Comments
 (0)