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;
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);
{
mNextDeviceId = mSharedPreferences.getInt("next_device_id", 0);
}
-
- initializeUSB();
- initializeBluetooth();
}
public Context getContext() {
private void initializeUSB() {
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
+ if (mUsbManager == null) {
+ return;
+ }
/*
// Logging
0x15e4, // Numark
0x162e, // Joytech
0x1689, // Razer Onza
+ 0x1949, // Lab126, Inc.
0x1bad, // Harmonix
0x24c6, // PowerA
};
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);
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 <= 30 &&
+ 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)) {
+ 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) {
////////// 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);
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) {
+ 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);