diff --git a/android/app/jni/CMakeLists.txt b/android/app/jni/CMakeLists.txt index b93e6ac..c714242 100644 --- a/android/app/jni/CMakeLists.txt +++ b/android/app/jni/CMakeLists.txt @@ -7,11 +7,10 @@ project(GAME) # android_ndk_import_module_cpufeatures() include(FetchContent) -# TODO: Use SDL2 2.0.11 once released FetchContent_Declare( SDL - URL https://hg.libsdl.org/SDL/archive/a5f93b21dfe0.tar.gz # rev 13383 - URL_HASH SHA1=a7e9696f7ef8af7c4b89671b096c38d1a4cbf90c + URL http://libsdl.org/release/SDL2-2.0.12.tar.gz + URL_HASH SHA1=e8ba91bf5eb438dbcf1fedf0530a1bcbe30d3bb6 PATCH_COMMAND patch -p1 -i ${CMAKE_CURRENT_LIST_DIR}/SDL.patch ) # TODO: Use SDL2_ttf 2.0.16 once released diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c8a5bc8..e951bb8 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -16,17 +16,31 @@ android:required="false" /> + + + + + + + + diff --git a/android/app/src/main/java/org/libsdl/app/HIDDevice.java b/android/app/src/main/java/org/libsdl/app/HIDDevice.java index aa358d1..955df5d 100644 --- a/android/app/src/main/java/org/libsdl/app/HIDDevice.java +++ b/android/app/src/main/java/org/libsdl/app/HIDDevice.java @@ -1,5 +1,7 @@ package org.libsdl.app; +import android.hardware.usb.UsbDevice; + interface HIDDevice { public int getId(); @@ -9,6 +11,7 @@ interface HIDDevice public int getVersion(); public String getManufacturerName(); public String getProductName(); + public UsbDevice getDevice(); public boolean open(); public int sendFeatureReport(byte[] report); public int sendOutputReport(byte[] report); diff --git a/android/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/android/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java index 51538fa..94a2818 100644 --- a/android/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java +++ b/android/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java @@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothGattService; +import android.hardware.usb.UsbDevice; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -165,13 +166,13 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe mHandler = new Handler(Looper.getMainLooper()); mGatt = connectGatt(); - final HIDDeviceBLESteamController finalThis = this; - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - finalThis.checkConnectionForChromebookIssue(); - } - }, CHROMEBOOK_CONNECTION_CHECK_INTERVAL); + // final HIDDeviceBLESteamController finalThis = this; + // mHandler.postDelayed(new Runnable() { + // @Override + // public void run() { + // finalThis.checkConnectionForChromebookIssue(); + // } + // }, CHROMEBOOK_CONNECTION_CHECK_INTERVAL); } public String getIdentifier() { @@ -469,7 +470,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe // Only register controller with the native side once it has been fully configured if (!isRegistered()) { Log.v(TAG, "Registering Steam Controller with ID: " + getId()); - mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0); + mManager.HIDDeviceConnected(getId(), getIdentifier(), getVendorId(), getProductId(), getSerialNumber(), getVersion(), getManufacturerName(), getProductName(), 0, 0, 0, 0); setRegistered(); } } @@ -563,6 +564,11 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe return "Steam Controller"; } + @Override + public UsbDevice getDevice() { + return null; + } + @Override public boolean open() { return true; diff --git a/android/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android/app/src/main/java/org/libsdl/app/HIDDeviceManager.java index bdd14aa..56f677e 100644 --- a/android/app/src/main/java/org/libsdl/app/HIDDeviceManager.java +++ b/android/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -19,8 +19,9 @@ import android.hardware.usb.*; import android.os.Handler; import android.os.Looper; -import java.util.HashMap; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; public class HIDDeviceManager { @@ -50,7 +51,6 @@ public class HIDDeviceManager { private Context mContext; private HashMap mDevicesById = new HashMap(); - private HashMap mUSBDevices = new HashMap(); private HashMap mBluetoothDevices = new HashMap(); private int mNextDeviceId = 0; private SharedPreferences mSharedPreferences = null; @@ -241,17 +241,7 @@ public class HIDDeviceManager { } } - private boolean isHIDDeviceUSB(UsbDevice usbDevice) { - for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); ++interface_number) { - if (isHIDDeviceInterface(usbDevice, interface_number)) { - return true; - } - } - return false; - } - - private boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) { - UsbInterface usbInterface = usbDevice.getInterface(interface_number); + private boolean isHIDDeviceInterface(UsbDevice usbDevice, UsbInterface usbInterface) { if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) { return true; } @@ -331,45 +321,45 @@ public class HIDDeviceManager { } private void handleUsbDeviceAttached(UsbDevice usbDevice) { - if (isHIDDeviceUSB(usbDevice)) { - connectHIDDeviceUSB(usbDevice); - } + connectHIDDeviceUSB(usbDevice); } private void handleUsbDeviceDetached(UsbDevice usbDevice) { - HIDDeviceUSB device = mUSBDevices.get(usbDevice); - if (device == null) - return; - - int id = device.getId(); - mUSBDevices.remove(usbDevice); - mDevicesById.remove(id); - device.shutdown(); - HIDDeviceDisconnected(id); + List devices = new ArrayList(); + for (HIDDevice device : mDevicesById.values()) { + if (usbDevice.equals(device.getDevice())) { + devices.add(device.getId()); + } + } + for (int id : devices) { + HIDDevice device = mDevicesById.get(id); + mDevicesById.remove(id); + device.shutdown(); + HIDDeviceDisconnected(id); + } } private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) { - HIDDeviceUSB device = mUSBDevices.get(usbDevice); - if (device == null) - return; - - boolean opened = false; - if (permission_granted) { - opened = device.open(); + for (HIDDevice device : mDevicesById.values()) { + if (usbDevice.equals(device.getDevice())) { + boolean opened = false; + if (permission_granted) { + opened = device.open(); + } + HIDDeviceOpenResult(device.getId(), opened); + } } - HIDDeviceOpenResult(device.getId(), opened); } private void connectHIDDeviceUSB(UsbDevice usbDevice) { synchronized (this) { - for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); interface_number++) { - if (isHIDDeviceInterface(usbDevice, interface_number)) { - HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_number); + for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) { + UsbInterface usbInterface = usbDevice.getInterface(interface_index); + if (isHIDDeviceInterface(usbDevice, usbInterface)) { + HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index); int id = device.getId(); - mUSBDevices.put(usbDevice, device); mDevicesById.put(id, device); - HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), interface_number); - break; + HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol()); } } } @@ -566,33 +556,27 @@ public class HIDDeviceManager { ////////////////////////////////////////////////////////////////////////////////////////////////////// public boolean openDevice(int deviceID) { + Log.v(TAG, "openDevice deviceID=" + deviceID); + HIDDevice device = getDevice(deviceID); + if (device == null) { + HIDDeviceDisconnected(deviceID); + return false; + } + // Look to see if this is a USB device and we have permission to access it - for (HIDDeviceUSB device : mUSBDevices.values()) { - if (deviceID == device.getId()) { - UsbDevice usbDevice = device.getDevice(); - if (!mUsbManager.hasPermission(usbDevice)) { - HIDDeviceOpenPending(deviceID); - try { - mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0)); - } catch (Exception e) { - Log.v(TAG, "Couldn't request permission for USB device " + usbDevice); - HIDDeviceOpenResult(deviceID, false); - } - return false; - } - break; + UsbDevice usbDevice = device.getDevice(); + if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) { + HIDDeviceOpenPending(deviceID); + try { + mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0)); + } catch (Exception e) { + Log.v(TAG, "Couldn't request permission for USB device " + usbDevice); + HIDDeviceOpenResult(deviceID, false); } + return false; } try { - Log.v(TAG, "openDevice deviceID=" + deviceID); - HIDDevice device; - device = getDevice(deviceID); - if (device == null) { - HIDDeviceDisconnected(deviceID); - return false; - } - return device.open(); } catch (Exception e) { Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); @@ -602,7 +586,7 @@ public class HIDDeviceManager { public int sendOutputReport(int deviceID, byte[] report) { try { - Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length); + //Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length); HIDDevice device; device = getDevice(deviceID); if (device == null) { @@ -619,7 +603,7 @@ public class HIDDeviceManager { public int sendFeatureReport(int deviceID, byte[] report) { try { - Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length); + //Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length); HIDDevice device; device = getDevice(deviceID); if (device == null) { @@ -636,7 +620,7 @@ public class HIDDeviceManager { public boolean getFeatureReport(int deviceID, byte[] report) { try { - Log.v(TAG, "getFeatureReport deviceID=" + deviceID); + //Log.v(TAG, "getFeatureReport deviceID=" + deviceID); HIDDevice device; device = getDevice(deviceID); if (device == null) { @@ -675,7 +659,7 @@ public class HIDDeviceManager { private native void HIDDeviceRegisterCallback(); private native void HIDDeviceReleaseCallback(); - native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number); + native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number, int interface_class, int interface_subclass, int interface_protocol); native void HIDDeviceOpenPending(int deviceID); native void HIDDeviceOpenResult(int deviceID, boolean opened); native void HIDDeviceDisconnected(int deviceID); diff --git a/android/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java b/android/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java index c9fc58e..33816e3 100644 --- a/android/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java +++ b/android/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java @@ -11,6 +11,7 @@ class HIDDeviceUSB implements HIDDevice { protected HIDDeviceManager mManager; protected UsbDevice mDevice; + protected int mInterfaceIndex; protected int mInterface; protected int mDeviceId; protected UsbDeviceConnection mConnection; @@ -20,16 +21,17 @@ class HIDDeviceUSB implements HIDDevice { protected boolean mRunning; protected boolean mFrozen; - public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_number) { + public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) { mManager = manager; mDevice = usbDevice; - mInterface = interface_number; + mInterfaceIndex = interface_index; + mInterface = mDevice.getInterface(mInterfaceIndex).getId(); mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier()); mRunning = false; } public String getIdentifier() { - return String.format("%s/%x/%x", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId()); + return String.format("%s/%x/%x/%d", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId(), mInterfaceIndex); } @Override @@ -88,6 +90,7 @@ class HIDDeviceUSB implements HIDDevice { return result; } + @Override public UsbDevice getDevice() { return mDevice; } @@ -104,19 +107,15 @@ class HIDDeviceUSB implements HIDDevice { return false; } - // Force claim all interfaces - for (int i = 0; i < mDevice.getInterfaceCount(); i++) { - UsbInterface iface = mDevice.getInterface(i); - - if (!mConnection.claimInterface(iface, true)) { - Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName()); - close(); - return false; - } + // Force claim our interface + UsbInterface iface = mDevice.getInterface(mInterfaceIndex); + if (!mConnection.claimInterface(iface, true)) { + Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName()); + close(); + return false; } // Find the endpoints - UsbInterface iface = mDevice.getInterface(mInterface); for (int j = 0; j < iface.getEndpointCount(); j++) { UsbEndpoint endpt = iface.getEndpoint(j); switch (endpt.getDirection()) { @@ -166,7 +165,7 @@ class HIDDeviceUSB implements HIDDevice { UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT, 0x09/*HID set_report*/, (3/*HID feature*/ << 8) | report_number, - 0, + mInterface, report, offset, length, 1000/*timeout millis*/); @@ -210,7 +209,7 @@ class HIDDeviceUSB implements HIDDevice { UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_IN, 0x01/*HID get_report*/, (3/*HID feature*/ << 8) | report_number, - 0, + mInterface, report, offset, length, 1000/*timeout millis*/); @@ -250,10 +249,8 @@ class HIDDeviceUSB implements HIDDevice { mInputThread = null; } if (mConnection != null) { - for (int i = 0; i < mDevice.getInterfaceCount(); i++) { - UsbInterface iface = mDevice.getInterface(i); - mConnection.releaseInterface(iface); - } + UsbInterface iface = mDevice.getInterface(mInterfaceIndex); + mConnection.releaseInterface(iface); mConnection.close(); mConnection = null; } diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android/app/src/main/java/org/libsdl/app/SDLActivity.java index 00e5f8f..443739c 100644 --- a/android/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -283,10 +283,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh return; } - if (mHIDDeviceManager != null) { - mHIDDeviceManager.setFrozen(true); - } - SDLActivity.handleNativeState(); } @@ -298,10 +294,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh return; } - if (mHIDDeviceManager != null) { - mHIDDeviceManager.setFrozen(false); - } - SDLActivity.handleNativeState(); } @@ -310,6 +302,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh protected void onPause() { Log.v(TAG, "onPause()"); super.onPause(); + + if (mHIDDeviceManager != null) { + mHIDDeviceManager.setFrozen(true); + } if (!mHasMultiWindow) { pauseNativeThread(); } @@ -319,6 +315,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh protected void onResume() { Log.v(TAG, "onResume()"); super.onResume(); + + if (mHIDDeviceManager != null) { + mHIDDeviceManager.setFrozen(false); + } if (!mHasMultiWindow) { resumeNativeThread(); } @@ -730,7 +730,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } } - if (bShouldWait) { + if (bShouldWait && (SDLActivity.getContext() != null)) { // We'll wait for the surfaceChanged() method, which will notify us // when called. That way, we know our current size is really the // size we need, instead of grabbing a size that's still got @@ -783,6 +783,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static native void nativeSetenv(String name, String value); public static native void onNativeOrientationChanged(int orientation); public static native void nativeAddTouch(int touchId, String name); + public static native void nativePermissionResult(int requestCode, boolean result); /** * This method is called by SDL using JNI. @@ -817,39 +818,62 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh */ public void setOrientationBis(int w, int h, boolean resizable, String hint) { - int orientation = -1; + int orientation_landscape = -1; + int orientation_portrait = -1; + /* If set, hint "explicitly controls which UI orientations are allowed". */ if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; } else if (hint.contains("LandscapeRight")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; } else if (hint.contains("LandscapeLeft")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; - } else if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; - } else if (hint.contains("Portrait")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - } else if (hint.contains("PortraitUpsideDown")) { - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; } - /* no valid hint */ - if (orientation == -1) { + if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + } else if (hint.contains("Portrait")) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + } else if (hint.contains("PortraitUpsideDown")) { + orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + } + + boolean is_landscape_allowed = (orientation_landscape == -1 ? false : true); + boolean is_portrait_allowed = (orientation_portrait == -1 ? false : true); + int req = -1; /* Requested orientation */ + + /* No valid hint, nothing is explicitly allowed */ + if (!is_portrait_allowed && !is_landscape_allowed) { if (resizable) { - /* no fixed orientation */ + /* All orientations are allowed */ + req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR; } else { - if (w > h) { - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + /* 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); + } + } else { + /* 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; } else { - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + /* Use the only one allowed "orientation" */ + req = (is_landscape_allowed ? orientation_landscape : orientation_portrait); + } + } else { + /* Fixed window and both orientations are allowed. Choose one. */ + if (is_portrait_allowed && is_landscape_allowed) { + req = (w > h ? orientation_landscape : orientation_portrait); + } else { + /* Use the only one allowed "orientation" */ + req = (is_landscape_allowed ? orientation_landscape : orientation_portrait); } } } - Log.v("SDL", "setOrientation() orientation=" + orientation + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint); - if (orientation != -1) { - mSingleton.setRequestedOrientation(orientation); - } + Log.v("SDL", "setOrientation() requestedOrientation=" + req + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint); + mSingleton.setRequestedOrientation(req); } /** @@ -976,6 +1000,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) { return true; } + if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV")) { + return true; + } return false; } @@ -985,6 +1012,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh public static boolean isTablet() { DisplayMetrics metrics = new DisplayMetrics(); Activity activity = (Activity)getContext(); + if (activity == null) { + return false; + } activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); double dWidthInches = metrics.widthPixels / (double)metrics.xdpi; @@ -1000,6 +1030,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh * This method is called by SDL using JNI. */ public static boolean isChromebook() { + if (getContext() == null) { + return false; + } return getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); } @@ -1571,6 +1604,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh } return true; } + + /** + * This method is called by SDL using JNI. + */ + public static void requestPermission(String permission, int requestCode) { + if (Build.VERSION.SDK_INT < 23) { + nativePermissionResult(requestCode, true); + return; + } + + Activity activity = (Activity)getContext(); + if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { + activity.requestPermissions(new String[]{permission}, requestCode); + } else { + nativePermissionResult(requestCode, true); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + nativePermissionResult(requestCode, true); + } else { + nativePermissionResult(requestCode, false); + } + } } /** @@ -1596,7 +1655,7 @@ class SDLMain implements Runnable { Log.v("SDL", "Finished main function"); - if (SDLActivity.mSingleton.isFinishing()) { + if (SDLActivity.mSingleton == null || SDLActivity.mSingleton.isFinishing()) { // Activity is already being destroyed } else { // Let's finish the Activity