Tuxera exFAT vold patch for Android 11.

Issue: FP3-A11#46
Change-Id: Ifbe147f8f8273d617c9fe447539d69e83607730e
diff --git a/fs/Filesystems.cpp b/fs/Filesystems.cpp
new file mode 100644
index 0000000..ff916d2
--- /dev/null
+++ b/fs/Filesystems.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2014-2021 Tuxera Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Filesystems.h"
+
+#include "Apfs.h"
+#include "HfsPlus.h"
+#include "Ntfs.h"
+#include "Exfat.h"
+#include "Vfat.h"
+
+#include <errno.h>
+
+namespace android {
+namespace vold {
+namespace filesystems {
+
+status_t Detect(const std::string& source, FSType *outFsType) {
+    int err;
+    bool result = false;
+
+    if ((err = hfsplus::Detect(source, &result)) == 0 && result) {
+        *outFsType = FSTYPE_HFSPLUS;
+    }
+    else if ((err = ntfs::Detect(source, &result)) == 0 && result) {
+        *outFsType = FSTYPE_NTFS;
+    }
+    else if ((err = exfat::Detect(source, &result)) == 0 && result) {
+        *outFsType = FSTYPE_EXFAT;
+    }
+    else if ((err = apfs::Detect(source, &result)) == 0 && result) {
+        *outFsType = FSTYPE_APFS;
+    }
+    else {
+        /* Until we implement reliable FAT detection code. */
+        *outFsType = FSTYPE_FAT;
+    }
+
+    return 0; /* Always succeed since FAT is the default fallback. */
+}
+
+bool IsSupported(FSType fsType) {
+    switch (fsType) {
+    case FSTYPE_APFS:
+        return false;
+    case FSTYPE_HFSPLUS:
+        return false;
+    case FSTYPE_NTFS:
+        return false;
+    case FSTYPE_EXFAT:
+        return exfat::IsSupported();
+    case FSTYPE_FAT:
+        return vfat::IsSupported();
+    default:
+        return false;
+    }
+}
+
+status_t Check(FSType fsType, const std::string& source) {
+    switch (fsType) {
+    case FSTYPE_APFS:
+        errno = ENODATA;
+        return -1;
+    case FSTYPE_HFSPLUS:
+        errno = ENODATA;
+        return -1;
+    case FSTYPE_NTFS:
+        errno = ENODATA;
+        return -1;
+    case FSTYPE_EXFAT:
+        return exfat::Check(source);
+    case FSTYPE_FAT:
+        return vfat::Check(source);
+    default:
+        errno = ENODATA;
+        return -1;
+    }
+}
+
+status_t Mount(FSType fsType, const std::string& source,
+        const std::string& target, bool ro, bool remount, bool executable,
+        int ownerUid, int ownerGid, int permMask, bool createLost) {
+    switch (fsType) {
+    case FSTYPE_APFS:
+        errno = ENOTSUP;
+        return -1;
+    case FSTYPE_HFSPLUS:
+        errno = ENOTSUP;
+        return -1;
+    case FSTYPE_NTFS:
+        errno = ENOTSUP;
+        return -1;
+    case FSTYPE_EXFAT:
+        return exfat::Mount(source, target, ro, remount, executable, ownerUid,
+                            ownerGid, permMask);
+    case FSTYPE_FAT:
+        return vfat::Mount(source, target, ro, remount, executable, ownerUid,
+                           ownerGid, permMask, createLost);
+    default:
+        errno = ENOTSUP;
+        return -1;
+    }
+}
+
+const char* FsName(FSType fsType) {
+    switch (fsType) {
+    case FSTYPE_FAT:
+        return "VFAT";
+    case FSTYPE_EXFAT:
+        return "exFAT";
+    case FSTYPE_NTFS:
+        return "NTFS";
+    case FSTYPE_HFSPLUS:
+        return "HFS+";
+    case FSTYPE_APFS:
+        return "APFS";
+    default:
+        return "<unknown filesystem>";
+    }
+}
+
+}  // namespace filesystems
+}  // namespace vold
+}  // namespace android