Merge "Fix renaming file and moving file issue in MTP" into rvc-qpr-dev am: d099321312
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13090503 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ibdb009f96a2e55bb29dd7189451a7cbf57d6919a
This commit is contained in:
@@ -19,8 +19,7 @@ package android.mtp;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
@@ -32,7 +31,6 @@ import android.media.ExifInterface;
|
|||||||
import android.media.ThumbnailUtils;
|
import android.media.ThumbnailUtils;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.storage.StorageVolume;
|
import android.os.storage.StorageVolume;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
@@ -103,8 +101,6 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
private MtpStorageManager mManager;
|
private MtpStorageManager mManager;
|
||||||
|
|
||||||
private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
|
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";
|
private static final String NO_MEDIA = ".nomedia";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -431,7 +427,7 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
// Add the new file to MediaProvider
|
// Add the new file to MediaProvider
|
||||||
if (succeeded) {
|
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;
|
return MtpConstants.RESPONSE_GENERAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally update MediaProvider
|
updateMediaStore(mContext, oldPath.toFile());
|
||||||
ContentValues values = new ContentValues();
|
updateMediaStore(mContext, newPath.toFile());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MtpConstants.RESPONSE_OK;
|
return MtpConstants.RESPONSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,48 +607,15 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
Log.e(TAG, "Failed to end move object");
|
Log.e(TAG, "Failed to end move object");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = mManager.getObject(objId);
|
obj = mManager.getObject(objId);
|
||||||
if (!success || obj == null)
|
if (!success || obj == null)
|
||||||
return;
|
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 path = newParentObj.getPath().resolve(name);
|
||||||
Path oldPath = oldParentObj.getPath().resolve(name);
|
Path oldPath = oldParentObj.getPath().resolve(name);
|
||||||
values.put(Files.FileColumns.DATA, path.toString());
|
|
||||||
if (obj.getParent().isRoot()) {
|
updateMediaStore(mContext, oldPath.toFile());
|
||||||
values.put(Files.FileColumns.PARENT, 0);
|
updateMediaStore(mContext, path.toFile());
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForNative
|
@VisibleForNative
|
||||||
@@ -699,7 +638,19 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
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
|
@VisibleForNative
|
||||||
@@ -928,26 +879,6 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
deleteFromMedia(obj, obj.getPath(), obj.isDir());
|
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) {
|
private void deleteFromMedia(MtpStorageManager.MtpObject obj, Path path, boolean isDir) {
|
||||||
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
final Uri objectsUri = MediaStore.Files.getContentUri(obj.getVolumeName());
|
||||||
try {
|
try {
|
||||||
@@ -963,13 +894,10 @@ public class MtpDatabase implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String[] whereArgs = new String[]{path.toString()};
|
String[] whereArgs = new String[]{path.toString()};
|
||||||
if (mMediaProvider.delete(objectsUri, PATH_WHERE, whereArgs) > 0) {
|
if (mMediaProvider.delete(objectsUri, PATH_WHERE, whereArgs) == 0) {
|
||||||
if (!isDir && path.toString().toLowerCase(Locale.US).endsWith(NO_MEDIA)) {
|
Log.i(TAG, "MediaProvider didn't delete " + path);
|
||||||
MediaStore.scanFile(mContext.getContentResolver(), path.getParent().toFile());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "Mediaprovider didn't delete " + path);
|
|
||||||
}
|
}
|
||||||
|
updateMediaStore(mContext, path.toFile());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "Failed to delete " + path + " from MediaProvider");
|
Log.d(TAG, "Failed to delete " + path + " from MediaProvider");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user