OSDN Git Service

Cache media/nomedia paths
authorMarco Nelissen <marcone@google.com>
Tue, 4 Feb 2014 20:52:10 +0000 (12:52 -0800)
committerMarco Nelissen <marcone@google.com>
Tue, 4 Feb 2014 20:52:10 +0000 (12:52 -0800)
Instead of checking all the parents of every path for presence of
a .nomedia file every time a new entry is inserted, build a cache
of paths and use that when possible.

Change-Id: I5b912fd54473db8f96d3511cbc2715e0b69dd16b

media/java/android/media/MediaScanner.java

index 53835e2..01485b8 100644 (file)
@@ -55,6 +55,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Locale;
@@ -1400,27 +1401,60 @@ public class MediaScanner
         return false;
     }
 
-    public static boolean isNoMediaPath(String path) {
-        if (path == null) return false;
+    private static HashMap<String,String> mNoMediaPaths = new HashMap<String,String>();
+    private static HashMap<String,String> mMediaPaths = new HashMap<String,String>();
 
+    /* MediaProvider calls this when a .nomedia file is added or removed */
+    public static void clearMediaPathCache(boolean clearMediaPaths, boolean clearNoMediaPaths) {
+        synchronized (MediaScanner.class) {
+            if (clearMediaPaths) {
+                mMediaPaths.clear();
+            }
+            if (clearNoMediaPaths) {
+                mNoMediaPaths.clear();
+            }
+        }
+    }
+
+    public static boolean isNoMediaPath(String path) {
+        if (path == null) {
+            return false;
+        }
         // return true if file or any parent directory has name starting with a dot
-        if (path.indexOf("/.") >= 0) return true;
-
-        // now check to see if any parent directories have a ".nomedia" file
-        // start from 1 so we don't bother checking in the root directory
-        int offset = 1;
-        while (offset >= 0) {
-            int slashIndex = path.indexOf('/', offset);
-            if (slashIndex > offset) {
-                slashIndex++; // move past slash
-                File file = new File(path.substring(0, slashIndex) + ".nomedia");
-                if (file.exists()) {
-                    // we have a .nomedia in one of the parent directories
-                    return true;
+        if (path.indexOf("/.") >= 0) {
+            return true;
+        }
+
+        int firstSlash = path.lastIndexOf('/');
+        if (firstSlash == 0) {
+            return false;
+        }
+        String parent = path.substring(0,  firstSlash);
+
+        synchronized (MediaScanner.class) {
+            if (mNoMediaPaths.containsKey(parent)) {
+                return true;
+            } else if (!mMediaPaths.containsKey(parent)) {
+                // check to see if any parent directories have a ".nomedia" file
+                // start from 1 so we don't bother checking in the root directory
+                int offset = 1;
+                while (offset >= 0) {
+                    int slashIndex = path.indexOf('/', offset);
+                    if (slashIndex > offset) {
+                        slashIndex++; // move past slash
+                        File file = new File(path.substring(0, slashIndex) + ".nomedia");
+                        if (file.exists()) {
+                            // we have a .nomedia in one of the parent directories
+                            mNoMediaPaths.put(parent, "");
+                            return true;
+                        }
+                    }
+                    offset = slashIndex;
                 }
+                mMediaPaths.put(parent, "");
             }
-            offset = slashIndex;
         }
+
         return isNoMediaFile(path);
     }