Allow excluding directories during scan

Android supports hidden directories of two kinds:
1. /sdcard/.foo
2. /sdcard/foo/.nomedia

In Android Q, hidden directories were not scanned by the
MediaProvider. In Android R, as part of integrating the FUSE
filesystem on /sdcard with the MediaProvider database, we started
scanning these directories.

These scans have led to performance issues where several apps can
contain millions of files in their directories.

This change addresses the issue by skipping hidden directories of
type (2) that are already scanned and are consistent with the
database.

The implementation relies on writing the path of the .nomedia file
into the .nomedia file itself, e.g /sdcard/foo/.nomedia will contain
/sdcard/foo.

During scan we do the following:
- preVisitDirectory: Skip scan if .nomedia exists and content matches
the path being scanned. Also add skipped path in mExcludeDirs
- postVisitDirectory: If directory contains .nomedia, write scanned
path into the file.
- reconcileAndClean: SQL match 'NOT LIKE' mExcludeDirs to avoid
removing db entries that skipped scan

This works becasue after an OTA, the entire volume is scanned without
skipping any dirs, on subsequent scans however, the top-most dirs
containing .nomedia files will be skipped and most modifications to
those dirs will keep the filesystem and db consistent so subsequent
scans on the dirs are not required.

We modify creat(2), unlink(2) and rename(2) via FUSE to clear the
top-level .nomedia content of the path if an app is by-passing the
database. This fixes edge cases where hidden dirs are modified outside
the database and can leave the filesystem and db inconsistent forever.

Note that this implementation does not handle hidden dirs of
type (1). We can extend it to force create .nomedia files in such dirs
and the algorithm here can be applied

Bug: 167523095
Test: Manual
Test: atest FileUtilsTest
Change-Id: I288bf5ee970cccd35ec86c0f89bdcf59916de47a
7 files changed