From d0613511b2c06c5210ec75a0cd55464c07f29c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 18 May 2017 14:21:13 +0200 Subject: [PATCH] Many reported ANRs were from homebrew installs. Make sure installs run on the background thread. --- Core/Util/GameManager.cpp | 23 ++++++++++------------- UI/MainScreen.cpp | 4 ++++ UI/Store.cpp | 13 +++++++++++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 945b030e70..178aca4bb9 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -115,13 +115,10 @@ void GameManager::Update() { curDownload_.reset(); return; } - // Install the game! - InstallGame(zipName); - // Doesn't matter if the install succeeds or not, we delete the temp file to not squander space. - // TODO: Handle disk full? - File::Delete(zipName.c_str()); + // Game downloaded to temporary file - install it! + InstallGameOnThread(zipName, true); } else { - ERROR_LOG(HLE, "Expected HTTP status code 200, got status code %i. Install cancelled.", curDownload_->ResultCode()); + ERROR_LOG(HLE, "Expected HTTP status code 200, got status code %i. Install cancelled, deleting partia lfile.", curDownload_->ResultCode()); File::Delete(zipName.c_str()); } curDownload_.reset(); @@ -134,17 +131,16 @@ bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { return false; } - I18NCategory *sy = GetI18NCategory("System"); - installInProgress_ = true; - - std::string pspGame = GetSysDirectory(DIRECTORY_GAME); - INFO_LOG(HLE, "Installing %s into %s", zipfile.c_str(), pspGame.c_str()); - if (!File::Exists(zipfile)) { ERROR_LOG(HLE, "ZIP file %s doesn't exist", zipfile.c_str()); return false; } + I18NCategory *sy = GetI18NCategory("System"); + installInProgress_ = true; + + std::string pspGame = GetSysDirectory(DIRECTORY_GAME); + INFO_LOG(HLE, "Installing %s into %s", zipfile.c_str(), pspGame.c_str()); int error; #ifdef _WIN32 struct zip *z = zip_open(ConvertUTF8ToWString(zipfile).c_str(), 0, &error); @@ -192,6 +188,8 @@ bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { installInProgress_ = false; installError_ = sy->T("Not a PSP game"); InstallDone(); + if (deleteAfter) + File::Delete(zipfile); return false; } @@ -312,7 +310,6 @@ bool GameManager::InstallGameOnThread(std::string zipFile, bool deleteAfter) { if (installInProgress_) { return false; } - installThread_.reset(new std::thread(std::bind(&GameManager::InstallGame, this, zipFile, deleteAfter))); installThread_->detach(); return true; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 97da89ddc3..65207a8510 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -34,6 +34,7 @@ #include "Core/System.h" #include "Core/Host.h" #include "Core/Reporting.h" +#include "Core/Util/GameManager.h" #include "UI/BackgroundAudio.h" #include "UI/EmuScreen.h" @@ -1047,6 +1048,9 @@ UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) { return UI::EVENT_DONE; } + if (g_GameManager.GetState() == GameManagerState::INSTALLING) + return UI::EVENT_DONE; + // Restore focus if it was highlighted (e.g. by gamepad.) restoreFocusGamePath_ = highlightedGamePath_; SetBackgroundAudioGame(path); diff --git a/UI/Store.cpp b/UI/Store.cpp index 5ef5be8986..b2fbd429b8 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -218,6 +218,7 @@ private: StoreEntry entry_; UI::Button *installButton_ = nullptr; + UI::Button *launchButton_ = nullptr; UI::Button *cancelButton_ = nullptr; bool wasInstalled_ = false; }; @@ -242,7 +243,9 @@ void ProductView::CreateViews() { installButton_ = nullptr; Add(new TextView(st->T("Already Installed"))); Add(new Button(st->T("Uninstall")))->OnClick.Handle(this, &ProductView::OnUninstall); - Add(new Button(st->T("Launch Game")))->OnClick.Handle(this, &ProductView::OnLaunchClick); + launchButton_ = new Button(st->T("Launch Game")); + launchButton_->OnClick.Handle(this, &ProductView::OnLaunchClick); + Add(launchButton_); } cancelButton_ = Add(new Button(di->T("Cancel"))); @@ -268,6 +271,8 @@ void ProductView::Update() { } if (cancelButton_ && g_GameManager.GetState() != GameManagerState::DOWNLOADING) cancelButton_->SetVisibility(UI::V_GONE); + if (launchButton_) + launchButton_->SetEnabled(g_GameManager.GetState() == GameManagerState::IDLE); View::Update(); } @@ -303,12 +308,16 @@ UI::EventReturn ProductView::OnUninstall(UI::EventParams &e) { } UI::EventReturn ProductView::OnLaunchClick(UI::EventParams &e) { + if (g_GameManager.GetState() != GameManagerState::IDLE) { + // Button should have been disabled. Just a safety check. + return UI::EVENT_DONE; + } + std::string pspGame = GetSysDirectory(DIRECTORY_GAME); std::string path = pspGame + entry_.file; #ifdef _WIN32 path = ReplaceAll(path, "\\", "/"); #endif - UI::EventParams e2{}; e2.v = e.v; e2.s = path;