Add vendor hook after userdata becoming available

The init process provides a vendor hook for dynamically initializing
system properties during early boot. During this hook, however, userdata
may not yet be available if the device is encrypted. Therefore, add an
additional hook here in vold that is triggered once userdata is
available, so that system properties can be set based on data previously
stored on the userdata partition.

Issue: FP2N-386
Change-Id: Ie7aa75d0768489b119ab3da0e1a75e2d90c9dc6b
diff --git a/Android.mk b/Android.mk
index 32dc9c0..23fc36b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -29,6 +29,7 @@
 	Benchmark.cpp \
 	TrimTask.cpp \
 	secontext.cpp \
+	vendor_post_fs_data_init.cpp \
 	main.cpp
 
 crypto_src_files := \
@@ -138,6 +139,14 @@
 LOCAL_SHARED_LIBRARIES += libcryptfs_hw
 endif
 
+# Allow vendor implementations to hook into the boot process directly after
+# userdata is mounted and decrypted, but before the framework is fully
+# initialized.
+# This hook is only called on encrypted devices.
+ifneq ($(strip $(TARGET_VOLD_VENDOR_LIB)),)
+LOCAL_WHOLE_STATIC_LIBRARIES += $(TARGET_VOLD_VENDOR_LIB)
+endif
+
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
diff --git a/cryptfs.c b/cryptfs.c
index 9603f34..b222b9d 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -61,6 +61,7 @@
 #include "f2fs_sparseblock.h"
 #include "CheckBattery.h"
 #include "Process.h"
+#include "vendor_post_fs_data_init.h"
 
 #include <bootloader_message/bootloader_message.h>
 #include <hardware/keymaster0.h>
@@ -1950,6 +1951,8 @@
             return -1;
         }
 
+        vendor_post_fs_data_load_properties();
+
         property_set("vold.decrypt", "trigger_load_persist_props");
         /* Create necessary paths on /data */
         if (prep_data_fs()) {
diff --git a/vendor_post_fs_data_init.cpp b/vendor_post_fs_data_init.cpp
new file mode 100644
index 0000000..f55a817
--- /dev/null
+++ b/vendor_post_fs_data_init.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019 Fairphone B.V.
+ *
+ * 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 "vendor_post_fs_data_init.h"
+
+/* vold vendor override stubs */
+
+__attribute__ ((weak))
+void vendor_post_fs_data_load_properties()
+{
+}
diff --git a/vendor_post_fs_data_init.h b/vendor_post_fs_data_init.h
new file mode 100644
index 0000000..dbae8f8
--- /dev/null
+++ b/vendor_post_fs_data_init.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Fairphone B.V.
+ *
+ * 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.
+ */
+
+#ifndef __VOLD_VENDOR_POST_FS_DATA_INIT__
+#define __VOLD_VENDOR_POST_FS_DATA_INIT__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Load vendor-specific system properties with access to userdata.
+ *
+ * This hook will only be called on encrypted devices. Make sure to use it
+ * together with vendor_load_properties if you need a hook on unencrypted
+ * devices as well.
+ *
+ * This will be called once userdata is mounted and decrypted, before the
+ * framework gets restarted to use the actual (non-temporary) userdata
+ * partition.
+ */
+extern void vendor_post_fs_data_load_properties(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VOLD_VENDOR_POST_FS_DATA_INIT__ */