blob: 612e9902683f034f23b75bf3ca0805b12ca18d8b [file] [log] [blame]
jrior001aad03112014-07-05 10:31:21 -04001/*update
Dees_Troya13d74f2013-03-24 08:54:55 -05002 Copyright 2013 bigbiff/Dees_Troy 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*/
Dees_Troy51a0e822012-09-05 15:24:24 -040018
19#include <stdarg.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <sys/time.h>
26#include <sys/mman.h>
27#include <sys/types.h>
28#include <sys/ioctl.h>
29#include <linux/input.h>
30#include <time.h>
31#include <unistd.h>
32#include <stdlib.h>
Dees_Troy657c3092012-09-10 20:32:10 -040033#include <sys/wait.h>
Dees_Troy83bd4832013-05-04 12:39:56 +000034#include <dirent.h>
Vojtech Bocek03fd6c52014-03-13 18:46:34 +010035#include <pwd.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040036
37#include <string>
38#include <sstream>
39#include "../partitions.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040040#include "../twrp-functions.hpp"
Dees_Troy812660f2012-09-20 09:55:17 -040041#include "../openrecoveryscript.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040042
Dees_Troy43d8b002012-09-17 16:00:01 -040043#include "../adb_install.h"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070044#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050045#include "blanktimer.hpp"
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070046#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040047extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000048#include "../twcommon.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040049#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040050#include "../variables.h"
Dees_Troy32c8eb82012-09-11 15:28:06 -040051#include "../twinstall.h"
Dees_Troy2673cec2013-04-02 20:22:16 +000052#include "cutils/properties.h"
Dees_Troy43d8b002012-09-17 16:00:01 -040053#include "../minadbd/adb.h"
54
Dees_Troy32c8eb82012-09-11 15:28:06 -040055int TWinstall_zip(const char* path, int* wipe_cache);
Dees_Troy51a0e822012-09-05 15:24:24 -040056void run_script(const char *str1, const char *str2, const char *str3, const char *str4, const char *str5, const char *str6, const char *str7, int request_confirm);
Dees_Troy51a0e822012-09-05 15:24:24 -040057int gui_console_only();
Dees_Troy51a0e822012-09-05 15:24:24 -040058int gui_start();
59};
60
61#include "rapidxml.hpp"
62#include "objects.hpp"
63
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070064#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -050065extern blanktimer blankTimer;
Ricardo Gomezc9ecd442013-07-05 16:13:52 -070066#endif
Dees_Troy43d8b002012-09-17 16:00:01 -040067
Dees_Troy51a0e822012-09-05 15:24:24 -040068void curtainClose(void);
69
70GUIAction::GUIAction(xml_node<>* node)
Vojtech Bocekede51c52014-02-07 23:58:09 +010071 : GUIObject(node)
Dees_Troy51a0e822012-09-05 15:24:24 -040072{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020073 xml_node<>* child;
74 xml_node<>* actions;
75 xml_attribute<>* attr;
Dees_Troy51a0e822012-09-05 15:24:24 -040076
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020077 if (!node) return;
Dees_Troy51a0e822012-09-05 15:24:24 -040078
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020079 // First, get the action
80 actions = node->first_node("actions");
81 if (actions) child = actions->first_node("action");
82 else child = node->first_node("action");
Dees_Troy51a0e822012-09-05 15:24:24 -040083
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020084 if (!child) return;
Dees_Troy51a0e822012-09-05 15:24:24 -040085
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020086 while (child)
87 {
88 Action action;
Dees_Troy51a0e822012-09-05 15:24:24 -040089
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020090 attr = child->first_attribute("function");
91 if (!attr) return;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -050092
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020093 action.mFunction = attr->value();
94 action.mArg = child->value();
95 mActions.push_back(action);
Dees_Troy51a0e822012-09-05 15:24:24 -040096
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020097 child = child->next_sibling("action");
98 }
Dees_Troy51a0e822012-09-05 15:24:24 -040099
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200100 // Now, let's get either the key or region
101 child = node->first_node("touch");
102 if (child)
103 {
104 attr = child->first_attribute("key");
105 if (attr)
106 {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100107 std::vector<std::string> keys = TWFunc::Split_String(attr->value(), "+");
108 for(size_t i = 0; i < keys.size(); ++i)
109 {
110 const int key = getKeyByName(keys[i]);
111 mKeys[key] = false;
112 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200113 }
114 else
115 {
116 attr = child->first_attribute("x");
117 if (!attr) return;
118 mActionX = atol(attr->value());
119 attr = child->first_attribute("y");
120 if (!attr) return;
121 mActionY = atol(attr->value());
122 attr = child->first_attribute("w");
123 if (!attr) return;
124 mActionW = atol(attr->value());
125 attr = child->first_attribute("h");
126 if (!attr) return;
127 mActionH = atol(attr->value());
128 }
129 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400130}
131
132int GUIAction::NotifyTouch(TOUCH_STATE state, int x, int y)
133{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200134 if (state == TOUCH_RELEASE)
135 doActions();
Dees_Troy51a0e822012-09-05 15:24:24 -0400136
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200137 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400138}
139
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100140int GUIAction::NotifyKey(int key, bool down)
Dees_Troy51a0e822012-09-05 15:24:24 -0400141{
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100142 if (mKeys.empty())
143 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400144
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100145 std::map<int, bool>::iterator itr = mKeys.find(key);
146 if(itr == mKeys.end())
147 return 0;
148
149 bool prevState = itr->second;
150 itr->second = down;
151
152 // If there is only one key for this action, wait for key up so it
153 // doesn't trigger with multi-key actions.
154 // Else, check if all buttons are pressed, then consume their release events
155 // so they don't trigger one-button actions and reset mKeys pressed status
156 if(mKeys.size() == 1) {
157 if(!down && prevState)
158 doActions();
159 } else if(down) {
160 for(itr = mKeys.begin(); itr != mKeys.end(); ++itr) {
161 if(!itr->second)
162 return 0;
163 }
164
165 // Passed, all req buttons are pressed, reset them and consume release events
166 HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
167 for(itr = mKeys.begin(); itr != mKeys.end(); ++itr) {
168 kb->ConsumeKeyRelease(itr->first);
169 itr->second = false;
170 }
171
172 doActions();
173 }
174
Dees_Troy51a0e822012-09-05 15:24:24 -0400175 return 0;
176}
177
Vojtech Bocek07220562014-02-08 02:05:33 +0100178int GUIAction::NotifyVarChange(const std::string& varName, const std::string& value)
Dees_Troy51a0e822012-09-05 15:24:24 -0400179{
Vojtech Bocek07220562014-02-08 02:05:33 +0100180 GUIObject::NotifyVarChange(varName, value);
181
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100182 if (varName.empty() && !isConditionValid() && mKeys.empty() && !mActionW)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200183 doActions();
Vojtech Bocek07220562014-02-08 02:05:33 +0100184 else if((varName.empty() || IsConditionVariable(varName)) && isConditionValid() && isConditionTrue())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200185 doActions();
Dees_Troy51a0e822012-09-05 15:24:24 -0400186
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200187 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400188}
189
190void GUIAction::simulate_progress_bar(void)
191{
Dees_Troy2673cec2013-04-02 20:22:16 +0000192 gui_print("Simulating actions...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400193 for (int i = 0; i < 5; i++)
194 {
195 usleep(500000);
196 DataManager::SetValue("ui_progress", i * 20);
197 }
198}
199
Dees_Troy657c3092012-09-10 20:32:10 -0400200int GUIAction::flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache)
Dees_Troy51a0e822012-09-05 15:24:24 -0400201{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 int ret_val = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400203
204 DataManager::SetValue("ui_progress", 0);
205
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200206 if (filename.empty())
207 {
208 LOGERR("No file specified.\n");
209 return -1;
210 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400211
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200212 // We're going to jump to this page first, like a loading page
213 gui_changePage(pageName);
Dees_Troy51a0e822012-09-05 15:24:24 -0400214
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200215 int fd = -1;
216 ZipArchive zip;
Dees_Troy51a0e822012-09-05 15:24:24 -0400217
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200218 if (!PartitionManager.Mount_By_Path(filename, true))
Dees_Troy657c3092012-09-10 20:32:10 -0400219 return -1;
220
Ethan Yonker57e35872014-11-07 14:52:22 -0600221 gui_changePage(pageName);
Dees_Troy51a0e822012-09-05 15:24:24 -0400222
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 if (fd >= 0)
224 close(fd);
Dees_Troy51a0e822012-09-05 15:24:24 -0400225
226 if (simulate) {
227 simulate_progress_bar();
228 } else {
Dees_Troy657c3092012-09-10 20:32:10 -0400229 ret_val = TWinstall_zip(filename.c_str(), wipe_cache);
Dees_Troy51a0e822012-09-05 15:24:24 -0400230
231 // Now, check if we need to ensure TWRP remains installed...
232 struct stat st;
233 if (stat("/sbin/installTwrp", &st) == 0)
234 {
235 DataManager::SetValue("tw_operation", "Configuring TWRP");
236 DataManager::SetValue("tw_partition", "");
Dees_Troy2673cec2013-04-02 20:22:16 +0000237 gui_print("Configuring TWRP...\n");
Vojtech Bocek05534202013-09-11 08:11:56 +0200238 if (TWFunc::Exec_Cmd("/sbin/installTwrp reinstall") < 0)
Dees_Troy51a0e822012-09-05 15:24:24 -0400239 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000240 gui_print("Unable to configure TWRP with this kernel.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400241 }
242 }
243 }
244
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 // Done
246 DataManager::SetValue("ui_progress", 100);
247 DataManager::SetValue("ui_progress", 0);
248 return ret_val;
Dees_Troy51a0e822012-09-05 15:24:24 -0400249}
250
251int GUIAction::doActions()
252{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200253 if (mActions.size() < 1) return -1;
254 if (mActions.size() == 1)
Dees_Troy51a0e822012-09-05 15:24:24 -0400255 return doAction(mActions.at(0), 0);
256
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200257 // For multi-action, we always use a thread
258 pthread_t t;
Dees_Troyab4963c2013-01-16 20:35:51 +0000259 pthread_attr_t tattr;
260
261 if (pthread_attr_init(&tattr)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000262 LOGERR("Unable to pthread_attr_init\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000263 return -1;
264 }
265 if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000266 LOGERR("Error setting pthread_attr_setdetachstate\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000267 return -1;
268 }
269 if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000270 LOGERR("Error setting pthread_attr_setscope\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000271 return -1;
272 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500273 /*if (pthread_attr_setstacksize(&tattr, 524288)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000274 LOGERR("Error setting pthread_attr_setstacksize\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000275 return -1;
276 }
bigbiff bigbiff3bf2b0e2013-01-21 21:26:43 -0500277 */
Dees_Troyab4963c2013-01-16 20:35:51 +0000278 int ret = pthread_create(&t, &tattr, thread_start, this);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200279 if (ret) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000280 LOGERR("Unable to create more threads for actions... continuing in same thread! %i\n", ret);
Dees_Troyab4963c2013-01-16 20:35:51 +0000281 thread_start(this);
282 } else {
283 if (pthread_join(t, NULL)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000284 LOGERR("Error joining threads\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000285 }
286 }
287 if (pthread_attr_destroy(&tattr)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000288 LOGERR("Failed to pthread_attr_destroy\n");
Dees_Troyab4963c2013-01-16 20:35:51 +0000289 return -1;
290 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400291
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200292 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400293}
294
295void* GUIAction::thread_start(void *cookie)
296{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200297 GUIAction* ourThis = (GUIAction*) cookie;
Dees_Troy51a0e822012-09-05 15:24:24 -0400298
299 DataManager::SetValue(TW_ACTION_BUSY, 1);
300
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200301 if (ourThis->mActions.size() > 1)
302 {
303 std::vector<Action>::iterator iter;
304 for (iter = ourThis->mActions.begin(); iter != ourThis->mActions.end(); iter++)
305 ourThis->doAction(*iter, 1);
306 }
307 else
308 {
309 ourThis->doAction(ourThis->mActions.at(0), 1);
310 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400311 int check = 0;
312 DataManager::GetValue("tw_background_thread_running", check);
313 if (check == 0)
314 DataManager::SetValue(TW_ACTION_BUSY, 0);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200315 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400316}
317
318void GUIAction::operation_start(const string operation_name)
319{
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +0000320 time(&Start);
Dees_Troy51a0e822012-09-05 15:24:24 -0400321 DataManager::SetValue(TW_ACTION_BUSY, 1);
322 DataManager::SetValue("ui_progress", 0);
323 DataManager::SetValue("tw_operation", operation_name);
324 DataManager::SetValue("tw_operation_status", 0);
325 DataManager::SetValue("tw_operation_state", 0);
326}
327
328void GUIAction::operation_end(const int operation_status, const int simulate)
329{
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +0000330 time_t Stop;
Dees_Troy51a0e822012-09-05 15:24:24 -0400331 int simulate_fail;
Dees_Troy51a0e822012-09-05 15:24:24 -0400332 DataManager::SetValue("ui_progress", 100);
333 if (simulate) {
334 DataManager::GetValue(TW_SIMULATE_FAIL, simulate_fail);
335 if (simulate_fail != 0)
336 DataManager::SetValue("tw_operation_status", 1);
337 else
338 DataManager::SetValue("tw_operation_status", 0);
339 } else {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500340 if (operation_status != 0) {
Dees_Troy51a0e822012-09-05 15:24:24 -0400341 DataManager::SetValue("tw_operation_status", 1);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500342 }
343 else {
Dees_Troy51a0e822012-09-05 15:24:24 -0400344 DataManager::SetValue("tw_operation_status", 0);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500345 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400346 }
347 DataManager::SetValue("tw_operation_state", 1);
348 DataManager::SetValue(TW_ACTION_BUSY, 0);
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700349#ifndef TW_NO_SCREEN_TIMEOUT
bigbiff bigbiff8a68c312013-02-10 14:28:30 -0500350 blankTimer.resetTimerAndUnblank();
Ricardo Gomezc9ecd442013-07-05 16:13:52 -0700351#endif
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +0000352 time(&Stop);
353 if ((int) difftime(Stop, Start) > 10)
Ethan Yonker03db3262014-02-05 08:02:06 -0600354 DataManager::Vibrate("tw_action_vibrate");
Dees_Troy51a0e822012-09-05 15:24:24 -0400355}
356
357int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
358{
359 static string zip_queue[10];
360 static int zip_queue_index;
361 static pthread_t terminal_command;
362 int simulate;
363
364 std::string arg = gui_parse_text(action.mArg);
365
366 std::string function = gui_parse_text(action.mFunction);
367
368 DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);
369
Dees_Troy6ef66352013-02-21 08:26:57 -0600370 if (function == "reboot")
371 {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200372 //curtainClose(); this sometimes causes a crash
Dees_Troy51a0e822012-09-05 15:24:24 -0400373
Dees_Troy6ef66352013-02-21 08:26:57 -0600374 sync();
375 DataManager::SetValue("tw_gui_done", 1);
376 DataManager::SetValue("tw_reboot_arg", arg);
Dees_Troy51a0e822012-09-05 15:24:24 -0400377
Dees_Troy6ef66352013-02-21 08:26:57 -0600378 return 0;
379 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200380 if (function == "home")
381 {
382 PageManager::SelectPackage("TWRP");
383 gui_changePage("main");
384 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400385 }
386
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200387 if (function == "key")
388 {
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100389 const int key = getKeyByName(arg);
390 PageManager::NotifyKey(key, true);
391 PageManager::NotifyKey(key, false);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200392 return 0;
393 }
394
395 if (function == "page") {
396 std::string page_name = gui_parse_text(arg);
397 return gui_changePage(page_name);
398 }
399
400 if (function == "reload") {
Dees_Troy51a0e822012-09-05 15:24:24 -0400401 int check = 0, ret_val = 0;
402 std::string theme_path;
403
404 operation_start("Reload Theme");
405 theme_path = DataManager::GetSettingsStoragePath();
Dees_Troy5bf43922012-09-07 16:07:55 -0400406 if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000407 LOGERR("Unable to mount %s during reload function startup.\n", theme_path.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400408 check = 1;
409 }
410
411 theme_path += "/TWRP/theme/ui.zip";
412 if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0)
413 {
414 // Loading the custom theme failed - try loading the stock theme
Dees_Troy2673cec2013-04-02 20:22:16 +0000415 LOGINFO("Attempting to reload stock theme...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400416 if (PageManager::ReloadPackage("TWRP", "/res/ui.xml"))
417 {
Dees_Troy2673cec2013-04-02 20:22:16 +0000418 LOGERR("Failed to load base packages.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400419 ret_val = 1;
420 }
421 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200422 operation_end(ret_val, simulate);
Dees_Troy83bd4832013-05-04 12:39:56 +0000423 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400424 }
425
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200426 if (function == "readBackup")
427 {
Dees_Troy51a0e822012-09-05 15:24:24 -0400428 string Restore_Name;
429 DataManager::GetValue("tw_restore", Restore_Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400430 PartitionManager.Set_Restore_Files(Restore_Name);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200431 return 0;
432 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400433
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200434 if (function == "set")
435 {
436 if (arg.find('=') != string::npos)
437 {
438 string varName = arg.substr(0, arg.find('='));
439 string value = arg.substr(arg.find('=') + 1, string::npos);
Dees_Troy51a0e822012-09-05 15:24:24 -0400440
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200441 DataManager::GetValue(value, value);
442 DataManager::SetValue(varName, value);
443 }
444 else
445 DataManager::SetValue(arg, "1");
446 return 0;
447 }
448 if (function == "clear")
449 {
450 DataManager::SetValue(arg, "0");
451 return 0;
452 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400453
Ethan Yonker8214f0a2014-02-16 15:15:34 -0600454 if (function == "mount") {
455 if (arg == "usb") {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200456 DataManager::SetValue(TW_ACTION_BUSY, 1);
Dees_Troy51a0e822012-09-05 15:24:24 -0400457 if (!simulate)
Dees_Troy8170a922012-09-18 15:40:25 -0400458 PartitionManager.usb_storage_enable();
Dees_Troy51a0e822012-09-05 15:24:24 -0400459 else
Dees_Troy2673cec2013-04-02 20:22:16 +0000460 gui_print("Simulating actions...\n");
Ethan Yonker8214f0a2014-02-16 15:15:34 -0600461 } else if (!simulate) {
462 PartitionManager.Mount_By_Path(arg, true);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200463 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000464 gui_print("Simulating actions...\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200465 return 0;
466 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400467
Ethan Yonker8214f0a2014-02-16 15:15:34 -0600468 if (function == "umount" || function == "unmount") {
469 if (arg == "usb") {
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200470 if (!simulate)
Dees_Troy8170a922012-09-18 15:40:25 -0400471 PartitionManager.usb_storage_disable();
Dees_Troy51a0e822012-09-05 15:24:24 -0400472 else
Dees_Troy2673cec2013-04-02 20:22:16 +0000473 gui_print("Simulating actions...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400474 DataManager::SetValue(TW_ACTION_BUSY, 0);
Ethan Yonker8214f0a2014-02-16 15:15:34 -0600475 } else if (!simulate) {
476 PartitionManager.UnMount_By_Path(arg, true);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200477 } else
Dees_Troy2673cec2013-04-02 20:22:16 +0000478 gui_print("Simulating actions...\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200479 return 0;
480 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500481
Dees_Troy51a0e822012-09-05 15:24:24 -0400482 if (function == "restoredefaultsettings")
483 {
484 operation_start("Restore Defaults");
485 if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
Dees_Troy2673cec2013-04-02 20:22:16 +0000486 gui_print("Simulating actions...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400487 else {
488 DataManager::ResetDefaults();
Dees_Troy5bf43922012-09-07 16:07:55 -0400489 PartitionManager.Update_System_Details();
490 PartitionManager.Mount_Current_Storage(true);
Dees_Troy51a0e822012-09-05 15:24:24 -0400491 }
492 operation_end(0, simulate);
Dees_Troy83bd4832013-05-04 12:39:56 +0000493 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400494 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500495
Dees_Troy51a0e822012-09-05 15:24:24 -0400496 if (function == "copylog")
497 {
498 operation_start("Copy Log");
499 if (!simulate)
500 {
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500501 string dst;
Dees_Troy5bf43922012-09-07 16:07:55 -0400502 PartitionManager.Mount_Current_Storage(true);
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500503 dst = DataManager::GetCurrentStoragePath() + "/recovery.log";
504 TWFunc::copy_file("/tmp/recovery.log", dst.c_str(), 0755);
Dees_Troy51a0e822012-09-05 15:24:24 -0400505 sync();
Dees_Troy2673cec2013-04-02 20:22:16 +0000506 gui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400507 } else
508 simulate_progress_bar();
509 operation_end(0, simulate);
510 return 0;
511 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500512
Dees_Troy51a0e822012-09-05 15:24:24 -0400513 if (function == "compute" || function == "addsubtract")
514 {
515 if (arg.find("+") != string::npos)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200516 {
517 string varName = arg.substr(0, arg.find('+'));
518 string string_to_add = arg.substr(arg.find('+') + 1, string::npos);
Dees_Troy51a0e822012-09-05 15:24:24 -0400519 int amount_to_add = atoi(string_to_add.c_str());
520 int value;
521
522 DataManager::GetValue(varName, value);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200523 DataManager::SetValue(varName, value + amount_to_add);
Dees_Troy51a0e822012-09-05 15:24:24 -0400524 return 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200525 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400526 if (arg.find("-") != string::npos)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200527 {
528 string varName = arg.substr(0, arg.find('-'));
529 string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos);
Dees_Troy51a0e822012-09-05 15:24:24 -0400530 int amount_to_subtract = atoi(string_to_subtract.c_str());
531 int value;
532
533 DataManager::GetValue(varName, value);
534 value -= amount_to_subtract;
535 if (value <= 0)
536 value = 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200537 DataManager::SetValue(varName, value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400538 return 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200539 }
Vojtech Bocek85932342013-04-01 22:11:33 +0200540 if (arg.find("*") != string::npos)
541 {
542 string varName = arg.substr(0, arg.find('*'));
543 string multiply_by_str = gui_parse_text(arg.substr(arg.find('*') + 1, string::npos));
544 int multiply_by = atoi(multiply_by_str.c_str());
545 int value;
546
547 DataManager::GetValue(varName, value);
548 DataManager::SetValue(varName, value*multiply_by);
549 return 0;
550 }
551 if (arg.find("/") != string::npos)
552 {
553 string varName = arg.substr(0, arg.find('/'));
554 string divide_by_str = gui_parse_text(arg.substr(arg.find('/') + 1, string::npos));
555 int divide_by = atoi(divide_by_str.c_str());
556 int value;
557
558 if(divide_by != 0)
559 {
560 DataManager::GetValue(varName, value);
561 DataManager::SetValue(varName, value/divide_by);
562 }
563 return 0;
564 }
565 LOGERR("Unable to perform compute '%s'\n", arg.c_str());
566 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400567 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500568
Dees_Troy51a0e822012-09-05 15:24:24 -0400569 if (function == "setguitimezone")
570 {
571 string SelectedZone;
572 DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone
573 string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone
574 string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500575
Dees_Troy51a0e822012-09-05 15:24:24 -0400576 int dst;
577 DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500578
Dees_Troy51a0e822012-09-05 15:24:24 -0400579 string offset;
580 DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500581
Dees_Troy51a0e822012-09-05 15:24:24 -0400582 string NewTimeZone = Zone;
583 if (offset != "0")
584 NewTimeZone += ":" + offset;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500585
Dees_Troy51a0e822012-09-05 15:24:24 -0400586 if (dst != 0)
587 NewTimeZone += DSTZone;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500588
Dees_Troy51a0e822012-09-05 15:24:24 -0400589 DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone);
Dees_Troy8170a922012-09-18 15:40:25 -0400590 DataManager::update_tz_environment_variables();
Dees_Troy51a0e822012-09-05 15:24:24 -0400591 return 0;
592 }
593
594 if (function == "togglestorage") {
Dees Troyf193f882013-09-11 14:56:20 +0000595 LOGERR("togglestorage action was deprecated from TWRP\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400596 return 0;
597 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500598
Dees_Troy51a0e822012-09-05 15:24:24 -0400599 if (function == "overlay")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200600 return gui_changeOverlay(arg);
Dees_Troy51a0e822012-09-05 15:24:24 -0400601
602 if (function == "queuezip")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200603 {
604 if (zip_queue_index >= 10) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000605 gui_print("Maximum zip queue reached!\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400606 return 0;
607 }
608 DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]);
609 if (strlen(zip_queue[zip_queue_index].c_str()) > 0) {
610 zip_queue_index++;
611 DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
612 }
613 return 0;
614 }
615
616 if (function == "cancelzip")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200617 {
618 if (zip_queue_index <= 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000619 gui_print("Minimum zip queue reached!\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400620 return 0;
621 } else {
622 zip_queue_index--;
623 DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
624 }
625 return 0;
626 }
627
628 if (function == "queueclear")
629 {
630 zip_queue_index = 0;
631 DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
632 return 0;
633 }
634
635 if (function == "sleep")
636 {
637 operation_start("Sleep");
638 usleep(atoi(arg.c_str()));
639 operation_end(0, simulate);
640 return 0;
641 }
642
Dees Troyb21cc642013-09-10 17:36:41 +0000643 if (function == "appenddatetobackupname")
644 {
645 operation_start("AppendDateToBackupName");
646 string Backup_Name;
647 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
648 Backup_Name += TWFunc::Get_Current_Date();
649 if (Backup_Name.size() > MAX_BACKUP_NAME_LEN)
650 Backup_Name.resize(MAX_BACKUP_NAME_LEN);
651 DataManager::SetValue(TW_BACKUP_NAME, Backup_Name);
652 operation_end(0, simulate);
653 return 0;
654 }
655
656 if (function == "generatebackupname")
657 {
658 operation_start("GenerateBackupName");
659 TWFunc::Auto_Generate_Backup_Name();
660 operation_end(0, simulate);
661 return 0;
662 }
Ethan Yonker87c7bac2014-05-25 21:41:08 -0500663 if (function == "checkpartitionlist") {
664 string Wipe_List, wipe_path;
665 int count = 0;
666
667 DataManager::GetValue("tw_wipe_list", Wipe_List);
668 LOGINFO("checkpartitionlist list '%s'\n", Wipe_List.c_str());
669 if (!Wipe_List.empty()) {
670 size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
671 while (end_pos != string::npos && start_pos < Wipe_List.size()) {
672 wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
673 LOGINFO("checkpartitionlist wipe_path '%s'\n", wipe_path.c_str());
674 if (wipe_path == "/and-sec" || wipe_path == "DALVIK" || wipe_path == "INTERNAL") {
675 // Do nothing
676 } else {
677 count++;
678 }
679 start_pos = end_pos + 1;
680 end_pos = Wipe_List.find(";", start_pos);
681 }
682 DataManager::SetValue("tw_check_partition_list", count);
683 } else {
684 DataManager::SetValue("tw_check_partition_list", 0);
685 }
686 return 0;
687 }
688 if (function == "getpartitiondetails") {
689 string Wipe_List, wipe_path;
690 int count = 0;
691
692 DataManager::GetValue("tw_wipe_list", Wipe_List);
693 LOGINFO("getpartitiondetails list '%s'\n", Wipe_List.c_str());
694 if (!Wipe_List.empty()) {
695 size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
696 while (end_pos != string::npos && start_pos < Wipe_List.size()) {
697 wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
698 LOGINFO("getpartitiondetails wipe_path '%s'\n", wipe_path.c_str());
699 if (wipe_path == "/and-sec" || wipe_path == "DALVIK" || wipe_path == "INTERNAL") {
700 // Do nothing
701 } else {
702 DataManager::SetValue("tw_partition_path", wipe_path);
703 break;
704 }
705 start_pos = end_pos + 1;
706 end_pos = Wipe_List.find(";", start_pos);
707 }
708 if (!wipe_path.empty()) {
709 TWPartition* Part = PartitionManager.Find_Partition_By_Path(wipe_path);
710 if (Part) {
711 unsigned long long mb = 1048576;
712
713 DataManager::SetValue("tw_partition_name", Part->Display_Name);
714 DataManager::SetValue("tw_partition_mount_point", Part->Mount_Point);
715 DataManager::SetValue("tw_partition_file_system", Part->Current_File_System);
716 DataManager::SetValue("tw_partition_size", Part->Size / mb);
717 DataManager::SetValue("tw_partition_used", Part->Used / mb);
718 DataManager::SetValue("tw_partition_free", Part->Free / mb);
719 DataManager::SetValue("tw_partition_backup_size", Part->Backup_Size / mb);
720 DataManager::SetValue("tw_partition_removable", Part->Removable);
721 DataManager::SetValue("tw_partition_is_present", Part->Is_Present);
722
723 if (Part->Can_Repair())
724 DataManager::SetValue("tw_partition_can_repair", 1);
725 else
726 DataManager::SetValue("tw_partition_can_repair", 0);
727 if (TWFunc::Path_Exists("/sbin/mkdosfs"))
728 DataManager::SetValue("tw_partition_vfat", 1);
729 else
730 DataManager::SetValue("tw_partition_vfat", 0);
731 if (TWFunc::Path_Exists("/sbin/mkfs.exfat"))
732 DataManager::SetValue("tw_partition_exfat", 1);
733 else
734 DataManager::SetValue("tw_partition_exfat", 0);
735 if (TWFunc::Path_Exists("/sbin/mkfs.f2fs"))
736 DataManager::SetValue("tw_partition_f2fs", 1);
737 else
738 DataManager::SetValue("tw_partition_f2fs", 0);
739 if (TWFunc::Path_Exists("/sbin/mke2fs"))
740 DataManager::SetValue("tw_partition_ext", 1);
741 else
742 DataManager::SetValue("tw_partition_ext", 0);
743 return 0;
744 } else {
745 LOGERR("Unable to locate partition: '%s'\n", wipe_path.c_str());
746 }
747 }
748 }
749 DataManager::SetValue("tw_partition_name", "");
750 DataManager::SetValue("tw_partition_file_system", "");
751 return 0;
752 }
Dees Troyb21cc642013-09-10 17:36:41 +0000753
Vojtech Bocek03fd6c52014-03-13 18:46:34 +0100754 if (function == "screenshot")
755 {
756 time_t tm;
757 char path[256];
758 int path_len;
759 uid_t uid = -1;
760 gid_t gid = -1;
761
762 struct passwd *pwd = getpwnam("media_rw");
763 if(pwd) {
764 uid = pwd->pw_uid;
765 gid = pwd->pw_gid;
766 }
767
768 const std::string storage = DataManager::GetCurrentStoragePath();
769 if(PartitionManager.Is_Mounted_By_Path(storage)) {
770 snprintf(path, sizeof(path), "%s/Pictures/Screenshots/", storage.c_str());
771 } else {
772 strcpy(path, "/tmp/");
773 }
774
775 if(!TWFunc::Create_Dir_Recursive(path, 0666, uid, gid))
776 return 0;
777
778 tm = time(NULL);
779 path_len = strlen(path);
780
781 // Screenshot_2014-01-01-18-21-38.png
782 strftime(path+path_len, sizeof(path)-path_len, "Screenshot_%Y-%m-%d-%H-%M-%S.png", localtime(&tm));
783
784 int res = gr_save_screenshot(path);
785 if(res == 0) {
786 chmod(path, 0666);
787 chown(path, uid, gid);
788
789 gui_print("Screenshot was saved to %s\n", path);
790
791 // blink to notify that the screenshow was taken
792 gr_color(255, 255, 255, 255);
793 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
794 gr_flip();
795 gui_forceRender();
796 } else {
797 LOGERR("Failed to take a screenshot!\n");
798 }
799 return 0;
800 }
801
xNUTxe85f02d2014-07-18 01:30:58 +0200802 if (function == "setbrightness")
803 {
804 return TWFunc::Set_Brightness(arg);
805 }
806
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200807 if (isThreaded)
808 {
809 if (function == "fileexists")
Dees_Troy51a0e822012-09-05 15:24:24 -0400810 {
811 struct stat st;
812 string newpath = arg + "/.";
813
814 operation_start("FileExists");
815 if (stat(arg.c_str(), &st) == 0 || stat(newpath.c_str(), &st) == 0)
816 operation_end(0, simulate);
817 else
818 operation_end(1, simulate);
Dees_Troy83bd4832013-05-04 12:39:56 +0000819 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400820 }
821
822 if (function == "flash")
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200823 {
Dees_Troy657c3092012-09-10 20:32:10 -0400824 int i, ret_val = 0, wipe_cache = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400825
826 for (i=0; i<zip_queue_index; i++) {
827 operation_start("Flashing");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200828 DataManager::SetValue("tw_filename", zip_queue[i]);
829 DataManager::SetValue(TW_ZIP_INDEX, (i + 1));
Dees_Troy51a0e822012-09-05 15:24:24 -0400830
Tom Hite5a926722014-09-15 01:31:03 +0000831 TWFunc::SetPerformanceMode(true);
Dees_Troy657c3092012-09-10 20:32:10 -0400832 ret_val = flash_zip(zip_queue[i], arg, simulate, &wipe_cache);
Tom Hite5a926722014-09-15 01:31:03 +0000833 TWFunc::SetPerformanceMode(false);
Dees_Troy51a0e822012-09-05 15:24:24 -0400834 if (ret_val != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000835 gui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -0400836 i = 10; // Error flashing zip - exit queue
837 ret_val = 1;
838 }
839 }
840 zip_queue_index = 0;
841 DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
842
Dees_Troy657c3092012-09-10 20:32:10 -0400843 if (wipe_cache)
844 PartitionManager.Wipe_By_Path("/cache");
Vojtech Bocek05534202013-09-11 08:11:56 +0200845
Dees_Troy51a0e822012-09-05 15:24:24 -0400846 if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
847 operation_start("ReinjectTWRP");
Dees_Troy2673cec2013-04-02 20:22:16 +0000848 gui_print("Injecting TWRP into boot image...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400849 if (simulate) {
850 simulate_progress_bar();
851 } else {
Dees_Troy06b4fe92012-10-16 11:43:20 -0400852 TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot");
853 if (Boot == NULL || Boot->Current_File_System != "emmc")
Vojtech Bocek05534202013-09-11 08:11:56 +0200854 TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
Dees_Troy06b4fe92012-10-16 11:43:20 -0400855 else {
856 string injectcmd = "injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash bd=" + Boot->Actual_Block_Device;
Vojtech Bocek05534202013-09-11 08:11:56 +0200857 TWFunc::Exec_Cmd(injectcmd);
Dees_Troy06b4fe92012-10-16 11:43:20 -0400858 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000859 gui_print("TWRP injection complete.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400860 }
861 }
Dees_Troy32c8eb82012-09-11 15:28:06 -0400862 PartitionManager.Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -0400863 operation_end(ret_val, simulate);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200864 return 0;
865 }
866 if (function == "wipe")
867 {
868 operation_start("Format");
869 DataManager::SetValue("tw_partition", arg);
Dees_Troy51a0e822012-09-05 15:24:24 -0400870
Dees_Troy38bd7602012-09-14 13:33:53 -0400871 int ret_val = false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400872
873 if (simulate) {
874 simulate_progress_bar();
875 } else {
876 if (arg == "data")
Dees_Troy38bd7602012-09-14 13:33:53 -0400877 ret_val = PartitionManager.Factory_Reset();
Dees_Troy51a0e822012-09-05 15:24:24 -0400878 else if (arg == "battery")
Dees_Troy38bd7602012-09-14 13:33:53 -0400879 ret_val = PartitionManager.Wipe_Battery_Stats();
Dees_Troy51a0e822012-09-05 15:24:24 -0400880 else if (arg == "rotate")
Dees_Troy38bd7602012-09-14 13:33:53 -0400881 ret_val = PartitionManager.Wipe_Rotate_Data();
Dees_Troy51a0e822012-09-05 15:24:24 -0400882 else if (arg == "dalvik")
Dees_Troy38bd7602012-09-14 13:33:53 -0400883 ret_val = PartitionManager.Wipe_Dalvik_Cache();
Dees_Troy51a0e822012-09-05 15:24:24 -0400884 else if (arg == "DATAMEDIA") {
Dees_Troy38bd7602012-09-14 13:33:53 -0400885 ret_val = PartitionManager.Format_Data();
Dees_Troy51a0e822012-09-05 15:24:24 -0400886 } else if (arg == "INTERNAL") {
887 int has_datamedia, dual_storage;
888
889 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia);
890 if (has_datamedia) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400891 ret_val = PartitionManager.Wipe_Media_From_Data();
Dees_Troy51a0e822012-09-05 15:24:24 -0400892 } else {
Dees_Troy38bd7602012-09-14 13:33:53 -0400893 ret_val = PartitionManager.Wipe_By_Path(DataManager::GetSettingsStoragePath());
Dees_Troy51a0e822012-09-05 15:24:24 -0400894 }
895 } else if (arg == "EXTERNAL") {
Dees_Troy38bd7602012-09-14 13:33:53 -0400896 string External_Path;
Dees_Troy51a0e822012-09-05 15:24:24 -0400897
Dees_Troy38bd7602012-09-14 13:33:53 -0400898 DataManager::GetValue(TW_EXTERNAL_PATH, External_Path);
899 ret_val = PartitionManager.Wipe_By_Path(External_Path);
Dees_Troy2ff5a8d2012-09-26 14:53:02 -0400900 } else if (arg == "ANDROIDSECURE") {
901 ret_val = PartitionManager.Wipe_Android_Secure();
Dees_Troya13d74f2013-03-24 08:54:55 -0500902 } else if (arg == "LIST") {
903 string Wipe_List, wipe_path;
904 bool skip = false;
905 ret_val = true;
906 TWPartition* wipe_part = NULL;
907
908 DataManager::GetValue("tw_wipe_list", Wipe_List);
Dees_Troy2673cec2013-04-02 20:22:16 +0000909 LOGINFO("wipe list '%s'\n", Wipe_List.c_str());
Dees_Troya13d74f2013-03-24 08:54:55 -0500910 if (!Wipe_List.empty()) {
911 size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
912 while (end_pos != string::npos && start_pos < Wipe_List.size()) {
913 wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
Dees_Troy2673cec2013-04-02 20:22:16 +0000914 LOGINFO("wipe_path '%s'\n", wipe_path.c_str());
Dees_Troya13d74f2013-03-24 08:54:55 -0500915 if (wipe_path == "/and-sec") {
916 if (!PartitionManager.Wipe_Android_Secure()) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000917 LOGERR("Unable to wipe android secure\n");
Dees_Troya13d74f2013-03-24 08:54:55 -0500918 ret_val = false;
919 break;
920 } else {
921 skip = true;
922 }
923 } else if (wipe_path == "DALVIK") {
924 if (!PartitionManager.Wipe_Dalvik_Cache()) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000925 LOGERR("Failed to wipe dalvik\n");
Dees_Troya13d74f2013-03-24 08:54:55 -0500926 ret_val = false;
927 break;
928 } else {
929 skip = true;
930 }
Dees_Troy74fb2e92013-04-15 14:35:47 +0000931 } else if (wipe_path == "INTERNAL") {
932 if (!PartitionManager.Wipe_Media_From_Data()) {
933 ret_val = false;
934 break;
935 } else {
936 skip = true;
937 }
Dees_Troya13d74f2013-03-24 08:54:55 -0500938 }
939 if (!skip) {
940 if (!PartitionManager.Wipe_By_Path(wipe_path)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000941 LOGERR("Unable to wipe '%s'\n", wipe_path.c_str());
Dees_Troya13d74f2013-03-24 08:54:55 -0500942 ret_val = false;
943 break;
944 } else if (wipe_path == DataManager::GetSettingsStoragePath()) {
945 arg = wipe_path;
946 }
947 } else {
948 skip = false;
949 }
950 start_pos = end_pos + 1;
951 end_pos = Wipe_List.find(";", start_pos);
952 }
953 }
Dees_Troy38bd7602012-09-14 13:33:53 -0400954 } else
955 ret_val = PartitionManager.Wipe_By_Path(arg);
Ethan Yonker83e82572014-04-04 10:59:28 -0500956#ifdef TW_OEM_BUILD
Dees_Troy38bd7602012-09-14 13:33:53 -0400957 if (arg == DataManager::GetSettingsStoragePath()) {
958 // If we wiped the settings storage path, recreate the TWRP folder and dump the settings
959 string Storage_Path = DataManager::GetSettingsStoragePath();
960
961 if (PartitionManager.Mount_By_Path(Storage_Path, true)) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000962 LOGINFO("Making TWRP folder and saving settings.\n");
Dees_Troy38bd7602012-09-14 13:33:53 -0400963 Storage_Path += "/TWRP";
964 mkdir(Storage_Path.c_str(), 0777);
965 DataManager::Flush();
966 } else {
Dees_Troy2673cec2013-04-02 20:22:16 +0000967 LOGERR("Unable to recreate TWRP folder and save settings.\n");
Dees_Troy38bd7602012-09-14 13:33:53 -0400968 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400969 }
Ethan Yonker83e82572014-04-04 10:59:28 -0500970#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400971 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400972 PartitionManager.Update_System_Details();
Dees_Troy38bd7602012-09-14 13:33:53 -0400973 if (ret_val)
974 ret_val = 0; // 0 is success
975 else
976 ret_val = 1; // 1 is failure
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200977 operation_end(ret_val, simulate);
978 return 0;
979 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400980 if (function == "refreshsizes")
981 {
982 operation_start("Refreshing Sizes");
983 if (simulate) {
984 simulate_progress_bar();
985 } else
Dees_Troy5bf43922012-09-07 16:07:55 -0400986 PartitionManager.Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -0400987 operation_end(0, simulate);
Dees_Troy83bd4832013-05-04 12:39:56 +0000988 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400989 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200990 if (function == "nandroid")
991 {
992 operation_start("Nandroid");
Dees_Troy43d8b002012-09-17 16:00:01 -0400993 int ret = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400994
995 if (simulate) {
996 DataManager::SetValue("tw_partition", "Simulation");
997 simulate_progress_bar();
998 } else {
999 if (arg == "backup") {
1000 string Backup_Name;
1001 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
Dees Troyb21cc642013-09-10 17:36:41 +00001002 if (Backup_Name == "(Auto Generate)" || Backup_Name == "(Current Date)" || Backup_Name == "0" || Backup_Name == "(" || PartitionManager.Check_Backup_Name(true) == 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -04001003 ret = PartitionManager.Run_Backup();
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001004 }
Dees_Troy43d8b002012-09-17 16:00:01 -04001005 else {
1006 operation_end(1, simulate);
Dees_Troy51a0e822012-09-05 15:24:24 -04001007 return -1;
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +00001008
Dees_Troy43d8b002012-09-17 16:00:01 -04001009 }
Dees Troyb21cc642013-09-10 17:36:41 +00001010 DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)");
Dees_Troy51a0e822012-09-05 15:24:24 -04001011 } else if (arg == "restore") {
1012 string Restore_Name;
1013 DataManager::GetValue("tw_restore", Restore_Name);
Dees_Troy43d8b002012-09-17 16:00:01 -04001014 ret = PartitionManager.Run_Restore(Restore_Name);
Dees_Troy51a0e822012-09-05 15:24:24 -04001015 } else {
1016 operation_end(1, simulate);
1017 return -1;
1018 }
1019 }
Dees_Troy83bd4832013-05-04 12:39:56 +00001020 DataManager::SetValue("tw_encrypt_backup", 0);
Dees_Troy43d8b002012-09-17 16:00:01 -04001021 if (ret == false)
1022 ret = 1; // 1 for failure
1023 else
1024 ret = 0; // 0 for success
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001025 operation_end(ret, simulate);
Dees_Troy83bd4832013-05-04 12:39:56 +00001026 return 0;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001027 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001028 if (function == "fixpermissions")
1029 {
1030 operation_start("Fix Permissions");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001031 LOGINFO("fix permissions started!\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001032 if (simulate) {
1033 simulate_progress_bar();
Dees_Troy4be841b2012-09-26 14:07:15 -04001034 } else {
Dees_Troy6480ce02012-10-10 10:26:54 -04001035 int op_status = PartitionManager.Fix_Permissions();
1036 if (op_status != 0)
1037 op_status = 1; // failure
1038 operation_end(op_status, simulate);
Dees_Troy4be841b2012-09-26 14:07:15 -04001039 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001040 return 0;
1041 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001042 if (function == "dd")
1043 {
1044 operation_start("imaging");
Dees_Troy51a0e822012-09-05 15:24:24 -04001045
1046 if (simulate) {
1047 simulate_progress_bar();
1048 } else {
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001049 string cmd = "dd " + arg;
Vojtech Bocek05534202013-09-11 08:11:56 +02001050 TWFunc::Exec_Cmd(cmd);
Dees_Troy51a0e822012-09-05 15:24:24 -04001051 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001052 operation_end(0, simulate);
1053 return 0;
1054 }
Dees_Troy51a0e822012-09-05 15:24:24 -04001055 if (function == "partitionsd")
1056 {
1057 operation_start("Partition SD Card");
Dees_Troy9350b8d2012-09-27 12:38:38 -04001058 int ret_val = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001059
1060 if (simulate) {
1061 simulate_progress_bar();
1062 } else {
1063 int allow_partition;
1064 DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition);
1065 if (allow_partition == 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001066 gui_print("This device does not have a real SD Card!\nAborting!\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001067 } else {
Dees_Troy9350b8d2012-09-27 12:38:38 -04001068 if (!PartitionManager.Partition_SDCard())
1069 ret_val = 1; // failed
Dees_Troy51a0e822012-09-05 15:24:24 -04001070 }
1071 }
Dees_Troy9350b8d2012-09-27 12:38:38 -04001072 operation_end(ret_val, simulate);
Dees_Troy51a0e822012-09-05 15:24:24 -04001073 return 0;
1074 }
1075 if (function == "installhtcdumlock")
1076 {
1077 operation_start("Install HTC Dumlock");
1078 if (simulate) {
1079 simulate_progress_bar();
1080 } else
Dees_Troy38bd7602012-09-14 13:33:53 -04001081 TWFunc::install_htc_dumlock();
Dees_Troy51a0e822012-09-05 15:24:24 -04001082
1083 operation_end(0, simulate);
1084 return 0;
1085 }
1086 if (function == "htcdumlockrestoreboot")
1087 {
1088 operation_start("HTC Dumlock Restore Boot");
1089 if (simulate) {
1090 simulate_progress_bar();
1091 } else
Dees_Troy38bd7602012-09-14 13:33:53 -04001092 TWFunc::htc_dumlock_restore_original_boot();
Dees_Troy51a0e822012-09-05 15:24:24 -04001093
1094 operation_end(0, simulate);
1095 return 0;
1096 }
1097 if (function == "htcdumlockreflashrecovery")
1098 {
1099 operation_start("HTC Dumlock Reflash Recovery");
1100 if (simulate) {
1101 simulate_progress_bar();
1102 } else
Dees_Troy38bd7602012-09-14 13:33:53 -04001103 TWFunc::htc_dumlock_reflash_recovery_to_boot();
Dees_Troy51a0e822012-09-05 15:24:24 -04001104
1105 operation_end(0, simulate);
1106 return 0;
1107 }
1108 if (function == "cmd")
1109 {
1110 int op_status = 0;
1111
1112 operation_start("Command");
Dees_Troy2673cec2013-04-02 20:22:16 +00001113 LOGINFO("Running command: '%s'\n", arg.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -04001114 if (simulate) {
1115 simulate_progress_bar();
1116 } else {
Vojtech Bocek05534202013-09-11 08:11:56 +02001117 op_status = TWFunc::Exec_Cmd(arg);
Dees_Troy51a0e822012-09-05 15:24:24 -04001118 if (op_status != 0)
1119 op_status = 1;
1120 }
1121
1122 operation_end(op_status, simulate);
1123 return 0;
1124 }
1125 if (function == "terminalcommand")
1126 {
1127 int op_status = 0;
1128 string cmdpath, command;
1129
1130 DataManager::GetValue("tw_terminal_location", cmdpath);
1131 operation_start("CommandOutput");
Dees_Troy2673cec2013-04-02 20:22:16 +00001132 gui_print("%s # %s\n", cmdpath.c_str(), arg.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -04001133 if (simulate) {
1134 simulate_progress_bar();
1135 operation_end(op_status, simulate);
1136 } else {
Dees_Troy4be841b2012-09-26 14:07:15 -04001137 command = "cd \"" + cmdpath + "\" && " + arg + " 2>&1";;
Dees_Troy2673cec2013-04-02 20:22:16 +00001138 LOGINFO("Actual command is: '%s'\n", command.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -04001139 DataManager::SetValue("tw_terminal_command_thread", command);
1140 DataManager::SetValue("tw_terminal_state", 1);
1141 DataManager::SetValue("tw_background_thread_running", 1);
1142 op_status = pthread_create(&terminal_command, NULL, command_thread, NULL);
1143 if (op_status != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001144 LOGERR("Error starting terminal command thread, %i.\n", op_status);
Dees_Troy51a0e822012-09-05 15:24:24 -04001145 DataManager::SetValue("tw_terminal_state", 0);
1146 DataManager::SetValue("tw_background_thread_running", 0);
1147 operation_end(1, simulate);
1148 }
1149 }
1150 return 0;
1151 }
1152 if (function == "killterminal")
1153 {
1154 int op_status = 0;
1155
Dees_Troy2673cec2013-04-02 20:22:16 +00001156 LOGINFO("Sending kill command...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001157 operation_start("KillCommand");
1158 DataManager::SetValue("tw_operation_status", 0);
1159 DataManager::SetValue("tw_operation_state", 1);
1160 DataManager::SetValue("tw_terminal_state", 0);
1161 DataManager::SetValue("tw_background_thread_running", 0);
1162 DataManager::SetValue(TW_ACTION_BUSY, 0);
1163 return 0;
1164 }
1165 if (function == "reinjecttwrp")
1166 {
1167 int op_status = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -04001168 operation_start("ReinjectTWRP");
Dees_Troy2673cec2013-04-02 20:22:16 +00001169 gui_print("Injecting TWRP into boot image...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001170 if (simulate) {
1171 simulate_progress_bar();
1172 } else {
Vojtech Bocek05534202013-09-11 08:11:56 +02001173 TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
Dees_Troy2673cec2013-04-02 20:22:16 +00001174 gui_print("TWRP injection complete.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001175 }
1176
1177 operation_end(op_status, simulate);
1178 return 0;
1179 }
1180 if (function == "checkbackupname")
1181 {
1182 int op_status = 0;
1183
1184 operation_start("CheckBackupName");
1185 if (simulate) {
1186 simulate_progress_bar();
1187 } else {
Dees_Troyc9ff7a32012-09-27 10:09:41 -04001188 op_status = PartitionManager.Check_Backup_Name(true);
Dees_Troy51a0e822012-09-05 15:24:24 -04001189 if (op_status != 0)
1190 op_status = 1;
1191 }
1192
1193 operation_end(op_status, simulate);
1194 return 0;
1195 }
1196 if (function == "decrypt")
1197 {
1198 int op_status = 0;
1199
1200 operation_start("Decrypt");
1201 if (simulate) {
1202 simulate_progress_bar();
1203 } else {
1204 string Password;
1205 DataManager::GetValue("tw_crypto_password", Password);
Dees_Troy5bf43922012-09-07 16:07:55 -04001206 op_status = PartitionManager.Decrypt_Device(Password);
Dees_Troy51a0e822012-09-05 15:24:24 -04001207 if (op_status != 0)
1208 op_status = 1;
1209 else {
1210 int load_theme = 1;
1211
1212 DataManager::SetValue(TW_IS_ENCRYPTED, 0);
Dees_Troy51a0e822012-09-05 15:24:24 -04001213
1214 if (load_theme) {
1215 int has_datamedia;
1216
1217 // Check for a custom theme and load it if exists
1218 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia);
1219 if (has_datamedia != 0) {
1220 struct stat st;
1221 int check = 0;
1222 std::string theme_path;
1223
1224 theme_path = DataManager::GetSettingsStoragePath();
Dees_Troy5bf43922012-09-07 16:07:55 -04001225 if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001226 LOGERR("Unable to mount %s during reload function startup.\n", theme_path.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -04001227 check = 1;
1228 }
1229
1230 theme_path += "/TWRP/theme/ui.zip";
1231 if (check == 0 && stat(theme_path.c_str(), &st) == 0) {
1232 if (PageManager::ReloadPackage("TWRP", theme_path) != 0)
1233 {
1234 // Loading the custom theme failed - try loading the stock theme
Dees_Troy2673cec2013-04-02 20:22:16 +00001235 LOGINFO("Attempting to reload stock theme...\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001236 if (PageManager::ReloadPackage("TWRP", "/res/ui.xml"))
1237 {
Dees_Troy2673cec2013-04-02 20:22:16 +00001238 LOGERR("Failed to load base packages.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001239 }
1240 }
1241 }
1242 }
1243 }
1244 }
1245 }
1246
1247 operation_end(op_status, simulate);
1248 return 0;
1249 }
Dees_Troy43d8b002012-09-17 16:00:01 -04001250 if (function == "adbsideload")
1251 {
1252 int ret = 0;
1253
1254 operation_start("Sideload");
1255 if (simulate) {
1256 simulate_progress_bar();
1257 } else {
1258 int wipe_cache = 0;
bigbiff bigbiff7ce7f0c2013-01-25 09:54:04 -05001259 int wipe_dalvik = 0;
Vojtech Bocek05534202013-09-11 08:11:56 +02001260 string Sideload_File;
Dees_Troycfb63ae2012-09-19 14:30:17 -04001261
Ethan Yonker45312e52014-02-26 09:23:53 -06001262 if (!PartitionManager.Mount_Current_Storage(false)) {
1263 gui_print("Using RAM for sideload storage.\n");
1264 Sideload_File = "/tmp/sideload.zip";
1265 } else {
1266 Sideload_File = DataManager::GetCurrentStoragePath() + "/sideload.zip";
Dees_Troycfb63ae2012-09-19 14:30:17 -04001267 }
Dees_Troy9a4b5692012-09-19 15:09:45 -04001268 if (TWFunc::Path_Exists(Sideload_File)) {
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001269 unlink(Sideload_File.c_str());
Dees_Troycfb63ae2012-09-19 14:30:17 -04001270 }
Dees_Troy2673cec2013-04-02 20:22:16 +00001271 gui_print("Starting ADB sideload feature...\n");
bigbiff bigbiff7ce7f0c2013-01-25 09:54:04 -05001272 DataManager::GetValue("tw_wipe_dalvik", wipe_dalvik);
Dees_Troy2673cec2013-04-02 20:22:16 +00001273 ret = apply_from_adb(Sideload_File.c_str());
1274 DataManager::SetValue("tw_has_cancel", 0); // Remove cancel button from gui now that the zip install is going to start
bigbiff bigbiff7ce7f0c2013-01-25 09:54:04 -05001275 if (ret != 0) {
Dees_Troycfb63ae2012-09-19 14:30:17 -04001276 ret = 1; // failure
Dees_Troy2673cec2013-04-02 20:22:16 +00001277 } else if (TWinstall_zip(Sideload_File.c_str(), &wipe_cache) == 0) {
bigbiff bigbiff7ce7f0c2013-01-25 09:54:04 -05001278 if (wipe_cache || DataManager::GetIntValue("tw_wipe_cache"))
1279 PartitionManager.Wipe_By_Path("/cache");
1280 if (wipe_dalvik)
1281 PartitionManager.Wipe_Dalvik_Cache();
Dees_Troy2673cec2013-04-02 20:22:16 +00001282 } else {
1283 ret = 1; // failure
bigbiff bigbiff7ce7f0c2013-01-25 09:54:04 -05001284 }
Dees_Troy06b4fe92012-10-16 11:43:20 -04001285 if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
1286 operation_start("ReinjectTWRP");
Dees_Troy2673cec2013-04-02 20:22:16 +00001287 gui_print("Injecting TWRP into boot image...\n");
Dees_Troy06b4fe92012-10-16 11:43:20 -04001288 if (simulate) {
1289 simulate_progress_bar();
1290 } else {
1291 TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot");
1292 if (Boot == NULL || Boot->Current_File_System != "emmc")
Vojtech Bocek05534202013-09-11 08:11:56 +02001293 TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
Dees_Troy06b4fe92012-10-16 11:43:20 -04001294 else {
1295 string injectcmd = "injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash bd=" + Boot->Actual_Block_Device;
Vojtech Bocek05534202013-09-11 08:11:56 +02001296 TWFunc::Exec_Cmd(injectcmd);
Dees_Troy06b4fe92012-10-16 11:43:20 -04001297 }
Dees_Troy2673cec2013-04-02 20:22:16 +00001298 gui_print("TWRP injection complete.\n");
Dees_Troy06b4fe92012-10-16 11:43:20 -04001299 }
1300 }
Dees_Troy43d8b002012-09-17 16:00:01 -04001301 }
1302 operation_end(ret, simulate);
1303 return 0;
1304 }
Dees_Troycfb63ae2012-09-19 14:30:17 -04001305 if (function == "adbsideloadcancel")
1306 {
1307 int child_pid;
Dees_Troy2673cec2013-04-02 20:22:16 +00001308 char child_prop[PROPERTY_VALUE_MAX];
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001309 string Sideload_File;
Dees_Troy9a4b5692012-09-19 15:09:45 -04001310 Sideload_File = DataManager::GetCurrentStoragePath() + "/sideload.zip";
bigbiff bigbiff9c754052013-01-09 09:09:08 -05001311 unlink(Sideload_File.c_str());
Dees_Troy2673cec2013-04-02 20:22:16 +00001312 property_get("tw_child_pid", child_prop, "error");
1313 if (strcmp(child_prop, "error") == 0) {
1314 LOGERR("Unable to get child ID from prop\n");
1315 return 0;
1316 }
1317 child_pid = atoi(child_prop);
1318 gui_print("Cancelling ADB sideload...\n");
Dees_Troycfb63ae2012-09-19 14:30:17 -04001319 kill(child_pid, SIGTERM);
Dees_Troy4bc09ae2013-01-18 17:00:54 +00001320 DataManager::SetValue("tw_page_done", "1"); // For OpenRecoveryScript support
Dees_Troycfb63ae2012-09-19 14:30:17 -04001321 return 0;
1322 }
Dees_Troy6ed34b72013-01-25 15:01:29 +00001323 if (function == "openrecoveryscript") {
1324 operation_start("OpenRecoveryScript");
1325 if (simulate) {
1326 simulate_progress_bar();
1327 } else {
1328 // Check for the SCRIPT_FILE_TMP first as these are AOSP recovery commands
1329 // that we converted to ORS commands during boot in recovery.cpp.
1330 // Run those first.
1331 int reboot = 0;
1332 if (TWFunc::Path_Exists(SCRIPT_FILE_TMP)) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001333 gui_print("Processing AOSP recovery commands...\n");
Dees_Troy6ed34b72013-01-25 15:01:29 +00001334 if (OpenRecoveryScript::run_script_file() == 0) {
1335 reboot = 1;
1336 }
1337 }
1338 // Check for the ORS file in /cache and attempt to run those commands.
1339 if (OpenRecoveryScript::check_for_script_file()) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001340 gui_print("Processing OpenRecoveryScript file...\n");
Dees_Troy6ed34b72013-01-25 15:01:29 +00001341 if (OpenRecoveryScript::run_script_file() == 0) {
1342 reboot = 1;
1343 }
1344 }
1345 if (reboot) {
1346 usleep(2000000); // Sleep for 2 seconds before rebooting
1347 TWFunc::tw_reboot(rb_system);
1348 } else {
1349 DataManager::SetValue("tw_page_done", 1);
1350 }
1351 }
Dees_Troy83bd4832013-05-04 12:39:56 +00001352 return 0;
Dees_Troy6ed34b72013-01-25 15:01:29 +00001353 }
Dees_Troy6ef66352013-02-21 08:26:57 -06001354 if (function == "installsu")
1355 {
1356 int op_status = 0;
1357
1358 operation_start("Install SuperSU");
1359 if (simulate) {
1360 simulate_progress_bar();
1361 } else {
1362 if (!TWFunc::Install_SuperSU())
1363 op_status = 1;
1364 }
1365
1366 operation_end(op_status, simulate);
1367 return 0;
1368 }
1369 if (function == "fixsu")
1370 {
1371 int op_status = 0;
1372
1373 operation_start("Fixing Superuser Permissions");
1374 if (simulate) {
1375 simulate_progress_bar();
1376 } else {
Dees Troyf193f882013-09-11 14:56:20 +00001377 LOGERR("Fixing su permissions was deprecated from TWRP.\n");
1378 LOGERR("4.3+ ROMs with SELinux will always lose su perms.\n");
Dees_Troy6ef66352013-02-21 08:26:57 -06001379 }
1380
1381 operation_end(op_status, simulate);
1382 return 0;
1383 }
Dees_Troy83bd4832013-05-04 12:39:56 +00001384 if (function == "decrypt_backup")
1385 {
1386 int op_status = 0;
1387
1388 operation_start("Try Restore Decrypt");
1389 if (simulate) {
1390 simulate_progress_bar();
1391 } else {
1392 string Restore_Path, Filename, Password;
1393 DataManager::GetValue("tw_restore", Restore_Path);
1394 Restore_Path += "/";
1395 DataManager::GetValue("tw_restore_password", Password);
Tom Hite5a926722014-09-15 01:31:03 +00001396 TWFunc::SetPerformanceMode(true);
Dees_Troy83bd4832013-05-04 12:39:56 +00001397 if (TWFunc::Try_Decrypting_Backup(Restore_Path, Password))
1398 op_status = 0; // success
1399 else
1400 op_status = 1; // fail
Tom Hite5a926722014-09-15 01:31:03 +00001401 TWFunc::SetPerformanceMode(false);
Dees_Troy83bd4832013-05-04 12:39:56 +00001402 }
1403
1404 operation_end(op_status, simulate);
1405 return 0;
1406 }
Ethan Yonker87c7bac2014-05-25 21:41:08 -05001407 if (function == "repair")
1408 {
1409 int op_status = 0;
1410
1411 operation_start("Repair Partition");
1412 if (simulate) {
1413 simulate_progress_bar();
1414 } else {
1415 string part_path;
1416 DataManager::GetValue("tw_partition_mount_point", part_path);
1417 if (PartitionManager.Repair_By_Path(part_path, true)) {
1418 op_status = 0; // success
1419 } else {
1420 LOGERR("Error repairing file system.\n");
1421 op_status = 1; // fail
1422 }
1423 }
1424
1425 operation_end(op_status, simulate);
1426 return 0;
1427 }
1428 if (function == "changefilesystem")
1429 {
1430 int op_status = 0;
1431
1432 operation_start("Change File System");
1433 if (simulate) {
1434 simulate_progress_bar();
1435 } else {
1436 string part_path, file_system;
1437 DataManager::GetValue("tw_partition_mount_point", part_path);
1438 DataManager::GetValue("tw_action_new_file_system", file_system);
1439 if (PartitionManager.Wipe_By_Path(part_path, file_system)) {
1440 op_status = 0; // success
1441 } else {
1442 LOGERR("Error changing file system.\n");
1443 op_status = 1; // fail
1444 }
1445 }
jrior001aad03112014-07-05 10:31:21 -04001446 PartitionManager.Update_System_Details();
Ethan Yonker87c7bac2014-05-25 21:41:08 -05001447 operation_end(op_status, simulate);
1448 return 0;
1449 }
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04001450 if (function == "startmtp")
1451 {
1452 int op_status = 0;
1453
1454 operation_start("Start MTP");
1455 if (PartitionManager.Enable_MTP())
1456 op_status = 0; // success
1457 else
1458 op_status = 1; // fail
1459
1460 operation_end(op_status, simulate);
1461 return 0;
1462 }
1463 if (function == "stopmtp")
1464 {
1465 int op_status = 0;
1466
1467 operation_start("Stop MTP");
1468 if (PartitionManager.Disable_MTP())
1469 op_status = 0; // success
1470 else
1471 op_status = 1; // fail
1472
1473 operation_end(op_status, simulate);
1474 return 0;
1475 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001476 }
1477 else
1478 {
Dees_Troy83bd4832013-05-04 12:39:56 +00001479 pthread_t t;
1480 pthread_create(&t, NULL, thread_start, this);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001481 return 0;
1482 }
Dees_Troy83bd4832013-05-04 12:39:56 +00001483 LOGERR("Unknown action '%s'\n", function.c_str());
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001484 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -04001485}
1486
1487int GUIAction::getKeyByName(std::string key)
1488{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001489 if (key == "home") return KEY_HOME;
1490 else if (key == "menu") return KEY_MENU;
1491 else if (key == "back") return KEY_BACK;
1492 else if (key == "search") return KEY_SEARCH;
1493 else if (key == "voldown") return KEY_VOLUMEDOWN;
1494 else if (key == "volup") return KEY_VOLUMEUP;
1495 else if (key == "power") {
Dees_Troy51a0e822012-09-05 15:24:24 -04001496 int ret_val;
1497 DataManager::GetValue(TW_POWER_BUTTON, ret_val);
1498 if (!ret_val)
1499 return KEY_POWER;
1500 else
1501 return ret_val;
1502 }
1503
Vojtech Bocekfafb0c52013-07-25 22:53:02 +02001504 return atol(key.c_str());
Dees_Troy51a0e822012-09-05 15:24:24 -04001505}
1506
1507void* GUIAction::command_thread(void *cookie)
1508{
1509 string command;
1510 FILE* fp;
1511 char line[512];
1512
1513 DataManager::GetValue("tw_terminal_command_thread", command);
Dees_Troy8170a922012-09-18 15:40:25 -04001514 fp = popen(command.c_str(), "r");
Dees_Troy51a0e822012-09-05 15:24:24 -04001515 if (fp == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +00001516 LOGERR("Error opening command to run.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001517 } else {
1518 int fd = fileno(fp), has_data = 0, check = 0, keep_going = -1, bytes_read = 0;
1519 struct timeval timeout;
1520 fd_set fdset;
1521
1522 while(keep_going)
1523 {
1524 FD_ZERO(&fdset);
1525 FD_SET(fd, &fdset);
1526 timeout.tv_sec = 0;
1527 timeout.tv_usec = 400000;
1528 has_data = select(fd+1, &fdset, NULL, NULL, &timeout);
1529 if (has_data == 0) {
1530 // Timeout reached
1531 DataManager::GetValue("tw_terminal_state", check);
1532 if (check == 0) {
1533 keep_going = 0;
1534 }
1535 } else if (has_data < 0) {
1536 // End of execution
1537 keep_going = 0;
1538 } else {
1539 // Try to read output
Dees_Troy4be841b2012-09-26 14:07:15 -04001540 memset(line, 0, sizeof(line));
Dees_Troy51a0e822012-09-05 15:24:24 -04001541 bytes_read = read(fd, line, sizeof(line));
1542 if (bytes_read > 0)
Dees_Troy2673cec2013-04-02 20:22:16 +00001543 gui_print("%s", line); // Display output
Dees_Troy51a0e822012-09-05 15:24:24 -04001544 else
1545 keep_going = 0; // Done executing
1546 }
1547 }
1548 fclose(fp);
1549 }
1550 DataManager::SetValue("tw_operation_status", 0);
1551 DataManager::SetValue("tw_operation_state", 1);
1552 DataManager::SetValue("tw_terminal_state", 0);
1553 DataManager::SetValue("tw_background_thread_running", 0);
1554 DataManager::SetValue(TW_ACTION_BUSY, 0);
1555 return NULL;
1556}