Merge "Fix renaming file and moving file issue in MTP" into rvc-qpr-dev

This commit is contained in:
TreeHugger Robot
2021-01-12 03:55:52 +00:00
committed by Android (Google) Code Review

View File

@@ -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");
}