Fingerprint data is now stored in one of two ways depending on the

shipping API version:

For devices shipped before Android P nothing changes, data
is stored under /data/system/users/<user-id>/fpdata/...

Devices shipped from now on will instead store
fingerprint data under /data/vendor_de/<user-id>/fpdata.

Support for /data/vendor_de and /data/vendor_ce has been added to vold.

Bug: 36997597
Change-Id: I615e90d1c9ab08e768a8713968fa043598a0a526
Test: manually
diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp
index 85ace4a..1b71365 100644
--- a/Ext4Crypt.cpp
+++ b/Ext4Crypt.cpp
@@ -663,6 +663,7 @@
         // DE_n key
         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
         auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
 
         if (volume_uuid.empty()) {
@@ -675,6 +676,7 @@
 
             if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
             if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
+            if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
         }
         if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
 
@@ -685,6 +687,7 @@
                 get_data_file_encryption_modes(&de_ref);
                 if (!ensure_policy(de_ref, system_de_path)) return false;
                 if (!ensure_policy(de_ref, misc_de_path)) return false;
+                if (!ensure_policy(de_ref, vendor_de_path)) return false;
             } else {
                 if (!read_or_create_volkey(misc_de_path, volume_uuid, &de_ref)) return false;
             }
@@ -696,12 +699,14 @@
         // CE_n key
         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
         auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
 
         if (volume_uuid.empty()) {
             if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
             if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
+            if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
         }
         if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
         if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
@@ -713,6 +718,7 @@
                 get_data_file_encryption_modes(&ce_ref);
                 if (!ensure_policy(ce_ref, system_ce_path)) return false;
                 if (!ensure_policy(ce_ref, misc_ce_path)) return false;
+                if (!ensure_policy(ce_ref, vendor_ce_path)) return false;
 
             } else {
                 if (!read_or_create_volkey(misc_ce_path, volume_uuid, &ce_ref)) return false;
@@ -745,6 +751,7 @@
         // CE_n key
         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
         auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
 
@@ -753,6 +760,7 @@
         if (volume_uuid.empty()) {
             res &= destroy_dir(system_ce_path);
             res &= destroy_dir(misc_ce_path);
+            res &= destroy_dir(vendor_ce_path);
         } else {
             if (e4crypt_is_native()) {
                 res &= destroy_volkey(misc_ce_path, volume_uuid);
@@ -769,6 +777,7 @@
         // DE_n key
         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
         auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
 
         res &= destroy_dir(user_de_path);
@@ -780,6 +789,7 @@
             res &= destroy_dir(profiles_de_path);
             res &= destroy_dir(system_de_path);
             res &= destroy_dir(misc_de_path);
+            res &= destroy_dir(vendor_de_path);
         } else {
             if (e4crypt_is_native()) {
                 res &= destroy_volkey(misc_de_path, volume_uuid);
diff --git a/Utils.cpp b/Utils.cpp
index 38edcb3..98e8a9b 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -635,6 +635,14 @@
     return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath("").c_str(), userId);
 }
 
+std::string BuildDataVendorCePath(userid_t userId) {
+    return StringPrintf("%s/vendor_ce/%u", BuildDataPath("").c_str(), userId);
+}
+
+std::string BuildDataVendorDePath(userid_t userId) {
+    return StringPrintf("%s/vendor_de/%u", BuildDataPath("").c_str(), userId);
+}
+
 std::string BuildDataPath(const std::string& volumeUuid) {
     // TODO: unify with installd path generation logic
     if (volumeUuid.empty()) {
diff --git a/Utils.h b/Utils.h
index c5955cc..5caa4e9 100644
--- a/Utils.h
+++ b/Utils.h
@@ -107,6 +107,8 @@
 std::string BuildDataMiscCePath(userid_t userid);
 std::string BuildDataMiscDePath(userid_t userid);
 std::string BuildDataProfilesDePath(userid_t userid);
+std::string BuildDataVendorCePath(userid_t userid);
+std::string BuildDataVendorDePath(userid_t userid);
 
 std::string BuildDataPath(const std::string& volumeUuid);
 std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userid);
diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp
index 02bedde..1b466e9 100644
--- a/vold_prepare_subdirs.cpp
+++ b/vold_prepare_subdirs.cpp
@@ -38,6 +38,8 @@
 #include "Utils.h"
 #include "android/os/IVold.h"
 
+#include <private/android_filesystem_config.h>
+
 static void usage(const char* progname) {
     std::cerr << "Usage: " << progname << " [ prepare | destroy ] <volume_uuid> <user_id> <flags>"
               << std::endl;
@@ -125,6 +127,11 @@
             auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/vold")) return false;
             if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/storaged")) return false;
+
+            auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
+            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, vendor_de_path + "/fpdata")) {
+                return false;
+            }
         }
         if (flags & android::os::IVold::STORAGE_FLAG_CE) {
             auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
@@ -141,10 +148,16 @@
         if (flags & android::os::IVold::STORAGE_FLAG_CE) {
             auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
             res &= rmrf_contents(misc_ce_path);
+
+            auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
+            res &= rmrf_contents(vendor_ce_path);
         }
         if (flags & android::os::IVold::STORAGE_FLAG_DE) {
             auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
             res &= rmrf_contents(misc_de_path);
+
+            auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
+            res &= rmrf_contents(vendor_de_path);
         }
     }
     return res;