Rework progressbar logic, implement scoped/split progressbar

Rework progressbar according to AOSP, this should fix various
issues with progressbar.

From AOSP:

   progress <frac> <secs>
       fill up the next <frac> part of of the progress bar over <secs> seconds. If <secs> is
       zero, use `set_progress` commands to manually control the progress of this segment of the
       bar.

   set_progress <frac>
       <frac> should be between 0.0 and 1.0; sets the progress bar within the segment defined by
       the most recent progress command.

Change-Id: I7f92359046288f3529cb2e98e6d54d410a248f1d
(cherry picked from commit ab16437de14fd9f1203b7e0ce82ea18eb56cae78)
diff --git a/data.cpp b/data.cpp
index b1e8404..85834d2 100755
--- a/data.cpp
+++ b/data.cpp
@@ -510,18 +510,56 @@
 	return SetValue(varName, valStr.str(), persist);
 }
 
+// For legacy code that doesn't set a scope
 int DataManager::SetProgress(const float Fraction) {
-	return SetValue("ui_progress", (float) (Fraction * 100.0));
+	if (SetValue("ui_portion_size", 0) != 0)
+		return -1;
+	if (SetValue("ui_portion_start", 0) != 0)
+		return -1;
+	ShowProgress(1, 0);
+	int res = _SetProgress(Fraction);
+	if (SetValue("ui_portion_size", 0) != 0)
+		return -1;
+	if (SetValue("ui_portion_start", 0) != 0)
+		return -1;
+	return res;
 }
 
-int DataManager::ShowProgress(const float Portion, const float Seconds)
+int DataManager::_SetProgress(float Fraction) {
+	float Portion_Start, Portion_Size;
+	GetValue("ui_portion_size", Portion_Size);
+	GetValue("ui_portion_start", Portion_Start);
+	//LOGINFO("SetProgress(%.2lf): Portion_Size: %.2lf Portion_Start: %.2lf\n", Fraction, Portion_Size, Portion_Start);
+	if (Fraction < 0.0)
+		Fraction = 0;
+	if (Fraction > 1.0)
+		Fraction = 1;
+	if (SetValue("ui_progress", (float) ((Portion_Start + (Portion_Size * Fraction)) * 100.0)) != 0)
+		return -1;
+	return (SetValue("ui_progress_portion", 0) != 0);
+}
+
+int DataManager::ShowProgress(float Portion, const float Seconds)
 {
-	float Starting_Portion;
-	GetValue("ui_progress_portion", Starting_Portion);
-	if (SetValue("ui_progress_portion", (float)(Portion * 100.0) + Starting_Portion) != 0)
+	float Portion_Start, Portion_Size;
+	GetValue("ui_portion_size", Portion_Size);
+	GetValue("ui_portion_start", Portion_Start);
+	Portion_Start += Portion_Size;
+	if(Portion + Portion_Start > 1.0)
+		Portion = 1.0 - Portion_Start;
+	//LOGINFO("ShowProgress(%.2lf, %.2lf): Portion_Start: %.2lf\n", Portion, Seconds, Portion_Start);
+	if (SetValue("ui_portion_start", Portion_Start) != 0)
 		return -1;
-	if (SetValue("ui_progress_frames", Seconds * 30) != 0)
+	if (SetValue("ui_portion_size", Portion) != 0)
 		return -1;
+	if (SetValue("ui_progress", (float)(Portion_Start * 100.0)) != 0)
+		return -1;
+	if(Seconds) {
+		if (SetValue("ui_progress_portion", (float)((Portion * 100.0) + Portion_Start)) != 0)
+			return -1;
+		if (SetValue("ui_progress_frames", Seconds * 48) != 0)
+			return -1;
+	}
 	return 0;
 }
 
diff --git a/data.hpp b/data.hpp
index d61fe8e..4770ed5 100755
--- a/data.hpp
+++ b/data.hpp
@@ -51,7 +51,8 @@
 	static int SetValue(const string& varName, const float value, const int persist = 0);
 	static int SetValue(const string& varName, const unsigned long long& value, const int persist = 0);
 	static int SetProgress(const float Fraction);
-	static int ShowProgress(const float Portion, const float Seconds);
+	static int _SetProgress(float Fraction);
+	static int ShowProgress(float Portion, const float Seconds);
 
 	static void DumpValues();
 	static void update_tz_environment_variables();
diff --git a/gui/action.cpp b/gui/action.cpp
index 52d924b..b7d9119 100755
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -370,6 +370,8 @@
 	int ret_val = 0;
 
 	DataManager::SetValue("ui_progress", 0);
+	DataManager::SetValue("ui_portion_size", 0);
+	DataManager::SetValue("ui_portion_start", 0);
 
 	if (filename.empty())
 	{
@@ -409,6 +411,8 @@
 	// Done
 	DataManager::SetValue("ui_progress", 100);
 	DataManager::SetValue("ui_progress", 0);
+	DataManager::SetValue("ui_portion_size", 0);
+	DataManager::SetValue("ui_portion_start", 0);
 	return ret_val;
 }
 
@@ -491,6 +495,8 @@
 	time(&Start);
 	DataManager::SetValue(TW_ACTION_BUSY, 1);
 	DataManager::SetValue("ui_progress", 0);
+	DataManager::SetValue("ui_portion_size", 0);
+	DataManager::SetValue("ui_portion_start", 0);
 	DataManager::SetValue("tw_operation", operation_name);
 	DataManager::SetValue("tw_operation_state", 0);
 	DataManager::SetValue("tw_operation_status", 0);
diff --git a/twinstall.cpp b/twinstall.cpp
index b550be1..f31e55c 100755
--- a/twinstall.cpp
+++ b/twinstall.cpp
@@ -302,7 +302,7 @@
 		} else if (strcmp(command, "set_progress") == 0) {
 			char* fraction_char = strtok(NULL, " \n");
 			float fraction_float = strtof(fraction_char, NULL);
-			DataManager::SetProgress(fraction_float);
+			DataManager::_SetProgress(fraction_float);
 		} else if (strcmp(command, "ui_print") == 0) {
 			char* display_value = strtok(NULL, "\n");
 			if (display_value) {