Skip to content

Commit

Permalink
Add progress bar (without %) to install/uninstall. Other fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Dec 8, 2023
1 parent 888b32e commit d234fa2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 28 deletions.
5 changes: 3 additions & 2 deletions Common/File/AndroidStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,9 @@ std::vector<File::FileInfo> Android_ListContentUri(const std::string &path, bool
env->DeleteLocalRef(fileList);

double elapsed = time_now_d() - start;
if (elapsed > 0.1) {
INFO_LOG(FILESYS, "Listing directory on content URI took %0.3f s (%d files)", elapsed, (int)items.size());
double threshold = 0.1;
if (elapsed >= threshold) {
INFO_LOG(FILESYS, "Listing directory on content URI '%s' took %0.3f s (%d files, log threshold = %0.3f)", path.c_str(), elapsed, (int)items.size(), threshold);
}
return items;
}
Expand Down
8 changes: 6 additions & 2 deletions Core/Util/GameDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,12 @@ bool GameDB::GetGameInfos(std::string_view id, std::vector<GameDBInfo> *infos) {
// Ignore version and stuff for now
if (IDMatches(id, serial)) {
GameDBInfo info;
sscanf(line.crc.data(), "%08x", &info.crc);
sscanf(line.size.data(), "%llu", &info.size);
if (1 != sscanf(line.crc.data(), "%08x", &info.crc)) {
continue;
}
if (1 != sscanf(line.size.data(), "%llu", (long long *)&info.size)) {
continue;
}
info.title = line.title;
info.foreignTitle = line.foreignTitle;
infos->push_back(info);
Expand Down
65 changes: 43 additions & 22 deletions Core/Util/GameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "Common/Data/Encoding/Utf8.h"
#include "Common/Data/Format/IniFile.h"
#include "Common/Log.h"
#include "Common/System/OSD.h"
#include "Common/File/FileUtil.h"
#include "Common/StringUtils.h"
#include "Common/Thread/ThreadUtil.h"
Expand Down Expand Up @@ -127,24 +128,32 @@ float GameManager::DownloadSpeedKBps() {
return 0.0f;
}

bool GameManager::UninstallGame(std::string name) {
void GameManager::UninstallGame(std::string name) {
SetCurrentThreadName("UninstallGame");

AndroidJNIThreadContext context; // Destructor detaches.

Path gameDir = GetSysDirectory(DIRECTORY_GAME) / name;

auto st = GetI18NCategory(I18NCat::STORE);

INFO_LOG(HLE, "Uninstalling '%s'", gameDir.c_str());
if (!File::Exists(gameDir)) {
ERROR_LOG(HLE, "Game '%s' not installed, cannot uninstall", name.c_str());
return false;
return;
}

g_OSD.SetProgressBar("install", st->T("Uninstall"), 0.0f, 0.0f, 0.0f, 0.1f);
bool success = File::DeleteDirRecursively(gameDir);
g_OSD.RemoveProgressBar("install", success, 0.5f);
if (success) {
INFO_LOG(HLE, "Successfully uninstalled game '%s'", name.c_str());
InstallDone();
cleanRecentsAfter_ = true;
return true;
return;
} else {
ERROR_LOG(HLE, "Failed to uninstalled game '%s'", name.c_str());
InstallDone();
return false;
return;
}
}

Expand Down Expand Up @@ -285,67 +294,80 @@ bool GameManager::InstallGame(Path url, Path fileName, bool deleteAfter) {
}

AndroidJNIThreadContext context; // Destructor detaches.

if (!File::Exists(fileName)) {
ERROR_LOG(HLE, "Game file '%s' doesn't exist", fileName.c_str());
return false;
}

auto st = GetI18NCategory(I18NCat::STORE);
auto di = GetI18NCategory(I18NCat::DIALOG);
auto sy = GetI18NCategory(I18NCat::SYSTEM);

g_OSD.SetProgressBar("install", di->T("Installing..."), 0.0f, 0.0f, 0.0f, 0.1f);

std::string extension = url.GetFileExtension();
// Examine the URL to guess out what we're installing.
if (extension == ".cso" || extension == ".iso") {
// It's a raw ISO or CSO file. We just copy it to the destination.
std::string shortFilename = url.GetFilename();
return InstallRawISO(fileName, shortFilename, deleteAfter);
bool success = InstallRawISO(fileName, shortFilename, deleteAfter);
g_OSD.RemoveProgressBar("install", success, 0.5f);
return success;
}

auto sy = GetI18NCategory(I18NCat::SYSTEM);

Path pspGame = GetSysDirectory(DIRECTORY_GAME);
Path dest = pspGame;
int error = 0;

struct zip *z = ZipOpenPath(fileName);
if (!z) {
g_OSD.RemoveProgressBar("install", false, 0.5f);
SetInstallError(sy->T("Unable to open zip file"));
return false;
}

ZipFileInfo info;
ZipFileContents contents = DetectZipFileContents(z, &info);
bool success = false;
switch (contents) {
case ZipFileContents::PSP_GAME_DIR:
INFO_LOG(HLE, "Installing '%s' into '%s'", fileName.c_str(), pspGame.c_str());
// InstallMemstickGame contains code to close z.
return InstallMemstickGame(z, fileName, pspGame, info, false, deleteAfter);
// InstallMemstickGame contains code to close (and delete) z.
success = InstallMemstickGame(z, fileName, pspGame, info, false, deleteAfter);
break;
case ZipFileContents::ISO_FILE:
INFO_LOG(HLE, "Installing '%s' into its containing directory", fileName.c_str());
// InstallZippedISO contains code to close z.
return InstallZippedISO(z, info.isoFileIndex, fileName, deleteAfter);
success = InstallZippedISO(z, info.isoFileIndex, fileName, deleteAfter);
break;
case ZipFileContents::TEXTURE_PACK:
// InstallMemstickGame contains code to close z, and works for textures too.
if (DetectTexturePackDest(z, info.textureIniIndex, dest)) {
INFO_LOG(HLE, "Installing '%s' into '%s'", fileName.c_str(), dest.c_str());
INFO_LOG(HLE, "Installing texture pack '%s' into '%s'", fileName.c_str(), dest.c_str());
File::CreateFullPath(dest);
// Install as a zip file if textures.ini is in the root. Performs better on Android.
if (info.stripChars == 0)
return InstallMemstickZip(z, fileName, dest / "textures.zip", info, deleteAfter);
File::CreateEmptyFile(dest / ".nomedia");
return InstallMemstickGame(z, fileName, dest, info, true, deleteAfter);
// Install as a zip file if textures.ini is in the root. Performs better on Android.
if (info.stripChars == 0) {
success = InstallMemstickZip(z, fileName, dest / "textures.zip", info, deleteAfter);
} else {
File::CreateEmptyFile(dest / ".nomedia");
success = InstallMemstickGame(z, fileName, dest, info, true, deleteAfter);
}
} else {
zip_close(z);
z = nullptr;
}
return false;
break;
default:
ERROR_LOG(HLE, "File not a PSP game, no EBOOT.PBP found.");
SetInstallError(sy->T("Not a PSP game"));
zip_close(z);
z = nullptr;
if (deleteAfter)
File::Delete(fileName);
return false;
break;
}
g_OSD.RemoveProgressBar("install", success, 0.5f);
return success;
}

bool GameManager::DetectTexturePackDest(struct zip *z, int iniIndex, Path &dest) {
Expand Down Expand Up @@ -598,11 +620,11 @@ bool GameManager::InstallMemstickGame(struct zip *z, const Path &zipfile, const
}
}
INFO_LOG(HLE, "Extracted %d files from zip (%d bytes / %d).", info.numFiles, (int)bytesCopied, (int)allBytes);

zip_close(z);
z = nullptr;
installProgress_ = 1.0f;
if (deleteAfter) {
INFO_LOG(HLE, "Deleting '%s' after extraction", zipfile.c_str());
File::Delete(zipfile);
}
InstallDone();
Expand Down Expand Up @@ -679,7 +701,6 @@ bool GameManager::InstallMemstickZip(struct zip *z, const Path &zipfile, const P

bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, const Path &zipfile, bool deleteAfter) {
// Let's place the output file in the currently selected Games directory.

std::string fn = zip_get_name(z, isoFileIndex, 0);
size_t nameOffset = fn.rfind('/');
if (nameOffset == std::string::npos) {
Expand Down
3 changes: 2 additions & 1 deletion Core/Util/GameManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ class GameManager {
bool UninstallGameOnThread(const std::string &name);

private:
// TODO: The return value on this is a bit pointless, we can't get at it.
bool InstallGame(Path url, Path tempFileName, bool deleteAfter);
bool InstallMemstickGame(struct zip *z, const Path &zipFile, const Path &dest, const ZipFileInfo &info, bool allowRoot, bool deleteAfter);
bool InstallMemstickZip(struct zip *z, const Path &zipFile, const Path &dest, const ZipFileInfo &info, bool deleteAfter);
bool InstallZippedISO(struct zip *z, int isoFileIndex, const Path &zipfile, bool deleteAfter);
bool InstallRawISO(const Path &zipFile, const std::string &originalName, bool deleteAfter);
bool UninstallGame(std::string name);
void UninstallGame(std::string name);

void InstallDone();

Expand Down
8 changes: 7 additions & 1 deletion UI/Store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class ProductView : public UI::LinearLayout {
std::string DownloadURL();

StoreEntry entry_;
UI::Button *uninstallButton_ = nullptr;
UI::Button *installButton_ = nullptr;
UI::Button *launchButton_ = nullptr;
UI::Button *cancelButton_ = nullptr;
Expand All @@ -300,6 +301,7 @@ void ProductView::CreateViews() {
LinearLayout *progressDisplay = new LinearLayout(ORIENT_HORIZONTAL);
installButton_ = progressDisplay->Add(new Button(st->T("Install")));
installButton_->OnClick.Handle(this, &ProductView::OnInstall);
uninstallButton_ = nullptr;

speedView_ = progressDisplay->Add(new TextView(""));
speedView_->SetVisibility(isDownloading ? V_VISIBLE : V_GONE);
Expand All @@ -308,7 +310,8 @@ void ProductView::CreateViews() {
installButton_ = nullptr;
speedView_ = nullptr;
Add(new TextView(st->T("Already Installed")));
Add(new Button(st->T("Uninstall")))->OnClick.Add([=](UI::EventParams &e) {
uninstallButton_ = new Button(st->T("Uninstall"));
Add(uninstallButton_)->OnClick.Add([=](UI::EventParams &e) {
g_GameManager.UninstallGameOnThread(entry_.file);
return UI::EVENT_DONE;
});
Expand Down Expand Up @@ -341,6 +344,9 @@ void ProductView::Update() {
if (installButton_) {
installButton_->SetEnabled(g_GameManager.GetState() == GameManagerState::IDLE);
}
if (uninstallButton_) {
uninstallButton_->SetEnabled(g_GameManager.GetState() == GameManagerState::IDLE);
}
if (g_GameManager.GetState() == GameManagerState::DOWNLOADING) {
if (speedView_) {
float speed = g_GameManager.DownloadSpeedKBps();
Expand Down

0 comments on commit d234fa2

Please sign in to comment.