Add partition list GUI element

Add partition list GUI element and update backup, restore, mount,
storage selection, and wipe sections of GUI and partition manager
code to reflect the new GUI element. Update ORS engine to handle
new backup and restore setup.

Fix a bug with decrypt.
Add 1080x1920 layout.

Change-Id: Iaa2f44cb707167e66f935452f076ba00e68a2aa4
This commit is contained in:
Dees_Troy 2013-03-24 08:54:55 -05:00
parent 3b51163329
commit a13d74fc95
79 changed files with 9597 additions and 9380 deletions

View File

@ -211,7 +211,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
/* the footer size is bigger than we expected.
* Skip to it's stated end so we can read the key.
*/
if (lseek(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
if (lseek64(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
printf("Cannot seek to start of key\n");
goto errout;
}

View File

@ -317,7 +317,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
/* the footer size is bigger than we expected.
* Skip to it's stated end so we can read the key.
*/
if (lseek(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
if (lseek64(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
SLOGE("Cannot seek to start of key\n");
goto errout;
}

168
data.cpp
View File

@ -226,7 +226,12 @@ int DataManager::LoadValues(const string filename)
// Read in the file, if possible
FILE* in = fopen(filename.c_str(), "rb");
if (!in) return 0;
if (!in) {
LOGI("Settings file '%s' not found.\n", filename.c_str());
return 0;
} else {
LOGI("Loading settings from '%s'.\n", filename.c_str());
}
int file_version;
if (fread(&file_version, 1, sizeof(int), in) != sizeof(int)) goto error;
@ -259,24 +264,19 @@ int DataManager::LoadValues(const string filename)
}
else
mValues.insert(TNameValuePair(Name, TStrIntPair(Value, 1)));
if (Name == "tw_screen_timeout_secs")
blankTimer.setTime(atoi(Value.c_str()));
}
fclose(in);
str = GetCurrentStoragePath();
str += "/TWRP/BACKUPS/";
str += dev_id;
SetValue(TW_BACKUPS_FOLDER_VAR, str, 0);
return 0;
error:
// File version mismatch. Use defaults.
fclose(in);
str = GetCurrentStoragePath();
str += "/TWRP/BACKUPS/";
str += dev_id;
SetValue(TW_BACKUPS_FOLDER_VAR, str, 0);
return -1;
string current = GetCurrentStoragePath();
string settings = GetSettingsStoragePath();
if (current != settings && !PartitionManager.Mount_By_Path(current, false)) {
SetValue("tw_storage_path", settings);
} else {
SetBackupFolder();
}
return 0;
}
int DataManager::Flush()
@ -433,10 +433,10 @@ int DataManager::SetValue(const string varName, string value, int persist /* = 0
SaveValues();
if (varName == "tw_screen_timeout_secs") {
blankTimer.setTime(atoi(value.c_str()));
} else if (varName == "tw_storage_path") {
SetBackupFolder();
}
else {
gui_notifyVarChange(varName.c_str(), value.c_str());
}
gui_notifyVarChange(varName.c_str(), value.c_str());
return 0;
}
@ -458,13 +458,8 @@ int DataManager::SetValue(const string varName, int value, int persist /* = 0 */
else
str = GetStrValue(TW_EXTERNAL_PATH);
string dev_id;
GetValue("device_id", dev_id);
str += "/TWRP/BACKUPS/";
str += dev_id;
SetValue(TW_BACKUPS_FOLDER_VAR, str);
SetValue("tw_storage_path", str);
SetBackupFolder();
}
return SetValue(varName, valStr.str(), persist);;
}
@ -501,13 +496,38 @@ void DataManager::update_tz_environment_variables(void) {
void DataManager::SetBackupFolder()
{
string str = GetCurrentStoragePath();
TWPartition* partition = PartitionManager.Find_Partition_By_Path(str);
str += "/TWRP/BACKUPS/";
string dev_id;
GetValue("device_id", dev_id);
str += dev_id;
LOGI("Backup folder set to '%s'\n", str.c_str());
SetValue(TW_BACKUPS_FOLDER_VAR, str, 0);
if (partition != NULL) {
SetValue("tw_storage_display_name", partition->Storage_Name);
char free_space[255];
sprintf(free_space, "%llu", partition->Free / 1024 / 1024);
SetValue("tw_storage_free_size", free_space);
string zip_path, zip_root, storage_path;
GetValue(TW_ZIP_LOCATION_VAR, zip_path);
if (partition->Has_Data_Media)
storage_path = partition->Symlink_Mount_Point;
else
storage_path = partition->Storage_Path;
if (zip_path.size() < storage_path.size()) {
SetValue(TW_ZIP_LOCATION_VAR, storage_path);
} else {
zip_root= zip_path;
zip_root.resize(storage_path.size() + 1);
if (zip_root != storage_path)
SetValue(TW_ZIP_LOCATION_VAR, storage_path);
}
} else {
if (PartitionManager.Fstab_Processed() != 0)
LOGE("Storage partition '%s' not found\n", str.c_str());
}
}
void DataManager::SetDefaultValues()
@ -522,6 +542,7 @@ void DataManager::SetDefaultValues()
mConstValues.insert(make_pair("false", "0"));
mConstValues.insert(make_pair(TW_VERSION_VAR, TW_VERSION_STR));
mValues.insert(make_pair("tw_storage_path", make_pair("/", 1)));
#ifdef TW_FORCE_CPUINFO_FOR_DEVICE_ID
printf("TW_FORCE_CPUINFO_FOR_DEVICE_ID := true\n");
@ -788,7 +809,12 @@ void DataManager::SetDefaultValues()
mConstValues.insert(make_pair(TW_SDEXT_DISABLE_EXT4, "0"));
#endif
mConstValues.insert(make_pair(TW_MIN_SYSTEM_VAR, TW_MIN_SYSTEM_SIZE));
#ifdef TW_HAS_NO_BOOT_PARTITION
mValues.insert(make_pair("tw_backup_list", make_pair("/system;/data;", 0)));
#else
mValues.insert(make_pair("tw_backup_list", make_pair("/system;/data;/boot;", 0)));
#endif
mConstValues.insert(make_pair(TW_MIN_SYSTEM_VAR, TW_MIN_SYSTEM_SIZE));
mValues.insert(make_pair(TW_BACKUP_NAME, make_pair("(Current Date)", 0)));
mValues.insert(make_pair(TW_BACKUP_SYSTEM_VAR, make_pair("1", 1)));
mValues.insert(make_pair(TW_BACKUP_DATA_VAR, make_pair("1", 1)));
@ -882,7 +908,7 @@ void DataManager::SetDefaultValues()
mConstValues.insert(make_pair("tw_has_brightnesss_file", "0"));
}
#endif
mValues.insert(make_pair(TW_MILITARY_TIME, make_pair("0", 0)));
mValues.insert(make_pair(TW_MILITARY_TIME, make_pair("0", 1)));
}
// Magic Values
@ -1018,7 +1044,7 @@ void DataManager::ReadSettingsFile(void)
{
usleep(500000);
if (!PartitionManager.Mount_Settings_Storage(false))
LOGE("Unable to mount %s when trying to read settings file.\n", DataManager_GetSettingsStorageMount());
LOGE("Unable to mount %s when trying to read settings file.\n", settings_file);
}
mkdir(mkdir_path, 0777);
@ -1063,86 +1089,22 @@ void DataManager::ReadSettingsFile(void)
string DataManager::GetCurrentStoragePath(void)
{
if (GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
if (GetIntValue(TW_USE_EXTERNAL_STORAGE) == 0)
return GetStrValue(TW_INTERNAL_PATH);
else
return GetStrValue(TW_EXTERNAL_PATH);
} else if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetStrValue(TW_INTERNAL_PATH);
else
return GetStrValue(TW_EXTERNAL_PATH);
return GetStrValue("tw_storage_path");
}
string& DataManager::CGetCurrentStoragePath()
{
if (GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
if (GetIntValue(TW_USE_EXTERNAL_STORAGE) == 0)
return GetValueRef(TW_INTERNAL_PATH);
else
return GetValueRef(TW_EXTERNAL_PATH);
} else if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetValueRef(TW_INTERNAL_PATH);
else
return GetValueRef(TW_EXTERNAL_PATH);
}
string DataManager::GetCurrentStorageMount(void)
{
if (GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
if (GetIntValue(TW_USE_EXTERNAL_STORAGE) == 0)
return GetStrValue(TW_INTERNAL_MOUNT);
else
return GetStrValue(TW_EXTERNAL_MOUNT);
} else if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetStrValue(TW_INTERNAL_MOUNT);
else
return GetStrValue(TW_EXTERNAL_MOUNT);
}
string& DataManager::CGetCurrentStorageMount()
{
if (GetIntValue(TW_HAS_DUAL_STORAGE) == 1) {
if (GetIntValue(TW_USE_EXTERNAL_STORAGE) == 0)
return GetValueRef(TW_INTERNAL_MOUNT);
else
return GetValueRef(TW_EXTERNAL_MOUNT);
} else if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetValueRef(TW_INTERNAL_MOUNT);
else
return GetValueRef(TW_EXTERNAL_MOUNT);
return GetValueRef("tw_storage_path");
}
string DataManager::GetSettingsStoragePath(void)
{
if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetStrValue(TW_INTERNAL_PATH);
else
return GetStrValue(TW_EXTERNAL_PATH);
return GetStrValue("tw_settings_path");
}
string& DataManager::CGetSettingsStoragePath()
{
if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetValueRef(TW_INTERNAL_PATH);
else
return GetValueRef(TW_EXTERNAL_PATH);
}
string DataManager::GetSettingsStorageMount(void)
{
if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetStrValue(TW_INTERNAL_MOUNT);
else
return GetStrValue(TW_EXTERNAL_MOUNT);
}
string& DataManager::CGetSettingsStorageMount()
{
if (GetIntValue(TW_HAS_INTERNAL) == 1)
return GetValueRef(TW_INTERNAL_MOUNT);
else
return GetValueRef(TW_EXTERNAL_MOUNT);
return GetValueRef("tw_settings_path");
}
extern "C" int DataManager_ResetDefaults()
@ -1194,18 +1156,6 @@ extern "C" const char* DataManager_GetSettingsStoragePath(void)
return str.c_str();
}
extern "C" const char* DataManager_GetCurrentStorageMount(void)
{
string& str = DataManager::CGetCurrentStorageMount();
return str.c_str();
}
extern "C" const char* DataManager_GetSettingsStorageMount(void)
{
string& str = DataManager::CGetSettingsStorageMount();
return str.c_str();
}
extern "C" int DataManager_GetIntValue(const char* varName)
{
return DataManager::GetIntValue(varName);

2
data.h
View File

@ -23,9 +23,7 @@ int DataManager_LoadValues(const char* filename);
int DataManager_Flush();
const char* DataManager_GetStrValue(const char* varName);
const char* DataManager_GetCurrentStoragePath();
const char* DataManager_GetCurrentStorageMount();
const char* DataManager_GetSettingsStoragePath();
const char* DataManager_GetSettingsStorageMount();
int DataManager_GetIntValue(const char* varName);
int DataManager_SetStrValue(const char* varName, char* value);

View File

@ -57,12 +57,8 @@ public:
static string GetCurrentStoragePath(void);
static string& CGetCurrentStoragePath();
static string GetCurrentStorageMount(void);
static string& CGetCurrentStorageMount();
static string GetSettingsStoragePath(void);
static string& CGetSettingsStoragePath();
static string GetSettingsStorageMount(void);
static string& CGetSettingsStorageMount();
protected:
typedef pair<string, int> TStrIntPair;

View File

@ -21,6 +21,7 @@ LOCAL_SRC_FILES := \
keyboard.cpp \
input.cpp \
blanktimer.cpp \
partitionlist.cpp \
../minuitwrp/graphics.c
ifneq ($(TWRP_CUSTOM_KEYBOARD),)

View File

@ -1,4 +1,20 @@
// image.cpp - GUIImage object
/*
Copyright 2013 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
@ -745,6 +761,51 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
ret_val = PartitionManager.Wipe_By_Path(External_Path);
} else if (arg == "ANDROIDSECURE") {
ret_val = PartitionManager.Wipe_Android_Secure();
} else if (arg == "LIST") {
string Wipe_List, wipe_path;
bool skip = false;
ret_val = true;
TWPartition* wipe_part = NULL;
DataManager::GetValue("tw_wipe_list", Wipe_List);
LOGI("wipe list '%s'\n", Wipe_List.c_str());
if (!Wipe_List.empty()) {
size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Wipe_List.size()) {
wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
LOGI("wipe_path '%s'\n", wipe_path.c_str());
if (wipe_path == "/and-sec") {
if (!PartitionManager.Wipe_Android_Secure()) {
LOGE("Unable to wipe android secure\n");
ret_val = false;
break;
} else {
skip = true;
}
} else if (wipe_path == "DALVIK") {
if (!PartitionManager.Wipe_Dalvik_Cache()) {
LOGE("Failed to wipe dalvik\n");
ret_val = false;
break;
} else {
skip = true;
}
}
if (!skip) {
if (!PartitionManager.Wipe_By_Path(wipe_path)) {
LOGE("Unable to wipe '%s'\n", wipe_path.c_str());
ret_val = false;
break;
} else if (wipe_path == DataManager::GetSettingsStoragePath()) {
arg = wipe_path;
}
} else {
skip = false;
}
start_pos = end_pos + 1;
end_pos = Wipe_List.find(";", start_pos);
}
}
} else
ret_val = PartitionManager.Wipe_By_Path(arg);

View File

@ -109,7 +109,17 @@ int blanktimer::getBrightness(void) {
string brightness_path = EXPAND(TW_BRIGHTNESS_PATH);
if ((TWFunc::read_file(brightness_path, results)) != 0)
return -1;
return atoi(results.c_str());
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;
}
}
return result;
}

View File

@ -1,4 +1,20 @@
// button.cpp - GUIButton object
/*
Copyright 2012 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
@ -39,6 +55,7 @@ GUIButton::GUIButton(xml_node<>* node)
mRendered = false;
hasHighlightColor = false;
renderHighlight = false;
hasFill = false;
if (!node) return;
@ -49,7 +66,6 @@ GUIButton::GUIButton(xml_node<>* node)
if (mButtonImg->Render() < 0)
{
LOGE("Unable to locate button image\n");
delete mButtonImg;
mButtonImg = NULL;
}
@ -58,6 +74,21 @@ GUIButton::GUIButton(xml_node<>* node)
delete mButtonLabel;
mButtonLabel = NULL;
}
// Load fill if it exists
memset(&mFillColor, 0, sizeof(COLOR));
child = node->first_node("fill");
if (child)
{
attr = child->first_attribute("color");
if (attr) {
hasFill = true;
std::string color = attr->value();
ConvertStrToColor(color, &mFillColor);
}
}
if (!hasFill && mButtonImg == NULL) {
LOGE("No image resource or fill specified for button.\n");
}
// The icon is a special case
child = node->first_node("icon");
@ -80,8 +111,12 @@ GUIButton::GUIButton(xml_node<>* node)
}
int x, y, w, h;
if (mButtonImg) mButtonImg->GetRenderPos(x, y, w, h);
SetRenderPos(x, y, w, h);
if (mButtonImg) {
mButtonImg->GetRenderPos(x, y, w, h);
} else if (hasFill) {
LoadPlacement(node->first_node("placement"), &x, &y, &w, &h);
}
SetRenderPos(x, y, w, h);
return;
}
@ -105,10 +140,32 @@ int GUIButton::Render(void)
if (mButtonImg) ret = mButtonImg->Render();
if (ret < 0) return ret;
if (hasFill) {
gr_color(mFillColor.red, mFillColor.green, mFillColor.blue, mFillColor.alpha);
gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
}
if (mButtonIcon && mButtonIcon->GetResource())
gr_blit(mButtonIcon->GetResource(), 0, 0, mIconW, mIconH, mIconX, mIconY);
if (mButtonLabel) ret = mButtonLabel->Render();
if (ret < 0) return ret;
if (mButtonLabel) {
int w, h;
mButtonLabel->GetCurrentBounds(w, h);
if (w != mTextW) {
mTextW = w;
// As a special case, we'll allow large text which automatically moves it to the right.
if (mTextW > mRenderW)
{
mTextX = mRenderW + mRenderX + 5;
mRenderW += mTextW + 5;
}
else
{
mTextX = mRenderX + ((mRenderW - mTextW) / 2);
}
mButtonLabel->SetRenderPos(mTextX, mTextY);
}
ret = mButtonLabel->Render();
if (ret < 0) return ret;
}
if (renderHighlight && hasHighlightColor) {
gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
@ -129,9 +186,11 @@ int GUIButton::Update(void)
if (ret == 0)
{
if (mButtonLabel) ret2 = mButtonLabel->Update();
if (ret2 < 0) return ret2;
if (ret2 > ret) ret = ret2;
if (mButtonLabel) {
ret2 = mButtonLabel->Update();
if (ret2 < 0) return ret2;
if (ret2 > ret) ret = ret2;
}
}
else if (ret == 1)
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,20 @@
// FileSelector.cpp - GUIFileSelector object
/*
Copyright 2012 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/input.h>
#include <pthread.h>
@ -1003,4 +1019,4 @@ void GUIFileSelector::SetPageFocus(int inFocus)
scrollingSpeed = 0;
mUpdate = 1;
}
}
}

View File

@ -35,8 +35,10 @@ GUIFill::GUIFill(xml_node<>* node)
return;
attr = node->first_attribute("color");
if (!attr)
if (!attr) {
LOGE("No color specified for fill\n");
return;
}
std::string color = attr->value();
ConvertStrToColor(color, &mColor);

View File

@ -1,4 +1,20 @@
// FileSelector.cpp - GUIFileSelector object
/*
Copyright 2013 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/input.h>
#include <pthread.h>

View File

@ -1,3 +1,20 @@
/*
Copyright 2013 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
// objects.h - Base classes for object manager of GUI
#ifndef _OBJECTS_HEADER
@ -17,6 +34,7 @@ using namespace rapidxml;
#include "../data.hpp"
#include "resources.hpp"
#include "pages.hpp"
#include "../partitions.hpp"
class RenderObject
{
@ -357,6 +375,8 @@ protected:
bool mRendered;
bool hasHighlightColor;
bool renderHighlight;
bool hasFill;
COLOR mFillColor;
COLOR mHighlightColor;
};
@ -586,6 +606,92 @@ protected:
int touchDebounce;
};
class GUIPartitionList : public RenderObject, public ActionObject
{
public:
GUIPartitionList(xml_node<>* node);
virtual ~GUIPartitionList();
public:
// Render - Render the full object to the GL surface
// Return 0 on success, <0 on error
virtual int Render(void);
// Update - Update any UI component animations (called <= 30 FPS)
// Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error
virtual int Update(void);
// NotifyTouch - Notify of a touch event
// Return 0 on success, >0 to ignore remainder of touch, and <0 on error
virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
// NotifyVarChange - Notify of a variable change
virtual int NotifyVarChange(std::string varName, std::string value);
// SetPos - Update the position of the render object
// Return 0 on success, <0 on error
virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);
// SetPageFocus - Notify when a page gains or loses focus
virtual void SetPageFocus(int inFocus);
protected:
protected:
virtual int GetSelection(int x, int y);
virtual void MatchList(void);
protected:
std::vector<PartitionList> mList;
std::string ListType;
std::string mVariable;
std::string selectedList;
std::string currentValue;
std::string mHeaderText;
std::string mLastValue;
int actualLineHeight;
int mStart;
int startY;
int mSeparatorH, mHeaderSeparatorH;
int mLineSpacing;
int mUpdate;
int mBackgroundX, mBackgroundY, mBackgroundW, mBackgroundH, mHeaderH;
int mFastScrollW;
int mFastScrollLineW;
int mFastScrollRectW;
int mFastScrollRectH;
int mFastScrollRectX;
int mFastScrollRectY;
int mIconWidth, mIconHeight, mSelectedIconWidth, mSelectedIconHeight, mUnselectedIconWidth, mUnselectedIconHeight, mHeaderIconHeight, mHeaderIconWidth;
int scrollingSpeed;
int scrollingY;
static int mSortOrder;
unsigned mFontHeight;
unsigned mLineHeight;
Resource* mHeaderIcon;
Resource* mIconSelected;
Resource* mIconUnselected;
Resource* mBackground;
Resource* mFont;
COLOR mBackgroundColor;
COLOR mFontColor;
COLOR mHeaderBackgroundColor;
COLOR mHeaderFontColor;
COLOR mSeparatorColor;
COLOR mHeaderSeparatorColor;
COLOR mFastScrollLineColor;
COLOR mFastScrollRectColor;
bool hasHighlightColor;
bool hasFontHighlightColor;
bool isHighlighted;
COLOR mHighlightColor;
COLOR mFontHighlightColor;
int mHeaderIsStatic;
int startSelection;
int touchDebounce;
bool updateList;
};
// GUIAnimation - Used for animations
class GUIAnimation : public RenderObject
{

View File

@ -1,4 +1,21 @@
// base_objects.cpp - Source to manage GUI base objects
/*
Copyright 2013 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
// pages.cpp - Source to manage GUI base objects
#include <stdarg.h>
#include <stdio.h>
@ -276,6 +293,12 @@ bool Page::ProcessNode(xml_node<>* page, xml_node<>* templates /* = NULL */, int
mActions.push_back(element);
mInputs.push_back(element);
}
else if (type == "partitionlist")
{
GUIPartitionList* element = new GUIPartitionList(child);
mRenders.push_back(element);
mActions.push_back(element);
}
else if (type == "template")
{
if (!templates || !child->first_attribute("name"))

926
gui/partitionlist.cpp Normal file
View File

@ -0,0 +1,926 @@
/*
Copyright 2013 bigbiff/Dees_Troy TeamWin
This file is part of TWRP/TeamWin Recovery Project.
TWRP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TWRP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/input.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <ctype.h>
#include <algorithm>
extern "C" {
#include "../common.h"
#include "../roots.h"
#include "../minuitwrp/minui.h"
#include "../recovery_ui.h"
}
#include "rapidxml.hpp"
#include "objects.hpp"
#include "../data.hpp"
#include "../twrp-functions.hpp"
#include "../partitions.hpp"
#define SCROLLING_SPEED_DECREMENT 6
#define SCROLLING_FLOOR 10
#define SCROLLING_MULTIPLIER 6
GUIPartitionList::GUIPartitionList(xml_node<>* node)
{
xml_attribute<>* attr;
xml_node<>* child;
int header_separator_color_specified = 0, header_separator_height_specified = 0, header_text_color_specified = 0, header_background_color_specified = 0;
mStart = mLineSpacing = startY = mFontHeight = mSeparatorH = scrollingY = scrollingSpeed = 0;
mIconWidth = mIconHeight = mSelectedIconHeight = mSelectedIconWidth = mUnselectedIconHeight = mUnselectedIconWidth = mHeaderIconHeight = mHeaderIconWidth = 0;
mHeaderSeparatorH = mLineHeight = mHeaderIsStatic = mHeaderH = actualLineHeight = 0;
mIconSelected = mIconUnselected = mBackground = mFont = mHeaderIcon = NULL;
mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0;
mFastScrollRectX = mFastScrollRectY = -1;
mUpdate = 0;
touchDebounce = 6;
ConvertStrToColor("black", &mBackgroundColor);
ConvertStrToColor("black", &mHeaderBackgroundColor);
ConvertStrToColor("black", &mSeparatorColor);
ConvertStrToColor("black", &mHeaderSeparatorColor);
ConvertStrToColor("white", &mFontColor);
ConvertStrToColor("white", &mHeaderFontColor);
ConvertStrToColor("white", &mFastScrollLineColor);
ConvertStrToColor("white", &mFastScrollRectColor);
hasHighlightColor = false;
hasFontHighlightColor = false;
isHighlighted = false;
updateList = false;
startSelection = -1;
// Load header text
child = node->first_node("header");
if (child)
{
attr = child->first_attribute("icon");
if (attr)
mHeaderIcon = PageManager::FindResource(attr->value());
attr = child->first_attribute("background");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mHeaderBackgroundColor);
header_background_color_specified = -1;
}
attr = child->first_attribute("textcolor");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mHeaderFontColor);
header_text_color_specified = -1;
}
attr = child->first_attribute("separatorcolor");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mHeaderSeparatorColor);
header_separator_color_specified = -1;
}
attr = child->first_attribute("separatorheight");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mHeaderSeparatorH = atoi(parsevalue.c_str());
header_separator_height_specified = -1;
}
}
child = node->first_node("text");
if (child) mHeaderText = child->value();
memset(&mHighlightColor, 0, sizeof(COLOR));
child = node->first_node("highlight");
if (child) {
attr = child->first_attribute("color");
if (attr) {
hasHighlightColor = true;
std::string color = attr->value();
ConvertStrToColor(color, &mHighlightColor);
}
}
// Simple way to check for static state
mLastValue = gui_parse_text(mHeaderText);
if (mLastValue != mHeaderText)
mHeaderIsStatic = 0;
else
mHeaderIsStatic = -1;
child = node->first_node("icon");
if (child)
{
attr = child->first_attribute("selected");
if (attr)
mIconSelected = PageManager::FindResource(attr->value());
attr = child->first_attribute("unselected");
if (attr)
mIconUnselected = PageManager::FindResource(attr->value());
}
child = node->first_node("background");
if (child)
{
attr = child->first_attribute("resource");
if (attr)
mBackground = PageManager::FindResource(attr->value());
attr = child->first_attribute("color");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mBackgroundColor);
if (!header_background_color_specified)
ConvertStrToColor(color, &mHeaderBackgroundColor);
}
}
// Load the placement
LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
// Load the font, and possibly override the color
child = node->first_node("font");
if (child)
{
attr = child->first_attribute("resource");
if (attr)
mFont = PageManager::FindResource(attr->value());
attr = child->first_attribute("color");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mFontColor);
if (!header_text_color_specified)
ConvertStrToColor(color, &mHeaderFontColor);
}
attr = child->first_attribute("spacing");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mLineSpacing = atoi(parsevalue.c_str());
}
attr = child->first_attribute("highlightcolor");
memset(&mFontHighlightColor, 0, sizeof(COLOR));
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mFontHighlightColor);
hasFontHighlightColor = true;
}
}
// Load the separator if it exists
child = node->first_node("separator");
if (child)
{
attr = child->first_attribute("color");
if (attr)
{
std::string color = attr->value();
ConvertStrToColor(color, &mSeparatorColor);
if (!header_separator_color_specified)
ConvertStrToColor(color, &mHeaderSeparatorColor);
}
attr = child->first_attribute("height");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mSeparatorH = atoi(parsevalue.c_str());
if (!header_separator_height_specified)
mHeaderSeparatorH = mSeparatorH;
}
}
// Handle the result variable
child = node->first_node("data");
if (child)
{
attr = child->first_attribute("name");
if (attr)
mVariable = attr->value();
attr = child->first_attribute("selectedlist");
if (attr)
selectedList = attr->value();
}
// Fast scroll colors
child = node->first_node("fastscroll");
if (child)
{
attr = child->first_attribute("linecolor");
if(attr)
ConvertStrToColor(attr->value(), &mFastScrollLineColor);
attr = child->first_attribute("rectcolor");
if(attr)
ConvertStrToColor(attr->value(), &mFastScrollRectColor);
attr = child->first_attribute("w");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mFastScrollW = atoi(parsevalue.c_str());
}
attr = child->first_attribute("linew");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mFastScrollLineW = atoi(parsevalue.c_str());
}
attr = child->first_attribute("rectw");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mFastScrollRectW = atoi(parsevalue.c_str());
}
attr = child->first_attribute("recth");
if (attr) {
string parsevalue = gui_parse_text(attr->value());
mFastScrollRectH = atoi(parsevalue.c_str());
}
}
// Retrieve the line height
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
mLineHeight = mFontHeight;
mHeaderH = mFontHeight;
if (mIconSelected && mIconSelected->GetResource())
{
mSelectedIconWidth = gr_get_width(mIconSelected->GetResource());
mSelectedIconHeight = gr_get_height(mIconSelected->GetResource());
if (mSelectedIconHeight > (int)mLineHeight)
mLineHeight = mSelectedIconHeight;
mIconWidth = mSelectedIconWidth;
}
if (mIconUnselected && mIconUnselected->GetResource())
{
mUnselectedIconWidth = gr_get_width(mIconUnselected->GetResource());
mUnselectedIconHeight = gr_get_height(mIconUnselected->GetResource());
if (mUnselectedIconHeight > (int)mLineHeight)
mLineHeight = mUnselectedIconHeight;
if (mUnselectedIconWidth > mIconWidth)
mIconWidth = mUnselectedIconWidth;
}
if (mHeaderIcon && mHeaderIcon->GetResource())
{
mHeaderIconWidth = gr_get_width(mHeaderIcon->GetResource());
mHeaderIconHeight = gr_get_height(mHeaderIcon->GetResource());
if (mHeaderIconHeight > mHeaderH)
mHeaderH = mHeaderIconHeight;
if (mHeaderIconWidth > mIconWidth)
mIconWidth = mHeaderIconWidth;
}
mHeaderH += mLineSpacing + mHeaderSeparatorH;
actualLineHeight = mLineHeight + mLineSpacing + mSeparatorH;
if (mHeaderH < actualLineHeight)
mHeaderH = actualLineHeight;
if (actualLineHeight / 3 > 6)
touchDebounce = actualLineHeight / 3;
if (mBackground && mBackground->GetResource())
{
mBackgroundW = gr_get_width(mBackground->GetResource());
mBackgroundH = gr_get_height(mBackground->GetResource());
}
child = node->first_node("listtype");
if (child) {
attr = child->first_attribute("name");
if (attr) {
ListType = attr->value();
PartitionManager.Get_Partition_List(ListType, &mList);
} else {
mList.clear();
LOGE("No partition listtype name specified for partitionlist GUI element\n");
return;
}
} else {
mList.clear();
LOGE("No partition listtype specified for partitionlist GUI element\n");
return;
}
}
GUIPartitionList::~GUIPartitionList()
{
}
int GUIPartitionList::Render(void)
{
// First step, fill background
gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
gr_fill(mRenderX, mRenderY + mHeaderH, mRenderW, mRenderH - mHeaderH);
// Next, render the background resource (if it exists)
if (mBackground && mBackground->GetResource())
{
mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
}
// This tells us how many lines we can actually render
int lines = (mRenderH - mHeaderH) / (actualLineHeight);
int line;
if (updateList) {
mList.clear();
PartitionManager.Get_Partition_List(ListType, &mList);
updateList = false;
if (ListType == "backup")
MatchList();
}
int listSize = mList.size();
int listW = mRenderW;
if (listSize < lines) {
lines = listSize;
scrollingY = 0;
mFastScrollRectX = mFastScrollRectY = -1;
} else {
lines++;
if (lines < listSize)
lines++;
if (listSize >= lines)
listW -= mFastScrollW; // space for fast scrollbar
else
mFastScrollRectX = mFastScrollRectY = -1; // no fast scrollbar
}
void* fontResource = NULL;
if (mFont) fontResource = mFont->GetResource();
int yPos = mRenderY + mHeaderH + scrollingY;
int fontOffsetY = (int)((actualLineHeight - mFontHeight) / 2);
int currentIconHeight = 0, currentIconWidth = 0;
int currentIconOffsetY = 0, currentIconOffsetX = 0;
int UnselectedIconOffsetY = (int)((actualLineHeight - mUnselectedIconHeight) / 2), SelectedIconOffsetY = (int)((actualLineHeight - mSelectedIconHeight) / 2);
int UnselectedIconOffsetX = (mIconWidth - mUnselectedIconWidth) / 2, SelectedIconOffsetX = (mIconWidth - mSelectedIconWidth) / 2;
int actualSelection = mStart;
if (isHighlighted) {
int selectY = scrollingY;
// Locate the correct line for highlighting
while (selectY + actualLineHeight < startSelection) {
selectY += actualLineHeight;
actualSelection++;
}
if (hasHighlightColor) {
// Highlight the area
gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, 255);
int HighlightHeight = actualLineHeight;
if (mRenderY + mHeaderH + selectY + actualLineHeight > mRenderH + mRenderY) {
HighlightHeight = actualLineHeight - (mRenderY + mHeaderH + selectY + actualLineHeight - mRenderH - mRenderY);
}
gr_fill(mRenderX, mRenderY + mHeaderH + selectY, mRenderW, HighlightHeight);
}
}
for (line = 0; line < lines; line++)
{
Resource* icon;
std::string label;
if (line + mStart >= listSize)
continue;
label = mList.at(line + mStart).Display_Name;
if (isHighlighted && hasFontHighlightColor && line + mStart == actualSelection) {
// Use the highlight color for the font
gr_color(mFontHighlightColor.red, mFontHighlightColor.green, mFontHighlightColor.blue, 255);
} else {
// Set the color for the font
gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, 255);
}
if (mList.at(line + mStart).selected != 0)
{
icon = mIconSelected;
currentIconHeight = mSelectedIconHeight;
currentIconWidth = mSelectedIconWidth;
currentIconOffsetY = SelectedIconOffsetY;
currentIconOffsetX = SelectedIconOffsetX;
}
else
{
icon = mIconUnselected;
currentIconHeight = mSelectedIconHeight;
currentIconWidth = mSelectedIconWidth;
currentIconOffsetY = SelectedIconOffsetY;
currentIconOffsetX = SelectedIconOffsetX;
}
if (icon && icon->GetResource())
{
int rect_y = 0, image_y = (yPos + currentIconOffsetY);
if (image_y + currentIconHeight > mRenderY + mRenderH)
rect_y = mRenderY + mRenderH - image_y;
else
rect_y = currentIconHeight;
gr_blit(icon->GetResource(), 0, 0, currentIconWidth, rect_y, mRenderX + currentIconOffsetX, image_y);
}
gr_textExWH(mRenderX + mIconWidth + 5, yPos + fontOffsetY, label.c_str(), fontResource, mRenderX + listW, mRenderY + mRenderH);
// Add the separator
if (yPos + actualLineHeight < mRenderH + mRenderY) {
gr_color(mSeparatorColor.red, mSeparatorColor.green, mSeparatorColor.blue, 255);
gr_fill(mRenderX, yPos + actualLineHeight - mSeparatorH, listW, mSeparatorH);
}
// Move the yPos
yPos += actualLineHeight;
}
// Render the Header (last so that it overwrites the top most row for per pixel scrolling)
// First step, fill background
gr_color(mHeaderBackgroundColor.red, mHeaderBackgroundColor.green, mHeaderBackgroundColor.blue, 255);
gr_fill(mRenderX, mRenderY, mRenderW, mHeaderH);
// Now, we need the header (icon + text)
yPos = mRenderY;
{
Resource* headerIcon;
int mIconOffsetX = 0;
// render the icon if it exists
headerIcon = mHeaderIcon;
if (headerIcon && headerIcon->GetResource())
{
gr_blit(headerIcon->GetResource(), 0, 0, mHeaderIconWidth, mHeaderIconHeight, mRenderX + ((mHeaderIconWidth - mIconWidth) / 2), (yPos + (int)((mHeaderH - mHeaderIconHeight) / 2)));
mIconOffsetX = mIconWidth;
}
// render the text
gr_color(mHeaderFontColor.red, mHeaderFontColor.green, mHeaderFontColor.blue, 255);
gr_textExWH(mRenderX + mIconOffsetX + 5, yPos + (int)((mHeaderH - mFontHeight) / 2), mLastValue.c_str(), fontResource, mRenderX + mRenderW, mRenderY + mRenderH);
// Add the separator
gr_color(mHeaderSeparatorColor.red, mHeaderSeparatorColor.green, mHeaderSeparatorColor.blue, 255);
gr_fill(mRenderX, yPos + mHeaderH - mHeaderSeparatorH, mRenderW, mHeaderSeparatorH);
}
// render fast scroll
lines = (mRenderH - mHeaderH) / (actualLineHeight);
if(mFastScrollW > 0 && listSize > lines)
{
int startX = listW + mRenderX;
int fWidth = mRenderW - listW;
int fHeight = mRenderH - mHeaderH;
// line
gr_color(mFastScrollLineColor.red, mFastScrollLineColor.green, mFastScrollLineColor.blue, 255);
gr_fill(startX + fWidth/2, mRenderY + mHeaderH, mFastScrollLineW, mRenderH - mHeaderH);
// rect
int pct = ((mStart*actualLineHeight - scrollingY)*100)/((listSize)*actualLineHeight-lines*actualLineHeight);
mFastScrollRectX = startX + (fWidth - mFastScrollRectW)/2;
mFastScrollRectY = mRenderY+mHeaderH + ((fHeight - mFastScrollRectH)*pct)/100;
gr_color(mFastScrollRectColor.red, mFastScrollRectColor.green, mFastScrollRectColor.blue, 255);
gr_fill(mFastScrollRectX, mFastScrollRectY, mFastScrollRectW, mFastScrollRectH);
}
mUpdate = 0;
return 0;
}
int GUIPartitionList::Update(void)
{
if (!mHeaderIsStatic) {
std::string newValue = gui_parse_text(mHeaderText);
if (mLastValue != newValue) {
mLastValue = newValue;
mUpdate = 1;
}
}
// Check for changes in mount points if the list type is mount and update the list and render if needed
if (ListType == "mount") {
int listSize = mList.size();
for (int i = 0; i < listSize; i++) {
if (PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && !mList.at(i).selected) {
mList.at(i).selected = 1;
mUpdate = 1;
} else if (!PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && mList.at(i).selected) {
mList.at(i).selected = 0;
mUpdate = 1;
}
}
}
if (mUpdate)
{
mUpdate = 0;
if (Render() == 0)
return 2;
}
// Handle kinetic scrolling
if (scrollingSpeed == 0) {
// Do nothing
} else if (scrollingSpeed > 0) {
if (scrollingSpeed < ((int) (actualLineHeight * 2.5))) {
scrollingY += scrollingSpeed;
scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
} else {
scrollingY += ((int) (actualLineHeight * 2.5));
scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
}
while (mStart && scrollingY > 0) {
mStart--;
scrollingY -= actualLineHeight;
}
if (mStart == 0 && scrollingY > 0) {
scrollingY = 0;
scrollingSpeed = 0;
} else if (scrollingSpeed < SCROLLING_FLOOR)
scrollingSpeed = 0;
mUpdate = 1;
} else if (scrollingSpeed < 0) {
int totalSize = mList.size();
int lines = (mRenderH - mHeaderH) / (actualLineHeight);
if (totalSize > lines) {
int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);
bottom_offset -= actualLineHeight;
if (abs(scrollingSpeed) < ((int) (actualLineHeight * 2.5))) {
scrollingY += scrollingSpeed;
scrollingSpeed += SCROLLING_SPEED_DECREMENT;
} else {
scrollingY -= ((int) (actualLineHeight * 2.5));
scrollingSpeed += SCROLLING_SPEED_DECREMENT;
}
while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
mStart++;
scrollingY += actualLineHeight;
}
if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
mStart = totalSize - lines - 1;
scrollingY = bottom_offset;
} else if (mStart + lines >= totalSize && scrollingY < 0) {
mStart = totalSize - lines;
scrollingY = 0;
} else if (scrollingSpeed * -1 < SCROLLING_FLOOR)
scrollingSpeed = 0;
mUpdate = 1;
}
}
return 0;
}
int GUIPartitionList::GetSelection(int x, int y)
{
// We only care about y position
if (y < mRenderY || y - mRenderY <= mHeaderH || y - mRenderY > mRenderH) return -1;
return (y - mRenderY - mHeaderH);
}
int GUIPartitionList::NotifyTouch(TOUCH_STATE state, int x, int y)
{
static int lastY = 0, last2Y = 0;
int selection = 0;
switch (state)
{
case TOUCH_START:
if (scrollingSpeed != 0)
startSelection = -1;
else
startSelection = GetSelection(x,y);
isHighlighted = (startSelection > -1);
if (isHighlighted)
mUpdate = 1;
startY = lastY = last2Y = y;
scrollingSpeed = 0;
break;
case TOUCH_DRAG:
// Check if we dragged out of the selection window
if (GetSelection(x, y) == -1) {
last2Y = lastY = 0;
if (isHighlighted) {
isHighlighted = false;
mUpdate = 1;
}
break;
}
// Fast scroll
if(mFastScrollRectX != -1 && x >= mRenderX + mRenderW - mFastScrollW)
{
int pct = ((y-mRenderY-mHeaderH)*100)/(mRenderH-mHeaderH);
int totalSize = mList.size();
int lines = (mRenderH - mHeaderH) / (actualLineHeight);
float l = float((totalSize-lines)*pct)/100;
if(l + lines >= totalSize)
{
mStart = totalSize - lines;
scrollingY = 0;
}
else
{
mStart = l;
scrollingY = -(l - int(l))*actualLineHeight;
}
startSelection = -1;
mUpdate = 1;
scrollingSpeed = 0;
isHighlighted = false;
break;
}
// Provide some debounce on initial touches
if (startSelection != -1 && abs(y - startY) < touchDebounce) {
isHighlighted = true;
mUpdate = 1;
break;
}
isHighlighted = false;
last2Y = lastY;
lastY = y;
startSelection = -1;
// Handle scrolling
scrollingY += y - startY;
startY = y;
while(mStart && scrollingY > 0) {
mStart--;
scrollingY -= actualLineHeight;
}
if (mStart == 0 && scrollingY > 0)
scrollingY = 0;
{
int totalSize = mList.size();
int lines = (mRenderH - mHeaderH) / (actualLineHeight);
if (totalSize > lines) {
int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);
bottom_offset -= actualLineHeight;
while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
mStart++;
scrollingY += actualLineHeight;
}
if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
mStart = totalSize - lines - 1;
scrollingY = bottom_offset;
} else if (mStart + lines >= totalSize && scrollingY < 0) {
mStart = totalSize - lines;
scrollingY = 0;
}
} else
scrollingY = 0;
}
mUpdate = 1;
break;
case TOUCH_RELEASE:
isHighlighted = false;
if (startSelection >= 0)
{
// We've selected an item!
int listSize = mList.size();
int selectY = scrollingY, actualSelection = mStart;
// Move the selection to the proper place in the array
while (selectY + actualLineHeight < startSelection) {
selectY += actualLineHeight;
actualSelection++;
}
if (actualSelection < listSize && ListType == "mount") {
if (!mList.at(actualSelection).selected) {
if (PartitionManager.Mount_By_Path(mList.at(actualSelection).Mount_Point, true)) {
mList.at(actualSelection).selected = 1;
mUpdate = 1;
}
} else {
if (PartitionManager.UnMount_By_Path(mList.at(actualSelection).Mount_Point, true)) {
mList.at(actualSelection).selected = 0;
mUpdate = 1;
}
}
} else if (actualSelection < listSize && !mVariable.empty()) {
if (ListType == "storage") {
int i;
std::string str = mList.at(actualSelection).Mount_Point;
bool update_size = false;
TWPartition* Part = PartitionManager.Find_Partition_By_Path(str);
if (Part == NULL) {
LOGE("Unable to locate partition for '%s'\n", str.c_str());
return 0;
}
if (!Part->Is_Mounted() && Part->Removable)
update_size = true;
if (!Part->Mount(true)) {
// Do Nothing
} else if (update_size && !Part->Update_Size(true)) {
// Do Nothing
} else {
for (i=0; i<listSize; i++)
mList.at(i).selected = 0;
if (update_size) {
char free_space[255];
sprintf(free_space, "%llu", Part->Free / 1024 / 1024);
mList.at(actualSelection).Display_Name = Part->Storage_Name + " (";
mList.at(actualSelection).Display_Name += free_space;
mList.at(actualSelection).Display_Name += "MB)";
}
mList.at(actualSelection).selected = 1;
mUpdate = 1;
DataManager::SetValue(mVariable, str);
}
} else {
if (mList.at(actualSelection).selected)
mList.at(actualSelection).selected = 0;
else
mList.at(actualSelection).selected = 1;
int i;
string variablelist;
for (i=0; i<listSize; i++) {
if (mList.at(i).selected) {
variablelist += mList.at(i).Mount_Point + ";";
}
}
mUpdate = 1;
if (selectedList.empty())
DataManager::SetValue(mVariable, variablelist);
else
DataManager::SetValue(selectedList, variablelist);
}
}
} else {
// This is for kinetic scrolling
scrollingSpeed = lastY - last2Y;
if (abs(scrollingSpeed) > SCROLLING_FLOOR)
scrollingSpeed *= SCROLLING_MULTIPLIER;
else
scrollingSpeed = 0;
}
case TOUCH_REPEAT:
case TOUCH_HOLD:
break;
}
return 0;
}
int GUIPartitionList::NotifyVarChange(std::string varName, std::string value)
{
if (!mHeaderIsStatic) {
std::string newValue = gui_parse_text(mHeaderText);
if (mLastValue != newValue) {
mLastValue = newValue;
mStart = 0;
scrollingY = 0;
scrollingSpeed = 0;
mUpdate = 1;
}
}
if (varName == mVariable && !mUpdate)
{
if (ListType == "storage") {
int i, listSize = mList.size(), selected_index = 0;
currentValue = value;
for (i=0; i<listSize; i++) {
if (mList.at(i).Mount_Point == currentValue) {
mList.at(i).selected = 1;
selected_index = i;
} else
mList.at(i).selected = 0;
}
int lines = mRenderH / (mLineHeight + mLineSpacing);
int line;
if (selected_index > mStart + lines - 1) {
mStart = selected_index;
} else if (selected_index < mStart) {
mStart = selected_index;
}
} else if (ListType == "backup") {
MatchList();
} else if (ListType == "restore") {
updateList = true;
}
mUpdate = 1;
return 0;
}
return 0;
}
int GUIPartitionList::SetRenderPos(int x, int y, int w /* = 0 */, int h /* = 0 */)
{
mRenderX = x;
mRenderY = y;
if (w || h)
{
mRenderW = w;
mRenderH = h;
}
SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
mUpdate = 1;
return 0;
}
void GUIPartitionList::SetPageFocus(int inFocus)
{
if (inFocus) {
if (ListType == "storage") {
int i, listSize = mList.size(), selected_index = 0;
DataManager::GetValue(mVariable, currentValue);
for (i=0; i<listSize; i++) {
if (mList.at(i).Mount_Point == currentValue) {
mList.at(i).selected = 1;
selected_index = i;
} else
mList.at(i).selected = 0;
}
int lines = mRenderH / (mLineHeight + mLineSpacing);
int line;
if (selected_index > mStart + lines - 1) {
mStart = selected_index;
} else if (selected_index < mStart) {
mStart = selected_index;
}
}
updateList = true;
mUpdate = 1;
}
}
void GUIPartitionList::MatchList(void) {
int i, listSize = mList.size();
string variablelist, searchvalue;
size_t pos;
DataManager::GetValue(mVariable, variablelist);
for (i=0; i<listSize; i++) {
searchvalue = mList.at(i).Mount_Point + ";";
pos = variablelist.find(searchvalue);
if (pos != string::npos) {
mList.at(i).selected = 1;
} else {
mList.at(i).selected = 0;
}
}
}

View File

@ -165,7 +165,10 @@ int GUIText::Update(void)
if (mIsStatic || !mVarChanged) return 0;
std::string newValue = parseText();
if (mLastValue == newValue) return 0;
if (mLastValue == newValue)
return 0;
else
mLastValue = newValue;
return 2;
}
@ -176,6 +179,7 @@ int GUIText::GetCurrentBounds(int& w, int& h)
if (mFont) fontResource = mFont->GetResource();
h = mFontHeight;
mLastValue = parseText();
w = gr_measureEx(mLastValue.c_str(), fontResource);
return 0;
}

View File

@ -215,52 +215,41 @@ int OpenRecoveryScript::run_script_file(void) {
DataManager::SetValue("tw_restore", folder_path);
PartitionManager.Set_Restore_Files(folder_path);
string Partition_List;
DataManager::GetValue("tw_restore_list", Partition_List);
if (strlen(partitions) != 0) {
int tw_restore_system = 0;
int tw_restore_data = 0;
int tw_restore_cache = 0;
int tw_restore_recovery = 0;
int tw_restore_boot = 0;
int tw_restore_andsec = 0;
int tw_restore_sdext = 0;
int tw_restore_sp1 = 0;
int tw_restore_sp2 = 0;
int tw_restore_sp3 = 0;
string Restore_List;
memset(value2, 0, sizeof(value2));
strcpy(value2, partitions);
ui_print("Setting restore options: '%s':\n", value2);
line_len = strlen(value2);
for (i=0; i<line_len; i++) {
if ((value2[i] == 'S' || value2[i] == 's') && DataManager::GetIntValue(TW_RESTORE_SYSTEM_VAR) > 0) {
tw_restore_system = 1;
if ((value2[i] == 'S' || value2[i] == 's') && Partition_List.find("/system;") != string::npos) {
Restore_List += "/system;";
ui_print("System\n");
} else if ((value2[i] == 'D' || value2[i] == 'd') && DataManager::GetIntValue(TW_RESTORE_DATA_VAR) > 0) {
tw_restore_data = 1;
} else if ((value2[i] == 'D' || value2[i] == 'd') && Partition_List.find("/data;") != string::npos) {
Restore_List += "/data;";
ui_print("Data\n");
} else if ((value2[i] == 'C' || value2[i] == 'c') && DataManager::GetIntValue(TW_RESTORE_CACHE_VAR) > 0) {
tw_restore_cache = 1;
} else if ((value2[i] == 'C' || value2[i] == 'c') && Partition_List.find("/cache;") != string::npos) {
Restore_List += "/cache;";
ui_print("Cache\n");
} else if ((value2[i] == 'R' || value2[i] == 'r') && DataManager::GetIntValue(TW_RESTORE_RECOVERY_VAR) > 0) {
tw_restore_recovery = 1;
ui_print("Recovery\n");
} else if ((value2[i] == 'R' || value2[i] == 'r') && Partition_List.find("/recovery;") != string::npos) {
ui_print("Recovery -- Not allowed to restore recovery\n");
} else if (value2[i] == '1' && DataManager::GetIntValue(TW_RESTORE_SP1_VAR) > 0) {
tw_restore_sp1 = 1;
ui_print("%s\n", "Special1");
ui_print("%s\n", "Special1 -- No Longer Supported...");
} else if (value2[i] == '2' && DataManager::GetIntValue(TW_RESTORE_SP2_VAR) > 0) {
tw_restore_sp2 = 1;
ui_print("%s\n", "Special2");
ui_print("%s\n", "Special2 -- No Longer Supported...");
} else if (value2[i] == '3' && DataManager::GetIntValue(TW_RESTORE_SP3_VAR) > 0) {
tw_restore_sp3 = 1;
ui_print("%s\n", "Special3");
} else if ((value2[i] == 'B' || value2[i] == 'b') && DataManager::GetIntValue(TW_RESTORE_BOOT_VAR) > 0) {
tw_restore_boot = 1;
ui_print("%s\n", "Special3 -- No Longer Supported...");
} else if ((value2[i] == 'B' || value2[i] == 'b') && Partition_List.find("/boot;") != string::npos) {
Restore_List += "/boot;";
ui_print("Boot\n");
} else if ((value2[i] == 'A' || value2[i] == 'a') && DataManager::GetIntValue(TW_RESTORE_ANDSEC_VAR) > 0) {
tw_restore_andsec = 1;
} else if ((value2[i] == 'A' || value2[i] == 'a') && Partition_List.find("/and-sec;") != string::npos) {
Restore_List += "/and-sec;";
ui_print("Android Secure\n");
} else if ((value2[i] == 'E' || value2[i] == 'e') && DataManager::GetIntValue(TW_RESTORE_SDEXT_VAR) > 0) {
tw_restore_sdext = 1;
} else if ((value2[i] == 'E' || value2[i] == 'e') && Partition_List.find("/sd-ext;") != string::npos) {
Restore_List += "/sd-ext;";
ui_print("SD-Ext\n");
} else if (value2[i] == 'M' || value2[i] == 'm') {
DataManager::SetValue(TW_SKIP_MD5_CHECK_VAR, 1);
@ -268,29 +257,14 @@ int OpenRecoveryScript::run_script_file(void) {
}
}
if (DataManager::GetIntValue(TW_RESTORE_SYSTEM_VAR) && !tw_restore_system)
DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_DATA_VAR) && !tw_restore_data)
DataManager::SetValue(TW_RESTORE_DATA_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_CACHE_VAR) && !tw_restore_cache)
DataManager::SetValue(TW_RESTORE_CACHE_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_RECOVERY_VAR) && !tw_restore_recovery)
DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_BOOT_VAR) && !tw_restore_boot)
DataManager::SetValue(TW_RESTORE_BOOT_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_ANDSEC_VAR) && !tw_restore_andsec)
DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_SDEXT_VAR) && !tw_restore_sdext)
DataManager::SetValue(TW_RESTORE_SDEXT_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_SP1_VAR) && !tw_restore_sp1)
DataManager::SetValue(TW_RESTORE_SP1_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_SP2_VAR) && !tw_restore_sp2)
DataManager::SetValue(TW_RESTORE_SP2_VAR, 0);
if (DataManager::GetIntValue(TW_RESTORE_SP3_VAR) && !tw_restore_sp3)
DataManager::SetValue(TW_RESTORE_SP3_VAR, 0);
DataManager::SetValue("tw_restore_selected", Restore_List);
} else {
DataManager::SetValue("tw_restore_selected", Partition_List);
}
PartitionManager.Run_Restore(folder_path);
ui_print("Restore complete!\n");
if (!PartitionManager.Run_Restore(folder_path))
ret_val = 1;
else
ui_print("Restore complete!\n");
} else if (strcmp(command, "mount") == 0) {
// Mount
DataManager::SetValue("tw_action_text2", "Mounting");
@ -493,20 +467,10 @@ string OpenRecoveryScript::Locate_Zip_File(string Zip, string Storage_Root) {
int OpenRecoveryScript::Backup_Command(string Options) {
char value1[SCRIPT_COMMAND_SIZE];
int line_len, i;
string Backup_List;
strcpy(value1, Options.c_str());
DataManager::SetValue(TW_BACKUP_SYSTEM_VAR, 0);
DataManager::SetValue(TW_BACKUP_DATA_VAR, 0);
DataManager::SetValue(TW_BACKUP_CACHE_VAR, 0);
DataManager::SetValue(TW_BACKUP_RECOVERY_VAR, 0);
DataManager::SetValue(TW_BACKUP_SP1_VAR, 0);
DataManager::SetValue(TW_BACKUP_SP2_VAR, 0);
DataManager::SetValue(TW_BACKUP_SP3_VAR, 0);
DataManager::SetValue(TW_BACKUP_BOOT_VAR, 0);
DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
DataManager::SetValue(TW_USE_COMPRESSION_VAR, 0);
DataManager::SetValue(TW_SKIP_MD5_GENERATE_VAR, 0);
@ -514,34 +478,31 @@ int OpenRecoveryScript::Backup_Command(string Options) {
line_len = Options.size();
for (i=0; i<line_len; i++) {
if (Options.substr(i, 1) == "S" || Options.substr(i, 1) == "s") {
DataManager::SetValue(TW_BACKUP_SYSTEM_VAR, 1);
Backup_List += "/system;";
ui_print("System\n");
} else if (Options.substr(i, 1) == "D" || Options.substr(i, 1) == "d") {
DataManager::SetValue(TW_BACKUP_DATA_VAR, 1);
Backup_List += "/data;";
ui_print("Data\n");
} else if (Options.substr(i, 1) == "C" || Options.substr(i, 1) == "c") {
DataManager::SetValue(TW_BACKUP_CACHE_VAR, 1);
Backup_List += "/cache;";
ui_print("Cache\n");
} else if (Options.substr(i, 1) == "R" || Options.substr(i, 1) == "r") {
DataManager::SetValue(TW_BACKUP_RECOVERY_VAR, 1);
Backup_List += "/recovery;";
ui_print("Recovery\n");
} else if (Options.substr(i, 1) == "1") {
DataManager::SetValue(TW_BACKUP_SP1_VAR, 1);
ui_print("%s\n", "Special1");
ui_print("%s\n", "Special1 -- No Longer Supported...");
} else if (Options.substr(i, 1) == "2") {
DataManager::SetValue(TW_BACKUP_SP2_VAR, 1);
ui_print("%s\n", "Special2");
ui_print("%s\n", "Special2 -- No Longer Supported...");
} else if (Options.substr(i, 1) == "3") {
DataManager::SetValue(TW_BACKUP_SP3_VAR, 1);
ui_print("%s\n", "Special3");
ui_print("%s\n", "Special3 -- No Longer Supported...");
} else if (Options.substr(i, 1) == "B" || Options.substr(i, 1) == "b") {
DataManager::SetValue(TW_BACKUP_BOOT_VAR, 1);
Backup_List += "/boot;";
ui_print("Boot\n");
} else if (Options.substr(i, 1) == "A" || Options.substr(i, 1) == "a") {
DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 1);
Backup_List += "/and-sec;";
ui_print("Android Secure\n");
} else if (Options.substr(i, 1) == "E" || Options.substr(i, 1) == "e") {
DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 1);
Backup_List += "/sd-ext;";
ui_print("SD-Ext\n");
} else if (Options.substr(i, 1) == "O" || Options.substr(i, 1) == "o") {
DataManager::SetValue(TW_USE_COMPRESSION_VAR, 1);
@ -551,6 +512,7 @@ int OpenRecoveryScript::Backup_Command(string Options) {
ui_print("MD5 Generation is off\n");
}
}
DataManager::SetValue("tw_backup_list", Backup_List);
if (!PartitionManager.Run_Backup()) {
LOGE("Backup failed!\n");
return 1;

View File

@ -56,6 +56,7 @@ using namespace std;
TWPartition::TWPartition(void) {
Can_Be_Mounted = false;
Can_Be_Wiped = false;
Can_Be_Backed_Up = false;
Wipe_During_Factory_Reset = false;
Wipe_Available_in_GUI = false;
Is_SubPartition = false;
@ -80,6 +81,8 @@ TWPartition::TWPartition(void) {
Is_Decrypted = false;
Decrypted_Block_Device = "";
Display_Name = "";
Backup_Display_Name = "";
Storage_Name = "";
Backup_Name = "";
Backup_FileName = "";
MTD_Name = "";
@ -87,6 +90,7 @@ TWPartition::TWPartition(void) {
Has_Data_Media = false;
Has_Android_Secure = false;
Is_Storage = false;
Is_Settings_Storage = false;
Storage_Path = "";
Current_File_System = "";
Fstab_File_System = "";
@ -108,14 +112,18 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
char* ptr;
string Flags;
strncpy(full_line, Line.c_str(), line_len);
bool skip = false;
for (index = 0; index < line_len; index++) {
if (full_line[index] <= 32)
if (full_line[index] == 34)
skip = !skip;
if (!skip && full_line[index] <= 32)
full_line[index] = '\0';
}
Mount_Point = full_line;
LOGI("Processing '%s'\n", Mount_Point.c_str());
Backup_Path = Mount_Point;
Storage_Path = Mount_Point;
index = Mount_Point.size();
while (index < line_len) {
while (index < line_len && full_line[index] == '\0')
@ -188,14 +196,22 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
Setup_File_System(Display_Error);
if (Mount_Point == "/system") {
Display_Name = "System";
Backup_Display_Name = Display_Name;
Storage_Name = Display_Name;
Wipe_Available_in_GUI = true;
Can_Be_Backed_Up = true;
} else if (Mount_Point == "/data") {
Display_Name = "Data";
Backup_Display_Name = Display_Name;
Storage_Name = Display_Name;
Wipe_Available_in_GUI = true;
Wipe_During_Factory_Reset = true;
Can_Be_Backed_Up = true;
#ifdef RECOVERY_SDCARD_ON_DATA
Storage_Name = "Internal Storage";
Has_Data_Media = true;
Is_Storage = true;
Is_Settings_Storage = true;
Storage_Path = "/data/media";
Symlink_Path = Storage_Path;
if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
@ -249,8 +265,11 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
#endif
} else if (Mount_Point == "/cache") {
Display_Name = "Cache";
Backup_Display_Name = Display_Name;
Storage_Name = Display_Name;
Wipe_Available_in_GUI = true;
Wipe_During_Factory_Reset = true;
Can_Be_Backed_Up = true;
if (Mount(false) && !TWFunc::Path_Exists("/cache/recovery/.")) {
LOGI("Recreating /cache/recovery folder.\n");
if (mkdir("/cache/recovery", S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP) != 0)
@ -259,28 +278,38 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
} else if (Mount_Point == "/datadata") {
Wipe_During_Factory_Reset = true;
Display_Name = "DataData";
Backup_Display_Name = Display_Name;
Storage_Name = Display_Name;
Is_SubPartition = true;
SubPartition_Of = "/data";
DataManager::SetValue(TW_HAS_DATADATA, 1);
Can_Be_Backed_Up = true;
} else if (Mount_Point == "/sd-ext") {
Wipe_During_Factory_Reset = true;
Display_Name = "SD-Ext";
Backup_Display_Name = Display_Name;
Storage_Name = Display_Name;
Wipe_Available_in_GUI = true;
Removable = true;
Can_Be_Backed_Up = true;
} else if (Mount_Point == "/boot") {
Display_Name = "Boot";
Backup_Display_Name = Display_Name;
DataManager::SetValue("tw_boot_is_mountable", 1);
Can_Be_Backed_Up = true;
}
#ifdef TW_EXTERNAL_STORAGE_PATH
if (Mount_Point == EXPAND(TW_EXTERNAL_STORAGE_PATH)) {
Is_Storage = true;
Storage_Path = EXPAND(TW_EXTERNAL_STORAGE_PATH);
Removable = true;
Wipe_Available_in_GUI = true;
#else
if (Mount_Point == "/sdcard") {
Is_Storage = true;
Storage_Path = "/sdcard";
Removable = true;
Wipe_Available_in_GUI = true;
#ifndef RECOVERY_SDCARD_ON_DATA
Setup_AndSec();
Mount_Storage_Retry();
@ -290,7 +319,9 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
#ifdef TW_INTERNAL_STORAGE_PATH
if (Mount_Point == EXPAND(TW_INTERNAL_STORAGE_PATH)) {
Is_Storage = true;
Is_Settings_Storage = true;
Storage_Path = EXPAND(TW_INTERNAL_STORAGE_PATH);
Wipe_Available_in_GUI = true;
#ifndef RECOVERY_SDCARD_ON_DATA
Setup_AndSec();
Mount_Storage_Retry();
@ -299,7 +330,9 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
#else
if (Mount_Point == "/emmc") {
Is_Storage = true;
Is_Settings_Storage = true;
Storage_Path = "/emmc";
Wipe_Available_in_GUI = true;
#ifndef RECOVERY_SDCARD_ON_DATA
Setup_AndSec();
Mount_Storage_Retry();
@ -309,6 +342,15 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
} else if (Is_Image(Fstab_File_System)) {
Find_Actual_Block_Device();
Setup_Image(Display_Error);
if (Mount_Point == "/boot") {
Display_Name = "Boot";
Backup_Display_Name = Display_Name;
Can_Be_Backed_Up = true;
} else if (Mount_Point == "/recovery") {
Display_Name = "Recovery";
Backup_Display_Name = Display_Name;
Can_Be_Backed_Up = true;
}
}
// Process any custom flags
@ -319,13 +361,16 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
char flags[MAX_FSTAB_LINE_LENGTH];
int flags_len, index = 0;
int flags_len, index = 0, ptr_len;
char* ptr;
bool skip = false, has_display_name = false, has_storage_name = false, has_backup_name = false;
strcpy(flags, Flags.c_str());
flags_len = Flags.size();
for (index = 0; index < flags_len; index++) {
if (flags[index] == ';')
if (flags[index] == 34)
skip = !skip;
if (!skip && flags[index] == ';')
flags[index] = '\0';
}
@ -336,12 +381,21 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
if (index >= flags_len)
continue;
ptr = flags + index;
ptr_len = strlen(ptr);
if (strcmp(ptr, "removable") == 0) {
Removable = true;
} else if (strcmp(ptr, "storage") == 0) {
Is_Storage = true;
} else if (strcmp(ptr, "settingsstorage") == 0) {
Is_Storage = true;
} else if (strcmp(ptr, "canbewiped") == 0) {
Can_Be_Wiped = true;
} else if (ptr_len > 7 && strncmp(ptr, "backup=", 7) == 0) {
ptr += 7;
if (*ptr == '1' || *ptr == 'y' || *ptr == 'Y')
Can_Be_Backed_Up = true;
else
Can_Be_Backed_Up = false;
} else if (strcmp(ptr, "wipeingui") == 0) {
Can_Be_Wiped = true;
Wipe_Available_in_GUI = true;
@ -349,7 +403,7 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
Can_Be_Wiped = true;
Wipe_Available_in_GUI = true;
Wipe_During_Factory_Reset = true;
} else if (strlen(ptr) > 15 && strncmp(ptr, "subpartitionof=", 15) == 0) {
} else if (ptr_len > 15 && strncmp(ptr, "subpartitionof=", 15) == 0) {
ptr += 15;
Is_SubPartition = true;
SubPartition_Of = ptr;
@ -357,16 +411,37 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
Ignore_Blkid = true;
} else if (strcmp(ptr, "retainlayoutversion") == 0) {
Retain_Layout_Version = true;
} else if (strlen(ptr) > 8 && strncmp(ptr, "symlink=", 8) == 0) {
} else if (ptr_len > 8 && strncmp(ptr, "symlink=", 8) == 0) {
ptr += 8;
Symlink_Path = ptr;
} else if (strlen(ptr) > 8 && strncmp(ptr, "display=", 8) == 0) {
} else if (ptr_len > 8 && strncmp(ptr, "display=", 8) == 0) {
has_display_name = true;
ptr += 8;
if (*ptr == '\"') ptr++;
Display_Name = ptr;
} else if (strlen(ptr) > 10 && strncmp(ptr, "blocksize=", 10) == 0) {
if (Display_Name.substr(Display_Name.size() - 1, 1) == "\"") {
Display_Name.resize(Display_Name.size() - 1);
}
} else if (ptr_len > 11 && strncmp(ptr, "storagename=", 11) == 0) {
has_storage_name = true;
ptr += 11;
if (*ptr == '\"') ptr++;
Storage_Name = ptr;
if (Storage_Name.substr(Storage_Name.size() - 1, 1) == "\"") {
Storage_Name.resize(Storage_Name.size() - 1);
}
} else if (ptr_len > 11 && strncmp(ptr, "backupname=", 10) == 0) {
has_backup_name = true;
ptr += 10;
if (*ptr == '\"') ptr++;
Backup_Display_Name = ptr;
if (Backup_Display_Name.substr(Backup_Display_Name.size() - 1, 1) == "\"") {
Backup_Display_Name.resize(Backup_Display_Name.size() - 1);
}
} else if (ptr_len > 10 && strncmp(ptr, "blocksize=", 10) == 0) {
ptr += 10;
Format_Block_Size = atoi(ptr);
} else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
} else if (ptr_len > 7 && strncmp(ptr, "length=", 7) == 0) {
ptr += 7;
Length = atoi(ptr);
} else {
@ -378,6 +453,14 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) {
while (index < flags_len && flags[index] != '\0')
index++;
}
if (has_display_name && !has_storage_name)
Storage_Name = Display_Name;
if (!has_display_name && has_storage_name)
Display_Name = Storage_Name;
if (has_display_name && !has_backup_name)
Backup_Display_Name = Display_Name;
if (!has_display_name && has_backup_name)
Display_Name = Backup_Display_Name;
return true;
}
@ -452,7 +535,9 @@ void TWPartition::Setup_Image(bool Display_Error) {
}
void TWPartition::Setup_AndSec(void) {
Backup_Display_Name = "Android Secure";
Backup_Name = "and-sec";
Can_Be_Backed_Up = true;
Has_Android_Secure = true;
Symlink_Path = Mount_Point + "/.android_secure";
Symlink_Mount_Point = "/and-sec";
@ -924,7 +1009,7 @@ bool TWPartition::Wipe_AndSec(void) {
if (!Mount(true))
return false;
ui_print("Wiping .android_secure\n");
ui_print("Wiping %s\n", Backup_Display_Name.c_str());
TWFunc::removeDir(Mount_Point + "/.android_secure/", true);
return true;
}
@ -1293,13 +1378,8 @@ bool TWPartition::Backup_Tar(string backup_folder) {
if (!Mount(true))
return false;
if (Backup_Path == "/and-sec") {
TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, "Android Secure", "Backing Up");
ui_print("Backing up %s...\n", "Android Secure");
} else {
TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
ui_print("Backing up %s...\n", Display_Name.c_str());
}
TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Backup_Display_Name, "Backing Up");
ui_print("Backing up %s...\n", Backup_Display_Name.c_str());
DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
@ -1398,7 +1478,6 @@ bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System)
char split_index[5];
if (Has_Android_Secure) {
ui_print("Wiping android secure...\n");
if (!Wipe_AndSec())
return false;
} else {
@ -1406,12 +1485,12 @@ bool TWPartition::Restore_Tar(string restore_folder, string Restore_File_System)
if (!Wipe(Restore_File_System))
return false;
}
TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, "Restoring");
ui_print("Restoring %s...\n", Backup_Display_Name.c_str());
if (!Mount(true))
return false;
TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
ui_print("Restoring %s...\n", Display_Name.c_str());
Full_FileName = restore_folder + "/" + Backup_FileName;
if (!TWFunc::Path_Exists(Full_FileName)) {
if (!TWFunc::Path_Exists(Full_FileName)) {
@ -1575,11 +1654,11 @@ void TWPartition::Recreate_Media_Folder(void) {
void TWPartition::Recreate_AndSec_Folder(void) {
if (!Has_Android_Secure)
return;
LOGI("Creating .android_secure: %s\n", Symlink_Path.c_str());
LOGI("Creating %s: %s\n", Backup_Display_Name.c_str(), Symlink_Path.c_str());
if (!Mount(true)) {
LOGE("Unable to recreate android secure folder.\n");
LOGE("Unable to recreate %s folder.\n", Backup_Name.c_str());
} else if (!TWFunc::Path_Exists(Symlink_Path)) {
LOGI("Recreating android secure folder.\n");
LOGI("Recreating %s folder.\n", Backup_Name.c_str());
PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
mkdir(Symlink_Path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
PartitionManager.UnMount_By_Path(Symlink_Mount_Point, true);

View File

@ -56,6 +56,7 @@ extern RecoveryUI* ui;
int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
FILE *fstabFile;
char fstab_line[MAX_FSTAB_LINE_LENGTH];
bool Found_Settings_Storage = false;
fstabFile = fopen(Fstab_Filename.c_str(), "rt");
if (fstabFile == NULL) {
@ -75,12 +76,36 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error)
memset(fstab_line, 0, sizeof(fstab_line));
if (partition->Process_Fstab_Line(line, Display_Error)) {
Partitions.push_back(partition);
if (!Found_Settings_Storage && partition->Is_Settings_Storage) {
Found_Settings_Storage = true;
Partitions.push_back(partition);
DataManager::SetValue("tw_settings_path", partition->Storage_Path);
DataManager::SetValue("tw_storage_path", partition->Storage_Path);
LOGI("Settings storage is '%s'\n", partition->Storage_Path.c_str());
} else {
partition->Is_Settings_Storage = false;
Partitions.push_back(partition);
}
} else {
delete partition;
}
}
fclose(fstabFile);
if (!Found_Settings_Storage) {
std::vector<TWPartition*>::iterator iter;
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Is_Storage) {
(*iter)->Is_Settings_Storage = true;
Found_Settings_Storage = true;
DataManager::SetValue("tw_settings_path", (*iter)->Storage_Path);
DataManager::SetValue("tw_storage_path", (*iter)->Storage_Path);
LOGI("Settings storage is '%s'\n", (*iter)->Storage_Path.c_str());
break;
}
}
if (!Found_Settings_Storage)
LOGE("Unable to locate storage partition for storing settings file.\n");
}
if (!Write_Fstab()) {
if (Display_Error)
LOGE("Error creating fstab\n");
@ -136,8 +161,12 @@ void TWPartitionManager::Output_Partition(TWPartition* Part) {
printf(" Used: %iMB Free: %iMB Backup Size: %iMB", (int)(Part->Used / mb), (int)(Part->Free / mb), (int)(Part->Backup_Size / mb));
}
printf("\n Flags: ");
if (Part->Can_Be_Mounted)
printf("Can_Be_Mounted ");
if (Part->Can_Be_Wiped)
printf("Can_Be_Wiped ");
if (Part->Can_Be_Backed_Up)
printf("Can_Be_Backed_Up ");
if (Part->Wipe_During_Factory_Reset)
printf("Wipe_During_Factory_Reset ");
if (Part->Wipe_Available_in_GUI)
@ -162,6 +191,8 @@ void TWPartitionManager::Output_Partition(TWPartition* Part) {
printf("Has_Android_Secure ");
if (Part->Is_Storage)
printf("Is_Storage ");
if (Part->Is_Settings_Storage)
printf("Is_Settings_Storage ");
if (Part->Ignore_Blkid)
printf("Ignore_Blkid ");
if (Part->Retain_Layout_Version)
@ -183,10 +214,14 @@ void TWPartitionManager::Output_Partition(TWPartition* Part) {
printf(" Length: %i\n", Part->Length);
if (!Part->Display_Name.empty())
printf(" Display_Name: %s\n", Part->Display_Name.c_str());
if (!Part->Storage_Name.empty())
printf(" Storage_Name: %s\n", Part->Storage_Name.c_str());
if (!Part->Backup_Path.empty())
printf(" Backup_Path: %s\n", Part->Backup_Path.c_str());
if (!Part->Backup_Name.empty())
printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
if (!Part->Backup_Display_Name.empty())
printf(" Backup_Display_Name: %s\n", Part->Backup_Display_Name.c_str());
if (!Part->Backup_FileName.empty())
printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
if (!Part->Storage_Path.empty())
@ -441,7 +476,7 @@ int TWPartitionManager::Check_Backup_Name(bool Display_Error) {
// Check each character
strncpy(backup_name, Backup_Name.c_str(), copy_size);
if (strcmp(backup_name, "0") == 0)
if (copy_size == 1 && strncmp(backup_name, "0", 1) == 0)
return 0; // A "0" (zero) means to use the current timestamp for the backup name
for (index=0; index<copy_size; index++) {
cur_char = (int)backup_name[index];
@ -462,13 +497,12 @@ int TWPartitionManager::Check_Backup_Name(bool Display_Error) {
// Check to make sure that a backup with this name doesn't already exist
DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Loc);
strcpy(backup_loc, Backup_Loc.c_str());
sprintf(tw_image_dir,"%s/%s/.", backup_loc, backup_name);
sprintf(tw_image_dir,"%s/%s", backup_loc, Backup_Name.c_str());
if (TWFunc::Path_Exists(tw_image_dir)) {
if (Display_Error)
LOGE("A backup with this name already exists.\n");
return -4;
}
// No problems found, return 0
return 0;
}
@ -571,7 +605,7 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde
std::vector<TWPartition*>::iterator subpart;
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
if (!(*subpart)->Backup(Backup_Folder))
return false;
if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
@ -602,23 +636,15 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde
int TWPartitionManager::Run_Backup(void) {
int check, do_md5, partition_count = 0;
string Backup_Folder, Backup_Name, Full_Backup_Path;
string Backup_Folder, Backup_Name, Full_Backup_Path, Backup_List, backup_path;
unsigned long long total_bytes = 0, file_bytes = 0, img_bytes = 0, free_space = 0, img_bytes_remaining, file_bytes_remaining, subpart_size;
unsigned long img_time = 0, file_time = 0;
TWPartition* backup_sys = NULL;
TWPartition* backup_data = NULL;
TWPartition* backup_cache = NULL;
TWPartition* backup_recovery = NULL;
TWPartition* backup_boot = NULL;
TWPartition* backup_andsec = NULL;
TWPartition* backup_sdext = NULL;
TWPartition* backup_sp1 = NULL;
TWPartition* backup_sp2 = NULL;
TWPartition* backup_sp3 = NULL;
TWPartition* backup_part = NULL;
TWPartition* storage = NULL;
std::vector<TWPartition*>::iterator subpart;
struct tm *t;
time_t start, stop, seconds, total_start, total_stop;
size_t start_pos = 0, end_pos = 0;
seconds = time(0);
t = localtime(&seconds);
@ -647,162 +673,38 @@ int TWPartitionManager::Run_Backup(void) {
LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
LOGI("Calculating backup details...\n");
DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
if (check) {
backup_sys = Find_Partition_By_Path("/system");
if (backup_sys != NULL) {
partition_count++;
if (backup_sys->Backup_Method == 1) {
file_bytes += backup_sys->Backup_Size;
}
else
img_bytes += backup_sys->Backup_Size;
} else {
LOGE("Unable to locate system partition.\n");
DataManager::SetValue(TW_BACKUP_SYSTEM_VAR, 0);
}
}
DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
if (check) {
backup_data = Find_Partition_By_Path("/data");
if (backup_data != NULL) {
partition_count++;
subpart_size = 0;
if (backup_data->Has_SubPartition) {
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
subpart_size += (*subpart)->Backup_Size;
DataManager::GetValue("tw_backup_list", Backup_List);
if (!Backup_List.empty()) {
end_pos = Backup_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Backup_List.size()) {
backup_path = Backup_List.substr(start_pos, end_pos - start_pos);
backup_part = Find_Partition_By_Path(backup_path);
if (backup_part != NULL) {
partition_count++;
if (backup_part->Backup_Method == 1)
file_bytes += backup_part->Backup_Size;
else
img_bytes += backup_part->Backup_Size;
if (backup_part->Has_SubPartition) {
std::vector<TWPartition*>::iterator subpart;
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_part->Mount_Point) {
partition_count++;
if ((*subpart)->Backup_Method == 1)
file_bytes += (*subpart)->Backup_Size;
else
img_bytes += (*subpart)->Backup_Size;
}
}
}
} else {
LOGE("Unable to locate '%s' partition for backup calculations.\n", backup_path.c_str());
}
if (backup_data->Backup_Method == 1)
file_bytes += backup_data->Backup_Size + subpart_size;
else
img_bytes += backup_data->Backup_Size + subpart_size;
} else {
LOGE("Unable to locate data partition.\n");
DataManager::SetValue(TW_BACKUP_DATA_VAR, 0);
start_pos = end_pos + 1;
end_pos = Backup_List.find(";", start_pos);
}
}
DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
if (check) {
backup_cache = Find_Partition_By_Path("/cache");
if (backup_cache != NULL) {
partition_count++;
if (backup_cache->Backup_Method == 1)
file_bytes += backup_cache->Backup_Size;
else
img_bytes += backup_cache->Backup_Size;
} else {
LOGE("Unable to locate cache partition.\n");
DataManager::SetValue(TW_BACKUP_CACHE_VAR, 0);
}
}
DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
if (check) {
backup_recovery = Find_Partition_By_Path("/recovery");
if (backup_recovery != NULL) {
partition_count++;
if (backup_recovery->Backup_Method == 1)
file_bytes += backup_recovery->Backup_Size;
else
img_bytes += backup_recovery->Backup_Size;
} else {
LOGE("Unable to locate recovery partition.\n");
DataManager::SetValue(TW_BACKUP_RECOVERY_VAR, 0);
}
}
#ifndef TW_HAS_NO_BOOT_PARTITION
DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
if (check) {
backup_boot = Find_Partition_By_Path("/boot");
if (backup_boot != NULL) {
partition_count++;
if (backup_boot->Backup_Method == 1)
file_bytes += backup_boot->Backup_Size;
else
img_bytes += backup_boot->Backup_Size;
} else {
LOGE("Unable to locate boot partition.\n");
DataManager::SetValue(TW_BACKUP_BOOT_VAR, 0);
}
}
#endif
DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
if (check) {
backup_andsec = Find_Partition_By_Path("/and-sec");
if (backup_andsec != NULL) {
partition_count++;
if (backup_andsec->Backup_Method == 1)
file_bytes += backup_andsec->Backup_Size;
else
img_bytes += backup_andsec->Backup_Size;
} else {
LOGE("Unable to locate android secure partition.\n");
DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
}
}
DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
if (check) {
backup_sdext = Find_Partition_By_Path("/sd-ext");
if (backup_sdext != NULL) {
partition_count++;
if (backup_sdext->Backup_Method == 1)
file_bytes += backup_sdext->Backup_Size;
else
img_bytes += backup_sdext->Backup_Size;
} else {
LOGE("Unable to locate sd-ext partition.\n");
DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
}
}
#ifdef SP1_NAME
DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
if (check) {
backup_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
if (backup_sp1 != NULL) {
partition_count++;
if (backup_sp1->Backup_Method == 1)
file_bytes += backup_sp1->Backup_Size;
else
img_bytes += backup_sp1->Backup_Size;
} else {
LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
DataManager::SetValue(TW_BACKUP_SP1_VAR, 0);
}
}
#endif
#ifdef SP2_NAME
DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
if (check) {
backup_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
if (backup_sp2 != NULL) {
partition_count++;
if (backup_sp2->Backup_Method == 1)
file_bytes += backup_sp2->Backup_Size;
else
img_bytes += backup_sp2->Backup_Size;
} else {
LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
DataManager::SetValue(TW_BACKUP_SP2_VAR, 0);
}
}
#endif
#ifdef SP3_NAME
DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
if (check) {
backup_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
if (backup_sp3 != NULL) {
partition_count++;
if (backup_sp3->Backup_Method == 1)
file_bytes += backup_sp3->Backup_Size;
else
img_bytes += backup_sp3->Backup_Size;
} else {
LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
DataManager::SetValue(TW_BACKUP_SP3_VAR, 0);
}
}
#endif
if (partition_count == 0) {
ui_print("No partitions selected for backup.\n");
@ -836,26 +738,20 @@ int TWPartitionManager::Run_Backup(void) {
ui->SetProgress(0.0);
if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
start_pos = 0;
end_pos = Backup_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Backup_List.size()) {
backup_path = Backup_List.substr(start_pos, end_pos - start_pos);
backup_part = Find_Partition_By_Path(backup_path);
if (backup_part != NULL) {
if (!Backup_Partition(backup_part, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
return false;
} else {
LOGE("Unable to locate '%s' partition for backup process.\n", backup_path.c_str());
}
start_pos = end_pos + 1;
end_pos = Backup_List.find(";", start_pos);
}
// Average BPS
if (img_time == 0)
@ -919,23 +815,17 @@ bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Nam
}
}
time(&Stop);
ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
ui_print("[%s done (%d seconds)]\n\n", Part->Backup_Display_Name.c_str(), (int)difftime(Stop, Start));
return true;
}
int TWPartitionManager::Run_Restore(string Restore_Name) {
int check_md5, check, partition_count = 0;
TWPartition* restore_sys = NULL;
TWPartition* restore_data = NULL;
TWPartition* restore_cache = NULL;
TWPartition* restore_boot = NULL;
TWPartition* restore_andsec = NULL;
TWPartition* restore_sdext = NULL;
TWPartition* restore_sp1 = NULL;
TWPartition* restore_sp2 = NULL;
TWPartition* restore_sp3 = NULL;
TWPartition* restore_part = NULL;
time_t rStart, rStop;
time(&rStart);
string Restore_List, restore_path;
size_t start_pos = 0, end_pos;
ui_print("\n[RESTORE STARTED]\n\n");
ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
@ -944,157 +834,65 @@ int TWPartitionManager::Run_Restore(string Restore_Name) {
return false;
DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
if (check > 0) {
restore_sys = Find_Partition_By_Path("/system");
if (restore_sys == NULL) {
LOGE("Unable to locate system partition.\n");
} else {
partition_count++;
if (check_md5 > 0) {
// Check MD5 files first before restoring to ensure that all of them match before starting a restore
TWFunc::GUI_Operation_Text(TW_VERIFY_MD5_TEXT, "Verifying MD5");
ui_print("Verifying MD5...\n");
} else {
ui_print("Skipping MD5 check based on user setting.\n");
}
DataManager::GetValue("tw_restore_selected", Restore_List);
if (!Restore_List.empty()) {
end_pos = Restore_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Restore_List.size()) {
restore_path = Restore_List.substr(start_pos, end_pos - start_pos);
restore_part = Find_Partition_By_Path(restore_path);
if (restore_part != NULL) {
partition_count++;
if (check_md5 > 0 && !restore_part->Check_MD5(Restore_Name))
return false;
if (restore_part->Has_SubPartition) {
std::vector<TWPartition*>::iterator subpart;
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_part->Mount_Point) {
if (!(*subpart)->Check_MD5(Restore_Name))
return false;
}
}
}
} else {
LOGE("Unable to locate '%s' partition for restoring.\n", restore_path.c_str());
}
start_pos = end_pos + 1;
end_pos = Restore_List.find(";", start_pos);
}
}
DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
if (check > 0) {
restore_data = Find_Partition_By_Path("/data");
if (restore_data == NULL) {
LOGE("Unable to locate data partition.\n");
} else {
partition_count++;
}
}
DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
if (check > 0) {
restore_cache = Find_Partition_By_Path("/cache");
if (restore_cache == NULL) {
LOGE("Unable to locate cache partition.\n");
} else {
partition_count++;
}
}
#ifndef TW_HAS_NO_BOOT_PARTITION
DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
if (check > 0) {
restore_boot = Find_Partition_By_Path("/boot");
if (restore_boot == NULL) {
LOGE("Unable to locate boot partition.\n");
} else {
partition_count++;
}
}
#endif
DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
if (check > 0) {
restore_andsec = Find_Partition_By_Path("/and-sec");
if (restore_andsec == NULL) {
LOGE("Unable to locate android secure partition.\n");
} else {
partition_count++;
}
}
DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
if (check > 0) {
restore_sdext = Find_Partition_By_Path("/sd-ext");
if (restore_sdext == NULL) {
LOGE("Unable to locate sd-ext partition.\n");
} else {
partition_count++;
}
}
#ifdef SP1_NAME
DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
if (check > 0) {
restore_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
if (restore_sp1 == NULL) {
LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
} else {
partition_count++;
}
}
#endif
#ifdef SP2_NAME
DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
if (check > 0) {
restore_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
if (restore_sp2 == NULL) {
LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
} else {
partition_count++;
}
}
#endif
#ifdef SP3_NAME
DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
if (check > 0) {
restore_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
if (restore_sp3 == NULL) {
LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
} else {
partition_count++;
}
}
#endif
if (partition_count == 0) {
LOGE("No partitions selected for restore.\n");
return false;
}
if (check_md5 > 0) {
// Check MD5 files first before restoring to ensure that all of them match before starting a restore
TWFunc::GUI_Operation_Text(TW_VERIFY_MD5_TEXT, "Verifying MD5");
ui_print("Verifying MD5...\n");
if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
return false;
if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
return false;
if (restore_data != NULL && restore_data->Has_SubPartition) {
std::vector<TWPartition*>::iterator subpart;
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
if (!(*subpart)->Check_MD5(Restore_Name))
return false;
}
}
}
if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
return false;
if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
return false;
if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
return false;
if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
return false;
if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
return false;
if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
return false;
if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
return false;
ui_print("Done verifying MD5.\n");
} else
ui_print("Skipping MD5 check based on user setting.\n");
ui_print("Restoring %i partitions...\n", partition_count);
ui->SetProgress(0.0);
if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name, partition_count))
return false;
if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name, partition_count))
return false;
if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name, partition_count))
return false;
if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name, partition_count))
return false;
if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name, partition_count))
return false;
if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name, partition_count))
return false;
if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name, partition_count))
return false;
if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name, partition_count))
return false;
if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name, partition_count))
return false;
start_pos = 0;
if (!Restore_List.empty()) {
end_pos = Restore_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Restore_List.size()) {
restore_path = Restore_List.substr(start_pos, end_pos - start_pos);
restore_part = Find_Partition_By_Path(restore_path);
if (restore_part != NULL) {
partition_count++;
if (!Restore_Partition(restore_part, Restore_Name, partition_count))
return false;
} else {
LOGE("Unable to locate '%s' partition for restoring.\n", restore_path.c_str());
}
start_pos = end_pos + 1;
end_pos = Restore_List.find(";", start_pos);
}
}
TWFunc::GUI_Operation_Text(TW_UPDATE_SYSTEM_DETAILS_TEXT, "Updating System Details");
Update_System_Details();
@ -1106,16 +904,7 @@ int TWPartitionManager::Run_Restore(string Restore_Name) {
void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
// Start with the default values
int tw_restore_system = -1;
int tw_restore_data = -1;
int tw_restore_cache = -1;
int tw_restore_recovery = -1;
int tw_restore_boot = -1;
int tw_restore_andsec = -1;
int tw_restore_sdext = -1;
int tw_restore_sp1 = -1;
int tw_restore_sp2 = -1;
int tw_restore_sp3 = -1;
string Restore_List;
bool get_date = true;
DIR* d;
@ -1170,7 +959,11 @@ void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
extn = ptr;
}
if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
if (strcmp(fstype, "log") == 0) continue;
int extnlength = strlen(extn);
if (extn == NULL || (extnlength != 3 && extnlength != 6)) continue;
if (extnlength == 3 && strncmp(extn, "win", 3) != 0) continue;
if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
TWPartition* Part = Find_Partition_By_Path(label);
if (Part == NULL)
@ -1184,48 +977,13 @@ void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
}
// Now, we just need to find the correct label
if (Part->Backup_Path == "/system")
tw_restore_system = 1;
if (Part->Backup_Path == "/data")
tw_restore_data = 1;
if (Part->Backup_Path == "/cache")
tw_restore_cache = 1;
if (Part->Backup_Path == "/recovery")
tw_restore_recovery = 1;
if (Part->Backup_Path == "/boot")
tw_restore_boot = 1;
if (Part->Backup_Path == "/and-sec")
tw_restore_andsec = 1;
if (Part->Backup_Path == "/sd-ext")
tw_restore_sdext = 1;
#ifdef SP1_NAME
if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP1_NAME)))
tw_restore_sp1 = 1;
#endif
#ifdef SP2_NAME
if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP2_NAME)))
tw_restore_sp2 = 1;
#endif
#ifdef SP3_NAME
if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP3_NAME)))
tw_restore_sp3 = 1;
#endif
Restore_List += Part->Backup_Path + ";";
}
closedir(d);
// Set the final values
DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
// Set the final value
DataManager::SetValue("tw_restore_list", Restore_List);
DataManager::SetValue("tw_restore_selected", Restore_List);
return;
}
@ -1322,7 +1080,7 @@ int TWPartitionManager::Wipe_Dalvik_Cache(void) {
dir.push_back("/cache/dalvik-cache");
dir.push_back("/cache/dc");
ui_print("\nWiping Dalvik Cache Directories...\n");
for (int i = 0; i < dir.size(); ++i) {
for (unsigned i = 0; i < dir.size(); ++i) {
if (stat(dir.at(i).c_str(), &st) == 0) {
TWFunc::removeDir(dir.at(i), false);
ui_print("Cleaned: %s...\n", dir.at(i).c_str());
@ -1993,3 +1751,104 @@ int TWPartitionManager::Partition_SDCard(void) {
ui_print("Partitioning complete.\n");
return true;
}
void TWPartitionManager::Get_Partition_List(string ListType, std::vector<PartitionList> *Partition_List) {
std::vector<TWPartition*>::iterator iter;
if (ListType == "mount") {
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Can_Be_Mounted && !(*iter)->Is_SubPartition) {
struct PartitionList part;
part.Display_Name = (*iter)->Display_Name;
part.Mount_Point = (*iter)->Mount_Point;
part.selected = (*iter)->Is_Mounted();
Partition_List->push_back(part);
}
}
} else if (ListType == "storage") {
char free_space[255];
string Current_Storage = DataManager::GetCurrentStoragePath();
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Is_Storage) {
struct PartitionList part;
sprintf(free_space, "%llu", (*iter)->Free / 1024 / 1024);
part.Display_Name = (*iter)->Storage_Name + " (";
part.Display_Name += free_space;
part.Display_Name += "MB)";
part.Mount_Point = (*iter)->Storage_Path;
if ((*iter)->Storage_Path == Current_Storage)
part.selected = 1;
else
part.selected = 0;
Partition_List->push_back(part);
}
}
} else if (ListType == "backup") {
char backup_size[255];
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Can_Be_Backed_Up && !(*iter)->Is_SubPartition) {
struct PartitionList part;
sprintf(backup_size, "%llu", (*iter)->Backup_Size / 1024 / 1024);
part.Display_Name = (*iter)->Backup_Display_Name + " (";
part.Display_Name += backup_size;
part.Display_Name += "MB)";
part.Mount_Point = (*iter)->Backup_Path;
part.selected = 0;
Partition_List->push_back(part);
}
}
} else if (ListType == "restore") {
string Restore_List, restore_path;
TWPartition* restore_part = NULL;
DataManager::GetValue("tw_restore_list", Restore_List);
if (!Restore_List.empty()) {
size_t start_pos = 0, end_pos = Restore_List.find(";", start_pos);
while (end_pos != string::npos && start_pos < Restore_List.size()) {
restore_path = Restore_List.substr(start_pos, end_pos - start_pos);
if ((restore_part = Find_Partition_By_Path(restore_path)) != NULL && !restore_part->Is_SubPartition) {
if (restore_part->Backup_Name == "recovery") {
// Don't allow restore of recovery (causes problems on some devices)
} else {
struct PartitionList part;
part.Display_Name = restore_part->Backup_Display_Name;
part.Mount_Point = restore_part->Backup_Path;
part.selected = 1;
Partition_List->push_back(part);
}
} else {
LOGE("Unable to locate '%s' partition for restore.\n", restore_path.c_str());
}
start_pos = end_pos + 1;
end_pos = Restore_List.find(";", start_pos);
}
}
} else if (ListType == "wipe") {
struct PartitionList dalvik;
dalvik.Display_Name = "Dalvik Cache";
dalvik.Mount_Point = "DALVIK";
dalvik.selected = 0;
Partition_List->push_back(dalvik);
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Wipe_Available_in_GUI && !(*iter)->Is_SubPartition) {
struct PartitionList part;
part.Display_Name = (*iter)->Display_Name;
part.Mount_Point = (*iter)->Mount_Point;
part.selected = 0;
Partition_List->push_back(part);
}
if ((*iter)->Has_Android_Secure) {
struct PartitionList part;
part.Display_Name = (*iter)->Backup_Display_Name;
part.Mount_Point = (*iter)->Backup_Path;
part.selected = 0;
Partition_List->push_back(part);
}
}
} else {
LOGE("Unknown list type '%s' requested for TWPartitionManager::Get_Partition_List\n", ListType.c_str());
}
}
int TWPartitionManager::Fstab_Processed(void) {
return Partitions.size();
}

View File

@ -30,6 +30,12 @@
using namespace std;
struct PartitionList {
std::string Display_Name;
std::string Mount_Point;
unsigned int selected;
};
// Partition class
class TWPartition
{
@ -67,6 +73,7 @@ public:
string Actual_Block_Device; // Actual block device (one of primary, alternate, or decrypted)
string MTD_Name; // Name of the partition for MTD devices
protected:
bool Process_Fstab_Line(string Line, bool Display_Error); // Processes a fstab line
void Find_Actual_Block_Device(); // Determines the correct block device and stores it in Actual_Block_Device
@ -74,6 +81,7 @@ protected:
protected:
bool Can_Be_Mounted; // Indicates that the partition can be mounted
bool Can_Be_Wiped; // Indicates that the partition can be wiped
bool Can_Be_Backed_Up; // Indicates that the partition will show up in the backup list
bool Wipe_During_Factory_Reset; // Indicates that this partition is wiped during a factory reset
bool Wipe_Available_in_GUI; // Inidcates that the wipe can be user initiated in the GUI system
bool Is_SubPartition; // Indicates that this partition is a sub-partition of another partition (e.g. datadata is a sub-partition of data)
@ -98,11 +106,14 @@ protected:
bool Is_Decrypted; // This partition has successfully been decrypted
string Display_Name; // Display name for the GUI
string Backup_Name; // Backup name -- used for backup filenames
string Backup_Display_Name; // Name displayed in the partition list for backup selection
string Storage_Name; // Name displayed in the partition list for storage selection
string Backup_FileName; // Actual backup filename
Backup_Method_enum Backup_Method; // Method used for backup
bool Has_Data_Media; // Indicates presence of /data/media, may affect wiping and backup methods
bool Has_Android_Secure; // Indicates the presence of .android_secure on this partition
bool Is_Storage; // Indicates if this partition is used for storage for backup, restore, and installing zips
bool Is_Settings_Storage; // Indicates that this storage partition is the location of the .twrps settings file and the location that is used for custom themes
string Storage_Path; // Indicates the path to the storage -- root indicates mount point, media/ indicates e.g. /data/media
string Fstab_File_System; // File system from the recovery.fstab
int Format_Block_Size; // Block size for formatting
@ -143,6 +154,8 @@ private:
void Mount_Storage_Retry(void); // Tries multiple times with a half second delay to mount a device in case storage is slow to mount
friend class TWPartitionManager;
friend class DataManager;
friend class GUIPartitionList;
};
class TWPartitionManager
@ -193,6 +206,9 @@ public:
virtual int Partition_SDCard(void); // Repartitions the sdcard
virtual int Fix_Permissions();
virtual void Get_Partition_List(string ListType, std::vector<PartitionList> *Partition_List);
virtual int Fstab_Processed(); // Indicates if the fstab has been processed or not
private:
bool Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename); // Generates an MD5 after a backup is made
bool Backup_Partition(TWPartition* Part, string Backup_Folder, bool generate_md5, unsigned long long* img_bytes_remaining, unsigned long long* file_bytes_remaining, unsigned long *img_time, unsigned long *file_time, unsigned long long *img_bytes, unsigned long long *file_bytes);

View File

@ -17,7 +17,7 @@
#ifndef _VARIABLES_HEADER_
#define _VARIABLES_HEADER_
#define TW_VERSION_STR "2.4.4.0"
#define TW_VERSION_STR "2.5.0.0"
#define TW_USE_COMPRESSION_VAR "tw_use_compression"
#define TW_FILENAME "tw_filename"