mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Enable scoped storage enforcement on Android 11+.
This has a number of UX issues and bugs we need to work through, but at least games are playable, things mostly work. Upgrades are handled smoothly by keeping existing storage access until you uninstall. After a reinstall, you'll need to re-select your old PSP directory manually in settings :(
This commit is contained in:
parent
02449326cd
commit
793e79945f
6 changed files with 42 additions and 16 deletions
|
@ -23,6 +23,7 @@
|
|||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/GPU/OpenGL/GLFeatures.h"
|
||||
#include "Common/File/AndroidStorage.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/Net/HTTPClient.h"
|
||||
#include "Common/UI/Context.h"
|
||||
|
@ -59,12 +60,8 @@
|
|||
int GetD3DCompilerVersion();
|
||||
#endif
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
|
||||
#include "android/jni/app-android.h"
|
||||
|
||||
#endif
|
||||
|
||||
static const char *logLevelList[] = {
|
||||
"Notice",
|
||||
"Error",
|
||||
|
@ -595,6 +592,7 @@ void SystemInfoScreen::CreateViews() {
|
|||
if (System_GetPropertyBool(SYSPROP_ANDROID_SCOPED_STORAGE)) {
|
||||
storage->Add(new InfoItem("Scoped Storage", di->T("Yes")));
|
||||
}
|
||||
storage->Add(new InfoItem("IsStoragePreservedLegacy", Android_IsExternalStoragePreservedLegacy() ? di->T("Yes") : di->T("No")));
|
||||
#endif
|
||||
|
||||
ViewGroup *buildConfigScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
|
|
|
@ -978,7 +978,8 @@ void MainScreen::CreateViews() {
|
|||
tabHolder_->SetClip(true);
|
||||
|
||||
bool showRecent = g_Config.iMaxRecent > 0;
|
||||
bool hasStorageAccess = System_GetPermissionStatus(SYSTEM_PERMISSION_STORAGE) == PERMISSION_STATUS_GRANTED;
|
||||
bool hasStorageAccess = !System_GetPropertyBool(SYSPROP_SUPPORTS_PERMISSIONS) ||
|
||||
System_GetPermissionStatus(SYSTEM_PERMISSION_STORAGE) == PERMISSION_STATUS_GRANTED;
|
||||
bool storageIsTemporary = IsTempPath(GetSysDirectory(DIRECTORY_SAVEDATA)) && !confirmedTemporary_;
|
||||
if (showRecent && !hasStorageAccess) {
|
||||
showRecent = !g_Config.recentIsos.empty();
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
|
||||
|
@ -45,7 +45,9 @@
|
|||
android:logo="@drawable/ic_banner"
|
||||
android:isGame="true"
|
||||
android:banner="@drawable/tv_banner"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:preserveLegacyExternalStorage="true"
|
||||
>
|
||||
<meta-data android:name="android.max_aspect" android:value="2.4" />
|
||||
<activity
|
||||
android:name=".PpssppActivity"
|
||||
|
|
|
@ -44,8 +44,8 @@ android {
|
|||
}
|
||||
}
|
||||
}
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.3'
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion '30.0.0'
|
||||
defaultConfig {
|
||||
applicationId 'org.ppsspp.ppsspp'
|
||||
if (androidGitVersion.name() != "unknown" && androidGitVersion.code() >= 14000000) {
|
||||
|
@ -61,7 +61,7 @@ android {
|
|||
new File("versioncode.txt").write(androidGitVersion.code().toString())
|
||||
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 30
|
||||
if (project.hasProperty("ANDROID_VERSION_CODE") && project.hasProperty("ANDROID_VERSION_NAME")) {
|
||||
versionCode ANDROID_VERSION_CODE
|
||||
versionName ANDROID_VERSION_NAME
|
||||
|
|
|
@ -97,8 +97,18 @@ struct JNIEnv {};
|
|||
|
||||
bool useCPUThread = true;
|
||||
|
||||
// We'll turn this on when we target Android 12.
|
||||
bool useScopedStorageIfRequired = false;
|
||||
// We turn this on now that when we target Android 11+.
|
||||
// Along with adding:
|
||||
// android:preserveLegacyExternalStorage="true"
|
||||
// To the already requested:
|
||||
// android:requestLegacyExternalStorage="true"
|
||||
//
|
||||
// This will cause Android 11+ to still behave like Android 10 until the app
|
||||
// is manually uninstalled. We can detect this state with
|
||||
// Android_IsExternalStoragePreservedLegacy(), but most of the app will just see
|
||||
// that scoped storage enforcement is disabled in this case.
|
||||
|
||||
static const bool useScopedStorageIfRequired = true;
|
||||
|
||||
enum class EmuThreadState {
|
||||
DISABLED,
|
||||
|
@ -433,7 +443,15 @@ float System_GetPropertyFloat(SystemProperty prop) {
|
|||
bool System_GetPropertyBool(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_SUPPORTS_PERMISSIONS:
|
||||
return androidVersion >= 23; // 6.0 Marshmallow introduced run time permissions.
|
||||
if (androidVersion < 23) {
|
||||
// 6.0 Marshmallow introduced run time permissions.
|
||||
return false;
|
||||
} else {
|
||||
// It gets a bit complicated here. If scoped storage enforcement is on,
|
||||
// we also don't need to request permissions. We'll have the access we request
|
||||
// on a per-folder basis.
|
||||
return !System_GetPropertyBool(SYSPROP_ANDROID_SCOPED_STORAGE);
|
||||
}
|
||||
case SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE:
|
||||
return sustainedPerfSupported; // 7.0 introduced sustained performance mode as an optional feature.
|
||||
case SYSPROP_HAS_ADDITIONAL_STORAGE:
|
||||
|
@ -458,8 +476,14 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
|||
case SYSPROP_CAN_JIT:
|
||||
return true;
|
||||
case SYSPROP_ANDROID_SCOPED_STORAGE:
|
||||
if (useScopedStorageIfRequired && androidVersion >= 28)
|
||||
return true;
|
||||
if (useScopedStorageIfRequired && androidVersion >= 28) {
|
||||
// Here we do a check to see if we ended up in the preserveLegacyExternalStorage path.
|
||||
// That won't last if the user uninstalls/reinstalls though, but would preserve the user
|
||||
// experience for simple upgrades so maybe let's support it.
|
||||
return !Android_IsExternalStoragePreservedLegacy();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Intent;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
|
Loading…
Add table
Reference in a new issue