Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

android: Update to SDL 2.30.9, Android 14; fix Android 11+ support #505

Merged
merged 1 commit into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arch/android/Makefile.deps
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ endif
# the android project from the new SDL release (SDL/android-project/app/src/...).
#

SDL_VERSION ?= 2.28.2
SDL_VERSION ?= 2.30.9
LIBOGG_VERSION ?= 1.3.5
LIBVORBIS_VERSION ?= 1.3.7
WGET ?= wget
Expand Down
9 changes: 5 additions & 4 deletions arch/android/project/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ android {
keyPassword keystoreProperties['keyPassword']
}
}
namespace "net.digitalmzx.megazeux"
ndkVersion "23.2.8568313"
compileSdkVersion 31
buildToolsVersion "30.0.3"
compileSdkVersion 34
buildToolsVersion "34.0.0"
defaultConfig {
if (buildAsApplication) {
applicationId "net.digitalmzx.megazeux"
}
minSdkVersion 16
targetSdkVersion 31
targetSdkVersion 34
versionCode 1
versionName "1.0"
externalNativeBuild {
Expand Down Expand Up @@ -62,7 +63,7 @@ android {
}

}
lintOptions {
lint {
abortOnError false
}

Expand Down
4 changes: 2 additions & 2 deletions arch/android/project/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="net.digitalmzx.megazeux"
android:installLocation="auto">

<!-- OpenGL ES 2.0 -->
Expand Down Expand Up @@ -30,6 +29,7 @@

<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
<!-- <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> -->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> -->
Expand All @@ -42,7 +42,7 @@
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".GameActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
import android.provider.Settings;
import android.view.View;

import java.io.File;
Expand All @@ -37,20 +40,56 @@

public class MainActivity extends Activity
{
private static final int MANAGE_EXTERNAL_STORAGE_INTENT_CODE = 100;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

if(Build.VERSION.SDK_INT >= 23)
// Ensure all necessary permissions are present
if(Build.VERSION.SDK_INT >= 30 /* Android 11.0 */)
{
if(!Environment.isExternalStorageManager())
{
try
{
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_INTENT_CODE);
}
catch (Exception e)
{
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_INTENT_CODE);
}
return;
}
}
else

if(Build.VERSION.SDK_INT >= 23 /* Android 6.0 */)
{
if(checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
return;
}
}

launchGame();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(Build.VERSION.SDK_INT >= 30 /* Android 11.0 */)
{
if(requestCode == MANAGE_EXTERNAL_STORAGE_INTENT_CODE)
{
if(Environment.isExternalStorageManager())
launchGame();
}
else
launchGame();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,11 @@ private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterfa
final int XB1_IFACE_SUBCLASS = 71;
final int XB1_IFACE_PROTOCOL = 208;
final int[] SUPPORTED_VENDORS = {
0x03f0, // HP
0x044f, // Thrustmaster
0x045e, // Microsoft
0x0738, // Mad Catz
0x0b05, // ASUS
0x0e6f, // PDP
0x0f0d, // Hori
0x10f5, // Turtle Beach
Expand All @@ -284,6 +286,7 @@ private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterfa
0x24c6, // PowerA
0x2dc8, // 8BitDo
0x2e24, // Hyperkin
0x3537, // Gamesir
};

if (usbInterface.getId() == 0 &&
Expand Down Expand Up @@ -357,6 +360,12 @@ private void connectHIDDeviceUSB(UsbDevice usbDevice) {
private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth");

if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ &&
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
return;
}

if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
Expand Down Expand Up @@ -582,7 +591,13 @@ public boolean openDevice(int deviceID) {
} else {
flags = 0;
}
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
if (Build.VERSION.SDK_INT >= 33 /* Android 14.0 (U) */) {
Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION);
intent.setPackage(mContext.getPackageName());
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags));
} else {
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
}
} catch (Exception e) {
Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
HIDDeviceOpenResult(deviceID, false);
Expand Down
13 changes: 8 additions & 5 deletions arch/android/project/app/src/main/java/org/libsdl/app/SDL.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ public static Context getContext() {
}

public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
loadLibrary(libraryName, mContext);
}

public static void loadLibrary(String libraryName, Context context) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
if (libraryName == null) {
throw new NullPointerException("No library name provided.");
}
Expand All @@ -53,10 +56,10 @@ public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError,
// To use ReLinker, just add it as a dependency. For more information, see
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
//
Class<?> relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
Class<?> relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
Class<?> contextClass = mContext.getClassLoader().loadClass("android.content.Context");
Class<?> stringClass = mContext.getClassLoader().loadClass("java.lang.String");
Class<?> relinkClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
Class<?> relinkListenerClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
Class<?> contextClass = context.getClassLoader().loadClass("android.content.Context");
Class<?> stringClass = context.getClassLoader().loadClass("java.lang.String");

// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
// they've changed during updates.
Expand All @@ -66,7 +69,7 @@ public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError,

// Actually load the library!
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
loadMethod.invoke(relinkInstance, context, libraryName, null, null);
}
catch (final Throwable e) {
// Fall back
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 28;
private static final int SDL_MICRO_VERSION = 2;
private static final int SDL_MINOR_VERSION = 30;
private static final int SDL_MICRO_VERSION = 9;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
Expand Down Expand Up @@ -89,7 +89,7 @@ public static void debugSource(int sources, String prefix) {
| InputDevice.SOURCE_CLASS_POSITION
| InputDevice.SOURCE_CLASS_TRACKBALL);

if (s2 != 0) cls += "Some_Unkown";
if (s2 != 0) cls += "Some_Unknown";

s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;

Expand Down Expand Up @@ -163,7 +163,7 @@ public static void debugSource(int sources, String prefix) {
if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
s2 &= ~FLAG_TAINTED;

if (s2 != 0) src += " Some_Unkown";
if (s2 != 0) src += " Some_Unknown";

Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
}
Expand Down Expand Up @@ -281,7 +281,7 @@ protected String[] getLibraries() {
// Load the .so
public void loadLibraries() {
for (String lib : getLibraries()) {
SDL.loadLibrary(lib);
SDL.loadLibrary(lib, this);
}
}

Expand Down Expand Up @@ -995,8 +995,8 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint)
/* No valid hint, nothing is explicitly allowed */
if (!is_portrait_allowed && !is_landscape_allowed) {
if (resizable) {
/* All orientations are allowed */
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
/* All orientations are allowed, respecting user orientation lock setting */
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
} else {
/* Fixed window and nothing specified. Get orientation from w/h of created window */
req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
Expand All @@ -1005,8 +1005,8 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint)
/* At least one orientation is allowed */
if (resizable) {
if (is_portrait_allowed && is_landscape_allowed) {
/* hint allows both landscape and portrait, promote to full sensor */
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
/* hint allows both landscape and portrait, promote to full user */
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
} else {
/* Use the only one allowed "orientation" */
req = (is_landscape_allowed ? orientation_landscape : orientation_portrait);
Expand Down Expand Up @@ -1345,23 +1345,6 @@ public static boolean handleKeyEvent(View v, int keyCode, KeyEvent event, InputC
}
}

if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (isTextInputEvent(event)) {
if (ic != null) {
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
} else {
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
}
}
onNativeKeyDown(keyCode);
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
onNativeKeyUp(keyCode);
return true;
}
}

if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
// on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
// they are ignored here because sending them as mouse input to SDL is messy
Expand All @@ -1376,6 +1359,21 @@ public static boolean handleKeyEvent(View v, int keyCode, KeyEvent event, InputC
}
}

if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (isTextInputEvent(event)) {
if (ic != null) {
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
} else {
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
}
}
onNativeKeyDown(keyCode);
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
onNativeKeyUp(keyCode);
return true;
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,15 @@ public void pollHapticDevices() {
if (haptic == null) {
InputDevice device = InputDevice.getDevice(deviceIds[i]);
Vibrator vib = device.getVibrator();
if (vib.hasVibrator()) {
haptic = new SDLHaptic();
haptic.device_id = deviceIds[i];
haptic.name = device.getName();
haptic.vib = vib;
mHaptics.add(haptic);
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
if (vib != null) {
if (vib.hasVibrator()) {
haptic = new SDLHaptic();
haptic.device_id = deviceIds[i];
haptic.name = device.getName();
haptic.vib = vib;
mHaptics.add(haptic);
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion arch/android/project/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen">
<!-- Customize your theme here. -->
</style>

Expand Down
2 changes: 1 addition & 1 deletion arch/android/project/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.4'
classpath 'com.android.tools.build:gradle:8.7.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
Binary file modified arch/android/project/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 3 additions & 2 deletions arch/android/project/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#Sun May 02 07:03:49 EDT 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
Loading
Loading