Loading media/java/android/mtp/MtpDatabase.java +24 −96 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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()); } } Loading Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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"); } Loading Loading
media/java/android/mtp/MtpDatabase.java +24 −96 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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()); } } Loading Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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"); } Loading