Merge "MTP: Fix problems with modification dates for folders and non-media files" into honeycomb
This commit is contained in:
committed by
Android (Google) Code Review
commit
0de274b34c
@@ -1177,7 +1177,8 @@ public class MediaScanner
|
|||||||
long lastModifiedSeconds = file.lastModified() / 1000;
|
long lastModifiedSeconds = file.lastModified() / 1000;
|
||||||
|
|
||||||
// always scan the file, so we can return the content://media Uri for existing files
|
// always scan the file, so we can return the content://media Uri for existing files
|
||||||
return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),false, true);
|
return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(),
|
||||||
|
false, true);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
|
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
|
||||||
return null;
|
return null;
|
||||||
@@ -1185,17 +1186,30 @@ public class MediaScanner
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void scanMtpFile(String path, String volumeName, int objectHandle, int format) {
|
public void scanMtpFile(String path, String volumeName, int objectHandle, int format) {
|
||||||
|
initialize(volumeName);
|
||||||
MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
|
MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
|
||||||
int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType);
|
int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType);
|
||||||
|
File file = new File(path);
|
||||||
|
long lastModifiedSeconds = file.lastModified() / 1000;
|
||||||
|
|
||||||
if (!MediaFile.isAudioFileType(fileType) && !MediaFile.isVideoFileType(fileType) &&
|
if (!MediaFile.isAudioFileType(fileType) && !MediaFile.isVideoFileType(fileType) &&
|
||||||
!MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType)) {
|
!MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType)) {
|
||||||
// nothing to do
|
|
||||||
|
// no need to use the media scanner, but we need to update last modified and file size
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(Files.FileColumns.SIZE, file.length());
|
||||||
|
values.put(Files.FileColumns.DATE_MODIFIED, lastModifiedSeconds);
|
||||||
|
try {
|
||||||
|
String[] whereArgs = new String[] { Integer.toString(objectHandle) };
|
||||||
|
mMediaProvider.update(Files.getMtpObjectsUri(volumeName), values, "_id=?",
|
||||||
|
whereArgs);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "RemoteException in scanMtpFile", e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMtpObjectHandle = objectHandle;
|
mMtpObjectHandle = objectHandle;
|
||||||
initialize(volumeName);
|
|
||||||
try {
|
try {
|
||||||
if (MediaFile.isPlayListFileType(fileType)) {
|
if (MediaFile.isPlayListFileType(fileType)) {
|
||||||
// build file cache so we can look up tracks in the playlist
|
// build file cache so we can look up tracks in the playlist
|
||||||
@@ -1213,11 +1227,6 @@ public class MediaScanner
|
|||||||
// MTP will create a file entry for us so we don't want to do it in prescan
|
// MTP will create a file entry for us so we don't want to do it in prescan
|
||||||
prescan(path, false);
|
prescan(path, false);
|
||||||
|
|
||||||
File file = new File(path);
|
|
||||||
|
|
||||||
// lastModified is in milliseconds on Files.
|
|
||||||
long lastModifiedSeconds = file.lastModified() / 1000;
|
|
||||||
|
|
||||||
// always scan the file, so we can return the content://media Uri for existing files
|
// always scan the file, so we can return the content://media Uri for existing files
|
||||||
mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(),
|
mClient.doScanFile(path, mediaFileType.mimeType, lastModifiedSeconds, file.length(),
|
||||||
(format == MtpConstants.FORMAT_ASSOCIATION), true);
|
(format == MtpConstants.FORMAT_ASSOCIATION), true);
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class MtpDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void endSendObject(String path, int handle, int format, long actualSize, boolean succeeded) {
|
private void endSendObject(String path, int handle, int format, boolean succeeded) {
|
||||||
if (succeeded) {
|
if (succeeded) {
|
||||||
// handle abstract playlists separately
|
// handle abstract playlists separately
|
||||||
// they do not exist in the file system so don't use the media scanner here
|
// they do not exist in the file system so don't use the media scanner here
|
||||||
@@ -208,18 +208,6 @@ public class MtpDatabase {
|
|||||||
Log.e(TAG, "RemoteException in endSendObject", e);
|
Log.e(TAG, "RemoteException in endSendObject", e);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
mMediaScanner.scanMtpFile(path, mVolumeName, handle, format);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ public:
|
|||||||
virtual void endSendObject(const char* path,
|
virtual void endSendObject(const char* path,
|
||||||
MtpObjectHandle handle,
|
MtpObjectHandle handle,
|
||||||
MtpObjectFormat format,
|
MtpObjectFormat format,
|
||||||
int64_t actualSize,
|
|
||||||
bool succeeded);
|
bool succeeded);
|
||||||
|
|
||||||
virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
|
virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
|
||||||
@@ -236,11 +235,11 @@ MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
|
void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
|
||||||
MtpObjectFormat format, int64_t actualSize, bool succeeded) {
|
MtpObjectFormat format, bool succeeded) {
|
||||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||||
jstring pathStr = env->NewStringUTF(path);
|
jstring pathStr = env->NewStringUTF(path);
|
||||||
env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
|
env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
|
||||||
(jint)handle, (jint)format, (jlong)actualSize, (jboolean)succeeded);
|
(jint)handle, (jint)format, (jboolean)succeeded);
|
||||||
|
|
||||||
if (pathStr)
|
if (pathStr)
|
||||||
env->DeleteLocalRef(pathStr);
|
env->DeleteLocalRef(pathStr);
|
||||||
@@ -1094,7 +1093,7 @@ int register_android_mtp_MtpDatabase(JNIEnv *env)
|
|||||||
LOGE("Can't find beginSendObject");
|
LOGE("Can't find beginSendObject");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIJZ)V");
|
method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
|
||||||
if (method_endSendObject == NULL) {
|
if (method_endSendObject == NULL) {
|
||||||
LOGE("Can't find endSendObject");
|
LOGE("Can't find endSendObject");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ public:
|
|||||||
virtual void endSendObject(const char* path,
|
virtual void endSendObject(const char* path,
|
||||||
MtpObjectHandle handle,
|
MtpObjectHandle handle,
|
||||||
MtpObjectFormat format,
|
MtpObjectFormat format,
|
||||||
int64_t size,
|
|
||||||
bool succeeded) = 0;
|
bool succeeded) = 0;
|
||||||
|
|
||||||
virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
|
virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
|
||||||
|
|||||||
@@ -700,6 +700,9 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
|
|||||||
if (ret && ret != -EEXIST)
|
if (ret && ret != -EEXIST)
|
||||||
return MTP_RESPONSE_GENERAL_ERROR;
|
return MTP_RESPONSE_GENERAL_ERROR;
|
||||||
chown((const char *)path, getuid(), mFileGroup);
|
chown((const char *)path, getuid(), mFileGroup);
|
||||||
|
|
||||||
|
// SendObject does not get sent for directories, so call endSendObject here instead
|
||||||
|
mDatabase->endSendObject(path, handle, MTP_FORMAT_ASSOCIATION, MTP_RESPONSE_OK);
|
||||||
} else {
|
} else {
|
||||||
mSendObjectFilePath = path;
|
mSendObjectFilePath = path;
|
||||||
// save the handle for the SendObject call, which should follow
|
// save the handle for the SendObject call, which should follow
|
||||||
@@ -718,7 +721,6 @@ MtpResponseCode MtpServer::doSendObject() {
|
|||||||
MtpResponseCode result = MTP_RESPONSE_OK;
|
MtpResponseCode result = MTP_RESPONSE_OK;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
int ret;
|
int ret;
|
||||||
uint64_t actualSize = -1;
|
|
||||||
|
|
||||||
if (mSendObjectHandle == kInvalidObjectHandle) {
|
if (mSendObjectHandle == kInvalidObjectHandle) {
|
||||||
LOGE("Expected SendObjectInfo before SendObject");
|
LOGE("Expected SendObjectInfo before SendObject");
|
||||||
@@ -761,18 +763,11 @@ MtpResponseCode MtpServer::doSendObject() {
|
|||||||
result = MTP_RESPONSE_TRANSACTION_CANCELLED;
|
result = MTP_RESPONSE_TRANSACTION_CANCELLED;
|
||||||
else
|
else
|
||||||
result = MTP_RESPONSE_GENERAL_ERROR;
|
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:
|
done:
|
||||||
mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat,
|
mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat,
|
||||||
actualSize, result == MTP_RESPONSE_OK);
|
result == MTP_RESPONSE_OK);
|
||||||
mSendObjectHandle = kInvalidObjectHandle;
|
mSendObjectHandle = kInvalidObjectHandle;
|
||||||
mSendObjectFormat = 0;
|
mSendObjectFormat = 0;
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user