summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gui/action.cpp27
-rw-r--r--gui/gui.cpp2
-rw-r--r--gui/pages.cpp84
-rw-r--r--gui/pages.hpp11
4 files changed, 78 insertions, 46 deletions
diff --git a/gui/action.cpp b/gui/action.cpp
index 86907a54f..c48c390f9 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -541,26 +541,13 @@ int GUIAction::page(std::string arg)
int GUIAction::reload(std::string arg __unused)
{
- int check = 0, ret_val = 0;
- std::string theme_path;
-
- theme_path = DataManager::GetSettingsStoragePath();
- if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) {
- LOGERR("Unable to mount %s during reload function startup.\n", theme_path.c_str());
- check = 1;
- }
-
- theme_path += "/TWRP/theme/ui.zip";
- if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0)
- {
- // Loading the custom theme failed - try loading the stock theme
- LOGINFO("Attempting to reload stock theme...\n");
- if (PageManager::ReloadPackage("TWRP", TWRES "ui.xml"))
- {
- LOGERR("Failed to load base packages.\n");
- ret_val = 1;
- }
- }
+ PageManager::RequestReload();
+ // The actual reload is handled in pages.cpp in PageManager::RunReload()
+ // The reload will occur on the next Update or Render call and will
+ // be performed in the rendoer thread instead of the action thread
+ // to prevent crashing which could occur when we start deleting
+ // GUI resources in the action thread while we attempt to render
+ // with those same resources in another thread.
return 0;
}
diff --git a/gui/gui.cpp b/gui/gui.cpp
index a5ac33e86..31b61be6d 100644
--- a/gui/gui.cpp
+++ b/gui/gui.cpp
@@ -663,6 +663,8 @@ static int runPages(const char *page_name, const int stop_on_page_done)
int ret = PageManager::Update();
if (ret == 0)
++idle_frames;
+ else if (ret == -2)
+ break; // Theme reload failure
else
idle_frames = 0;
// due to possible animation objects, we need to delay activating the input timeout
diff --git a/gui/pages.cpp b/gui/pages.cpp
index 0a1de96f3..0511b1ab5 100644
--- a/gui/pages.cpp
+++ b/gui/pages.cpp
@@ -55,6 +55,8 @@ PageSet* PageManager::mCurrentSet;
PageSet* PageManager::mBaseSet = NULL;
MouseCursor *PageManager::mMouseCursor = NULL;
HardwareKeyboard *PageManager::mHardwareKeyboard = NULL;
+bool PageManager::mReloadTheme = false;
+std::string PageManager::mStartPage = "main";
int tw_x_offset = 0;
int tw_y_offset = 0;
@@ -650,15 +652,12 @@ int Page::NotifyVarChange(std::string varName, std::string value)
return 0;
}
-PageSet::PageSet(char* xmlFile)
+PageSet::PageSet(const char* xmlFile)
{
mResources = new ResourceManager;
mCurrentPage = NULL;
- mXmlFile = xmlFile;
- if (xmlFile)
- mDoc.parse<0>(mXmlFile);
- else
+ if (!xmlFile)
mCurrentPage = new Page(NULL, NULL);
}
@@ -669,23 +668,17 @@ PageSet::~PageSet()
delete *itr;
delete mResources;
- free(mXmlFile);
-
- mDoc.clear();
-
- for (std::vector<xml_document<>*>::iterator itr = mIncludedDocs.begin(); itr != mIncludedDocs.end(); ++itr) {
- (*itr)->clear();
- delete *itr;
- }
}
-int PageSet::Load(ZipArchive* package)
+int PageSet::Load(ZipArchive* package, char* xmlFile)
{
+ xml_document<> mDoc;
xml_node<>* parent;
xml_node<>* child;
xml_node<>* xmltemplate;
xml_node<>* xmlstyle;
+ mDoc.parse<0>(xmlFile);
parent = mDoc.first_node("recovery");
if (!parent)
parent = mDoc.first_node("install");
@@ -772,11 +765,15 @@ int PageSet::Load(ZipArchive* package)
if (child) {
if (LoadPages(child)) {
LOGERR("PageSet::Load returning -1\n");
+ mDoc.clear();
return -1;
}
}
- return CheckInclude(package, &mDoc);
+ int ret = CheckInclude(package, &mDoc);
+ mDoc.clear();
+ templates.clear();
+ return ret;
}
int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc)
@@ -867,17 +864,19 @@ int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc)
return -1;
}
- mIncludedDocs.push_back(doc);
-
if (CheckInclude(package, doc)) {
+ doc->clear();
+ delete doc;
free(xmlFile);
return -1;
}
+ doc->clear();
+ delete doc;
+ free(xmlFile);
chld = chld->next_sibling("xmlfile");
}
- if (xmlFile)
- free(xmlFile);
+
return 0;
}
@@ -1192,6 +1191,9 @@ int PageManager::LoadPackage(std::string name, std::string package, std::string
int ret;
MemMapping map;
+ mReloadTheme = false;
+ mStartPage = startpage;
+
// Open the XML file
LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str());
if (package.size() > 4 && package.substr(package.size() - 4) != ".zip")
@@ -1229,7 +1231,7 @@ int PageManager::LoadPackage(std::string name, std::string package, std::string
pageSet = mCurrentSet;
mCurrentSet = new PageSet(xmlFile);
- ret = mCurrentSet->Load(pZip);
+ ret = mCurrentSet->Load(pZip, xmlFile);
if (ret == 0)
{
mCurrentSet->SetPage(startpage);
@@ -1297,6 +1299,8 @@ int PageManager::ReloadPackage(std::string name, std::string package)
{
std::map<std::string, PageSet*>::iterator iter;
+ mReloadTheme = false;
+
iter = mPageSets.find(name);
if (iter == mPageSets.end())
return -1;
@@ -1307,7 +1311,7 @@ int PageManager::ReloadPackage(std::string name, std::string package)
PageSet* set = (*iter).second;
mPageSets.erase(iter);
- if (LoadPackage(name, package, "main") != 0)
+ if (LoadPackage(name, package, mStartPage) != 0)
{
LOGERR("Failed to load package '%s'.\n", package.c_str());
mPageSets.insert(std::pair<std::string, PageSet*>(name, set));
@@ -1335,6 +1339,38 @@ void PageManager::ReleasePackage(std::string name)
return;
}
+int PageManager::RunReload() {
+ int ret_val = 0;
+ std::string theme_path;
+
+ if (!mReloadTheme)
+ return 0;
+
+ mReloadTheme = false;
+ theme_path = DataManager::GetSettingsStoragePath();
+ if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) {
+ LOGERR("Unable to mount %s during gui_reload_theme function.\n", theme_path.c_str());
+ ret_val = 1;
+ }
+
+ theme_path += "/TWRP/theme/ui.zip";
+ if (ret_val != 0 || ReloadPackage("TWRP", theme_path) != 0)
+ {
+ // Loading the custom theme failed - try loading the stock theme
+ LOGINFO("Attempting to reload stock theme...\n");
+ if (ReloadPackage("TWRP", TWRES "ui.xml"))
+ {
+ LOGERR("Failed to load base packages.\n");
+ ret_val = 1;
+ }
+ }
+ return ret_val;
+}
+
+void PageManager::RequestReload() {
+ mReloadTheme = true;
+}
+
int PageManager::ChangePage(std::string name)
{
DataManager::SetValue("tw_operation_state", 0);
@@ -1383,6 +1419,9 @@ int PageManager::IsCurrentPage(Page* page)
int PageManager::Render(void)
{
+ if(blankTimer.isScreenOff())
+ return 0;
+
int res = (mCurrentSet ? mCurrentSet->Render() : -1);
if(mMouseCursor)
mMouseCursor->Render();
@@ -1433,6 +1472,9 @@ int PageManager::Update(void)
if(blankTimer.isScreenOff())
return 0;
+ if (RunReload())
+ return -2;
+
int res = (mCurrentSet ? mCurrentSet->Update() : -1);
if(mMouseCursor)
diff --git a/gui/pages.hpp b/gui/pages.hpp
index 03fb0e5de..018c2cab2 100644
--- a/gui/pages.hpp
+++ b/gui/pages.hpp
@@ -78,11 +78,11 @@ protected:
class PageSet
{
public:
- PageSet(char* xmlFile);
+ PageSet(const char* xmlFile);
virtual ~PageSet();
public:
- int Load(ZipArchive* package);
+ int Load(ZipArchive* package, char* xmlFile);
int CheckInclude(ZipArchive* package, xml_document<> *parentDoc);
Page* FindPage(std::string name);
@@ -109,14 +109,11 @@ protected:
int LoadVariables(xml_node<>* vars);
protected:
- char* mXmlFile;
- xml_document<> mDoc;
ResourceManager* mResources;
std::vector<Page*> mPages;
std::vector<xml_node<>*> templates;
Page* mCurrentPage;
std::vector<Page*> mOverlays; // Special case for popup dialogs and the lock screen
- std::vector<xml_document<>*> mIncludedDocs;
};
class PageManager
@@ -128,6 +125,8 @@ public:
static PageSet* SelectPackage(std::string name);
static int ReloadPackage(std::string name, std::string package);
static void ReleasePackage(std::string name);
+ static int RunReload();
+ static void RequestReload();
// Used for actions and pages
static int ChangePage(std::string name);
@@ -166,6 +165,8 @@ protected:
static PageSet* mBaseSet;
static MouseCursor *mMouseCursor;
static HardwareKeyboard *mHardwareKeyboard;
+ static bool mReloadTheme;
+ static std::string mStartPage;
};
#endif // _PAGES_HEADER_HPP