Use /persist as Qualcomm time fix source during early boot
* /persist can be mounted early while TWRP is parsing the fstab so
as soon as the partition is parsed, mount and adjust the time
accordingly.
* Store a backup settings file on /persist. Having a 2nd copy of
the settings file in the /persist partition allows for early
reading of the file and adjust timezone and brightness to user
preference while still on TWRP splash.
* Add the qcom ats time offset in TWRP settings file and use it
if no better ats file is found. This will also allow devices
with a persist partition, but no ats files in it, to adjust
the time offset during early boot.
* Use /persist/time/ as Qualcomm time fix source, based on
Xuefer <xuefer@gmail.com> patch:
https://gerrit.omnirom.org/c/27265/
https://gerrit.omnirom.org/c/24384/
Change-Id: I6c21538eec58d87edfb639d9ce3871f33b886c1d
diff --git a/data.cpp b/data.cpp
index 599b5c0..4dfbde2 100644
--- a/data.cpp
+++ b/data.cpp
@@ -230,7 +230,7 @@
int DataManager::LoadValues(const string& filename)
{
- string str, dev_id;
+ string dev_id;
if (!mInitialized)
SetDefaultValues();
@@ -263,6 +263,44 @@
return 0;
}
+int DataManager::LoadPersistValues(void)
+{
+ static bool loaded = false;
+ string dev_id;
+
+ // Only run this function once, and make sure normal settings file has not yet been read
+ if (loaded || !mBackingFile.empty() || !TWFunc::Path_Exists(PERSIST_SETTINGS_FILE))
+ return -1;
+
+ LOGINFO("Attempt to load settings from /persist settings file...\n");
+
+ if (!mInitialized)
+ SetDefaultValues();
+
+ GetValue("device_id", dev_id);
+ mPersist.SetFile(PERSIST_SETTINGS_FILE);
+ mPersist.SetFileVersion(FILE_VERSION);
+
+ // Read in the file, if possible
+ pthread_mutex_lock(&m_valuesLock);
+ mPersist.LoadValues();
+
+#ifndef TW_NO_SCREEN_TIMEOUT
+ blankTimer.setTime(mPersist.GetIntValue("tw_screen_timeout_secs"));
+#endif
+
+ update_tz_environment_variables();
+ TWFunc::Set_Brightness(GetStrValue("tw_brightness"));
+
+ pthread_mutex_unlock(&m_valuesLock);
+
+ /* Don't set storage nor backup paths this early */
+
+ loaded = true;
+
+ return 0;
+}
+
int DataManager::Flush()
{
return SaveValues();
@@ -271,6 +309,15 @@
int DataManager::SaveValues()
{
#ifndef TW_OEM_BUILD
+ if (PartitionManager.Mount_By_Path("/persist", false)) {
+ mPersist.SetFile(PERSIST_SETTINGS_FILE);
+ mPersist.SetFileVersion(FILE_VERSION);
+ pthread_mutex_lock(&m_valuesLock);
+ mPersist.SaveValues();
+ pthread_mutex_unlock(&m_valuesLock);
+ LOGINFO("Saved settings file values to %s\n", PERSIST_SETTINGS_FILE);
+ }
+
if (mBackingFile.empty())
return -1;
@@ -284,7 +331,7 @@
pthread_mutex_unlock(&m_valuesLock);
tw_set_default_metadata(mBackingFile.c_str());
- LOGINFO("Saved settings file values\n");
+ LOGINFO("Saved settings file values to '%s'\n", mBackingFile.c_str());
#endif // ifdef TW_OEM_BUILD
return 0;
}
@@ -353,7 +400,7 @@
return 0;
}
-unsigned long long DataManager::GetValue(const string& varName, unsigned long long& value)
+int DataManager::GetValue(const string& varName, unsigned long long& value)
{
string data;
diff --git a/data.hpp b/data.hpp
index 790efc9..d61fe8e 100644
--- a/data.hpp
+++ b/data.hpp
@@ -23,6 +23,8 @@
#include <pthread.h>
#include "infomanager.hpp"
+#define PERSIST_SETTINGS_FILE "/persist/.twrps"
+
using namespace std;
class DataManager
@@ -30,13 +32,14 @@
public:
static int ResetDefaults();
static int LoadValues(const string& filename);
+ static int LoadPersistValues(void);
static int Flush();
// Core get routines
static int GetValue(const string& varName, string& value);
static int GetValue(const string& varName, int& value);
static int GetValue(const string& varName, float& value);
- static unsigned long long GetValue(const string& varName, unsigned long long& value);
+ static int GetValue(const string& varName, unsigned long long& value);
// Helper functions
static string GetStrValue(const string& varName);
diff --git a/partition.cpp b/partition.cpp
index 3957c65..59bd168 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -581,6 +581,18 @@
Process_TW_Flags(flagptr, Display_Error, 1); // Forcing the fstab to ver 1 because this data is coming from the /etc/twrp.flags which should be using the TWRP v1 flags format
}
}
+
+ if (Mount_Point == "/persist" && Can_Be_Mounted) {
+ bool mounted = Is_Mounted();
+ if (mounted || Mount(false)) {
+ // Read the backup settings file
+ DataManager::LoadPersistValues();
+ TWFunc::Fixup_Time_On_Boot("/persist/time/");
+ if (!mounted)
+ UnMount(false);
+ }
+ }
+
return true;
}
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 5df44c6..b7bcebe 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -881,9 +881,12 @@
}
}
-void TWFunc::Fixup_Time_On_Boot()
+void TWFunc::Fixup_Time_On_Boot(const string& time_paths /* = "" */)
{
#ifdef QCOM_RTC_FIX
+ static bool fixed = false;
+ if (fixed)
+ return;
LOGINFO("TWFunc::Fixup_Time: Pre-fix date and time: %s\n", TWFunc::Get_Current_Date().c_str());
@@ -904,6 +907,7 @@
if (tv.tv_sec > 1405209403) { // Anything older then 12 Jul 2014 23:56:43 GMT will do nicely thank you ;)
LOGINFO("TWFunc::Fixup_Time: Date and time corrected: %s\n", TWFunc::Get_Current_Date().c_str());
+ fixed = true;
return;
}
@@ -925,22 +929,28 @@
// 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/" };
+ std::vector<std::string> paths; // space separated list of paths
+ if (time_paths.empty()) {
+ paths = Split_String("/data/system/time/ /data/time/", " ");
+ if (!PartitionManager.Mount_By_Path("/data", false))
+ return;
+ } else {
+ // When specific path(s) are used, Fixup_Time needs those
+ // partitions to already be mounted!
+ paths = Split_String(time_paths, " ");
+ }
FILE *f;
offset = 0;
struct dirent *dt;
std::string ats_path;
- 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)
+ for (size_t i = 0; i < paths.size(); ++i)
{
- DIR *d = opendir(paths[i]);
+ DIR *d = opendir(paths[i].c_str());
if (!d)
continue;
@@ -950,34 +960,38 @@
continue;
if (ats_path.empty() || strcmp(dt->d_name, "ats_2") == 0)
- ats_path = std::string(paths[i]).append(dt->d_name);
+ ats_path = paths[i] + dt->d_name;
}
closedir(d);
}
- if (ats_path.empty())
- {
+ if (ats_path.empty()) {
LOGINFO("TWFunc::Fixup_Time: no ats files found, leaving untouched!\n");
- return;
- }
-
- f = fopen(ats_path.c_str(), "r");
- if (!f)
- {
+ } else if ((f = fopen(ats_path.c_str(), "r")) == NULL) {
LOGINFO("TWFunc::Fixup_Time: failed to open file %s\n", ats_path.c_str());
- return;
- }
-
- if (fread(&offset, sizeof(offset), 1, f) != 1)
- {
+ } else if (fread(&offset, sizeof(offset), 1, f) != 1) {
LOGINFO("TWFunc::Fixup_Time: failed load uint64 from file %s\n", ats_path.c_str());
fclose(f);
- return;
- }
- fclose(f);
+ } else {
+ fclose(f);
- LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), offset);
+ LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), (unsigned long long) offset);
+ DataManager::SetValue("tw_qcom_ats_offset", (unsigned long long) offset, 1);
+ fixed = true;
+ }
+
+ if (!fixed) {
+ // Failed to get offset from ats file, check twrp settings
+ unsigned long long value;
+ if (DataManager::GetValue("tw_qcom_ats_offset", value) < 0) {
+ return;
+ } else {
+ offset = (uint64_t) value;
+ LOGINFO("TWFunc::Fixup_Time: Setting time offset from twrp setting file, offset %llu\n", (unsigned long long) offset);
+ // Do not consider the settings file as a definitive answer, keep fixed=false so next run will try ats files again
+ }
+ }
gettimeofday(&tv, NULL);
@@ -993,7 +1007,6 @@
settimeofday(&tv, NULL);
LOGINFO("TWFunc::Fixup_Time: Date and time corrected: %s\n", TWFunc::Get_Current_Date().c_str());
-
#endif
}
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 9c149ea..a1f67f2 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -88,7 +88,7 @@
static string System_Property_Get(string Prop_Name); // Returns value of Prop_Name from reading /system/build.prop
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
+ static void Fixup_Time_On_Boot(const string& time_paths = ""); // Fixes time on devices which need it (time_paths is a space separated list of paths to check for ats_* files)
static std::vector<std::string> Split_String(const std::string& str, const std::string& delimiter, bool removeEmpty = true); // Splits string by delimiter
static bool Create_Dir_Recursive(const std::string& path, mode_t mode = 0755, uid_t uid = -1, gid_t gid = -1); // Create directory and it's parents, if they don't exist. mode, uid and gid are set to all _newly_ created folders. If whole path exists, do nothing.
static int Set_Brightness(std::string brightness_value); // Well, you can read, it does what it says, passing return int from TWFunc::Write_File ;)