Handle _ and % in paths

When doing a "like" match on a path, add a second non-like constraint
so that sqlite wildcard characters don't match arbitrary other characters.
b/6501408

Change-Id: I21f9b1c2d8e7c7ef27c0ad5fe24c3e01cd67fb61
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 987c0ac..c6c1ccb 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1444,7 +1444,9 @@
         String where;
         String[] selectionArgs;
         if (mCaseInsensitivePaths) {
-            where = Files.FileColumns.DATA + " LIKE ?";
+            // the 'like' makes it use the index, the 'lower()' makes it correct
+            // when the path contains sqlite wildcard characters
+            where = "_data LIKE ?1 AND lower(_data)=lower(?1)";
             selectionArgs = new String[] { path };
         } else {
             where = Files.FileColumns.DATA + "=?";
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 18aa4b3..c365e4c 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -932,8 +932,11 @@
             if (format == MtpConstants.FORMAT_ASSOCIATION) {
                 // recursive case - delete all children first
                 Uri uri = Files.getMtpObjectsUri(mVolumeName);
-                int count = mMediaProvider.delete(uri, "_data LIKE ?",
-                        new String[] { path + "/%"});
+                int count = mMediaProvider.delete(uri,
+                        // the 'like' makes it use the index, the 'lower()' makes it correct
+                        // when the path contains sqlite wildcard characters
+                        "_data LIKE ? AND lower(substr(_data,?))=lower(?)",
+                        new String[] { path + "/%", "" + path.length() + 1, path + "/"});
             }
 
             Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);