Skip to content

Commit

Permalink
Update SDL version used by Android to v2.30.0 (#72154)
Browse files Browse the repository at this point in the history
* Committing first shot at an automated builder script for Android SDL

* Updating, hopefully builds most SDL projects now

* third try at this, i think its working now

* last few changes, got everything to build

* Updated SDL java files based on v2.30.0 android sources with Cataclysm patches.

* build SDL sources based on my forked v2.30.0 repo with Cataclysm patches
  • Loading branch information
katemonster33 authored and Procyonae committed May 20, 2024
1 parent e8f7249 commit 217a94d
Show file tree
Hide file tree
Showing 10 changed files with 1,519 additions and 990 deletions.
Binary file modified android/app/deps.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public BluetoothGatt getGatt() {
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead
// of TRANSPORT_LE. Let's force ourselves to connect low energy.
private BluetoothGatt connectGatt(boolean managed) {
if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
try {
return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE);
} catch (Exception e) {
Expand Down Expand Up @@ -429,7 +429,7 @@ public void run() {
}
});
}
}
}
else if (newState == 0) {
mIsConnected = false;
}
Expand Down Expand Up @@ -564,10 +564,10 @@ public String getProductName() {
return "Steam Controller";
}

@Override
@Override
public UsbDevice getDevice() {
return null;
}
return null;
}

@Override
public boolean open() {
Expand Down
96 changes: 59 additions & 37 deletions android/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.os.Build;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Context;
Expand Down Expand Up @@ -104,36 +105,6 @@ public void onReceive(Context context, Intent intent) {
private HIDDeviceManager(final Context context) {
mContext = context;

// Make sure we have the HIDAPI library loaded with the native functions
try {
SDL.loadLibrary("hidapi");
} catch (Throwable e) {
Log.w(TAG, "Couldn't load hidapi: " + e.toString());

AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false);
builder.setTitle("SDL HIDAPI Error");
builder.setMessage("Please report the following error to the SDL maintainers: " + e.getMessage());
builder.setNegativeButton("Quit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
// If our context is an activity, exit rather than crashing when we can't
// call our native functions.
Activity activity = (Activity)context;

activity.finish();
}
catch (ClassCastException cce) {
// Context wasn't an activity, there's nothing we can do. Give up and return.
}
}
});
builder.show();

return;
}

HIDDeviceRegisterCallback();

mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
Expand All @@ -148,9 +119,6 @@ public void onClick(DialogInterface dialog, int which) {
{
mNextDeviceId = mSharedPreferences.getInt("next_device_id", 0);
}

initializeUSB();
initializeBluetooth();
}

public Context getContext() {
Expand All @@ -173,6 +141,9 @@ public int getDeviceIDForIdentifier(String identifier) {

private void initializeUSB() {
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
if (mUsbManager == null) {
return;
}

/*
// Logging
Expand All @@ -199,7 +170,7 @@ private void initializeUSB() {
Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
// Get endpoint details
// Get endpoint details
for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
{
UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
Expand Down Expand Up @@ -275,8 +246,13 @@ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterfa
0x15e4, // Numark
0x162e, // Joytech
0x1689, // Razer Onza
0x1949, // Lab126, Inc.
0x1bad, // Harmonix
0x20d6, // PowerA
0x24c6, // PowerA
0x2c22, // Qanba
0x2dc8, // 8BitDo
0x9886, // ASTRO Gaming
};

if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
Expand All @@ -297,13 +273,19 @@ 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
0x0e6f, // PDP
0x0f0d, // Hori
0x10f5, // Turtle Beach
0x1532, // Razer Wildcat
0x20d6, // PowerA
0x24c6, // PowerA
0x2dc8, // 8BitDo
0x2e24, // Hyperkin
0x3537, // GameSir
};

if (usbInterface.getId() == 0 &&
Expand Down Expand Up @@ -353,9 +335,18 @@ private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_g

private void connectHIDDeviceUSB(UsbDevice usbDevice) {
synchronized (this) {
int interface_mask = 0;
for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) {
UsbInterface usbInterface = usbDevice.getInterface(interface_index);
if (isHIDDeviceInterface(usbDevice, usbInterface)) {
// Check to see if we've already added this interface
// This happens with the Xbox Series X controller which has a duplicate interface 0, which is inactive
int interface_id = usbInterface.getId();
if ((interface_mask & (1 << interface_id)) != 0) {
continue;
}
interface_mask |= (1 << interface_id);

HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index);
int id = device.getId();
mDevicesById.put(id, device);
Expand All @@ -368,11 +359,23 @@ private void connectHIDDeviceUSB(UsbDevice usbDevice) {
private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth");

if (mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
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");
return;
}

if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18 /* Android 4.3 (JELLY_BEAN_MR2) */)) {
Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
return;
}

// Find bonded bluetooth controllers and create SteamControllers for them
mBluetoothManager = (BluetoothManager)mContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Expand Down Expand Up @@ -533,7 +536,7 @@ public void setFrozen(boolean frozen) {
for (HIDDevice device : mDevicesById.values()) {
device.setFrozen(frozen);
}
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -555,6 +558,18 @@ private HIDDevice getDevice(int id) {
////////// JNI interface functions
//////////////////////////////////////////////////////////////////////////////////////////////////////

public boolean initialize(boolean usb, boolean bluetooth) {
Log.v(TAG, "initialize(" + usb + ", " + bluetooth + ")");

if (usb) {
initializeUSB();
}
if (bluetooth) {
initializeBluetooth();
}
return true;
}

public boolean openDevice(int deviceID) {
Log.v(TAG, "openDevice deviceID=" + deviceID);
HIDDevice device = getDevice(deviceID);
Expand All @@ -568,7 +583,14 @@ public boolean openDevice(int deviceID) {
if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
HIDDeviceOpenPending(deviceID);
try {
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
int flags;
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
flags = FLAG_MUTABLE;
} else {
flags = 0;
}
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
6 changes: 3 additions & 3 deletions android/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public int getProductId() {
@Override
public String getSerialNumber() {
String result = null;
if (Build.VERSION.SDK_INT >= 21) {
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
try {
result = mDevice.getSerialNumber();
}
Expand All @@ -74,7 +74,7 @@ public int getVersion() {
@Override
public String getManufacturerName() {
String result = null;
if (Build.VERSION.SDK_INT >= 21) {
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
result = mDevice.getManufacturerName();
}
if (result == null) {
Expand All @@ -86,7 +86,7 @@ public String getManufacturerName() {
@Override
public String getProductName() {
String result = null;
if (Build.VERSION.SDK_INT >= 21) {
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
result = mDevice.getProductName();
}
if (result == null) {
Expand Down
16 changes: 9 additions & 7 deletions android/app/src/main/java/org/libsdl/app/SDL.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import android.content.Context;

import java.lang.reflect.*;
import java.lang.Class;
import java.lang.reflect.Method;

/**
SDL library initialization
Expand All @@ -28,6 +29,7 @@ public static void initialize() {

// This function stores the current activity (SDL or not)
public static void setContext(Context context) {
SDLAudioManager.setContext(context);
mContext = context;
}

Expand All @@ -51,16 +53,16 @@ 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 = 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");

// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
// they've changed during updates.
Method forceMethod = relinkClass.getDeclaredMethod("force");
Object relinkInstance = forceMethod.invoke(null);
Class relinkInstanceClass = relinkInstance.getClass();
Class<?> relinkInstanceClass = relinkInstance.getClass();

// Actually load the library!
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
Expand All @@ -77,7 +79,7 @@ public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError,
catch (final SecurityException se) {
throw se;
}
}
}
}

protected static Context mContext;
Expand Down
Loading

0 comments on commit 217a94d

Please sign in to comment.