diff --git a/Common/System/System.h b/Common/System/System.h index f82d39e5c728..09560191e077 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -99,6 +99,9 @@ enum SystemProperty { SYSPROP_SUPPORTS_PERMISSIONS, SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE, + // Android-specific. + SYSPROP_ANDROID_SCOPED_STORAGE, + SYSPROP_CAN_JIT, }; diff --git a/Core/Config.h b/Core/Config.h index 8eeeea1e1088..3084c36f7580 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -470,6 +470,7 @@ struct Config { // Volatile development settings bool bShowFrameProfiler; + // Various directories. Autoconfigured, not read from ini. std::string currentDirectory; std::string externalDirectory; std::string memStickDirectory; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index dd7632ac56ad..bbbfb27848ac 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -59,6 +59,12 @@ int GetD3DCompilerVersion(); #endif +#if PPSSPP_PLATFORM(ANDROID) + +#include "android/jni/app-android.h" + +#endif + static const char *logLevelList[] = { "Notice", "Error", @@ -574,6 +580,24 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem("Moga", moga)); #endif + ViewGroup *storageScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); + storageScroll->SetTag("DevSystemInfoBuildConfig"); + LinearLayout *storage = new LinearLayout(ORIENT_VERTICAL); + storage->SetSpacing(0); + storageScroll->Add(storage); + tabHolder->AddTab(si->T("Storage"), storageScroll); + + storage->Add(new ItemHeader(si->T("Directories"))); + // Intentionally non-translated + storage->Add(new InfoItem("MemStickDirectory", g_Config.memStickDirectory)); + storage->Add(new InfoItem("InternalDataDirectory", g_Config.internalDataDirectory)); + storage->Add(new InfoItem("AppCacheDir", g_Config.appCacheDirectory)); + storage->Add(new InfoItem("ExtStorageDir", g_Config.externalDirectory)); + +#if PPSSPP_PLATFORM(ANDROID) + storage->Add(new InfoItem("ExtFilesDir", g_extFilesDir)); +#endif + ViewGroup *buildConfigScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); buildConfigScroll->SetTag("DevSystemInfoBuildConfig"); LinearLayout *buildConfig = new LinearLayout(ORIENT_VERTICAL); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 93bf0dfbb418..d958181536ed 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -492,6 +492,8 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch g_Config.externalDirectory = external_dir; #if defined(__ANDROID__) + // TODO: This needs to change in Android 12. + // // Maybe there should be an option to use internal memory instead, but I think // that for most people, using external memory (SDCard/USB Storage) makes the // most sense. diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 6b71ea07d604..0690c702a2ed 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -93,6 +93,9 @@ struct JNIEnv {}; bool useCPUThread = true; +// We'll turn this on when we target Android 12. +bool useScopedStorageIfRequired = false; + enum class EmuThreadState { DISABLED, START_REQUESTED, @@ -124,6 +127,8 @@ std::string langRegion; std::string mogaVersion; std::string boardName; +std::string g_extFilesDir; + std::vector g_additionalStorageDirs; static float left_joystick_x_async; @@ -445,6 +450,9 @@ bool System_GetPropertyBool(SystemProperty prop) { #endif case SYSPROP_CAN_JIT: return true; + case SYSPROP_ANDROID_SCOPED_STORAGE: + if (useScopedStorageIfRequired && androidVersion >= 28) + return true; default: return false; } @@ -560,7 +568,7 @@ static void parse_args(std::vector &args, const std::string value) extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init (JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath, - jstring jdataDir, jstring jexternalStorageDir, jstring jadditionalStorageDirs, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam, + jstring jdataDir, jstring jexternalStorageDir, jstring jexternalFilesDir, jstring jadditionalStorageDirs, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam, jint jAndroidVersion, jstring jboard) { setCurrentThreadName("androidInit"); @@ -592,6 +600,9 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init std::string externalStorageDir = GetJavaString(env, jexternalStorageDir); std::string additionalStorageDirsString = GetJavaString(env, jadditionalStorageDirs); + std::string externalFilesDir = GetJavaString(env, jexternalFilesDir); + + g_extFilesDir = externalFilesDir; if (!additionalStorageDirsString.empty()) { SplitString(additionalStorageDirsString, ':', g_additionalStorageDirs); diff --git a/android/jni/app-android.h b/android/jni/app-android.h index aa21dd9ade4c..276d55810f17 100644 --- a/android/jni/app-android.h +++ b/android/jni/app-android.h @@ -17,3 +17,5 @@ class AndroidLogger : public LogListener { public: void Log(const LogMessage &message) override; }; + +extern std::string g_extFilesDir; diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 598bd3849fb8..8b3aae2eea4b 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -402,8 +402,10 @@ public void Initialize() { String extStorageState = Environment.getExternalStorageState(); String extStorageDir = Environment.getExternalStorageDirectory().getAbsolutePath(); + String externalFilesDir = this.getExternalFilesDir(null).getAbsolutePath(); Log.i(TAG, "Ext storage: " + extStorageState + " " + extStorageDir); + Log.i(TAG, "Ext files dir: " + externalFilesDir); String additionalStorageDirs = ""; try { @@ -442,7 +444,7 @@ public void Initialize() { overrideShortcutParam = null; NativeApp.audioConfig(optimalFramesPerBuffer, optimalSampleRate); - NativeApp.init(model, deviceType, languageRegion, apkFilePath, dataDir, extStorageDir, additionalStorageDirs, libraryDir, cacheDir, shortcut, Build.VERSION.SDK_INT, Build.BOARD); + NativeApp.init(model, deviceType, languageRegion, apkFilePath, dataDir, extStorageDir, externalFilesDir, additionalStorageDirs, libraryDir, cacheDir, shortcut, Build.VERSION.SDK_INT, Build.BOARD); // Allow C++ to tell us to use JavaGL or not. javaGL = "true".equalsIgnoreCase(NativeApp.queryConfig("androidJavaGL")); diff --git a/android/src/org/ppsspp/ppsspp/NativeApp.java b/android/src/org/ppsspp/ppsspp/NativeApp.java index 4a72d4c6a99a..9442f9b809a7 100644 --- a/android/src/org/ppsspp/ppsspp/NativeApp.java +++ b/android/src/org/ppsspp/ppsspp/NativeApp.java @@ -12,7 +12,7 @@ public class NativeApp { public static final int DEVICE_TYPE_TV = 1; public static final int DEVICE_TYPE_DESKTOP = 2; - public static native void init(String model, int deviceType, String languageRegion, String apkPath, String dataDir, String externalStorageDir, String additionalStorageDirs, String libraryDir, String cacheDir, String shortcutParam, int androidVersion, String board); + public static native void init(String model, int deviceType, String languageRegion, String apkPath, String dataDir, String externalStorageDir, String extFilesDir, String additionalStorageDirs, String libraryDir, String cacheDir, String shortcutParam, int androidVersion, String board); public static native void audioInit(); public static native void audioShutdown(); public static native void audioConfig(int optimalFramesPerBuffer, int optimalSampleRate);