Update to SDL 2.0.12

This commit is contained in:
Joshua Granick
2020-03-18 13:36:35 -07:00
parent c0c061c866
commit 42283e61bb
7 changed files with 196 additions and 139 deletions

View File

@@ -46,7 +46,7 @@ This product bundles pixman 0.32.8, which is available under an
This product bundles libpng 1.6.12, which is available under a This product bundles libpng 1.6.12, which is available under a
"zlib" (BSD-style) license. For details, see [project/lib/png/](project/lib). "zlib" (BSD-style) license. For details, see [project/lib/png/](project/lib).
This product bundles SDL 2.10, which is available under a This product bundles SDL 2.0.12, which is available under a
"zlib" (BSD-style) license. For details, see [project/lib/sdl/](project/lib). "zlib" (BSD-style) license. For details, see [project/lib/sdl/](project/lib).
This product bundles tinyfiledialogs 2.9.3, which is available under a This product bundles tinyfiledialogs 2.9.3, which is available under a

View File

@@ -1,5 +1,7 @@
package org.libsdl.app; package org.libsdl.app;
import android.hardware.usb.UsbDevice;
interface HIDDevice interface HIDDevice
{ {
public int getId(); public int getId();
@@ -9,6 +11,7 @@ interface HIDDevice
public int getVersion(); public int getVersion();
public String getManufacturerName(); public String getManufacturerName();
public String getProductName(); public String getProductName();
public UsbDevice getDevice();
public boolean open(); public boolean open();
public int sendFeatureReport(byte[] report); public int sendFeatureReport(byte[] report);
public int sendOutputReport(byte[] report); public int sendOutputReport(byte[] report);

View File

@@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothGattService;
import android.hardware.usb.UsbDevice;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.util.Log;
@@ -165,13 +166,13 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper());
mGatt = connectGatt(); mGatt = connectGatt();
final HIDDeviceBLESteamController finalThis = this; // final HIDDeviceBLESteamController finalThis = this;
mHandler.postDelayed(new Runnable() { // mHandler.postDelayed(new Runnable() {
@Override // @Override
public void run() { // public void run() {
finalThis.checkConnectionForChromebookIssue(); // finalThis.checkConnectionForChromebookIssue();
} // }
}, CHROMEBOOK_CONNECTION_CHECK_INTERVAL); // }, CHROMEBOOK_CONNECTION_CHECK_INTERVAL);
} }
public String getIdentifier() { 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 // Only register controller with the native side once it has been fully configured
if (!isRegistered()) { if (!isRegistered()) {
Log.v(TAG, "Registering Steam Controller with ID: " + getId()); 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(); setRegistered();
} }
} }
@@ -564,6 +565,11 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
} }
@Override @Override
public UsbDevice getDevice() {
return null;
}
@Override
public boolean open() { public boolean open() {
return true; return true;
} }

View File

@@ -19,8 +19,9 @@ import android.hardware.usb.*;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import java.util.HashMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class HIDDeviceManager { public class HIDDeviceManager {
@@ -50,7 +51,6 @@ public class HIDDeviceManager {
private Context mContext; private Context mContext;
private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>(); private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
private HashMap<UsbDevice, HIDDeviceUSB> mUSBDevices = new HashMap<UsbDevice, HIDDeviceUSB>();
private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>(); private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
private int mNextDeviceId = 0; private int mNextDeviceId = 0;
private SharedPreferences mSharedPreferences = null; private SharedPreferences mSharedPreferences = null;
@@ -241,31 +241,20 @@ public class HIDDeviceManager {
} }
} }
private boolean isHIDDeviceUSB(UsbDevice usbDevice) { private boolean isHIDDeviceInterface(UsbDevice usbDevice, UsbInterface usbInterface) {
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);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) { if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
return true; return true;
} }
if (interface_number == 0) {
if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) { if (isXbox360Controller(usbDevice, usbInterface) || isXboxOneController(usbDevice, usbInterface)) {
return true; return true;
} }
}
return false; return false;
} }
private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) { private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) {
final int XB360_IFACE_SUBCLASS = 93; final int XB360_IFACE_SUBCLASS = 93;
final int XB360_IFACE_PROTOCOL = 1; // Wired only final int XB360_IFACE_PROTOCOL = 1; // Wired
final int XB360W_IFACE_PROTOCOL = 129; // Wireless
final int[] SUPPORTED_VENDORS = { final int[] SUPPORTED_VENDORS = {
0x0079, // GPD Win 2 0x0079, // GPD Win 2
0x044f, // Thrustmaster 0x044f, // Thrustmaster
@@ -275,8 +264,9 @@ public class HIDDeviceManager {
0x06a3, // Saitek 0x06a3, // Saitek
0x0738, // Mad Catz 0x0738, // Mad Catz
0x07ff, // Mad Catz 0x07ff, // Mad Catz
0x0e6f, // Unknown 0x0e6f, // PDP
0x0f0d, // Hori 0x0f0d, // Hori
0x1038, // SteelSeries
0x11c9, // Nacon 0x11c9, // Nacon
0x12ab, // Unknown 0x12ab, // Unknown
0x1430, // RedOctane 0x1430, // RedOctane
@@ -291,7 +281,8 @@ public class HIDDeviceManager {
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
usbInterface.getInterfaceSubclass() == XB360_IFACE_SUBCLASS && usbInterface.getInterfaceSubclass() == XB360_IFACE_SUBCLASS &&
usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL) { (usbInterface.getInterfaceProtocol() == XB360_IFACE_PROTOCOL ||
usbInterface.getInterfaceProtocol() == XB360W_IFACE_PROTOCOL)) {
int vendor_id = usbDevice.getVendorId(); int vendor_id = usbDevice.getVendorId();
for (int supportedVid : SUPPORTED_VENDORS) { for (int supportedVid : SUPPORTED_VENDORS) {
if (vendor_id == supportedVid) { if (vendor_id == supportedVid) {
@@ -308,13 +299,15 @@ public class HIDDeviceManager {
final int[] SUPPORTED_VENDORS = { final int[] SUPPORTED_VENDORS = {
0x045e, // Microsoft 0x045e, // Microsoft
0x0738, // Mad Catz 0x0738, // Mad Catz
0x0e6f, // Unknown 0x0e6f, // PDP
0x0f0d, // Hori 0x0f0d, // Hori
0x1532, // Razer Wildcat 0x1532, // Razer Wildcat
0x24c6, // PowerA 0x24c6, // PowerA
0x2e24, // Hyperkin
}; };
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && if (usbInterface.getId() == 0 &&
usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
usbInterface.getInterfaceSubclass() == XB1_IFACE_SUBCLASS && usbInterface.getInterfaceSubclass() == XB1_IFACE_SUBCLASS &&
usbInterface.getInterfaceProtocol() == XB1_IFACE_PROTOCOL) { usbInterface.getInterfaceProtocol() == XB1_IFACE_PROTOCOL) {
int vendor_id = usbDevice.getVendorId(); int vendor_id = usbDevice.getVendorId();
@@ -328,45 +321,45 @@ public class HIDDeviceManager {
} }
private void handleUsbDeviceAttached(UsbDevice usbDevice) { private void handleUsbDeviceAttached(UsbDevice usbDevice) {
if (isHIDDeviceUSB(usbDevice)) {
connectHIDDeviceUSB(usbDevice); connectHIDDeviceUSB(usbDevice);
} }
}
private void handleUsbDeviceDetached(UsbDevice usbDevice) { private void handleUsbDeviceDetached(UsbDevice usbDevice) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice); List<Integer> devices = new ArrayList<Integer>();
if (device == null) for (HIDDevice device : mDevicesById.values()) {
return; if (usbDevice.equals(device.getDevice())) {
devices.add(device.getId());
int id = device.getId(); }
mUSBDevices.remove(usbDevice); }
for (int id : devices) {
HIDDevice device = mDevicesById.get(id);
mDevicesById.remove(id); mDevicesById.remove(id);
device.shutdown(); device.shutdown();
HIDDeviceDisconnected(id); HIDDeviceDisconnected(id);
} }
}
private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) { private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice); for (HIDDevice device : mDevicesById.values()) {
if (device == null) if (usbDevice.equals(device.getDevice())) {
return;
boolean opened = false; boolean opened = false;
if (permission_granted) { if (permission_granted) {
opened = device.open(); opened = device.open();
} }
HIDDeviceOpenResult(device.getId(), opened); HIDDeviceOpenResult(device.getId(), opened);
} }
}
}
private void connectHIDDeviceUSB(UsbDevice usbDevice) { private void connectHIDDeviceUSB(UsbDevice usbDevice) {
synchronized (this) { synchronized (this) {
for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); interface_number++) { for (int interface_index = 0; interface_index < usbDevice.getInterfaceCount(); interface_index++) {
if (isHIDDeviceInterface(usbDevice, interface_number)) { UsbInterface usbInterface = usbDevice.getInterface(interface_index);
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_number); if (isHIDDeviceInterface(usbDevice, usbInterface)) {
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_index);
int id = device.getId(); int id = device.getId();
mUSBDevices.put(usbDevice, device);
mDevicesById.put(id, device); mDevicesById.put(id, device);
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), interface_number); HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), usbInterface.getId(), usbInterface.getInterfaceClass(), usbInterface.getInterfaceSubclass(), usbInterface.getInterfaceProtocol());
break;
} }
} }
} }
@@ -563,11 +556,16 @@ public class HIDDeviceManager {
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
public boolean openDevice(int deviceID) { 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 // 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(); UsbDevice usbDevice = device.getDevice();
if (!mUsbManager.hasPermission(usbDevice)) { if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
HIDDeviceOpenPending(deviceID); HIDDeviceOpenPending(deviceID);
try { try {
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0)); mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
@@ -577,19 +575,8 @@ public class HIDDeviceManager {
} }
return false; return false;
} }
break;
}
}
try { try {
Log.v(TAG, "openDevice deviceID=" + deviceID);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
HIDDeviceDisconnected(deviceID);
return false;
}
return device.open(); return device.open();
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e)); Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
@@ -599,7 +586,7 @@ public class HIDDeviceManager {
public int sendOutputReport(int deviceID, byte[] report) { public int sendOutputReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length); //Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device; HIDDevice device;
device = getDevice(deviceID); device = getDevice(deviceID);
if (device == null) { if (device == null) {
@@ -616,7 +603,7 @@ public class HIDDeviceManager {
public int sendFeatureReport(int deviceID, byte[] report) { public int sendFeatureReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length); //Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device; HIDDevice device;
device = getDevice(deviceID); device = getDevice(deviceID);
if (device == null) { if (device == null) {
@@ -633,7 +620,7 @@ public class HIDDeviceManager {
public boolean getFeatureReport(int deviceID, byte[] report) { public boolean getFeatureReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "getFeatureReport deviceID=" + deviceID); //Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
HIDDevice device; HIDDevice device;
device = getDevice(deviceID); device = getDevice(deviceID);
if (device == null) { if (device == null) {
@@ -672,7 +659,7 @@ public class HIDDeviceManager {
private native void HIDDeviceRegisterCallback(); private native void HIDDeviceRegisterCallback();
private native void HIDDeviceReleaseCallback(); 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 HIDDeviceOpenPending(int deviceID);
native void HIDDeviceOpenResult(int deviceID, boolean opened); native void HIDDeviceOpenResult(int deviceID, boolean opened);
native void HIDDeviceDisconnected(int deviceID); native void HIDDeviceDisconnected(int deviceID);

View File

@@ -11,6 +11,7 @@ class HIDDeviceUSB implements HIDDevice {
protected HIDDeviceManager mManager; protected HIDDeviceManager mManager;
protected UsbDevice mDevice; protected UsbDevice mDevice;
protected int mInterfaceIndex;
protected int mInterface; protected int mInterface;
protected int mDeviceId; protected int mDeviceId;
protected UsbDeviceConnection mConnection; protected UsbDeviceConnection mConnection;
@@ -20,16 +21,17 @@ class HIDDeviceUSB implements HIDDevice {
protected boolean mRunning; protected boolean mRunning;
protected boolean mFrozen; protected boolean mFrozen;
public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_number) { public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) {
mManager = manager; mManager = manager;
mDevice = usbDevice; mDevice = usbDevice;
mInterface = interface_number; mInterfaceIndex = interface_index;
mInterface = mDevice.getInterface(mInterfaceIndex).getId();
mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier()); mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier());
mRunning = false; mRunning = false;
} }
public String getIdentifier() { 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 @Override
@@ -88,6 +90,7 @@ class HIDDeviceUSB implements HIDDevice {
return result; return result;
} }
@Override
public UsbDevice getDevice() { public UsbDevice getDevice() {
return mDevice; return mDevice;
} }
@@ -104,19 +107,15 @@ class HIDDeviceUSB implements HIDDevice {
return false; return false;
} }
// Force claim all interfaces // Force claim our interface
for (int i = 0; i < mDevice.getInterfaceCount(); i++) { UsbInterface iface = mDevice.getInterface(mInterfaceIndex);
UsbInterface iface = mDevice.getInterface(i);
if (!mConnection.claimInterface(iface, true)) { if (!mConnection.claimInterface(iface, true)) {
Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName()); Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName());
close(); close();
return false; return false;
} }
}
// Find the endpoints // Find the endpoints
UsbInterface iface = mDevice.getInterface(mInterface);
for (int j = 0; j < iface.getEndpointCount(); j++) { for (int j = 0; j < iface.getEndpointCount(); j++) {
UsbEndpoint endpt = iface.getEndpoint(j); UsbEndpoint endpt = iface.getEndpoint(j);
switch (endpt.getDirection()) { switch (endpt.getDirection()) {
@@ -166,7 +165,7 @@ class HIDDeviceUSB implements HIDDevice {
UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT, UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT,
0x09/*HID set_report*/, 0x09/*HID set_report*/,
(3/*HID feature*/ << 8) | report_number, (3/*HID feature*/ << 8) | report_number,
0, mInterface,
report, offset, length, report, offset, length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -210,7 +209,7 @@ class HIDDeviceUSB implements HIDDevice {
UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_IN, UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_IN,
0x01/*HID get_report*/, 0x01/*HID get_report*/,
(3/*HID feature*/ << 8) | report_number, (3/*HID feature*/ << 8) | report_number,
0, mInterface,
report, offset, length, report, offset, length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -250,10 +249,8 @@ class HIDDeviceUSB implements HIDDevice {
mInputThread = null; mInputThread = null;
} }
if (mConnection != null) { if (mConnection != null) {
for (int i = 0; i < mDevice.getInterfaceCount(); i++) { UsbInterface iface = mDevice.getInterface(mInterfaceIndex);
UsbInterface iface = mDevice.getInterface(i);
mConnection.releaseInterface(iface); mConnection.releaseInterface(iface);
}
mConnection.close(); mConnection.close();
mConnection = null; mConnection = null;
} }

View File

@@ -284,10 +284,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return; return;
} }
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(true);
}
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
} }
@@ -299,10 +295,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return; return;
} }
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(false);
}
SDLActivity.handleNativeState(); SDLActivity.handleNativeState();
} }
@@ -311,6 +303,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
protected void onPause() { protected void onPause() {
Log.v(TAG, "onPause()"); Log.v(TAG, "onPause()");
super.onPause(); super.onPause();
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(true);
}
if (!mHasMultiWindow) { if (!mHasMultiWindow) {
pauseNativeThread(); pauseNativeThread();
} }
@@ -320,6 +316,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
protected void onResume() { protected void onResume() {
Log.v(TAG, "onResume()"); Log.v(TAG, "onResume()");
super.onResume(); super.onResume();
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(false);
}
if (!mHasMultiWindow) { if (!mHasMultiWindow) {
resumeNativeThread(); resumeNativeThread();
} }
@@ -454,8 +454,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
} }
// Default system back button behavior. // Default system back button behavior.
if (!isFinishing()) {
super.onBackPressed(); super.onBackPressed();
} }
}
// Called by JNI from SDL. // Called by JNI from SDL.
public static void manualBackButton() { public static void manualBackButton() {
@@ -467,8 +469,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!SDLActivity.this.isFinishing()) {
SDLActivity.this.superOnBackPressed(); SDLActivity.this.superOnBackPressed();
} }
}
}); });
} }
@@ -634,6 +638,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
mScreenKeyboardShown = false; mScreenKeyboardShown = false;
mSurface.requestFocus();
} }
break; break;
case COMMAND_SET_KEEP_SCREEN_ON: case COMMAND_SET_KEEP_SCREEN_ON:
@@ -725,7 +731,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 // We'll wait for the surfaceChanged() method, which will notify us
// when called. That way, we know our current size is really the // when called. That way, we know our current size is really the
// size we need, instead of grabbing a size that's still got // size we need, instead of grabbing a size that's still got
@@ -778,6 +784,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
public static native void nativeSetenv(String name, String value); public static native void nativeSetenv(String name, String value);
public static native void onNativeOrientationChanged(int orientation); public static native void onNativeOrientationChanged(int orientation);
public static native void nativeAddTouch(int touchId, String name); 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. * This method is called by SDL using JNI.
@@ -812,39 +819,62 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/ */
public void setOrientationBis(int w, int h, boolean resizable, String hint) 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")) { 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")) { } else if (hint.contains("LandscapeRight")) {
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hint.contains("LandscapeLeft")) { } else if (hint.contains("LandscapeLeft")) {
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
} else if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { }
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (hint.contains("Portrait")) { } else if (hint.contains("Portrait")) {
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (hint.contains("PortraitUpsideDown")) { } else if (hint.contains("PortraitUpsideDown")) {
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
} }
/* no valid hint */ boolean is_landscape_allowed = (orientation_landscape == -1 ? false : true);
if (orientation == -1) { 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) { if (resizable) {
/* no fixed orientation */ /* All orientations are allowed */
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
} else { } else {
if (w > h) { /* Fixed window and nothing specified. Get orientation from w/h of created window */
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
} else { } else {
orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; /* 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 {
/* 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); Log.v("SDL", "setOrientation() requestedOrientation=" + req + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint);
if (orientation != -1) { mSingleton.setRequestedOrientation(req);
mSingleton.setRequestedOrientation(orientation);
}
} }
/** /**
@@ -971,6 +1001,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) { if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) {
return true; return true;
} }
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.startsWith("TV")) {
return true;
}
return false; return false;
} }
@@ -980,6 +1013,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
public static boolean isTablet() { public static boolean isTablet() {
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity)getContext(); Activity activity = (Activity)getContext();
if (activity == null) {
return false;
}
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
double dWidthInches = metrics.widthPixels / (double)metrics.xdpi; double dWidthInches = metrics.widthPixels / (double)metrics.xdpi;
@@ -995,6 +1031,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
* This method is called by SDL using JNI. * This method is called by SDL using JNI.
*/ */
public static boolean isChromebook() { public static boolean isChromebook() {
if (getContext() == null) {
return false;
}
return getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); return getContext().getPackageManager().hasSystemFeature("org.chromium.arc.device_management");
} }
@@ -1566,6 +1605,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
} }
return true; 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);
}
}
} }
/** /**
@@ -1591,7 +1656,7 @@ class SDLMain implements Runnable {
Log.v("SDL", "Finished main function"); Log.v("SDL", "Finished main function");
if (SDLActivity.mSingleton.isFinishing()) { if (SDLActivity.mSingleton == null || SDLActivity.mSingleton.isFinishing()) {
// Activity is already being destroyed // Activity is already being destroyed
} else { } else {
// Let's finish the Activity // Let's finish the Activity
@@ -1826,8 +1891,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
if (source == InputDevice.SOURCE_UNKNOWN) { if (source == InputDevice.SOURCE_UNKNOWN) {
InputDevice device = InputDevice.getDevice(deviceId); InputDevice device = InputDevice.getDevice(deviceId);
if ( device != null ) if (device != null) {
{
source = device.getSources(); source = device.getSources();
} }
} }