Handle adding/removing/renaming nomedia paths

b/5849015
Change-Id: I3ec7419498d1ecc83db6d4605b3d7610349231f7
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 4e01672..d11219b 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -62,6 +62,14 @@
     public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
 
     /**
+     * The method name used by the media scanner and mtp to tell the media provider to
+     * rescan and reclassify that have become unhidden because of renaming folders or
+     * removing nomedia files
+     * @hide
+     */
+    public static final String UNHIDE_CALL = "unhide";
+
+    /**
      * Activity Action: Launch a music player.
      * The activity should be able to play, browse, or manipulate music files stored on the device.
      *
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index b06ef95..fbf65fd 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -35,6 +35,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.provider.MediaStore;
+import android.provider.MediaStore.Files.FileColumns;
 import android.provider.Settings;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
@@ -58,6 +59,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Locale;
 
 /**
  * Internal service helper that no-one should use directly.
@@ -946,6 +948,22 @@
                 // path should never change, and we want to avoid replacing mixed cased paths
                 // with squashed lower case paths
                 values.remove(MediaStore.MediaColumns.DATA);
+
+                int mediaType = 0;
+                if (!MediaScanner.isNoMediaPath(entry.mPath)) {
+                    int fileType = MediaFile.getFileTypeForMimeType(mMimeType);
+                    if (MediaFile.isAudioFileType(fileType)) {
+                        mediaType = FileColumns.MEDIA_TYPE_AUDIO;
+                    } else if (MediaFile.isVideoFileType(fileType)) {
+                        mediaType = FileColumns.MEDIA_TYPE_VIDEO;
+                    } else if (MediaFile.isImageFileType(fileType)) {
+                        mediaType = FileColumns.MEDIA_TYPE_IMAGE;
+                    } else if (MediaFile.isPlayListFileType(fileType)) {
+                        mediaType = FileColumns.MEDIA_TYPE_PLAYLIST;
+                    }
+                    values.put(FileColumns.MEDIA_TYPE, mediaType);
+                }
+
                 mMediaProvider.update(result, values, null, null);
             }
 
@@ -1180,6 +1198,10 @@
                     mMediaProvider.delete(ContentUris.withAppendedId(mFilesUri, entry.mRowId),
                             null, null);
                     iterator.remove();
+                    if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+                        File f = new File(path);
+                        mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null);
+                    }
                 }
             }
         }
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 19db1c0..6bb578b 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -752,6 +752,29 @@
             return MtpConstants.RESPONSE_GENERAL_ERROR;
         }
 
+        // check if nomedia status changed
+        if (newFile.isDirectory()) {
+            // for directories, check if renamed from something hidden to something non-hidden
+            if (oldFile.getName().startsWith(".") && !newPath.startsWith(".")) {
+                // directory was unhidden
+                try {
+                    mMediaProvider.call(MediaStore.UNHIDE_CALL, newPath, null);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "failed to unhide/rescan for " + newPath);
+                }
+            }
+        } else {
+            // for files, check if renamed from .nomedia to something else
+            if (oldFile.getName().toLowerCase(Locale.US).equals(".nomedia")
+                    && !newPath.toLowerCase(Locale.US).equals(".nomedia")) {
+                try {
+                    mMediaProvider.call(MediaStore.UNHIDE_CALL, oldFile.getParent(), null);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "failed to unhide/rescan for " + newPath);
+                }
+            }
+        }
+
         return MtpConstants.RESPONSE_OK;
     }
 
@@ -915,6 +938,15 @@
 
             Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);
             if (mMediaProvider.delete(uri, null, null) > 0) {
+                if (format != MtpConstants.FORMAT_ASSOCIATION
+                        && path.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+                    try {
+                        String parentPath = path.substring(0, path.lastIndexOf("/"));
+                        mMediaProvider.call(MediaStore.UNHIDE_CALL, parentPath, null);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "failed to unhide/rescan for " + path);
+                    }
+                }
                 return MtpConstants.RESPONSE_OK;
             } else {
                 return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;