From cf5f737f53be381207f44887c800d822d4a2e038 Mon Sep 17 00:00:00 2001
From: Simon <6168240+DrBeef@users.noreply.github.com>
Date: Wed, 1 May 2024 22:40:39 +0100
Subject: [PATCH] Various version upgrades
Gradle 8
API level 32
Using Scoped Storage
NDK version 25
---
Projects/Android/AndroidManifest.xml | 4 +
Projects/Android/build.gradle | 121 +++++++--
.../gradle/wrapper/gradle-wrapper.properties | 2 +-
.../jni/QuakeQuestSrc/QuakeQuest_OpenXR.c | 2 +-
Projects/Android/local.properties | 1 -
Projects/Android/settings.gradle | 3 -
XrApp.gradle | 238 ------------------
build.gradle | 22 --
gradle.properties | 7 +-
.../drbeef/quakequest/GLES3JNIActivity.java | 27 +-
local.properties | 1 -
11 files changed, 137 insertions(+), 291 deletions(-)
delete mode 100644 XrApp.gradle
delete mode 100644 build.gradle
diff --git a/Projects/Android/AndroidManifest.xml b/Projects/Android/AndroidManifest.xml
index 614da97..da5e543 100644
--- a/Projects/Android/AndroidManifest.xml
+++ b/Projects/Android/AndroidManifest.xml
@@ -25,12 +25,14 @@
+
+
+
diff --git a/Projects/Android/build.gradle b/Projects/Android/build.gradle
index b9e1731..07a5f94 100644
--- a/Projects/Android/build.gradle
+++ b/Projects/Android/build.gradle
@@ -1,7 +1,20 @@
+buildscript {
+ repositories {
+ google() // For Gradle 4.0+
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.2.1'
+ }
+}
+
apply plugin: 'com.android.application'
-apply from: "${rootProject.projectDir}/XrApp.gradle"
android {
+
+ namespace = "com.drbeef.quakequest"
+
// This is the name of the generated apk file, which will have
// -debug.apk or -release.apk appended to it.
// The filename doesn't effect the Android installation process.
@@ -15,19 +28,82 @@ android {
applicationId "com.drbeef." + project.archivesBaseName
// override app plugin abiFilters for both 32 and 64-bit support
- externalNativeBuild {
- ndk {
- abiFilters 'arm64-v8a'
- }
- ndkBuild {
- abiFilters 'arm64-v8a'
- }
- }
+ externalNativeBuild {
+ ndk {
+ abiFilters 'arm64-v8a'
+ }
+ ndkBuild {
+ abiFilters 'arm64-v8a'
+ }
+ }
- minSdkVersion 26
- targetSdkVersion 26
+ minSdkVersion 32
+ targetSdkVersion 32
}
+ externalNativeBuild {
+ ndkBuild {
+ path file('jni/Android.mk')
+ }
+ }
+
+ signingConfigs {
+ def keystorePath = (project.hasProperty('key.store')) ?
+ new File(project.getProperty('key.store')) :
+ project.file('android.debug.keystore')
+
+ def keystorePassword = (project.hasProperty('key.store.password')) ?
+ project.getProperty('key.store.password') : 'android'
+
+ def keystoreKeyAlias = (project.hasProperty('key.alias')) ?
+ project.getProperty('key.alias') : 'androiddebugkey'
+
+ def keystoreKeyPassword = (project.hasProperty('key.alias.password')) ?
+ project.getProperty('key.alias.password') : 'android'
+
+ debug {
+ storeFile keystorePath
+ storePassword keystorePassword
+ keyAlias keystoreKeyAlias
+ keyPassword keystoreKeyPassword
+ v2SigningEnabled true
+ }
+
+ release {
+ storeFile keystorePath
+ storePassword keystorePassword
+ keyAlias keystoreKeyAlias
+ keyPassword keystoreKeyPassword
+ v2SigningEnabled true
+ }
+ }
+
+ buildTypes {
+ debug {
+ signingConfig signingConfigs.debug
+ debuggable true
+ jniDebuggable true
+
+ externalNativeBuild {
+ ndkBuild {
+ arguments "NDK_DEBUG=1","USE_ASAN=1"
+ }
+ }
+ }
+
+ release {
+ signingConfig signingConfigs.release
+ debuggable false
+ jniDebuggable false
+
+ externalNativeBuild {
+ ndkBuild {
+ arguments "NDK_DEBUG=0","USE_ASAN=0"
+ }
+ }
+ }
+ }
+
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
@@ -42,25 +118,40 @@ android {
targetCompatibility = '1.8'
}
+ lintOptions {
+ checkReleaseBuilds false
+ disable 'ExpiredTargetSdkVersion'
+ }
+
packagingOptions {
exclude 'lib/arm64-v8a/libopenxr_loader.so'
}
+ compileSdkVersion = 32
- compileSdkVersion = 26
- buildToolsVersion = '29.0.1'
+ buildToolsVersion = '29.0.3'
+
+ ndkVersion '25.1.8937393'
}
dependencies {
- implementation "com.android.support:support-compat:26.1.0"
- implementation "com.android.support:support-core-utils:26.1.0"
+ implementation "com.android.support:support-compat:28.0.0"
+ implementation "com.android.support:support-core-utils:28.0.0"
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
repositories {
google()
}
+
buildscript {
repositories {
google()
}
+}
+
+// Workaround to fix issue in Android Studio Chipmunk 2021.2.1 and later
+// where opening a project would result in a 'prepareKotlinBuildScriptModel'
+// not found error
+if (!tasks.findByName("prepareKotlinBuildScriptModel")) {
+ tasks.register("prepareKotlinBuildScriptModel") {}
}
\ No newline at end of file
diff --git a/Projects/Android/gradle/wrapper/gradle-wrapper.properties b/Projects/Android/gradle/wrapper/gradle-wrapper.properties
index 7cb9b3b..352274c 100644
--- a/Projects/Android/gradle/wrapper/gradle-wrapper.properties
+++ b/Projects/Android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
diff --git a/Projects/Android/jni/QuakeQuestSrc/QuakeQuest_OpenXR.c b/Projects/Android/jni/QuakeQuestSrc/QuakeQuest_OpenXR.c
index f90564b..214da31 100644
--- a/Projects/Android/jni/QuakeQuestSrc/QuakeQuest_OpenXR.c
+++ b/Projects/Android/jni/QuakeQuestSrc/QuakeQuest_OpenXR.c
@@ -221,7 +221,7 @@ void VR_Init()
//init randomiser
srand(time(NULL));
- chdir("/sdcard/QuakeQuest");
+ chdir((char*)getenv("QUAKEQUEST_DIR"));
}
extern int runStatus;
diff --git a/Projects/Android/local.properties b/Projects/Android/local.properties
index 4494cdd..14c1faf 100644
--- a/Projects/Android/local.properties
+++ b/Projects/Android/local.properties
@@ -5,5 +5,4 @@
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
-ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk\\21.1.6352462
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk
diff --git a/Projects/Android/settings.gradle b/Projects/Android/settings.gradle
index a868f2f..71aad3f 100644
--- a/Projects/Android/settings.gradle
+++ b/Projects/Android/settings.gradle
@@ -1,4 +1 @@
-rootProject.projectDir = new File(settingsDir, '../..')
rootProject.name = "QuakeQuest"
-
-include ':', 'Projects:Android'
diff --git a/XrApp.gradle b/XrApp.gradle
deleted file mode 100644
index d349e51..0000000
--- a/XrApp.gradle
+++ /dev/null
@@ -1,238 +0,0 @@
-import org.gradle.internal.os.OperatingSystem;
-import com.android.ddmlib.AndroidDebugBridge
-import com.android.ddmlib.IDevice
-import com.android.ddmlib.CollectingOutputReceiver
-import org.apache.tools.ant.taskdefs.condition.Os
-
-buildscript {
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0'
- }
-
- tasks.register("wrapper")
-}
-
-class XrAppPlugin implements Plugin {
- Project project = null
-
- void installApk( IDevice device, File apkFile, String applicationId ) {
- project.logger.quiet "Installing ${applicationId} on device ${device.serialNumber}"
-
- String toinstall = "/data/local/tmp/toinstall.apk"
-
- try {
- device.pushFile( apkFile.path, toinstall )
- } catch ( Exception e ) {
- throw new RuntimeException( "Failed to push ${apkFile.path} to ${toinstall}. ${e}", e )
- }
-
- while ( true ) {
- try {
- device.installRemotePackage( toinstall, true )
- break
- } catch ( Exception e ) {
- project.logger.quiet "Failed to install ${applicationId} on device ${device.serialNumber} (${e}). Trying to uninstall first."
- }
- try {
- device.uninstallPackage( applicationId )
- } catch ( Exception e ) {
- throw new RuntimeException( "Failed to uninstall ${applicationId}. ${e}", e )
- }
- }
- }
-
- void stopApk( IDevice device, String packageName ) {
- CollectingOutputReceiver receiver = new CollectingOutputReceiver()
- device.executeShellCommand( "am force-stop ${packageName}", receiver )
- }
-
- void runApk( IDevice device, manifestFile ) {
- CollectingOutputReceiver receiver = new CollectingOutputReceiver()
- def activityClass = new XmlSlurper().parse( manifestFile ).application.activity.find{ it.'intent-filter'.find{ filter ->
- return filter.action .find{it.'@android:name'.text() == 'android.intent.action.MAIN' } \
- && ( filter.category.find{it.'@android:name'.text() == 'android.intent.category.LAUNCHER'} \
- || filter.category.find{it.'@android:name'.text() == 'android.intent.category.INFO'} )
- }}.'@android:name'
- def startActivity = "${project.android.defaultConfig.applicationId}/${activityClass}"
- project.logger.quiet "Starting \'$startActivity\' on ${project.deviceMap.size()} devices:"
- project.logger.quiet "- ${device.serialNumber}"
- device.executeShellCommand( "am start $startActivity", receiver )
- }
-
- void apply( Project project ) {
- this.project = project
-
- // FIXME: The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
- project.task( "cleanWorkAround" ) {
- description "Workaround for .externalNativeBuild not being deleted on clean"
- }.doLast {
- project.delete project.file( ".externalNativeBuild" )
- }
-
- project.android {
- compileSdkVersion 26
-
- defaultConfig {
- minSdkVersion 24
- targetSdkVersion 25
-
- externalNativeBuild {
- ndk {
- }
- ndkBuild {
- def numProcs = Runtime.runtime.availableProcessors()
- arguments "V=0", "-j$numProcs", "-C$project.buildDir.parent", "APP_PLATFORM=android-24", "NDK_TOOLCHAIN_VERSION=clang", "APP_STL=c++_static"
- }
- }
- }
-
- externalNativeBuild {
- ndkBuild {
- path 'jni/Android.mk'
- }
- }
-
- signingConfigs {
- def keystorePath = (project.hasProperty('key.store')) ?
- new File(project.getProperty('key.store')) :
- project.file('android.debug.keystore')
-
- def keystorePassword = (project.hasProperty('key.store.password')) ?
- project.getProperty('key.store.password') : 'android'
-
- def keystoreKeyAlias = (project.hasProperty('key.alias')) ?
- project.getProperty('key.alias') : 'androiddebugkey'
-
- def keystoreKeyPassword = (project.hasProperty('key.alias.password')) ?
- project.getProperty('key.alias.password') : 'android'
-
- debug {
- storeFile keystorePath
- storePassword keystorePassword
- keyAlias keystoreKeyAlias
- keyPassword keystoreKeyPassword
- v2SigningEnabled true
- }
-
- release {
- storeFile keystorePath
- storePassword keystorePassword
- keyAlias keystoreKeyAlias
- keyPassword keystoreKeyPassword
- v2SigningEnabled true
- }
- }
-
- buildTypes {
- debug {
- signingConfig signingConfigs.debug
- debuggable true
- jniDebuggable true
-
- externalNativeBuild {
- ndkBuild {
- arguments "NDK_DEBUG=1","USE_ASAN=1"
- }
- }
- }
-
- release {
- signingConfig signingConfigs.release
- debuggable false
- jniDebuggable false
-
- externalNativeBuild {
- ndkBuild {
- arguments "NDK_DEBUG=0","USE_ASAN=0"
- }
- }
- }
- }
- }
-
- // WORKAROUND: On Mac OS X, running ndk-build clean with a high num of parallel executions
- // set may result in the following build error: rm: fts_read: No such file or directory.
- // Currently, there isn't a good way to specify numProcs=1 only on clean. So, in order
- // to work around the issue, delete the auto-generated .externalNativeBuild artifacts
- // (where $numProcs specified) before executing the clean task.
- project.clean.dependsOn project.cleanWorkAround
-
- project.clean {
- // remove the auto-generated debug keystore (currently generated by python build script)
- // delete "android.debug.keystore"
- }
-
- project.afterEvaluate {
- Task initDeviceList = project.task( "initDeviceList()" ).doLast {
- project.ext.deviceMap = [ : ]
- if (project.hasProperty( "should_install" ) == true) {
- AndroidDebugBridge.initIfNeeded( false )
- AndroidDebugBridge bridge = AndroidDebugBridge.createBridge( project.android.getAdbExe().absolutePath, false )
-
- long timeOut = 30000 // 30 sec
- int sleepTime = 1000
- while ( !bridge.hasInitialDeviceList() && timeOut > 0 ) {
- sleep( sleepTime )
- timeOut -= sleepTime
- }
- if ( timeOut <= 0 && !bridge.hasInitialDeviceList() ) {
- throw new RuntimeException( "Timeout getting device list.", null )
- }
-
- // if a device is connected both physically and over the network, only include the physical ID
- if ( project.hasProperty( "should_install" ) == true ) {
- bridge.devices.split { it.getProperty( "ro.serialno" ) != it.serialNumber }.each {
- it.collectEntries( project.deviceMap, { [ ( it.getProperty( "ro.serialno" )) : it ] } )
- }
- }
- }
- }
-
- project.task( "stopApk", dependsOn: initDeviceList ) {
- description "Stops app if currently running on device"
- }.doLast {
- project.deviceMap.each { deviceSerial, device ->
- stopApk( device, android.defaultConfig.applicationId )
- }
- }
-
- project.android.applicationVariants.all { variant ->
- Task installAndRun = project.task( "installAndRun${variant.name.capitalize()}" ) {
- dependsOn variant.assembleProvider.get()
- dependsOn initDeviceList
- onlyIf { project.hasProperty( "should_install" ) }
- description "Installs and runs the APK file"
- }.doLast { variant.outputs.each { output ->
- if ( output.outputFile.exists() ) {
- if ( project.deviceMap.size() == 0 ) {
- project.logger.quiet "Install requested, but no devices found."
- } else {
- project.deviceMap.each { deviceSerial, device ->
- installApk( device, output.outputFile, project.android.defaultConfig.applicationId )
- runApk( device, new File(output.processManifest.manifestOutputDirectory.get().asFile, "AndroidManifest.xml"))
- }
- }
- }
- }
- }
- variant.assembleProvider.get().finalizedBy installAndRun
- }
- }
- }
-}
-
-// Workaround to fix issue in Android Studio Chipmunk 2021.2.1 and later
-// where opening a project would result in a 'prepareKotlinBuildScriptModel'
-// not found error
-if (!tasks.findByName("prepareKotlinBuildScriptModel")) {
- tasks.register("prepareKotlinBuildScriptModel") {}
-}
-
-
-
-apply plugin: XrAppPlugin
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 05092ac..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,22 +0,0 @@
-buildscript {
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0'
- }
-}
-
-allprojects {
- repositories {
- google()
- jcenter()
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
-
diff --git a/gradle.properties b/gradle.properties
index b38e197..a8083b7 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,8 @@
-org.gradle.jvmargs=-Xmx1536M
+org.gradle.jvmargs=-Xmx1536M \
+--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
+--add-opens=java.base/java.lang=ALL-UNNAMED \
+--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
+--add-opens=java.base/java.io=ALL-UNNAMED \
+--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
org.gradle.caching=true
org.gradle.configureondemand=true
diff --git a/java/com/drbeef/quakequest/GLES3JNIActivity.java b/java/com/drbeef/quakequest/GLES3JNIActivity.java
index 0202b56..cf98383 100644
--- a/java/com/drbeef/quakequest/GLES3JNIActivity.java
+++ b/java/com/drbeef/quakequest/GLES3JNIActivity.java
@@ -21,6 +21,7 @@ import android.content.res.AssetManager;
import android.os.Build;
import android.os.Bundle;
+import android.system.ErrnoException;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -66,6 +67,8 @@ import android.support.v4.content.ContextCompat;
private SurfaceHolder mSurfaceHolder;
private long mNativeHandle;
+ String dir;
+
private final boolean m_asynchronousTracking = false;
@Override protected void onCreate( Bundle icicle )
@@ -78,6 +81,8 @@ import android.support.v4.content.ContextCompat;
setContentView( mView );
mView.getHolder().addCallback( this );
+ dir = getBaseContext().getExternalFilesDir(null).getAbsolutePath();
+
// Force the screen to stay on, rather than letting it dim and shut off
// while the user is watching a movie.
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
@@ -120,7 +125,12 @@ import android.support.v4.content.ContextCompat;
if (permissionCount == 2) {
// Permissions have already been granted.
- create();
+ try {
+ create();
+ } catch (Exception ignored)
+ {
+
+ }
}
}
@@ -150,22 +160,23 @@ import android.support.v4.content.ContextCompat;
checkPermissionsAndInitialize();
}
- public void create()
- {
+ public void create() throws ErrnoException {
//This will copy the shareware version of quake if user doesn't have anything installed
- copy_asset("/sdcard/QuakeQuest/id1", "pak0.pak");
- copy_asset("/sdcard/QuakeQuest/id1", "config.cfg");
- copy_asset("/sdcard/QuakeQuest", "commandline.txt");
+ copy_asset(dir + "/id1", "pak0.pak");
+ copy_asset(dir + "/id1", "config.cfg");
+ copy_asset(dir, "commandline.txt");
+
+ setenv("QUAKEQUEST_DIR", dir, true);
//Read these from a file and pass through
commandLineParams = new String("quake");
//See if user is trying to use command line params
- if(new File("/sdcard/QuakeQuest/commandline.txt").exists()) // should exist!
+ if(new File(dir + "/commandline.txt").exists()) // should exist!
{
BufferedReader br;
try {
- br = new BufferedReader(new FileReader("/sdcard/QuakeQuest/commandline.txt"));
+ br = new BufferedReader(new FileReader(dir + "/commandline.txt"));
String s;
StringBuilder sb=new StringBuilder(0);
while ((s=br.readLine())!=null)
diff --git a/local.properties b/local.properties
index 4494cdd..14c1faf 100644
--- a/local.properties
+++ b/local.properties
@@ -5,5 +5,4 @@
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
-ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk\\21.1.6352462
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk