kernel_module_loader: Load Modules as early as possible

 * This fixes unusually checking for unneeded directories for modules

 * Load Modules early, as it may required by decryption process

 * Tests: fastboot boot, ramdisk boot, fastbootd boot

Change-Id: I2aae88b6dfc0c98867209d4e4eb7e9d503682199
Signed-off-by: Mohd Faraz <androiabledroid@gmail.com>
diff --git a/kernel_module_loader.cpp b/kernel_module_loader.cpp
index 73304a6..292d18f 100644
--- a/kernel_module_loader.cpp
+++ b/kernel_module_loader.cpp
@@ -1,8 +1,24 @@
 #include "kernel_module_loader.hpp"
 #include "common.h"
+#include "variables.h"
 
 const std::vector<std::string> kernel_modules_requested = TWFunc::split_string(EXPAND(TW_LOAD_VENDOR_MODULES), ' ', true);
 
+BOOT_MODE KernelModuleLoader::Get_Boot_Mode() {
+	std::string cmdline;
+	std::string bootconfig;
+	android::base::ReadFileToString("/proc/bootconfig", &bootconfig);
+	android::base::ReadFileToString("/proc/cmdline", &cmdline);
+
+	if (cmdline.find("twrpfastboot=1") != std::string::npos && (bootconfig.find("androidboot.force_normal_boot = \"1\"") != std::string::npos ||
+		cmdline.find("androidboot.force_normal_boot=1") != std::string::npos))
+		return RECOVERY_FASTBOOT_MODE;
+	else if (android::base::GetProperty(TW_FASTBOOT_MODE_PROP, "0") == "1")
+		return FASTBOOTD_MODE;
+
+	return RECOVERY_IN_BOOT_MODE;
+}
+
 bool KernelModuleLoader::Load_Vendor_Modules() {
 	// check /lib/modules (ramdisk vendor_boot)
 	// check /lib/modules/N.N (ramdisk vendor_boot)
@@ -12,6 +28,7 @@
 	// check /vendor/lib/modules/N.N (vendor mounted)
 	// check /vendor/lib/modules/N.N-gki (vendor mounted)
 	// check /vendor_dlkm/lib/modules (vendor_dlkm mounted)
+	if (android::base::GetBoolProperty(TW_MODULES_MOUNTED_PROP, false)) return true;
 	int modules_loaded = 0;
 
 	LOGINFO("Attempting to load modules\n");
@@ -43,14 +60,23 @@
 	vendor_module_dirs.push_back(vendor_base_dir + gki);
 #endif
 
-	for (auto&& module_dir:module_dirs) {
-		modules_loaded += Try_And_Load_Modules(module_dir, false);
-		if (modules_loaded >= expected_module_count) goto exit;
-	}
+	switch(Get_Boot_Mode()) {
+		case RECOVERY_FASTBOOT_MODE:
+			/* On bootmode: once, there is not always stock kernel
+			 * so try only with twrp prebuilt modules.
+			 */
+			for (auto&& module_dir:vendor_module_dirs) {
+				modules_loaded += Try_And_Load_Modules(module_dir, false);
+				if (modules_loaded >= expected_module_count) goto exit;
+			}
+			break;
 
-	for (auto&& module_dir:vendor_module_dirs) {
-		modules_loaded += Try_And_Load_Modules(module_dir, false);
-		if (modules_loaded >= expected_module_count) goto exit;
+		case FASTBOOTD_MODE:
+		case RECOVERY_IN_BOOT_MODE:
+			/* In both mode vendor_boot or vendor modules are used
+			 * Because Ramdisk is flashed in both.
+			 */
+			break;
 	}
 
 	if (ven) {
@@ -76,7 +102,7 @@
 	if (ven_dlkm)
 		ven_dlkm->UnMount(false);
 
-	android::base::SetProperty("twrp.modules.loaded", "true");
+	android::base::SetProperty(TW_MODULES_MOUNTED_PROP, "true");
 
 	return true;
 }
diff --git a/kernel_module_loader.hpp b/kernel_module_loader.hpp
index afdfd8f..9a32940 100644
--- a/kernel_module_loader.hpp
+++ b/kernel_module_loader.hpp
@@ -4,6 +4,7 @@
 #include <dirent.h>
 #include <string>
 #include <vector>
+#include <android-base/file.h>
 #include <android-base/strings.h>
 #include <modprobe/modprobe.h>
 #include <sys/mount.h>
@@ -24,13 +25,14 @@
 class KernelModuleLoader
 {
 public:
-    static bool Load_Vendor_Modules(); // Load specific maintainer defined kernel modules in TWRP
+	static bool Load_Vendor_Modules(); // Load specific maintainer defined kernel modules in TWRP
 
 private:
 	static int Try_And_Load_Modules(std::string module_dir, bool vendor_is_mounted); // Use libmodprobe to attempt loading kernel modules
 	static bool Write_Module_List(std::string module_dir); // Write list of modules to load from TW_LOAD_VENDOR_MODULES
-    static bool Copy_Modules_To_Tmpfs(std::string module_dir); // Copy modules to ramdisk for loading
+	static bool Copy_Modules_To_Tmpfs(std::string module_dir); // Copy modules to ramdisk for loading
 	static std::vector<string> Skip_Loaded_Kernel_Modules(); // return list of loaded kernel modules already done by init
+	static BOOT_MODE Get_Boot_Mode(); // For getting the current boot mode
 };
 
-#endif // _KERNELMODULELOADER_HPP
\ No newline at end of file
+#endif // _KERNELMODULELOADER_HPP
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 2695b65..f741cb3 100755
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -75,6 +75,10 @@
 #include "twrpRepacker.hpp"
 #include "adbbu/libtwadbbu.hpp"
 
+#ifdef TW_LOAD_VENDOR_MODULES
+#include "kernel_module_loader.hpp"
+#endif
+
 #ifdef TW_HAS_MTP
 #ifdef TW_HAS_LEGACY_MTP
 #include "mtp/legacy/mtp_MtpServer.hpp"
@@ -342,9 +346,14 @@
 			mapit->second.fstab_line = NULL;
 		}
 	}
+
+#ifdef TW_LOAD_VENDOR_MODULES
+	KernelModuleLoader::Load_Vendor_Modules();
+#endif
+
 	TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor");
 	TWPartition* odm = PartitionManager.Find_Partition_By_Path("/odm");
-	if (!parse_userdata) {
+	if (recovery_mode && !parse_userdata) {
 		if (ven) ven->Mount(Display_Error);
 		if (odm) odm->Mount(Display_Error);
 		if (TWFunc::Find_Fstab(Fstab_Filename)) {
diff --git a/twrp.cpp b/twrp.cpp
index b7f4058..0362b80 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -48,10 +48,6 @@
 #include "twrp-functions.hpp"
 #include "data.hpp"
 
-#ifdef TW_LOAD_VENDOR_MODULES
-#include "kernel_module_loader.hpp"
-#endif
-
 #include "partitions.hpp"
 #ifdef __ANDROID_API_N__
 #include <android-base/strings.h>
@@ -391,6 +387,7 @@
 	DataManager::SetDefaultValues();
 	startupArgs startup;
 	startup.parse(&argc, &argv);
+	android::base::SetProperty(TW_FASTBOOT_MODE_PROP, startup.Get_Fastboot_Mode() ? "1" : "0");
 	printf("=> Linking mtab\n");
 	symlink("/proc/mounts", "/etc/mtab");
 	std::string fstab_filename = "/etc/twrp.fstab";
@@ -406,13 +403,11 @@
 #ifdef TW_LOAD_VENDOR_MODULES
 	if (startup.Get_Fastboot_Mode()) {
 		TWPartition* ven_dlkm = PartitionManager.Find_Partition_By_Path("/vendor_dlkm");
-		android::base::SetProperty("ro.twrp.fastbootd", "1");
 		PartitionManager.Prepare_Super_Volume(PartitionManager.Find_Partition_By_Path("/vendor"));
 		if(ven_dlkm) {
 			PartitionManager.Prepare_Super_Volume(ven_dlkm);
 		}
 	}
-	KernelModuleLoader::Load_Vendor_Modules();
 #endif
 
 	printf("Starting the UI...\n");
diff --git a/variables.h b/variables.h
index 54ddfd9..f481b2e 100755
--- a/variables.h
+++ b/variables.h
@@ -150,6 +150,10 @@
 #define TW_VIRTUAL_AB_ENABLED       "tw_virtual_ab.enabled"
 #define TW_AUTO_REFLASHTWRP_VAR     "tw_auto_reflashtwrp"
 
+// BUILD PROPS
+#define TW_FASTBOOT_MODE_PROP         "ro.twrp.fastbootd"
+#define TW_MODULES_MOUNTED_PROP       "twrp.modules.loaded"     // property for successfully mounted modules
+
 // Theme versioning
 // version 2 requires theme to handle power button as action togglebacklight
 // version 4 adds listbox support to reboot page