blob: 0cf2ccea681a8f04d4bc6a24c3ba2d69351c3177 [file] [log] [blame]
Matt Mowere04eee72016-12-31 00:38:57 -06001/*
2 Copyright 2017 TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
that20fb95d2015-09-12 11:27:47 +020019// object.cpp - GUIObject base class
Dees_Troy51a0e822012-09-05 15:24:24 -040020
Dees_Troy51a0e822012-09-05 15:24:24 -040021#include <stdio.h>
22#include <stdlib.h>
Ethan Yonker3fdcda42016-11-30 12:29:37 -060023#include <sys/stat.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040024#include <string>
25
26extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000027#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040028#include "../variables.h"
29}
30
31#include "rapidxml.hpp"
32#include "objects.hpp"
33#include "../data.hpp"
34
Vojtech Bocekede51c52014-02-07 23:58:09 +010035GUIObject::GUIObject(xml_node<>* node)
Dees_Troy51a0e822012-09-05 15:24:24 -040036{
Vojtech Bocek07220562014-02-08 02:05:33 +010037 mConditionsResult = true;
that20fb95d2015-09-12 11:27:47 +020038 if (node)
39 LoadConditions(node, mConditions);
40}
Vojtech Bocek07220562014-02-08 02:05:33 +010041
that20fb95d2015-09-12 11:27:47 +020042void GUIObject::LoadConditions(xml_node<>* node, std::vector<Condition>& conditions)
43{
Ethan Yonker21ff02a2015-02-18 14:35:00 -060044 xml_node<>* condition = FindNode(node, "conditions");
45 if (condition) condition = FindNode(condition, "condition");
46 else condition = FindNode(node, "condition");
Dees_Troy51a0e822012-09-05 15:24:24 -040047
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020048 while (condition)
49 {
50 Condition cond;
Dees_Troy51a0e822012-09-05 15:24:24 -040051
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020052 cond.mCompareOp = "=";
Dees_Troy51a0e822012-09-05 15:24:24 -040053
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020054 xml_attribute<>* attr;
55 attr = condition->first_attribute("var1");
56 if (attr) cond.mVar1 = attr->value();
Dees_Troy51a0e822012-09-05 15:24:24 -040057
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020058 attr = condition->first_attribute("op");
59 if (attr) cond.mCompareOp = attr->value();
Dees_Troy51a0e822012-09-05 15:24:24 -040060
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020061 attr = condition->first_attribute("var2");
62 if (attr) cond.mVar2 = attr->value();
Matt Mowerfb1c4ff2014-04-16 13:43:36 -050063
that20fb95d2015-09-12 11:27:47 +020064 conditions.push_back(cond);
Dees_Troy51a0e822012-09-05 15:24:24 -040065
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020066 condition = condition->next_sibling("condition");
67 }
Dees_Troy51a0e822012-09-05 15:24:24 -040068}
69
Vojtech Bocekede51c52014-02-07 23:58:09 +010070GUIObject::~GUIObject()
71{
72}
73
74bool GUIObject::IsConditionVariable(std::string var)
Dees_Troy51a0e822012-09-05 15:24:24 -040075{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020076 std::vector<Condition>::iterator iter;
77 for (iter = mConditions.begin(); iter != mConditions.end(); iter++)
78 {
79 if (iter->mVar1 == var)
80 return true;
81 }
82 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -040083}
84
Vojtech Bocekede51c52014-02-07 23:58:09 +010085bool GUIObject::isConditionTrue()
Dees_Troy51a0e822012-09-05 15:24:24 -040086{
Vojtech Bocek07220562014-02-08 02:05:33 +010087 return mConditionsResult;
Dees_Troy51a0e822012-09-05 15:24:24 -040088}
89
Vojtech Bocekede51c52014-02-07 23:58:09 +010090bool GUIObject::isConditionTrue(Condition* condition)
Dees_Troy51a0e822012-09-05 15:24:24 -040091{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020092 // This is used to hold the proper value of "true" based on the '!' NOT flag
93 bool bTrue = true;
Dees_Troy51a0e822012-09-05 15:24:24 -040094
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020095 if (condition->mVar1.empty())
96 return bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -040097
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020098 if (!condition->mCompareOp.empty() && condition->mCompareOp[0] == '!')
99 bTrue = false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400100
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200101 if (condition->mVar2.empty() && condition->mCompareOp != "modified")
102 {
103 if (!DataManager::GetStrValue(condition->mVar1).empty())
104 return bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -0400105
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200106 return !bTrue;
107 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400108
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200109 string var1, var2;
110 if (DataManager::GetValue(condition->mVar1, var1))
111 var1 = condition->mVar1;
112 if (DataManager::GetValue(condition->mVar2, var2))
113 var2 = condition->mVar2;
Dees_Troy51a0e822012-09-05 15:24:24 -0400114
that675ddae2016-02-02 22:12:50 +0100115 if (var2.substr(0, 2) == "{@")
116 // translate resource string in value
117 var2 = gui_parse_text(var2);
118
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200119 // This is a special case, we stat the file and that determines our result
120 if (var1 == "fileexists")
121 {
122 struct stat st;
123 if (stat(var2.c_str(), &st) == 0)
124 var2 = var1;
125 else
126 var2 = "FAILED";
127 }
128 if (var1 == "mounted")
129 {
130 if (isMounted(condition->mVar2))
131 var2 = var1;
132 else
133 var2 = "FAILED";
134 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400135
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200136 if (condition->mCompareOp.find('=') != string::npos && var1 == var2)
137 return bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -0400138
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200139 if (condition->mCompareOp.find('>') != string::npos && (atof(var1.c_str()) > atof(var2.c_str())))
140 return bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -0400141
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200142 if (condition->mCompareOp.find('<') != string::npos && (atof(var1.c_str()) < atof(var2.c_str())))
143 return bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -0400144
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200145 if (condition->mCompareOp == "modified")
146 {
147 // This is a hack to allow areas to reset the default value
148 if (var1.empty())
149 {
150 condition->mLastVal = var1;
151 return !bTrue;
152 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400153
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200154 if (var1 != condition->mLastVal)
155 return bTrue;
156 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400157
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200158 return !bTrue;
Dees_Troy51a0e822012-09-05 15:24:24 -0400159}
160
Vojtech Bocekede51c52014-02-07 23:58:09 +0100161bool GUIObject::isConditionValid()
Dees_Troy51a0e822012-09-05 15:24:24 -0400162{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200163 return !mConditions.empty();
Dees_Troy51a0e822012-09-05 15:24:24 -0400164}
165
Ethan Yonkerd0514ba2015-10-22 14:17:47 -0500166int GUIObject::NotifyVarChange(const std::string& varName, const std::string& value __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400167{
that20fb95d2015-09-12 11:27:47 +0200168 mConditionsResult = UpdateConditions(mConditions, varName);
169 return 0;
170}
171
172bool GUIObject::UpdateConditions(std::vector<Condition>& conditions, const std::string& varName)
173{
174 bool result = true;
Vojtech Bocek07220562014-02-08 02:05:33 +0100175
176 const bool varNameEmpty = varName.empty();
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200177 std::vector<Condition>::iterator iter;
that20fb95d2015-09-12 11:27:47 +0200178 for (iter = conditions.begin(); iter != conditions.end(); ++iter)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200179 {
Matt Mowera8a89d12016-12-30 18:10:37 -0600180 if (varNameEmpty && iter->mCompareOp == "modified")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200181 {
182 string val;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500183
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200184 // If this fails, val will not be set, which is perfect
185 if (DataManager::GetValue(iter->mVar1, val))
186 {
187 DataManager::SetValue(iter->mVar1, "");
188 DataManager::GetValue(iter->mVar1, val);
189 }
190 iter->mLastVal = val;
191 }
Vojtech Bocek07220562014-02-08 02:05:33 +0100192
Matt Mowera8a89d12016-12-30 18:10:37 -0600193 if (varNameEmpty || iter->mVar1 == varName || iter->mVar2 == varName)
Vojtech Bocek07220562014-02-08 02:05:33 +0100194 iter->mLastResult = isConditionTrue(&(*iter));
195
Matt Mowera8a89d12016-12-30 18:10:37 -0600196 if (!iter->mLastResult)
that20fb95d2015-09-12 11:27:47 +0200197 result = false;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200198 }
that20fb95d2015-09-12 11:27:47 +0200199 return result;
Dees_Troy51a0e822012-09-05 15:24:24 -0400200}
201
Vojtech Bocekede51c52014-02-07 23:58:09 +0100202bool GUIObject::isMounted(string vol)
Dees_Troy51a0e822012-09-05 15:24:24 -0400203{
204 FILE *fp;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 char tmpOutput[255];
Dees_Troy51a0e822012-09-05 15:24:24 -0400206
Dees_Troy51a0e822012-09-05 15:24:24 -0400207 fp = fopen("/proc/mounts", "rt");
208 while (fgets(tmpOutput,255,fp) != NULL)
209 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200210 char* mnt = tmpOutput;
211 while (*mnt > 32) mnt++;
212 while (*mnt > 0 && *mnt <= 32) mnt++;
213 char* pos = mnt;
214 while (*pos > 32) pos++;
215 *pos = 0;
216 if (vol == mnt)
217 {
218 fclose(fp);
219 return true;
220 }
221 }
222 fclose(fp);
223 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400224}