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>
This commit is contained in:
Mike Lockwood
2012-09-12 15:50:59 -07:00
parent d428e95eb5
commit f6f1661457
2 changed files with 41 additions and 40 deletions

View File

@@ -84,11 +84,10 @@ public class MtpDatabase {
Files.FileColumns._ID, // 0
Files.FileColumns.DATA, // 1
};
private static final String[] PATH_SIZE_FORMAT_PROJECTION = new String[] {
private static final String[] PATH_FORMAT_PROJECTION = new String[] {
Files.FileColumns._ID, // 0
Files.FileColumns.DATA, // 1
Files.FileColumns.SIZE, // 2
Files.FileColumns.FORMAT, // 3
Files.FileColumns.FORMAT, // 2
};
private static final String[] OBJECT_INFO_PROJECTION = new String[] {
Files.FileColumns._ID, // 0
@@ -96,8 +95,7 @@ public class MtpDatabase {
Files.FileColumns.FORMAT, // 2
Files.FileColumns.PARENT, // 3
Files.FileColumns.DATA, // 4
Files.FileColumns.SIZE, // 5
Files.FileColumns.DATE_MODIFIED, // 6
Files.FileColumns.DATE_MODIFIED, // 5
};
private static final String ID_WHERE = Files.FileColumns._ID + "=?";
private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
@@ -834,7 +832,7 @@ public class MtpDatabase {
}
private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
char[] outName, long[] outSizeModified) {
char[] outName, long[] outModified) {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
@@ -855,8 +853,7 @@ public class MtpDatabase {
path.getChars(start, end, outName, 0);
outName[end - start] = 0;
outSizeModified[0] = c.getLong(5);
outSizeModified[1] = c.getLong(6);
outModified[0] = c.getLong(5);
return true;
}
} catch (RemoteException e) {
@@ -880,14 +877,16 @@ public class MtpDatabase {
}
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
c = mMediaProvider.query(mObjectsUri, PATH_FORMAT_PROJECTION,
ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
String path = c.getString(1);
path.getChars(0, path.length(), outFilePath, 0);
outFilePath[path.length()] = 0;
outFileLengthFormat[0] = c.getLong(2);
outFileLengthFormat[1] = c.getLong(3);
// File transfers from device to host will likely fail if the size is incorrect.
// So to be safe, use the actual file size here.
outFileLengthFormat[0] = new File(path).length();
outFileLengthFormat[1] = c.getLong(2);
return MtpConstants.RESPONSE_OK;
} else {
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
@@ -909,13 +908,13 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
c = mMediaProvider.query(mObjectsUri, PATH_FORMAT_PROJECTION,
ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
// don't convert to media path here, since we will be matching
// against paths in the database matching /data/media
path = c.getString(1);
format = c.getInt(3);
format = c.getInt(2);
} else {
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
}

View File

@@ -751,13 +751,22 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpObjectInfo& info) {
char date[20];
char date[20];
MtpString path;
int64_t length;
MtpObjectFormat format;
MtpResponseCode result = getObjectFilePath(handle, path, length, format);
if (result != MTP_RESPONSE_OK) {
return result;
}
info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
JNIEnv* env = AndroidRuntime::getJNIEnv();
jboolean result = env->CallBooleanMethod(mDatabase, method_getObjectInfo,
(jint)handle, mIntBuffer, mStringBuffer, mLongBuffer);
if (!result)
if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
(jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
}
jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
info.mStorageID = intValues[0];
@@ -766,9 +775,7 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
uint64_t size = longValues[0];
info.mCompressedSize = (size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size);
info.mDateModified = longValues[1];
info.mDateModified = longValues[0];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
@@ -783,28 +790,23 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
// read EXIF data for thumbnail information
if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
MtpString path;
int64_t length;
MtpObjectFormat format;
if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
ResetJpgfile();
// Start with an empty image information structure.
memset(&ImageInfo, 0, sizeof(ImageInfo));
ImageInfo.FlashUsed = -1;
ImageInfo.MeteringMode = -1;
ImageInfo.Whitebalance = -1;
strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
if (ReadJpegFile((const char*)path, READ_METADATA)) {
Section_t* section = FindSection(M_EXIF);
if (section) {
info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
info.mImagePixWidth = ImageInfo.Width;
info.mImagePixHeight = ImageInfo.Height;
}
ResetJpgfile();
// Start with an empty image information structure.
memset(&ImageInfo, 0, sizeof(ImageInfo));
ImageInfo.FlashUsed = -1;
ImageInfo.MeteringMode = -1;
ImageInfo.Whitebalance = -1;
strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
if (ReadJpegFile((const char*)path, READ_METADATA)) {
Section_t* section = FindSection(M_EXIF);
if (section) {
info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
info.mImagePixWidth = ImageInfo.Width;
info.mImagePixHeight = ImageInfo.Height;
}
DiscardData();
}
DiscardData();
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);