Merge "Fix renaming file and moving file issue in MTP" into rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d099321312
@@ -19,8 +19,7 @@ package android.mtp;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -32,7 +31,6 @@ import android.media.ExifInterface;
|
||||
import android.media.ThumbnailUtils;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.storage.StorageVolume;
|
||||
import android.provider.MediaStore;
|
||||
@@ -103,8 +101,6 @@ public class MtpDatabase implements AutoCloseable {
|
||||
private MtpStorageManager mManager;
|
||||
|
||||
private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
|
||||
private static final String[] ID_PROJECTION = new String[] {Files.FileColumns._ID};
|
||||
private static final String[] PATH_PROJECTION = new String[] {Files.FileColumns.DATA};
|
||||
private static final String NO_MEDIA = ".nomedia";
|
||||
|
||||
static {
|
||||
@@ -431,7 +427,7 @@ public class MtpDatabase implements AutoCloseable {
|
||||
}
|
||||
// Add the new file to MediaProvider
|
||||
if (succeeded) {
|
||||
MediaStore.scanFile(mContext.getContentResolver(), obj.getPath().toFile());
|
||||
updateMediaStore(mContext, obj.getPath().toFile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,32 +576,8 @@ public class MtpDatabase implements AutoCloseable {
|
||||
return MtpConstants.RESPONSE_GENERAL_ERROR;
|
||||
}
|
||||
|
||||
// finally update MediaProvider
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Files.FileColumns.DATA, newPath.toString());
|
||||
String[] whereArgs = new String[]{oldPath.toString()};
|
||||
try {
|
||||
// note - we are relying on a special case in MediaProvider.update() to update
|
||||
// the paths for all children in the case where this is a directory.
|
||||
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
||||
mMediaProvider.update(objectsUri, values, PATH_WHERE, whereArgs);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in mMediaProvider.update", e);
|
||||
}
|
||||
|
||||
// check if nomedia status changed
|
||||
if (obj.isDir()) {
|
||||
// for directories, check if renamed from something hidden to something non-hidden
|
||||
if (oldPath.getFileName().startsWith(".") && !newPath.startsWith(".")) {
|
||||
MediaStore.scanFile(mContext.getContentResolver(), newPath.toFile());
|
||||
}
|
||||
} else {
|
||||
// for files, check if renamed from .nomedia to something else
|
||||
if (oldPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA)
|
||||
&& !newPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA)) {
|
||||
MediaStore.scanFile(mContext.getContentResolver(), newPath.getParent().toFile());
|
||||
}
|
||||
}
|
||||
updateMediaStore(mContext, oldPath.toFile());
|
||||
updateMediaStore(mContext, newPath.toFile());
|
||||
return MtpConstants.RESPONSE_OK;
|
||||
}
|
||||
|
||||
@@ -635,48 +607,15 @@ public class MtpDatabase implements AutoCloseable {
|
||||
Log.e(TAG, "Failed to end move object");
|
||||
return;
|
||||
}
|
||||
|
||||
obj = mManager.getObject(objId);
|
||||
if (!success || obj == null)
|
||||
return;
|
||||
// Get parent info from MediaProvider, since the id is different from MTP's
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
Path path = newParentObj.getPath().resolve(name);
|
||||
Path oldPath = oldParentObj.getPath().resolve(name);
|
||||
values.put(Files.FileColumns.DATA, path.toString());
|
||||
if (obj.getParent().isRoot()) {
|
||||
values.put(Files.FileColumns.PARENT, 0);
|
||||
} else {
|
||||
int parentId = findInMedia(newParentObj, path.getParent());
|
||||
if (parentId != -1) {
|
||||
values.put(Files.FileColumns.PARENT, parentId);
|
||||
} else {
|
||||
// The new parent isn't in MediaProvider, so delete the object instead
|
||||
deleteFromMedia(obj, oldPath, obj.isDir());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// update MediaProvider
|
||||
Cursor c = null;
|
||||
String[] whereArgs = new String[]{oldPath.toString()};
|
||||
try {
|
||||
int parentId = -1;
|
||||
if (!oldParentObj.isRoot()) {
|
||||
parentId = findInMedia(oldParentObj, oldPath.getParent());
|
||||
}
|
||||
if (oldParentObj.isRoot() || parentId != -1) {
|
||||
// Old parent exists in MediaProvider - perform a move
|
||||
// note - we are relying on a special case in MediaProvider.update() to update
|
||||
// the paths for all children in the case where this is a directory.
|
||||
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
||||
mMediaProvider.update(objectsUri, values, PATH_WHERE, whereArgs);
|
||||
} else {
|
||||
// Old parent doesn't exist - add the object
|
||||
MediaStore.scanFile(mContext.getContentResolver(), path.toFile());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in mMediaProvider.update", e);
|
||||
}
|
||||
|
||||
updateMediaStore(mContext, oldPath.toFile());
|
||||
updateMediaStore(mContext, path.toFile());
|
||||
}
|
||||
|
||||
@VisibleForNative
|
||||
@@ -699,7 +638,19 @@ public class MtpDatabase implements AutoCloseable {
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
MediaStore.scanFile(mContext.getContentResolver(), obj.getPath().toFile());
|
||||
|
||||
updateMediaStore(mContext, obj.getPath().toFile());
|
||||
}
|
||||
|
||||
private static void updateMediaStore(@NonNull Context context, @NonNull File file) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
// For file, check whether the file name is .nomedia or not.
|
||||
// If yes, scan the parent directory to update all files in the directory.
|
||||
if (!file.isDirectory() && file.getName().toLowerCase(Locale.ROOT).endsWith(NO_MEDIA)) {
|
||||
MediaStore.scanFile(resolver, file.getParentFile());
|
||||
} else {
|
||||
MediaStore.scanFile(resolver, file);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForNative
|
||||
@@ -928,26 +879,6 @@ public class MtpDatabase implements AutoCloseable {
|
||||
deleteFromMedia(obj, obj.getPath(), obj.isDir());
|
||||
}
|
||||
|
||||
private int findInMedia(MtpStorageManager.MtpObject obj, Path path) {
|
||||
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
||||
|
||||
int ret = -1;
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = mMediaProvider.query(objectsUri, ID_PROJECTION, PATH_WHERE,
|
||||
new String[]{path.toString()}, null, null);
|
||||
if (c != null && c.moveToNext()) {
|
||||
ret = c.getInt(0);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error finding " + path + " in MediaProvider");
|
||||
} finally {
|
||||
if (c != null)
|
||||
c.close();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void deleteFromMedia(MtpStorageManager.MtpObject obj, Path path, boolean isDir) {
|
||||
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
||||
try {
|
||||
@@ -963,13 +894,10 @@ public class MtpDatabase implements AutoCloseable {
|
||||
}
|
||||
|
||||
String[] whereArgs = new String[]{path.toString()};
|
||||
if (mMediaProvider.delete(objectsUri, PATH_WHERE, whereArgs) > 0) {
|
||||
if (!isDir && path.toString().toLowerCase(Locale.US).endsWith(NO_MEDIA)) {
|
||||
MediaStore.scanFile(mContext.getContentResolver(), path.getParent().toFile());
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "Mediaprovider didn't delete " + path);
|
||||
if (mMediaProvider.delete(objectsUri, PATH_WHERE, whereArgs) == 0) {
|
||||
Log.i(TAG, "MediaProvider didn't delete " + path);
|
||||
}
|
||||
updateMediaStore(mContext, path.toFile());
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Failed to delete " + path + " from MediaProvider");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user