for android-10 This will support updating the ramdisk to a different compression format and co-exist with magisk. We are also cleaning up and removing non android-10 api makefile actions. We are also moving twrp repacking to its own class. We check the new ramdisk format and if it's different we have magisk compress using the new ramdisk format. Change-Id: I770030aae7797e75817178b2f0fccd9f39dc23af
1144 lines
32 KiB
C++
Executable File
1144 lines
32 KiB
C++
Executable File
/*
|
|
Copyright 2012 to 2016 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 <pthread.h>
|
|
#include <time.h>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <cctype>
|
|
#include <cutils/properties.h>
|
|
#include <unistd.h>
|
|
|
|
#include "variables.h"
|
|
#include "data.hpp"
|
|
#include "partitions.hpp"
|
|
#include "twrp-functions.hpp"
|
|
#ifndef TW_NO_SCREEN_TIMEOUT
|
|
#include "gui/blanktimer.hpp"
|
|
#endif
|
|
#include "find_file.hpp"
|
|
#include "set_metadata.h"
|
|
#include "gui/gui.hpp"
|
|
#include "infomanager.hpp"
|
|
|
|
#define DEVID_MAX 64
|
|
#define HWID_MAX 32
|
|
|
|
extern "C"
|
|
{
|
|
#include "twcommon.h"
|
|
#include "gui/pages.h"
|
|
void gui_notifyVarChange(const char *name, const char* value);
|
|
}
|
|
#include "minuitwrp/minui.h"
|
|
|
|
#define FILE_VERSION 0x00010010 // Do not set to 0
|
|
|
|
using namespace std;
|
|
|
|
string DataManager::mBackingFile;
|
|
int DataManager::mInitialized = 0;
|
|
InfoManager DataManager::mPersist; // Data that that is not constant and will be saved to the settings file
|
|
InfoManager DataManager::mData; // Data that is not constant and will not be saved to settings file
|
|
InfoManager DataManager::mConst; // Data that is constant and will not be saved to settings file
|
|
|
|
extern bool datamedia;
|
|
|
|
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
|
pthread_mutex_t DataManager::m_valuesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
|
|
#else
|
|
pthread_mutex_t DataManager::m_valuesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
#endif
|
|
|
|
// Device ID functions
|
|
void DataManager::sanitize_device_id(char* device_id) {
|
|
const char* whitelist ="-._";
|
|
char str[DEVID_MAX];
|
|
char* c = str;
|
|
|
|
snprintf(str, DEVID_MAX, "%s", device_id);
|
|
memset(device_id, 0, strlen(device_id));
|
|
while (*c) {
|
|
if (isalnum(*c) || strchr(whitelist, *c))
|
|
strncat(device_id, c, 1);
|
|
c++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#define CMDLINE_SERIALNO "androidboot.serialno="
|
|
#define CMDLINE_SERIALNO_LEN (strlen(CMDLINE_SERIALNO))
|
|
#define CPUINFO_SERIALNO "Serial"
|
|
#define CPUINFO_SERIALNO_LEN (strlen(CPUINFO_SERIALNO))
|
|
#define CPUINFO_HARDWARE "Hardware"
|
|
#define CPUINFO_HARDWARE_LEN (strlen(CPUINFO_HARDWARE))
|
|
|
|
void DataManager::get_device_id(void) {
|
|
FILE *fp;
|
|
char line[2048];
|
|
char hardware_id[HWID_MAX] = { 0 };
|
|
char device_id[DEVID_MAX] = { 0 };
|
|
char* token;
|
|
|
|
#ifdef TW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID
|
|
// Use (product_model)_(hardware_id) as device id
|
|
char model_id[PROPERTY_VALUE_MAX];
|
|
property_get("ro.product.model", model_id, "error");
|
|
if (strcmp(model_id, "error") != 0) {
|
|
LOGINFO("=> product model: '%s'\n", model_id);
|
|
// Replace spaces with underscores
|
|
for (size_t i = 0; i < strlen(model_id); i++) {
|
|
if (model_id[i] == ' ')
|
|
model_id[i] = '_';
|
|
}
|
|
snprintf(device_id, DEVID_MAX, "%s", model_id);
|
|
|
|
if (strlen(device_id) < DEVID_MAX) {
|
|
fp = fopen("proc_cpuinfo.txt", "rt");
|
|
if (fp != NULL) {
|
|
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
if (memcmp(line, CPUINFO_HARDWARE,
|
|
CPUINFO_HARDWARE_LEN) == 0) {
|
|
// skip past "Hardware", spaces, and colon
|
|
token = line + CPUINFO_HARDWARE_LEN;
|
|
while (*token && (!isgraph(*token) || *token == ':'))
|
|
token++;
|
|
|
|
if (*token && *token != '\n'
|
|
&& strcmp("UNKNOWN\n", token)) {
|
|
snprintf(hardware_id, HWID_MAX, "%s", token);
|
|
if (hardware_id[strlen(hardware_id)-1] == '\n')
|
|
hardware_id[strlen(hardware_id)-1] = 0;
|
|
LOGINFO("=> hardware id from cpuinfo: '%s'\n",
|
|
hardware_id);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
}
|
|
|
|
if (hardware_id[0] != 0)
|
|
snprintf(device_id, DEVID_MAX, "%s_%s", model_id, hardware_id);
|
|
|
|
sanitize_device_id(device_id);
|
|
mConst.SetValue("device_id", device_id);
|
|
LOGINFO("=> using device id: '%s'\n", device_id);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#ifndef TW_FORCE_CPUINFO_FOR_DEVICE_ID
|
|
#ifdef TW_USE_SERIALNO_PROPERTY_FOR_DEVICE_ID
|
|
// Check serial number system property
|
|
if (property_get("ro.serialno", line, "")) {
|
|
snprintf(device_id, DEVID_MAX, "%s", line);
|
|
sanitize_device_id(device_id);
|
|
mConst.SetValue("device_id", device_id);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// Check the cmdline to see if the serial number was supplied
|
|
fp = fopen("/proc/cmdline", "rt");
|
|
if (fp != NULL) {
|
|
fgets(line, sizeof(line), fp);
|
|
fclose(fp); // cmdline is only one line long
|
|
|
|
token = strtok(line, " ");
|
|
while (token) {
|
|
if (memcmp(token, CMDLINE_SERIALNO, CMDLINE_SERIALNO_LEN) == 0) {
|
|
token += CMDLINE_SERIALNO_LEN;
|
|
snprintf(device_id, DEVID_MAX, "%s", token);
|
|
sanitize_device_id(device_id); // also removes newlines
|
|
mConst.SetValue("device_id", device_id);
|
|
return;
|
|
}
|
|
token = strtok(NULL, " ");
|
|
}
|
|
}
|
|
#endif
|
|
// Check cpuinfo for serial number; if found, use as device_id
|
|
// If serial number is not found, fallback to hardware_id for the device_id
|
|
fp = fopen("/proc/cpuinfo", "rt");
|
|
if (fp != NULL) {
|
|
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
if (memcmp(line, CPUINFO_SERIALNO, CPUINFO_SERIALNO_LEN) == 0) {
|
|
// skip past "Serial", spaces, and colon
|
|
token = line + CPUINFO_SERIALNO_LEN;
|
|
while (*token && (!isgraph(*token) || *token == ':'))
|
|
token++;
|
|
|
|
if (*token && *token != '\n') {
|
|
snprintf(device_id, DEVID_MAX, "%s", token);
|
|
sanitize_device_id(device_id); // also removes newlines
|
|
LOGINFO("=> serial from cpuinfo: '%s'\n", device_id);
|
|
mConst.SetValue("device_id", device_id);
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
} else if (memcmp(line, CPUINFO_HARDWARE,
|
|
CPUINFO_HARDWARE_LEN) == 0) {
|
|
// skip past "Hardware", spaces, and colon
|
|
token = line + CPUINFO_HARDWARE_LEN;
|
|
while (*token && (!isgraph(*token) || *token == ':'))
|
|
token++;
|
|
|
|
if (*token && *token != '\n') {
|
|
snprintf(hardware_id, HWID_MAX, "%s", token);
|
|
if (hardware_id[strlen(hardware_id)-1] == '\n')
|
|
hardware_id[strlen(hardware_id)-1] = 0;
|
|
LOGINFO("=> hardware id from cpuinfo: '%s'\n", hardware_id);
|
|
}
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
|
|
if (hardware_id[0] != 0) {
|
|
LOGINFO("\nusing hardware id for device id: '%s'\n", hardware_id);
|
|
snprintf(device_id, DEVID_MAX, "%s", hardware_id);
|
|
sanitize_device_id(device_id);
|
|
mConst.SetValue("device_id", device_id);
|
|
return;
|
|
}
|
|
|
|
strcpy(device_id, "serialno");
|
|
LOGINFO("=> device id not found, using '%s'\n", device_id);
|
|
mConst.SetValue("device_id", device_id);
|
|
return;
|
|
}
|
|
|
|
int DataManager::ResetDefaults()
|
|
{
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
mPersist.Clear();
|
|
mData.Clear();
|
|
mConst.Clear();
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
|
|
SetDefaultValues();
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::LoadValues(const string& filename)
|
|
{
|
|
string dev_id;
|
|
|
|
if (!mInitialized)
|
|
SetDefaultValues();
|
|
|
|
GetValue("device_id", dev_id);
|
|
// Save off the backing file for set operations
|
|
mBackingFile = filename;
|
|
mPersist.SetFile(filename);
|
|
mPersist.SetFileVersion(FILE_VERSION);
|
|
|
|
// Read in the file, if possible
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
mPersist.LoadValues();
|
|
|
|
#ifndef TW_NO_SCREEN_TIMEOUT
|
|
blankTimer.setTime(mPersist.GetIntValue("tw_screen_timeout_secs"));
|
|
#endif
|
|
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
string current = GetCurrentStoragePath();
|
|
TWPartition* Part = PartitionManager.Find_Partition_By_Path(current);
|
|
if (!Part)
|
|
Part = PartitionManager.Get_Default_Storage_Partition();
|
|
if (Part && current != Part->Storage_Path && Part->Mount(false)) {
|
|
LOGINFO("LoadValues setting storage path to '%s'\n", Part->Storage_Path.c_str());
|
|
SetValue("tw_storage_path", Part->Storage_Path);
|
|
} else {
|
|
SetBackupFolder();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::Flush()
|
|
{
|
|
return SaveValues();
|
|
}
|
|
|
|
int DataManager::SaveValues()
|
|
{
|
|
#ifndef TW_OEM_BUILD
|
|
if (mBackingFile.empty())
|
|
return -1;
|
|
|
|
string mount_path = GetSettingsStoragePath();
|
|
PartitionManager.Mount_By_Path(mount_path.c_str(), 1);
|
|
|
|
mPersist.SetFile(mBackingFile);
|
|
mPersist.SetFileVersion(FILE_VERSION);
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
mPersist.SaveValues();
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
|
|
tw_set_default_metadata(mBackingFile.c_str());
|
|
LOGINFO("Saved settings file values to '%s'\n", mBackingFile.c_str());
|
|
#endif // ifdef TW_OEM_BUILD
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::GetValue(const string& varName, string& value)
|
|
{
|
|
string localStr = varName;
|
|
int ret = 0;
|
|
|
|
if (!mInitialized)
|
|
SetDefaultValues();
|
|
|
|
// Strip off leading and trailing '%' if provided
|
|
if (localStr.length() > 2 && localStr[0] == '%' && localStr[localStr.length()-1] == '%')
|
|
{
|
|
localStr.erase(0, 1);
|
|
localStr.erase(localStr.length() - 1, 1);
|
|
}
|
|
|
|
// Handle magic values
|
|
if (GetMagicValue(localStr, value) == 0)
|
|
return 0;
|
|
|
|
// Handle property
|
|
if (localStr.length() > 9 && localStr.substr(0, 9) == "property.") {
|
|
char property_value[PROPERTY_VALUE_MAX];
|
|
property_get(localStr.substr(9).c_str(), property_value, "");
|
|
value = property_value;
|
|
return 0;
|
|
}
|
|
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
ret = mConst.GetValue(localStr, value);
|
|
if (ret == 0)
|
|
goto exit;
|
|
|
|
ret = mPersist.GetValue(localStr, value);
|
|
if (ret == 0)
|
|
goto exit;
|
|
|
|
ret = mData.GetValue(localStr, value);
|
|
exit:
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
return ret;
|
|
}
|
|
|
|
int DataManager::GetValue(const string& varName, int& value)
|
|
{
|
|
string data;
|
|
|
|
if (GetValue(varName,data) != 0)
|
|
return -1;
|
|
|
|
value = atoi(data.c_str());
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::GetValue(const string& varName, float& value)
|
|
{
|
|
string data;
|
|
|
|
if (GetValue(varName,data) != 0)
|
|
return -1;
|
|
|
|
value = atof(data.c_str());
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::GetValue(const string& varName, unsigned long long& value)
|
|
{
|
|
string data;
|
|
|
|
if (GetValue(varName,data) != 0)
|
|
return -1;
|
|
|
|
value = strtoull(data.c_str(), NULL, 10);
|
|
return 0;
|
|
}
|
|
|
|
// This function will return an empty string if the value doesn't exist
|
|
string DataManager::GetStrValue(const string& varName)
|
|
{
|
|
string retVal;
|
|
|
|
GetValue(varName, retVal);
|
|
return retVal;
|
|
}
|
|
|
|
// This function will return 0 if the value doesn't exist
|
|
int DataManager::GetIntValue(const string& varName)
|
|
{
|
|
string retVal;
|
|
|
|
GetValue(varName, retVal);
|
|
return atoi(retVal.c_str());
|
|
}
|
|
|
|
int DataManager::SetValue(const string& varName, const string& value, const int persist /* = 0 */)
|
|
{
|
|
if (!mInitialized)
|
|
SetDefaultValues();
|
|
|
|
// Handle property
|
|
if (varName.length() > 9 && varName.substr(0, 9) == "property.") {
|
|
int ret = property_set(varName.substr(9).c_str(), value.c_str());
|
|
if (ret)
|
|
LOGERR("Error setting property '%s' to '%s'\n", varName.substr(9).c_str(), value.c_str());
|
|
return ret;
|
|
}
|
|
|
|
// Don't allow empty values or numerical starting values
|
|
if (varName.empty() || (varName[0] >= '0' && varName[0] <= '9'))
|
|
return -1;
|
|
|
|
string test;
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
int constChk = mConst.GetValue(varName, test);
|
|
if (constChk == 0) {
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
return -1;
|
|
}
|
|
|
|
if (persist) {
|
|
mPersist.SetValue(varName, value);
|
|
} else {
|
|
int persistChk = mPersist.GetValue(varName, test);
|
|
if (persistChk == 0) {
|
|
mPersist.SetValue(varName, value);
|
|
} else {
|
|
mData.SetValue(varName, value);
|
|
}
|
|
}
|
|
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
|
|
#ifndef TW_NO_SCREEN_TIMEOUT
|
|
if (varName == "tw_screen_timeout_secs") {
|
|
blankTimer.setTime(atoi(value.c_str()));
|
|
} else
|
|
#endif
|
|
if (varName == "tw_storage_path") {
|
|
SetBackupFolder();
|
|
}
|
|
gui_notifyVarChange(varName.c_str(), value.c_str());
|
|
return 0;
|
|
}
|
|
|
|
int DataManager::SetValue(const string& varName, const int value, const int persist /* = 0 */)
|
|
{
|
|
ostringstream valStr;
|
|
valStr << value;
|
|
return SetValue(varName, valStr.str(), persist);
|
|
}
|
|
|
|
int DataManager::SetValue(const string& varName, const float value, const int persist /* = 0 */)
|
|
{
|
|
ostringstream valStr;
|
|
valStr << value;
|
|
return SetValue(varName, valStr.str(), persist);;
|
|
}
|
|
|
|
int DataManager::SetValue(const string& varName, const unsigned long long& value, const int persist /* = 0 */)
|
|
{
|
|
ostringstream valStr;
|
|
valStr << value;
|
|
return SetValue(varName, valStr.str(), persist);
|
|
}
|
|
|
|
// For legacy code that doesn't set a scope
|
|
int DataManager::SetProgress(const float Fraction) {
|
|
if (SetValue("ui_portion_size", 0) != 0)
|
|
return -1;
|
|
if (SetValue("ui_portion_start", 0) != 0)
|
|
return -1;
|
|
ShowProgress(1, 0);
|
|
int res = _SetProgress(Fraction);
|
|
if (SetValue("ui_portion_size", 0) != 0)
|
|
return -1;
|
|
if (SetValue("ui_portion_start", 0) != 0)
|
|
return -1;
|
|
return res;
|
|
}
|
|
|
|
int DataManager::_SetProgress(float Fraction) {
|
|
float Portion_Start, Portion_Size;
|
|
GetValue("ui_portion_size", Portion_Size);
|
|
GetValue("ui_portion_start", Portion_Start);
|
|
//LOGINFO("SetProgress(%.2lf): Portion_Size: %.2lf Portion_Start: %.2lf\n", Fraction, Portion_Size, Portion_Start);
|
|
if (Fraction < 0.0)
|
|
Fraction = 0;
|
|
if (Fraction > 1.0)
|
|
Fraction = 1;
|
|
if (SetValue("ui_progress", (float) ((Portion_Start + (Portion_Size * Fraction)) * 100.0)) != 0)
|
|
return -1;
|
|
return (SetValue("ui_progress_portion", 0) != 0);
|
|
}
|
|
|
|
int DataManager::ShowProgress(float Portion, const float Seconds)
|
|
{
|
|
float Portion_Start, Portion_Size;
|
|
GetValue("ui_portion_size", Portion_Size);
|
|
GetValue("ui_portion_start", Portion_Start);
|
|
Portion_Start += Portion_Size;
|
|
if(Portion + Portion_Start > 1.0)
|
|
Portion = 1.0 - Portion_Start;
|
|
//LOGINFO("ShowProgress(%.2lf, %.2lf): Portion_Start: %.2lf\n", Portion, Seconds, Portion_Start);
|
|
if (SetValue("ui_portion_start", Portion_Start) != 0)
|
|
return -1;
|
|
if (SetValue("ui_portion_size", Portion) != 0)
|
|
return -1;
|
|
if (SetValue("ui_progress", (float)(Portion_Start * 100.0)) != 0)
|
|
return -1;
|
|
if(Seconds) {
|
|
if (SetValue("ui_progress_portion", (float)((Portion * 100.0) + Portion_Start)) != 0)
|
|
return -1;
|
|
if (SetValue("ui_progress_frames", Seconds * 48) != 0)
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void DataManager::update_tz_environment_variables(void)
|
|
{
|
|
setenv("TZ", GetStrValue(TW_TIME_ZONE_VAR).c_str(), 1);
|
|
tzset();
|
|
}
|
|
|
|
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;
|
|
LOGINFO("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 && !partition->Symlink_Mount_Point.empty())
|
|
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 = TWFunc::Get_Root_Path(zip_path);
|
|
if (zip_root != storage_path) {
|
|
LOGINFO("DataManager::SetBackupFolder zip path was %s changing to %s, %s\n", zip_path.c_str(), storage_path.c_str(), zip_root.c_str());
|
|
SetValue(TW_ZIP_LOCATION_VAR, storage_path);
|
|
}
|
|
}
|
|
} else {
|
|
if (PartitionManager.Fstab_Processed() != 0) {
|
|
LOGINFO("Storage partition '%s' not found\n", str.c_str());
|
|
gui_err("unable_locate_storage=Unable to locate storage device.");
|
|
}
|
|
}
|
|
}
|
|
|
|
void DataManager::SetDefaultValues()
|
|
{
|
|
string str, path;
|
|
|
|
mConst.SetConst();
|
|
|
|
get_device_id();
|
|
|
|
pthread_mutex_lock(&m_valuesLock);
|
|
|
|
mInitialized = 1;
|
|
|
|
mConst.SetValue("true", "1");
|
|
mConst.SetValue("false", "0");
|
|
|
|
mConst.SetValue(TW_VERSION_VAR, TW_VERSION_STR);
|
|
|
|
#ifndef TW_NO_HAPTICS
|
|
mPersist.SetValue("tw_button_vibrate", "80");
|
|
mPersist.SetValue("tw_keyboard_vibrate", "40");
|
|
mPersist.SetValue("tw_action_vibrate", "160");
|
|
mConst.SetValue("tw_disable_haptics", "0");
|
|
#else
|
|
LOGINFO("TW_NO_HAPTICS := true\n");
|
|
mConst.SetValue("tw_disable_haptics", "1");
|
|
#endif
|
|
|
|
TWPartition *store = PartitionManager.Get_Default_Storage_Partition();
|
|
if (store)
|
|
mPersist.SetValue("tw_storage_path", store->Storage_Path);
|
|
else
|
|
mPersist.SetValue("tw_storage_path", "/");
|
|
|
|
#ifdef TW_FORCE_CPUINFO_FOR_DEVICE_ID
|
|
printf("TW_FORCE_CPUINFO_FOR_DEVICE_ID := true\n");
|
|
#endif
|
|
|
|
#ifdef BOARD_HAS_NO_REAL_SDCARD
|
|
printf("BOARD_HAS_NO_REAL_SDCARD := true\n");
|
|
mConst.SetValue(TW_ALLOW_PARTITION_SDCARD, "0");
|
|
#else
|
|
mConst.SetValue(TW_ALLOW_PARTITION_SDCARD, "1");
|
|
#endif
|
|
|
|
#ifdef TW_INCLUDE_DUMLOCK
|
|
printf("TW_INCLUDE_DUMLOCK := true\n");
|
|
mConst.SetValue(TW_SHOW_DUMLOCK, "1");
|
|
#else
|
|
mConst.SetValue(TW_SHOW_DUMLOCK, "0");
|
|
#endif
|
|
|
|
str = GetCurrentStoragePath();
|
|
mPersist.SetValue(TW_ZIP_LOCATION_VAR, str);
|
|
str += "/TWRP/BACKUPS/";
|
|
|
|
string dev_id;
|
|
mConst.GetValue("device_id", dev_id);
|
|
|
|
str += dev_id;
|
|
mData.SetValue(TW_BACKUPS_FOLDER_VAR, str);
|
|
|
|
mConst.SetValue(TW_REBOOT_SYSTEM, "1");
|
|
#ifdef TW_NO_REBOOT_RECOVERY
|
|
printf("TW_NO_REBOOT_RECOVERY := true\n");
|
|
mConst.SetValue(TW_REBOOT_RECOVERY, "0");
|
|
#else
|
|
mConst.SetValue(TW_REBOOT_RECOVERY, "1");
|
|
#endif
|
|
mConst.SetValue(TW_REBOOT_POWEROFF, "1");
|
|
#ifdef TW_NO_REBOOT_BOOTLOADER
|
|
printf("TW_NO_REBOOT_BOOTLOADER := true\n");
|
|
mConst.SetValue(TW_REBOOT_BOOTLOADER, "0");
|
|
#else
|
|
mConst.SetValue(TW_REBOOT_BOOTLOADER, "1");
|
|
#endif
|
|
#ifdef RECOVERY_SDCARD_ON_DATA
|
|
printf("RECOVERY_SDCARD_ON_DATA := true\n");
|
|
mConst.SetValue(TW_HAS_DATA_MEDIA, "1");
|
|
datamedia = true;
|
|
#else
|
|
mData.SetValue(TW_HAS_DATA_MEDIA, "0");
|
|
#endif
|
|
#ifdef TW_NO_BATT_PERCENT
|
|
printf("TW_NO_BATT_PERCENT := true\n");
|
|
mConst.SetValue(TW_NO_BATTERY_PERCENT, "1");
|
|
#else
|
|
mConst.SetValue(TW_NO_BATTERY_PERCENT, "0");
|
|
#endif
|
|
#ifdef TW_NO_CPU_TEMP
|
|
printf("TW_NO_CPU_TEMP := true\n");
|
|
mConst.SetValue("tw_no_cpu_temp", "1");
|
|
#else
|
|
string cpu_temp_file;
|
|
#ifdef TW_CUSTOM_CPU_TEMP_PATH
|
|
cpu_temp_file = EXPAND(TW_CUSTOM_CPU_TEMP_PATH);
|
|
#else
|
|
cpu_temp_file = "/sys/class/thermal/thermal_zone0/temp";
|
|
#endif
|
|
if (TWFunc::Path_Exists(cpu_temp_file)) {
|
|
mConst.SetValue("tw_no_cpu_temp", "0");
|
|
} else {
|
|
LOGINFO("CPU temperature file '%s' not found, disabling CPU temp.\n", cpu_temp_file.c_str());
|
|
mConst.SetValue("tw_no_cpu_temp", "1");
|
|
}
|
|
#endif
|
|
#ifdef TW_CUSTOM_POWER_BUTTON
|
|
printf("TW_POWER_BUTTON := %s\n", EXPAND(TW_CUSTOM_POWER_BUTTON));
|
|
mConst.SetValue(TW_POWER_BUTTON, EXPAND(TW_CUSTOM_POWER_BUTTON));
|
|
#else
|
|
mConst.SetValue(TW_POWER_BUTTON, "0");
|
|
#endif
|
|
#ifdef TW_ALWAYS_RMRF
|
|
printf("TW_ALWAYS_RMRF := true\n");
|
|
mConst.SetValue(TW_RM_RF_VAR, "1");
|
|
#endif
|
|
#ifdef TW_NEVER_UNMOUNT_SYSTEM
|
|
printf("TW_NEVER_UNMOUNT_SYSTEM := true\n");
|
|
mConst.SetValue(TW_DONT_UNMOUNT_SYSTEM, "1");
|
|
#else
|
|
mConst.SetValue(TW_DONT_UNMOUNT_SYSTEM, "0");
|
|
#endif
|
|
#ifdef TW_NO_USB_STORAGE
|
|
printf("TW_NO_USB_STORAGE := true\n");
|
|
mConst.SetValue(TW_HAS_USB_STORAGE, "0");
|
|
#else
|
|
char lun_file[255];
|
|
string Lun_File_str = CUSTOM_LUN_FILE;
|
|
size_t found = Lun_File_str.find("%");
|
|
if (found != string::npos) {
|
|
sprintf(lun_file, CUSTOM_LUN_FILE, 0);
|
|
Lun_File_str = lun_file;
|
|
}
|
|
if (!TWFunc::Path_Exists(Lun_File_str)) {
|
|
LOGINFO("Lun file '%s' does not exist, USB storage mode disabled\n", Lun_File_str.c_str());
|
|
mConst.SetValue(TW_HAS_USB_STORAGE, "0");
|
|
} else {
|
|
LOGINFO("Lun file '%s'\n", Lun_File_str.c_str());
|
|
mData.SetValue(TW_HAS_USB_STORAGE, "1");
|
|
}
|
|
#endif
|
|
#ifdef TW_INCLUDE_INJECTTWRP
|
|
printf("TW_INCLUDE_INJECTTWRP := true\n");
|
|
mConst.SetValue(TW_HAS_INJECTTWRP, "1");
|
|
mPersist(TW_INJECT_AFTER_ZIP, "1");
|
|
#else
|
|
mConst.SetValue(TW_HAS_INJECTTWRP, "0");
|
|
#endif
|
|
#ifdef TW_HAS_DOWNLOAD_MODE
|
|
printf("TW_HAS_DOWNLOAD_MODE := true\n");
|
|
mConst.SetValue(TW_DOWNLOAD_MODE, "1");
|
|
#endif
|
|
#ifdef TW_HAS_EDL_MODE
|
|
printf("TW_HAS_EDL_MODE := true\n");
|
|
mConst.SetValue(TW_EDL_MODE, "1");
|
|
#endif
|
|
#ifdef TW_INCLUDE_CRYPTO
|
|
mConst.SetValue(TW_HAS_CRYPTO, "1");
|
|
printf("TW_INCLUDE_CRYPTO := true\n");
|
|
#endif
|
|
#ifdef TW_SDEXT_NO_EXT4
|
|
printf("TW_SDEXT_NO_EXT4 := true\n");
|
|
mConst.SetValue(TW_SDEXT_DISABLE_EXT4, "1");
|
|
#else
|
|
mConst.SetValue(TW_SDEXT_DISABLE_EXT4, "0");
|
|
#endif
|
|
|
|
#ifdef TW_HAS_NO_BOOT_PARTITION
|
|
mPersist.SetValue("tw_backup_list", "/system;/data;");
|
|
#else
|
|
#ifdef PRODUCT_USE_DYNAMIC_PARTITIONS
|
|
mPersist.SetValue("tw_backup_list", "/data;");
|
|
#else
|
|
mPersist.SetValue("tw_backup_list", "/system;/data;/boot;");
|
|
#endif
|
|
#endif
|
|
mConst.SetValue(TW_MIN_SYSTEM_VAR, TW_MIN_SYSTEM_SIZE);
|
|
mData.SetValue(TW_BACKUP_NAME, "(Auto Generate)");
|
|
|
|
mPersist.SetValue(TW_INSTALL_REBOOT_VAR, "0");
|
|
mPersist.SetValue(TW_SIGNED_ZIP_VERIFY_VAR, "0");
|
|
mPersist.SetValue(TW_DISABLE_FREE_SPACE_VAR, "0");
|
|
mPersist.SetValue(TW_FORCE_DIGEST_CHECK_VAR, "0");
|
|
mPersist.SetValue(TW_USE_COMPRESSION_VAR, "0");
|
|
mPersist.SetValue(TW_TIME_ZONE_VAR, "CST6CDT,M3.2.0,M11.1.0");
|
|
mPersist.SetValue(TW_GUI_SORT_ORDER, "1");
|
|
mPersist.SetValue(TW_RM_RF_VAR, "0");
|
|
mPersist.SetValue(TW_SKIP_DIGEST_CHECK_VAR, "0");
|
|
mPersist.SetValue(TW_SKIP_DIGEST_GENERATE_VAR, "0");
|
|
mPersist.SetValue(TW_SDEXT_SIZE, "0");
|
|
mPersist.SetValue(TW_SWAP_SIZE, "0");
|
|
mPersist.SetValue(TW_SDPART_FILE_SYSTEM, "ext3");
|
|
mPersist.SetValue(TW_TIME_ZONE_GUISEL, "CST6;CDT,M3.2.0,M11.1.0");
|
|
mPersist.SetValue(TW_TIME_ZONE_GUIOFFSET, "0");
|
|
mPersist.SetValue(TW_TIME_ZONE_GUIDST, "1");
|
|
mData.SetValue(TW_ACTION_BUSY, "0");
|
|
mData.SetValue("tw_wipe_cache", "0");
|
|
mData.SetValue("tw_wipe_dalvik", "0");
|
|
mData.SetValue(TW_ZIP_INDEX, "0");
|
|
mData.SetValue(TW_ZIP_QUEUE_COUNT, "0");
|
|
mData.SetValue(TW_FILENAME, "/sdcard");
|
|
mData.SetValue(TW_SIMULATE_ACTIONS, "0");
|
|
mData.SetValue(TW_SIMULATE_FAIL, "0");
|
|
mData.SetValue(TW_IS_ENCRYPTED, "0");
|
|
mData.SetValue(TW_IS_DECRYPTED, "0");
|
|
mData.SetValue(TW_CRYPTO_PASSWORD, "0");
|
|
mData.SetValue("tw_terminal_state", "0");
|
|
mData.SetValue("tw_background_thread_running", "0");
|
|
mData.SetValue(TW_RESTORE_FILE_DATE, "0");
|
|
mPersist.SetValue("tw_military_time", "0");
|
|
mData.SetValue(TW_IS_SUPER, "0");
|
|
|
|
#ifdef TW_INCLUDE_CRYPTO
|
|
mPersist.SetValue(TW_USE_SHA2, "1");
|
|
mPersist.SetValue(TW_NO_SHA2, "0");
|
|
#else
|
|
mPersist.SetValue(TW_NO_SHA2, "1");
|
|
#endif
|
|
mPersist.SetValue(TW_UNMOUNT_SYSTEM, "1");
|
|
|
|
#ifdef TW_NO_SCREEN_TIMEOUT
|
|
mConst.SetValue("tw_screen_timeout_secs", "0");
|
|
mConst.SetValue("tw_no_screen_timeout", "1");
|
|
#else
|
|
mPersist.SetValue("tw_screen_timeout_secs", "60");
|
|
mPersist.SetValue("tw_no_screen_timeout", "0");
|
|
#endif
|
|
mData.SetValue("tw_gui_done", "0");
|
|
mData.SetValue("tw_encrypt_backup", "0");
|
|
mData.SetValue("tw_sleep_total", "5");
|
|
mData.SetValue("tw_sleep", "5");
|
|
|
|
// Brightness handling
|
|
string findbright;
|
|
#ifdef TW_BRIGHTNESS_PATH
|
|
findbright = EXPAND(TW_BRIGHTNESS_PATH);
|
|
LOGINFO("TW_BRIGHTNESS_PATH := %s\n", findbright.c_str());
|
|
if (!TWFunc::Path_Exists(findbright)) {
|
|
LOGINFO("Specified brightness file '%s' not found.\n", findbright.c_str());
|
|
findbright = "";
|
|
}
|
|
#endif
|
|
if (findbright.empty()) {
|
|
// Attempt to locate the brightness file
|
|
findbright = Find_File::Find("brightness", "/sys/class/backlight");
|
|
if (findbright.empty()) findbright = Find_File::Find("brightness", "/sys/class/leds/lcd-backlight");
|
|
}
|
|
if (findbright.empty()) {
|
|
LOGINFO("Unable to locate brightness file\n");
|
|
mConst.SetValue("tw_has_brightnesss_file", "0");
|
|
} else {
|
|
LOGINFO("Found brightness file at '%s'\n", findbright.c_str());
|
|
mConst.SetValue("tw_has_brightnesss_file", "1");
|
|
mConst.SetValue("tw_brightness_file", findbright);
|
|
string maxBrightness;
|
|
#ifdef TW_MAX_BRIGHTNESS
|
|
ostringstream maxVal;
|
|
maxVal << TW_MAX_BRIGHTNESS;
|
|
maxBrightness = maxVal.str();
|
|
#else
|
|
// Attempt to locate the max_brightness file
|
|
string maxbrightpath = findbright.insert(findbright.rfind('/') + 1, "max_");
|
|
if (TWFunc::Path_Exists(maxbrightpath)) {
|
|
ifstream maxVal(maxbrightpath.c_str());
|
|
if (maxVal >> maxBrightness) {
|
|
LOGINFO("Got max brightness %s from '%s'\n", maxBrightness.c_str(), maxbrightpath.c_str());
|
|
} else {
|
|
// Something went wrong, set that to indicate error
|
|
maxBrightness = "-1";
|
|
}
|
|
}
|
|
if (atoi(maxBrightness.c_str()) <= 0)
|
|
{
|
|
// Fallback into default
|
|
ostringstream maxVal;
|
|
maxVal << 255;
|
|
maxBrightness = maxVal.str();
|
|
}
|
|
#endif
|
|
mConst.SetValue("tw_brightness_max", maxBrightness);
|
|
mPersist.SetValue("tw_brightness", maxBrightness);
|
|
mPersist.SetValue("tw_brightness_pct", "100");
|
|
#ifdef TW_SECONDARY_BRIGHTNESS_PATH
|
|
string secondfindbright = EXPAND(TW_SECONDARY_BRIGHTNESS_PATH);
|
|
if (secondfindbright != "" && TWFunc::Path_Exists(secondfindbright)) {
|
|
LOGINFO("Will use a second brightness file at '%s'\n", secondfindbright.c_str());
|
|
mConst.SetValue("tw_secondary_brightness_file", secondfindbright);
|
|
} else {
|
|
LOGINFO("Specified secondary brightness file '%s' not found.\n", secondfindbright.c_str());
|
|
}
|
|
#endif
|
|
#ifdef TW_DEFAULT_BRIGHTNESS
|
|
int defValInt = TW_DEFAULT_BRIGHTNESS;
|
|
int maxValInt = atoi(maxBrightness.c_str());
|
|
// Deliberately int so the % is always a whole number
|
|
int defPctInt = ( ( (double)defValInt / maxValInt ) * 100 );
|
|
ostringstream defPct;
|
|
defPct << defPctInt;
|
|
mPersist.SetValue("tw_brightness_pct", defPct.str());
|
|
|
|
ostringstream defVal;
|
|
defVal << TW_DEFAULT_BRIGHTNESS;
|
|
mPersist.SetValue("tw_brightness", defVal.str());
|
|
TWFunc::Set_Brightness(defVal.str());
|
|
#else
|
|
TWFunc::Set_Brightness(maxBrightness);
|
|
#endif
|
|
}
|
|
|
|
#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
|
|
mConst.SetValue("tw_include_encrypted_backup", "1");
|
|
#else
|
|
LOGINFO("TW_EXCLUDE_ENCRYPTED_BACKUPS := true\n");
|
|
mConst.SetValue("tw_include_encrypted_backup", "0");
|
|
#endif
|
|
#ifdef TW_HAS_MTP
|
|
mConst.SetValue("tw_has_mtp", "1");
|
|
mPersist.SetValue("tw_mtp_enabled", "1");
|
|
mPersist.SetValue("tw_mtp_debug", "0");
|
|
#else
|
|
LOGINFO("TW_EXCLUDE_MTP := true\n");
|
|
mConst.SetValue("tw_has_mtp", "0");
|
|
mConst.SetValue("tw_mtp_enabled", "0");
|
|
#endif
|
|
mPersist.SetValue("tw_mount_system_ro", "2");
|
|
mPersist.SetValue("tw_never_show_system_ro_page", "0");
|
|
mPersist.SetValue("tw_language", EXPAND(TW_DEFAULT_LANGUAGE));
|
|
LOGINFO("LANG: %s\n", EXPAND(TW_DEFAULT_LANGUAGE));
|
|
|
|
mData.SetValue("tw_has_adopted_storage", "0");
|
|
|
|
#ifdef AB_OTA_UPDATER
|
|
LOGINFO("AB_OTA_UPDATER := true\n");
|
|
mConst.SetValue("tw_has_boot_slots", "1");
|
|
#else
|
|
mConst.SetValue("tw_has_boot_slots", "0");
|
|
#endif
|
|
|
|
#ifdef TW_NO_LEGACY_PROPS
|
|
LOGINFO("TW_NO_LEGACY_PROPS := true\n");
|
|
#endif
|
|
|
|
#ifdef TW_OEM_BUILD
|
|
LOGINFO("TW_OEM_BUILD := true\n");
|
|
mConst.SetValue("tw_oem_build", "1");
|
|
mConst.SetValue("tw_app_installed_in_system", "0");
|
|
#else
|
|
mConst.SetValue("tw_oem_build", "0");
|
|
mPersist.SetValue("tw_app_prompt", "1");
|
|
mPersist.SetValue("tw_app_install_system", "1");
|
|
mData.SetValue("tw_app_install_status", "0"); // 0 = no status, 1 = not installed, 2 = already installed
|
|
mData.SetValue("tw_app_installed_in_system", "0");
|
|
#endif
|
|
|
|
mData.SetValue("tw_enable_adb_backup", "0");
|
|
|
|
if (TWFunc::Path_Exists("/system/bin/magiskboot"))
|
|
mConst.SetValue("tw_has_repack_tools", "1");
|
|
else
|
|
mConst.SetValue("tw_has_repack_tools", "0");
|
|
|
|
pthread_mutex_unlock(&m_valuesLock);
|
|
}
|
|
|
|
// Magic Values
|
|
int DataManager::GetMagicValue(const string& varName, string& value)
|
|
{
|
|
// Handle special dynamic cases
|
|
if (varName == "tw_time")
|
|
{
|
|
char tmp[32];
|
|
|
|
struct tm *current;
|
|
time_t now;
|
|
int tw_military_time;
|
|
now = time(0);
|
|
current = localtime(&now);
|
|
GetValue(TW_MILITARY_TIME, tw_military_time);
|
|
if (current->tm_hour >= 12)
|
|
{
|
|
if (tw_military_time == 1)
|
|
sprintf(tmp, "%d:%02d", current->tm_hour, current->tm_min);
|
|
else
|
|
sprintf(tmp, "%d:%02d PM", current->tm_hour == 12 ? 12 : current->tm_hour - 12, current->tm_min);
|
|
}
|
|
else
|
|
{
|
|
if (tw_military_time == 1)
|
|
sprintf(tmp, "%d:%02d", current->tm_hour, current->tm_min);
|
|
else
|
|
sprintf(tmp, "%d:%02d AM", current->tm_hour == 0 ? 12 : current->tm_hour, current->tm_min);
|
|
}
|
|
value = tmp;
|
|
return 0;
|
|
}
|
|
else if (varName == "tw_cpu_temp")
|
|
{
|
|
int tw_no_cpu_temp;
|
|
GetValue("tw_no_cpu_temp", tw_no_cpu_temp);
|
|
if (tw_no_cpu_temp == 1) return -1;
|
|
|
|
string cpu_temp_file;
|
|
static unsigned long convert_temp = 0;
|
|
static time_t cpuSecCheck = 0;
|
|
struct timeval curTime;
|
|
string results;
|
|
|
|
gettimeofday(&curTime, NULL);
|
|
if (curTime.tv_sec > cpuSecCheck)
|
|
{
|
|
#ifdef TW_CUSTOM_CPU_TEMP_PATH
|
|
cpu_temp_file = EXPAND(TW_CUSTOM_CPU_TEMP_PATH);
|
|
if (TWFunc::read_file(cpu_temp_file, results) != 0)
|
|
return -1;
|
|
#else
|
|
cpu_temp_file = "/sys/class/thermal/thermal_zone0/temp";
|
|
if (TWFunc::read_file(cpu_temp_file, results) != 0)
|
|
return -1;
|
|
#endif
|
|
convert_temp = strtoul(results.c_str(), NULL, 0) / 1000;
|
|
if (convert_temp <= 0)
|
|
convert_temp = strtoul(results.c_str(), NULL, 0);
|
|
if (convert_temp >= 150)
|
|
convert_temp = strtoul(results.c_str(), NULL, 0) / 10;
|
|
cpuSecCheck = curTime.tv_sec + 5;
|
|
}
|
|
value = TWFunc::to_string(convert_temp);
|
|
return 0;
|
|
}
|
|
else if (varName == "tw_battery")
|
|
{
|
|
char tmp[16];
|
|
static char charging = ' ';
|
|
static int lastVal = -1;
|
|
static time_t nextSecCheck = 0;
|
|
struct timeval curTime;
|
|
gettimeofday(&curTime, NULL);
|
|
if (curTime.tv_sec > nextSecCheck)
|
|
{
|
|
char cap_s[4];
|
|
#ifdef TW_CUSTOM_BATTERY_PATH
|
|
string capacity_file = EXPAND(TW_CUSTOM_BATTERY_PATH);
|
|
capacity_file += "/capacity";
|
|
FILE * cap = fopen(capacity_file.c_str(),"rt");
|
|
#else
|
|
FILE * cap = fopen("/sys/class/power_supply/battery/capacity","rt");
|
|
#endif
|
|
if (cap) {
|
|
fgets(cap_s, 4, cap);
|
|
fclose(cap);
|
|
lastVal = atoi(cap_s);
|
|
if (lastVal > 100) lastVal = 101;
|
|
if (lastVal < 0) lastVal = 0;
|
|
}
|
|
#ifdef TW_CUSTOM_BATTERY_PATH
|
|
string status_file = EXPAND(TW_CUSTOM_BATTERY_PATH);
|
|
status_file += "/status";
|
|
cap = fopen(status_file.c_str(),"rt");
|
|
#else
|
|
cap = fopen("/sys/class/power_supply/battery/status","rt");
|
|
#endif
|
|
if (cap) {
|
|
fgets(cap_s, 2, cap);
|
|
fclose(cap);
|
|
if (cap_s[0] == 'C')
|
|
charging = '+';
|
|
else
|
|
charging = ' ';
|
|
}
|
|
nextSecCheck = curTime.tv_sec + 60;
|
|
}
|
|
|
|
sprintf(tmp, "%i%%%c", lastVal, charging);
|
|
value = tmp;
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void DataManager::Output_Version(void)
|
|
{
|
|
#ifndef TW_OEM_BUILD
|
|
string Path;
|
|
char version[255];
|
|
|
|
std::string logDir = TWFunc::get_log_dir();
|
|
if (logDir.empty()) {
|
|
LOGINFO("Unable to find cache directory\n");
|
|
return;
|
|
}
|
|
|
|
std::string recoveryLogDir = logDir + "recovery/";
|
|
|
|
if (logDir == CACHE_LOGS_DIR) {
|
|
if (!PartitionManager.Mount_By_Path(CACHE_LOGS_DIR, false)) {
|
|
LOGINFO("Unable to mount '%s' to write version number.\n", Path.c_str());
|
|
return;
|
|
}
|
|
|
|
if (!TWFunc::Path_Exists(recoveryLogDir)) {
|
|
LOGINFO("Recreating %s folder.\n", recoveryLogDir.c_str());
|
|
if (!TWFunc::Create_Dir_Recursive(recoveryLogDir.c_str(), S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP, 0, 0)) {
|
|
LOGERR("DataManager::Output_Version -- Unable to make %s: %s\n", recoveryLogDir.c_str(), strerror(errno));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string verPath = recoveryLogDir + ".version";
|
|
if (TWFunc::Path_Exists(verPath)) {
|
|
unlink(verPath.c_str());
|
|
}
|
|
FILE *fp = fopen(verPath.c_str(), "w");
|
|
if (fp == NULL) {
|
|
gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(verPath)(strerror(errno)));
|
|
return;
|
|
}
|
|
strcpy(version, TW_VERSION_STR);
|
|
fwrite(version, sizeof(version[0]), strlen(version) / sizeof(version[0]), fp);
|
|
fclose(fp);
|
|
TWFunc::copy_file("/etc/recovery.fstab", recoveryLogDir + "recovery.fstab", 0644);
|
|
PartitionManager.Output_Storage_Fstab();
|
|
sync();
|
|
LOGINFO("Version number saved to '%s'\n", verPath.c_str());
|
|
#endif
|
|
}
|
|
|
|
void DataManager::ReadSettingsFile(void)
|
|
{
|
|
#ifndef TW_OEM_BUILD
|
|
// Load up the values for TWRP - Sleep to let the card be ready
|
|
char mkdir_path[255], settings_file[255];
|
|
int is_enc, has_data_media;
|
|
|
|
GetValue(TW_IS_ENCRYPTED, is_enc);
|
|
GetValue(TW_HAS_DATA_MEDIA, has_data_media);
|
|
|
|
memset(mkdir_path, 0, sizeof(mkdir_path));
|
|
memset(settings_file, 0, sizeof(settings_file));
|
|
sprintf(mkdir_path, "%s/TWRP", GetSettingsStoragePath().c_str());
|
|
sprintf(settings_file, "%s/.twrps", mkdir_path);
|
|
|
|
if (!PartitionManager.Mount_Settings_Storage(false))
|
|
{
|
|
usleep(500000);
|
|
if (!PartitionManager.Mount_Settings_Storage(false))
|
|
gui_msg(Msg(msg::kError, "unable_to_mount=Unable to mount {1}")(settings_file));
|
|
}
|
|
|
|
mkdir(mkdir_path, 0777);
|
|
|
|
LOGINFO("Attempt to load settings from settings file...\n");
|
|
LoadValues(settings_file);
|
|
Output_Version();
|
|
#endif // ifdef TW_OEM_BUILD
|
|
PartitionManager.Mount_All_Storage();
|
|
update_tz_environment_variables();
|
|
TWFunc::Set_Brightness(GetStrValue("tw_brightness"));
|
|
}
|
|
|
|
string DataManager::GetCurrentStoragePath(void)
|
|
{
|
|
return GetStrValue("tw_storage_path");
|
|
}
|
|
|
|
string DataManager::GetSettingsStoragePath(void)
|
|
{
|
|
return GetStrValue("tw_settings_path");
|
|
}
|
|
|
|
void DataManager::Vibrate(const string& varName)
|
|
{
|
|
#ifndef TW_NO_HAPTICS
|
|
int vib_value = 0;
|
|
GetValue(varName, vib_value);
|
|
if (vib_value) {
|
|
vibrate(vib_value);
|
|
}
|
|
#endif
|
|
}
|