Support reading since_epoch and secondary brightness files

TWFunc::Fixup_Time_On_Boot: Will now try to read
/sys/class/rtc/rtc0/since_epoch to correct time, if that fails
it will try to use the ats files to correct time.

TWFunc::Set_Brightness: One single function to set brightness
from both the automated functions and the gui actions. It is
able to set a second brightness path if present, it will set
them both the same value. Many Sony devices have 2 brightness
files in the sysfs that must be set to properly set the
brightness.

Change-Id: I7ca582109085dfbcb46b8de73ad031e4b7903fca
diff --git a/Android.mk b/Android.mk
index 6d0b840..921a84b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -261,6 +261,9 @@
 ifneq ($(TW_BRIGHTNESS_PATH),)
 	LOCAL_CFLAGS += -DTW_BRIGHTNESS_PATH=$(TW_BRIGHTNESS_PATH)
 endif
+ifneq ($(TW_SECONDARY_BRIGHTNESS_PATH),)
+	LOCAL_CFLAGS += -DTW_SECONDARY_BRIGHTNESS_PATH=$(TW_SECONDARY_BRIGHTNESS_PATH)
+endif
 ifneq ($(TW_MAX_BRIGHTNESS),)
 	LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=$(TW_MAX_BRIGHTNESS)
 endif
diff --git a/data.cpp b/data.cpp
index 79d3f78..afa676d 100644
--- a/data.cpp
+++ b/data.cpp
@@ -976,8 +976,17 @@
 		mConstValues.insert(make_pair("tw_brightness_max", maxVal.str()));
 		mValues.insert(make_pair("tw_brightness", make_pair(maxVal.str(), 1)));
 		mValues.insert(make_pair("tw_brightness_pct", make_pair("100", 1)));
+#ifdef TW_SECONDARY_BRIGHTNESS_PATH
+		string secondfindbright = EXPAND(TW_SECONDARY_BRIGHTNESS_PATH);
+		if (secondfindbright != "" && TWFunc::Path_Exists(secondfindbright)) {
+			LOGINFO("Will use a second brightness file at '%s'\n", secondfindbright.c_str());
+			mConstValues.insert(make_pair("tw_secondary_brightness_file", secondfindbright));
+		} else {
+			LOGINFO("Specified secondary brightness file '%s' not found.\n", secondfindbright.c_str());
+		}
+#endif
 		string max_bright = maxVal.str();
-		TWFunc::write_file(findbright, max_bright);
+		TWFunc::Set_Brightness(max_bright);
 	}
 #endif
 	mValues.insert(make_pair(TW_MILITARY_TIME, make_pair("0", 1)));
@@ -1139,12 +1148,11 @@
 #endif // ifdef TW_OEM_BUILD
 	PartitionManager.Mount_All_Storage();
 	update_tz_environment_variables();
-
-	string brightness_path = GetStrValue("tw_brightness_file");
-	if (!brightness_path.empty() && brightness_path != "/nobrightness" && TWFunc::Path_Exists(brightness_path)) {
-		string brightness_value = GetStrValue("tw_brightness");
-		TWFunc::write_file(brightness_path, brightness_value);
+#ifdef TW_MAX_BRIGHTNESS
+	if (GetStrValue("tw_brightness_path") != "/nobrightness") {
+		TWFunc::Set_Brightness(GetStrValue("tw_brightness"));
 	}
+#endif
 }
 
 string DataManager::GetCurrentStoragePath(void)
diff --git a/gui/action.cpp b/gui/action.cpp
index b77e7e7..c471533 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -824,6 +824,11 @@
 		return 0;
 	}
 
+	if (function == "setbrightness")
+	{
+		return TWFunc::Set_Brightness(arg);
+	}
+
 	if (isThreaded)
 	{
 		if (function == "fileexists")
diff --git a/gui/blanktimer.cpp b/gui/blanktimer.cpp
index 383b157..1b18429 100644
--- a/gui/blanktimer.cpp
+++ b/gui/blanktimer.cpp
@@ -97,11 +97,11 @@
 		if (sleepTimer > 2 && diff.tv_sec > (sleepTimer - 2) && conblank == 0) {
 			orig_brightness = getBrightness();
 			setConBlank(1);
-			setBrightness(5);
+			TWFunc::Set_Brightness("5");
 		}
 		if (sleepTimer && diff.tv_sec > sleepTimer && conblank < 2) {
 			setConBlank(2);
-			setBrightness(0);
+			TWFunc::Set_Brightness("0");
 			screenoff = true;
 			TWFunc::check_and_run_script("/sbin/postscreenblank.sh", "blank");
 			PageManager::ChangeOverlay("lock");
@@ -115,39 +115,20 @@
 	return -1; //shouldn't get here
 }
 
-int blanktimer::getBrightness(void) {
-	string results;
+string blanktimer::getBrightness(void) {
+	string result;
 	string brightness_path;
 	DataManager::GetValue("tw_brightness_file", brightness_path);
-	if ((TWFunc::read_file(brightness_path, results)) != 0)
-		return -1;
-	int result = atoi(results.c_str());
-	if (result == 0) {
-		int tw_brightness;
-		DataManager::GetValue("tw_brightness", tw_brightness);
-		if (tw_brightness) {
-			result = tw_brightness;
-		} else {
-			result = 255;
-		}
+	if (brightness_path == "/nobrightness")
+		return brightness_path;
+	DataManager::GetValue("tw_brightness", result);
+	if (result == "") {
+		result = "255";
 	}
 	return result;
 
 }
 
-int blanktimer::setBrightness(int brightness) {
-	string brightness_path;
-	string bstring;
-	char buff[100];
-	DataManager::GetValue("tw_brightness_file", brightness_path);
-	sprintf(buff, "%d", brightness);
-	bstring = buff;
-	if ((TWFunc::write_file(brightness_path, bstring)) != 0)
-		return -1;
-	gui_forceRender();
-	return 0;
-}
-
 void blanktimer::resetTimerAndUnblank(void) {
 	setTimer();
 	switch (conblank) {
@@ -165,7 +146,8 @@
 			screenoff = false;
 			// No break here, we want to keep going
 		case 1:
-			setBrightness(orig_brightness);
+			if (orig_brightness != "/nobrightness")
+				TWFunc::Set_Brightness(orig_brightness);
 			setConBlank(0);
 			break;
 	}
diff --git a/gui/blanktimer.hpp b/gui/blanktimer.hpp
index 01c1dfb..c8159f6 100644
--- a/gui/blanktimer.hpp
+++ b/gui/blanktimer.hpp
@@ -41,7 +41,7 @@
 	void setConBlank(int blank);
 	void setTimer(void);
 	timespec getTimer(void);
-	int getBrightness(void);
+	string getBrightness(void);
 	int setBrightness(int brightness);
 	int setBlankTimer(void);
 	int setClockTimer(void);
@@ -51,7 +51,7 @@
 	int conblank;
 	timespec btimer;
 	unsigned long long sleepTimer;
-	int orig_brightness;
+	string orig_brightness;
 	bool screenoff;
 };
 
diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml
index 9029949..2bed2a5 100644
--- a/gui/devices/landscape/res/landscape.xml
+++ b/gui/devices/landscape/res/landscape.xml
@@ -2589,7 +2589,7 @@
 					<action function="set">tw_brightness=%tw_brightness_max%</action>
 					<action function="compute">tw_brightness*%tw_brightness_pct%</action>
 					<action function="compute">tw_brightness/100</action>
-					<action function="cmd">echo %tw_brightness% > &quot;%tw_brightness_file%&quot;</action>
+					<action function="setbrightness">%tw_brightness%</action>
 				</actions>
 			</object>
 
diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml
index 6a3618e..0be6855 100644
--- a/gui/devices/portrait/res/portrait.xml
+++ b/gui/devices/portrait/res/portrait.xml
@@ -2628,7 +2628,7 @@
 					<action function="set">tw_brightness=%tw_brightness_max%</action>
 					<action function="compute">tw_brightness*%tw_brightness_pct%</action>
 					<action function="compute">tw_brightness/100</action>
-					<action function="cmd">echo %tw_brightness% > &quot;%tw_brightness_file%&quot;</action>
+					<action function="setbrightness">%tw_brightness%</action>
 				</actions>
 			</object>
 
diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml
index b4b7062..686b24b 100644
--- a/gui/devices/watch/res/watch.xml
+++ b/gui/devices/watch/res/watch.xml
@@ -2592,7 +2592,7 @@
 					<action function="set">tw_brightness=%tw_brightness_max%</action>
 					<action function="compute">tw_brightness*%tw_brightness_pct%</action>
 					<action function="compute">tw_brightness/100</action>
-					<action function="cmd">echo %tw_brightness% > &quot;%tw_brightness_file%&quot;</action>
+					<action function="setbrightness">%tw_brightness%</action>
 				</actions>
 			</object>
 
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 1788c7e..885d352 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -659,6 +659,20 @@
 	return -1;
 }
 
+int TWFunc::read_file(string fn, uint64_t& results) {
+	ifstream file;
+	file.open(fn.c_str(), ios::in);
+
+	if (file.is_open()) {
+		file >> results;
+		file.close();
+		return 0;
+	}
+
+	LOGINFO("Cannot find file %s\n", fn.c_str());
+	return -1;
+}
+
 int TWFunc::write_file(string fn, string& line) {
 	FILE *file;
 	file = fopen(fn.c_str(), "w");
@@ -1076,6 +1090,38 @@
 void TWFunc::Fixup_Time_On_Boot()
 {
 #ifdef QCOM_RTC_FIX
+
+	LOGINFO("TWFunc::Fixup_Time: Pre-fix date and time: %s\n", TWFunc::Get_Current_Date().c_str());
+
+	struct timeval tv;
+	uint64_t offset = 0;
+	std::string sepoch = "/sys/class/rtc/rtc0/since_epoch";
+
+	if (TWFunc::read_file(sepoch, offset) == 0) {
+
+		LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s\n", sepoch.c_str());
+
+		tv.tv_sec = offset;
+		tv.tv_usec = 0;
+		settimeofday(&tv, NULL);
+
+		gettimeofday(&tv, NULL);
+
+		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());
+			return;
+
+		}
+
+	} else {
+
+		LOGINFO("TWFunc::Fixup_Time: opening %s failed\n", sepoch.c_str());
+
+	}
+
+	LOGINFO("TWFunc::Fixup_Time: will attempt to use the ats files now.\n", sepoch.c_str());
+
 	// 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
@@ -1087,10 +1133,9 @@
 
 	static const char *paths[] = { "/data/system/time/", "/data/time/"  };
 
-	DIR *d;
 	FILE *f;
-	uint64_t offset = 0;
-	struct timeval tv;
+	DIR *d;
+	offset = 0;
 	struct dirent *dt;
 	std::string ats_path;
 
@@ -1120,7 +1165,7 @@
 
 	if(ats_path.empty())
 	{
-		LOGINFO("TWFunc::Fixup_Time: no ats files found, leaving time as-is!\n");
+		LOGINFO("TWFunc::Fixup_Time: no ats files found, leaving untouched!\n");
 		return;
 	}
 
@@ -1153,6 +1198,9 @@
 	}
 
 	settimeofday(&tv, NULL);
+
+	LOGINFO("TWFunc::Fixup_Time: Date and time corrected: %s\n", TWFunc::Get_Current_Date().c_str());
+
 #endif
 }
 
@@ -1194,4 +1242,22 @@
 	return true;
 }
 
+int TWFunc::Set_Brightness(std::string brightness_value)
+{
+
+	std::string brightness_file = DataManager::GetStrValue("tw_brightness_file");;
+
+	if (brightness_file.compare("/nobrightness") != 0) {
+		std::string secondary_brightness_file = DataManager::GetStrValue("tw_secondary_brightness_file");
+		LOGINFO("TWFunc::Set_Brightness: Setting brightness control to %s\n", brightness_value.c_str());
+		int result = TWFunc::write_file(brightness_file, brightness_value);
+		if (secondary_brightness_file != "") {
+			LOGINFO("TWFunc::Set_Brightness: Setting SECONDARY brightness control to %s\n", brightness_value.c_str());
+			TWFunc::write_file(secondary_brightness_file, brightness_value);
+		}
+		return result;
+	}
+	return -1;
+}
+
 #endif // ndef BUILD_TWRPTAR_MAIN
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index a0c7151..5f46d4f 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -70,6 +70,7 @@
 	static int32_t timespec_diff_ms(timespec& start, timespec& end);            // Returns diff in ms
 	static int read_file(string fn, vector<string>& results); //read from file
 	static int read_file(string fn, string& results); //read from file
+	static int read_file(string fn, uint64_t& results); //read from file
 	static int write_file(string fn, string& line); //write from file
 	static int drop_caches(void); //drop linux cache memory
 	static int Check_su_Perms(void); // check perms and owner of su binary in various locations
@@ -83,6 +84,7 @@
 	static void Fixup_Time_On_Boot(); // Fixes time on devices which need it
 	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 ;)
 
 private:
 	static void Copy_Log(string Source, string Destination);