Minor improvements on Android 9/10. Let the user reset to root of storage.

This includes handling weird "raw:/" content URIs. These I haven't seen
on newer versions.
This commit is contained in:
Henrik Rydgård 2021-08-04 23:21:28 +02:00
parent 93673cb565
commit a0a5f7a67a
7 changed files with 74 additions and 29 deletions

View file

@ -279,7 +279,9 @@ const char *Android_ErrorToString(StorageError error) {
#else
// This string should never appear except on Android.
// These strings should never appear except on Android.
// Very hacky.
std::string g_extFilesDir = "(IF YOU SEE THIS THERE'S A BUG)";
std::string g_externalDir = "(IF YOU SEE THIS THERE'S A BUG (2))";
#endif

View file

@ -30,12 +30,13 @@ inline StorageError StorageErrorFromInt(int ival) {
}
}
extern std::string g_extFilesDir;
extern std::string g_externalDir;
#if PPSSPP_PLATFORM(ANDROID) && !defined(__LIBRETRO__)
#include <jni.h>
extern std::string g_extFilesDir;
void Android_StorageSetNativeActivity(jobject nativeActivity);
bool Android_IsContentUri(const std::string &uri);
@ -59,8 +60,6 @@ void Android_RegisterStorageCallbacks(JNIEnv * env, jobject obj);
#else
extern std::string g_extFilesDir;
// Stub out the Android Storage wrappers, so that we can avoid ifdefs everywhere.
inline bool Android_IsContentUri(const std::string &uri) { return false; }

View file

@ -10,16 +10,6 @@
#include "android/jni/AndroidContentURI.h"
Path::Path(const std::string &str) {
if (str.empty()) {
type_ = PathType::UNDEFINED;
} else if (startsWith(str, "http://") || startsWith(str, "https://")) {
type_ = PathType::HTTP;
} else if (Android_IsContentUri(str)) {
type_ = PathType::CONTENT_URI;
} else {
type_ = PathType::NATIVE;
}
Init(str);
}
@ -31,7 +21,35 @@ Path::Path(const std::wstring &str) {
#endif
void Path::Init(const std::string &str) {
path_ = str;
if (str.empty()) {
type_ = PathType::UNDEFINED;
path_.clear();
} else if (startsWith(str, "http://") || startsWith(str, "https://")) {
type_ = PathType::HTTP;
path_ = str;
} else if (Android_IsContentUri(str)) {
// Content URIs on non scoped-storage (and possibly other cases?) can contain
// "raw:/" URIs inside. This happens when picking the Download folder using the folder browser
// on Android 9.
// Here's an example:
// content://com.android.providers.downloads.documents/tree/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Fp/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Fp
//
// Since this is a legacy use case, I think it's safe enough to just detect this
// and flip it to a NATIVE url and hope for the best.
AndroidContentURI uri(str);
if (startsWith(uri.FilePath(), "raw:/")) {
INFO_LOG(SYSTEM, "Raw path detected: %s", uri.FilePath().c_str());
path_ = uri.FilePath().substr(4);
type_ = PathType::NATIVE;
} else {
// A normal content URI path.
type_ = PathType::CONTENT_URI;
path_ = str;
}
} else {
type_ = PathType::NATIVE;
path_ = str;
}
#if PPSSPP_PLATFORM(WINDOWS)
// Flip all the slashes around. We flip them back on ToWString().

View file

@ -903,9 +903,6 @@ void GameSettingsScreen::CreateViews() {
systemSettings->Add(new ItemHeader(sy->T("PSP Memory Stick")));
systemSettings->Add(new CheckBox(&g_Config.bMemStickInserted, sy->T("Memory Stick inserted")));
systemSettings->Add(new PopupSliderChoice(&g_Config.iMemStickSizeGB, 1, 32, sy->T("Change Memory Stick Size", "Memory Stick Size (GB)"), screenManager(), "GB"));
#if PPSSPP_PLATFORM(ANDROID)
memstickDisplay_ = g_Config.memStickDirectory.ToVisualString();
auto memstickPath = systemSettings->Add(new ChoiceWithValueDisplay(&memstickDisplay_, sy->T("Change Memory Stick folder", "Memory Stick folder"), (const char *)nullptr));
@ -955,6 +952,9 @@ void GameSettingsScreen::CreateViews() {
}
}
#endif
systemSettings->Add(new CheckBox(&g_Config.bMemStickInserted, sy->T("Memory Stick inserted")));
systemSettings->Add(new PopupSliderChoice(&g_Config.iMemStickSizeGB, 1, 32, sy->T("Change Memory Stick Size", "Memory Stick Size (GB)"), screenManager(), "GB"));
systemSettings->Add(new ItemHeader(sy->T("General")));
#if PPSSPP_PLATFORM(ANDROID)

View file

@ -102,7 +102,6 @@ static std::string FormatSpaceString(int64_t space) {
MemStickScreen::MemStickScreen(bool initialSetup)
: initialSetup_(initialSetup) {
pendingMemStickFolder_ = g_Config.memStickDirectory;
}
void MemStickScreen::CreateViews() {
@ -129,6 +128,14 @@ void MemStickScreen::CreateViews() {
leftColumn->Add(new TextView(iz->T("MemoryStickDescription", "Choose PSP data storage (Memory Stick)"), ALIGN_LEFT, false));
// For legacy Android systems, so you can switch back to the old ways if you move to SD or something.
// TODO: Gonna need a scroll view.
#if PPSSPP_PLATFORM(ANDROID)
if (!System_GetPropertyBool(SYSPROP_ANDROID_SCOPED_STORAGE)) {
leftColumn->Add(new Choice(iz->T("Use PSP folder at root of storage")))->OnClick.Handle(this, &MemStickScreen::OnUseStorageRoot);
}
#endif
leftColumn->Add(new Choice(iz->T("Create or Choose a PSP folder")))->OnClick.Handle(this, &MemStickScreen::OnBrowse);
leftColumn->Add(new TextView(iz->T("ChooseFolderDesc", "* Data will stay even if you uninstall PPSSPP.\n* Data can be shared with PPSSPP Gold\n* Easy USB access"), ALIGN_LEFT, false));
@ -145,19 +152,37 @@ void MemStickScreen::CreateViews() {
}
UI::EventReturn MemStickScreen::OnUseInternalStorage(UI::EventParams &params) {
pendingMemStickFolder_ = Path(g_extFilesDir);
Path pendingMemStickFolder = Path(g_extFilesDir);
if (initialSetup_) {
// There's not gonna be any files here in this case since it's a fresh install.
// Let's just accept it and move on. No need to move files either.
if (SwitchMemstickFolderTo(pendingMemStickFolder_)) {
if (SwitchMemstickFolderTo(pendingMemStickFolder)) {
TriggerFinish(DialogResult::DR_OK);
} else {
// This can't really happen?? Not worth making an error message.
}
} else {
// Always ask for confirmation when called from the UI. Likely there's already some data.
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder_, false));
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
}
return UI::EVENT_DONE;
}
UI::EventReturn MemStickScreen::OnUseStorageRoot(UI::EventParams &params) {
Path pendingMemStickFolder = Path(g_externalDir);
if (initialSetup_) {
// There's not gonna be any files here in this case since it's a fresh install.
// Let's just accept it and move on. No need to move files either.
if (SwitchMemstickFolderTo(pendingMemStickFolder)) {
TriggerFinish(DialogResult::DR_OK);
} else {
// This can't really happen?? Not worth making an error message.
}
} else {
// Always ask for confirmation when called from the UI. Likely there's already some data.
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
}
return UI::EVENT_DONE;
}
@ -179,9 +204,9 @@ void MemStickScreen::sendMessage(const char *message, const char *value) {
INFO_LOG(SYSTEM, "Got folder: '%s'", filename.c_str());
// Browse finished. Let's pop up the confirmation dialog.
pendingMemStickFolder_ = Path(filename);
bool existingFiles = FolderSeemsToBeUsed(pendingMemStickFolder_);
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder_, initialSetup_));
Path pendingMemStickFolder = Path(filename);
bool existingFiles = FolderSeemsToBeUsed(pendingMemStickFolder);
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, initialSetup_));
}
}
}

View file

@ -58,9 +58,8 @@ private:
// Event handlers
UI::EventReturn OnBrowse(UI::EventParams &e);
UI::EventReturn OnUseInternalStorage(UI::EventParams &params);
UI::EventReturn OnUseStorageRoot(UI::EventParams &params);
// TODO: probably not necessary to store here, we just forward to the confirmation dialog.
Path pendingMemStickFolder_;
SettingInfoMessage *settingInfo_ = nullptr;
bool initialSetup_;

View file

@ -128,7 +128,8 @@ std::string langRegion;
std::string mogaVersion;
std::string boardName;
std::string g_extFilesDir;
std::string g_externalDir; // Original external dir (root of Android storage).
std::string g_extFilesDir; // App private external dir.
std::vector<std::string> g_additionalStorageDirs;
@ -637,6 +638,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
std::string additionalStorageDirsString = GetJavaString(env, jadditionalStorageDirs);
std::string externalFilesDir = GetJavaString(env, jexternalFilesDir);
g_externalDir = externalStorageDir;
g_extFilesDir = externalFilesDir;
if (!additionalStorageDirsString.empty()) {