Test apps can create hidden files using file path.

Test that apps can create hidden file, write to and read from hidden
file and delete hidden file using file path.
Test: atest FuseDaemonHostTest#testCanCreateHiddenFile
Bug: b/147741933

Change-Id: Ifb4ac9f1d86814cf72681e027011cdf3938b86ff
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index d797ba9..f5c93fe 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -5025,7 +5025,6 @@
                 return res;
             }
 
-            // TODO(b/147741933): Quick fix. Add tests
             path = getAbsoluteSanitizedPath(path);
             if (path == null) {
                 throw new IOException("Invalid path " + path);
@@ -5162,7 +5161,6 @@
                 return OsConstants.EACCES;
             }
 
-            // TODO(b/147741933): Quick fix. Add tests
             path = getAbsoluteSanitizedPath(path);
             if (path == null) {
                 Log.e(TAG, "Invalid path " + path);
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
index 224b8ec..c0cbff9 100644
--- a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
+++ b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
@@ -208,4 +208,9 @@
     public void testCantAccessOtherAppsContents() throws Exception {
         runDeviceTest("testCantAccessOtherAppsContents");
     }
+
+    @Test
+    public void testCanCreateHiddenFile() throws Exception {
+        runDeviceTest("testCanCreateHiddenFile");
+    }
 }
diff --git a/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java b/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
index f8c1e86..fa4f338 100644
--- a/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
+++ b/tests/jni/FuseDaemonTest/src/com/android/tests/fused/FilePathAccessTest.java
@@ -1252,6 +1252,37 @@
         }
     }
 
+    /**
+     * Test that apps can create hidden file
+     */
+    @Test
+    public void testCanCreateHiddenFile() throws Exception {
+        final File hiddenFile = new File(DOWNLOAD_DIR, ".hiddenFile");
+        try {
+            assertThat(hiddenFile.createNewFile()).isTrue();
+            // Write to hidden file is allowed.
+            try (final FileOutputStream fos = new FileOutputStream(hiddenFile)) {
+                fos.write(BYTES_DATA1);
+            }
+            assertFileContent(hiddenFile, BYTES_DATA1);
+            // We can delete hidden file
+            // TODO(b/148579340): Uncomment these once we support hidden file deletion.
+            // assertThat(hiddenFile.delete()).isTrue();
+            // assertThat(hiddenFile.exists()).isFalse();
+        } finally {
+            // TODO(b/148579340): Remove below workaround once the hidden file deletion is
+            // supported.
+            executeShellCommand("rm " + hiddenFile.getAbsolutePath());
+            String selection = MediaColumns.RELATIVE_PATH + " = ? AND "
+                    + MediaColumns.DISPLAY_NAME + " = ?";
+            String[] selectionArgs = {hiddenFile.getParentFile().getName() + "/", "_.hiddenFile" };
+            getContentResolver().delete(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL),
+                    selection, selectionArgs);
+
+            hiddenFile.delete();
+        }
+    }
+
     private void deleteWithMediaProvider(String relativePath, String displayName) throws Exception {
         String selection = MediaColumns.RELATIVE_PATH + " = ? AND "
                 + MediaColumns.DISPLAY_NAME + " = ?";