diff options
-rw-r--r-- | Android.mk | 7 | ||||
-rw-r--r-- | twrp-functions.cpp | 93 | ||||
-rw-r--r-- | twrp-functions.hpp | 1 | ||||
-rw-r--r-- | twrp.cpp | 3 |
4 files changed, 104 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk index ff1f5a2f6..4ab358a9d 100644 --- a/Android.mk +++ b/Android.mk @@ -265,6 +265,13 @@ ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true) else LOCAL_CFLAGS += -DTW_EXCLUDE_ENCRYPTED_BACKUPS endif +ifeq ($(TARGET_RECOVERY_QCOM_RTC_FIX),) + ifeq ($(TARGET_CPU_VARIANT),krait) + LOCAL_CFLAGS += -DQCOM_RTC_FIX + endif +else ifeq ($(TARGET_RECOVERY_QCOM_RTC_FIX),true) + LOCAL_CFLAGS += -DQCOM_RTC_FIX +endif include $(BUILD_EXECUTABLE) diff --git a/twrp-functions.cpp b/twrp-functions.cpp index e172f3da0..3f44fd2ce 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -1019,3 +1019,96 @@ void TWFunc::Auto_Generate_Backup_Name() { if (!mount_state) PartitionManager.UnMount_By_Path("/system", false); } + +void TWFunc::Fixup_Time_On_Boot() +{ +#ifdef QCOM_RTC_FIX + // Devices with Qualcomm Snapdragon 800 do some shenanigans with RTC. + // They never set it, it just ticks forward from 1970-01-01 00:00, + // and then they have files /data/system/time/ats_* with 64bit offset + // in miliseconds which, when added to the RTC, gives the correct time. + // So, the time is: (offset_from_ats + value_from_RTC) + // There are multiple ats files, they are for different systems? Bases? + // Like, ats_1 is for modem and ats_2 is for TOD (time of day?). + // Look at file time_genoff.h in CodeAurora, qcom-opensource/time-services + + static const char *paths[] = { "/data/system/time/", "/data/time/" }; + + DIR *d; + FILE *f; + uint64_t offset = 0; + struct timeval tv; + struct dirent *dt; + std::string ats_path; + + + // Don't fix the time of it already is over year 2000, it is likely already okay, either + // because the RTC is fine or because the recovery already set it and then crashed + gettimeofday(&tv, NULL); + if(tv.tv_sec > 946684800) // timestamp of 2000-01-01 00:00:00 + { + LOGINFO("TWFunc::Fixup_Time: not fixing time, it seems to be already okay (after year 2000).\n"); + return; + } + + if(!PartitionManager.Mount_By_Path("/data", false)) + return; + + // Prefer ats_2, it seems to be the one we want according to logcat on hammerhead + // - it is the one for ATS_TOD (time of day?). + // However, I never saw a device where the offset differs between ats files. + for(size_t i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) + { + DIR *d = opendir(paths[i]); + if(!d) + continue; + + while((dt = readdir(d))) + { + if(dt->d_type != DT_REG || strncmp(dt->d_name, "ats_", 4) != 0) + continue; + + if(ats_path.empty() || strcmp(dt->d_name, "ats_2") == 0) + ats_path = std::string(paths[i]).append(dt->d_name); + } + + closedir(d); + } + + if(ats_path.empty()) + { + LOGERR("TWFunc::Fixup_Time: no ats files found, leaving time as-is!\n"); + return; + } + + f = fopen(ats_path.c_str(), "r"); + if(!f) + { + LOGERR("TWFunc::Fixup_Time: failed to open file %s\n", ats_path.c_str()); + return; + } + + if(fread(&offset, sizeof(offset), 1, f) != 1) + { + LOGERR("TWFunc::Fixup_Time: failed load uint64 from file %s\n", ats_path.c_str()); + fclose(f); + return; + } + fclose(f); + + LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), offset); + + gettimeofday(&tv, NULL); + + tv.tv_sec += offset/1000; + tv.tv_usec += (offset%1000)*1000; + + while(tv.tv_usec >= 1000000) + { + ++tv.tv_sec; + tv.tv_usec -= 1000000; + } + + settimeofday(&tv, NULL); +#endif +} diff --git a/twrp-functions.hpp b/twrp-functions.hpp index 1050f5644..eb88ae2f3 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -75,6 +75,7 @@ public: static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status static string Get_Current_Date(void); // Returns the current date in ccyy-m-dd--hh-nn-ss format static void Auto_Generate_Backup_Name(); // Populates TW_BACKUP_NAME with a backup name based on current date and ro.build.display.id from /system/build.prop + static void Fixup_Time_On_Boot(); // Fixes time on devices which need it private: static void Copy_Log(string Source, string Destination); @@ -268,6 +268,9 @@ int main(int argc, char **argv) { if (DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) { OpenRecoveryScript::Run_OpenRecoveryScript(); } + + TWFunc::Fixup_Time_On_Boot(); + // Launch the main GUI gui_start(); |