1
0

Android: minor update

This commit is contained in:
Maksym H 2023-07-08 18:19:24 +03:00
parent 63fa8c286f
commit 4e2d7463cd
11 changed files with 274 additions and 101 deletions

View File

@ -186,7 +186,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead // 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. // of TRANSPORT_LE. Let's force ourselves to connect low energy.
private BluetoothGatt connectGatt(boolean managed) { private BluetoothGatt connectGatt(boolean managed) {
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
try { try {
return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE); return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE);
} catch (Exception e) { } catch (Exception e) {
@ -429,7 +429,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
} }
}); });
} }
} }
else if (newState == 0) { else if (newState == 0) {
mIsConnected = false; mIsConnected = false;
} }

View File

@ -170,7 +170,7 @@ public class HIDDeviceManager {
Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol()); Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount()); Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
// Get endpoint details // Get endpoint details
for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++) for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
{ {
UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi); UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
@ -251,6 +251,8 @@ public class HIDDeviceManager {
0x20d6, // PowerA 0x20d6, // PowerA
0x24c6, // PowerA 0x24c6, // PowerA
0x2c22, // Qanba 0x2c22, // Qanba
0x2dc8, // 8BitDo
0x9886, // ASTRO Gaming
}; };
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC && if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
@ -271,14 +273,16 @@ public class HIDDeviceManager {
final int XB1_IFACE_SUBCLASS = 71; final int XB1_IFACE_SUBCLASS = 71;
final int XB1_IFACE_PROTOCOL = 208; final int XB1_IFACE_PROTOCOL = 208;
final int[] SUPPORTED_VENDORS = { final int[] SUPPORTED_VENDORS = {
0x044f, // Thrustmaster
0x045e, // Microsoft 0x045e, // Microsoft
0x0738, // Mad Catz 0x0738, // Mad Catz
0x0e6f, // PDP 0x0e6f, // PDP
0x0f0d, // Hori 0x0f0d, // Hori
0x10f5, // Turtle Beach
0x1532, // Razer Wildcat 0x1532, // Razer Wildcat
0x20d6, // PowerA 0x20d6, // PowerA
0x24c6, // PowerA 0x24c6, // PowerA
0x2dc8, /* 8BitDo */ 0x2dc8, // 8BitDo
0x2e24, // Hyperkin 0x2e24, // Hyperkin
}; };
@ -353,13 +357,13 @@ public class HIDDeviceManager {
private void initializeBluetooth() { private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth"); Log.d(TAG, "Initializing Bluetooth");
if (Build.VERSION.SDK_INT <= 30 && if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) { mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH"); Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
return; return;
} }
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18)) { 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"); Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
return; return;
} }
@ -524,7 +528,7 @@ public class HIDDeviceManager {
for (HIDDevice device : mDevicesById.values()) { for (HIDDevice device : mDevicesById.values()) {
device.setFrozen(frozen); device.setFrozen(frozen);
} }
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
@ -573,7 +577,7 @@ public class HIDDeviceManager {
try { try {
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31 final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
int flags; int flags;
if (Build.VERSION.SDK_INT >= 31) { if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
flags = FLAG_MUTABLE; flags = FLAG_MUTABLE;
} else { } else {
flags = 0; flags = 0;

View File

@ -52,7 +52,7 @@ class HIDDeviceUSB implements HIDDevice {
@Override @Override
public String getSerialNumber() { public String getSerialNumber() {
String result = null; String result = null;
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
try { try {
result = mDevice.getSerialNumber(); result = mDevice.getSerialNumber();
} }
@ -74,7 +74,7 @@ class HIDDeviceUSB implements HIDDevice {
@Override @Override
public String getManufacturerName() { public String getManufacturerName() {
String result = null; String result = null;
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
result = mDevice.getManufacturerName(); result = mDevice.getManufacturerName();
} }
if (result == null) { if (result == null) {
@ -86,7 +86,7 @@ class HIDDeviceUSB implements HIDDevice {
@Override @Override
public String getProductName() { public String getProductName() {
String result = null; String result = null;
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
result = mDevice.getProductName(); result = mDevice.getProductName();
} }
if (result == null) { if (result == null) {

View File

@ -29,6 +29,7 @@ public class SDL {
// This function stores the current activity (SDL or not) // This function stores the current activity (SDL or not)
public static void setContext(Context context) { public static void setContext(Context context) {
SDLAudioManager.setContext(context);
mContext = context; mContext = context;
} }

View File

@ -60,8 +60,8 @@ import java.util.Locale;
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener { public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
private static final String TAG = "SDL"; private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2; private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 26; private static final int SDL_MINOR_VERSION = 28;
private static final int SDL_MICRO_VERSION = 5; private static final int SDL_MICRO_VERSION = 1;
/* /*
// Display InputType.SOURCE/CLASS of events and devices // Display InputType.SOURCE/CLASS of events and devices
// //
@ -93,7 +93,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class; s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= 23) {
tst = InputDevice.SOURCE_BLUETOOTH_STYLUS; tst = InputDevice.SOURCE_BLUETOOTH_STYLUS;
if ((s & tst) == tst) src += " BLUETOOTH_STYLUS"; if ((s & tst) == tst) src += " BLUETOOTH_STYLUS";
s2 &= ~tst; s2 &= ~tst;
@ -107,7 +107,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if ((s & tst) == tst) src += " GAMEPAD"; if ((s & tst) == tst) src += " GAMEPAD";
s2 &= ~tst; s2 &= ~tst;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= 21) {
tst = InputDevice.SOURCE_HDMI; tst = InputDevice.SOURCE_HDMI;
if ((s & tst) == tst) src += " HDMI"; if ((s & tst) == tst) src += " HDMI";
s2 &= ~tst; s2 &= ~tst;
@ -146,7 +146,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if ((s & tst) == tst) src += " TOUCHSCREEN"; if ((s & tst) == tst) src += " TOUCHSCREEN";
s2 &= ~tst; s2 &= ~tst;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (Build.VERSION.SDK_INT >= 18) {
tst = InputDevice.SOURCE_TOUCH_NAVIGATION; tst = InputDevice.SOURCE_TOUCH_NAVIGATION;
if ((s & tst) == tst) src += " TOUCH_NAVIGATION"; if ((s & tst) == tst) src += " TOUCH_NAVIGATION";
s2 &= ~tst; s2 &= ~tst;
@ -170,7 +170,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/ */
public static boolean mIsResumedCalled, mHasFocus; public static boolean mIsResumedCalled, mHasFocus;
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24); public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */);
// Cursor types // Cursor types
// private static final int SDL_SYSTEM_CURSOR_NONE = -1; // private static final int SDL_SYSTEM_CURSOR_NONE = -1;
@ -224,9 +224,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
protected static SDLGenericMotionListener_API12 getMotionListener() { protected static SDLGenericMotionListener_API12 getMotionListener() {
if (mMotionListener == null) { if (mMotionListener == null) {
if (Build.VERSION.SDK_INT >= 26) { if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
mMotionListener = new SDLGenericMotionListener_API26(); mMotionListener = new SDLGenericMotionListener_API26();
} else if (Build.VERSION.SDK_INT >= 24) { } else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
mMotionListener = new SDLGenericMotionListener_API24(); mMotionListener = new SDLGenericMotionListener_API24();
} else { } else {
mMotionListener = new SDLGenericMotionListener_API12(); mMotionListener = new SDLGenericMotionListener_API12();
@ -393,7 +393,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mHIDDeviceManager = HIDDeviceManager.acquire(this); mHIDDeviceManager = HIDDeviceManager.acquire(this);
// Set up the surface // Set up the surface
mSurface = createSDLSurface(getApplication()); mSurface = createSDLSurface(this);
mLayout = new RelativeLayout(this); mLayout = new RelativeLayout(this);
mLayout.addView(mSurface); mLayout.addView(mSurface);
@ -404,7 +404,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
SDLActivity.onNativeOrientationChanged(mCurrentOrientation); SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
try { try {
if (Build.VERSION.SDK_INT < 24) { if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
mCurrentLocale = getContext().getResources().getConfiguration().locale; mCurrentLocale = getContext().getResources().getConfiguration().locale;
} else { } else {
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0); mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
@ -588,6 +588,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mHIDDeviceManager = null; mHIDDeviceManager = null;
} }
SDLAudioManager.release(this);
if (SDLActivity.mBrokenLibraries) { if (SDLActivity.mBrokenLibraries) {
super.onDestroy(); super.onDestroy();
return; return;
@ -766,7 +768,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
} }
break; break;
case COMMAND_CHANGE_WINDOW_STYLE: case COMMAND_CHANGE_WINDOW_STYLE:
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
if (context instanceof Activity) { if (context instanceof Activity) {
Window window = ((Activity) context).getWindow(); Window window = ((Activity) context).getWindow();
if (window != null) { if (window != null) {
@ -841,7 +843,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
msg.obj = data; msg.obj = data;
boolean result = commandHandler.sendMessage(msg); boolean result = commandHandler.sendMessage(msg);
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
if (command == COMMAND_CHANGE_WINDOW_STYLE) { if (command == COMMAND_CHANGE_WINDOW_STYLE) {
// Ensure we don't return until the resize has actually happened, // Ensure we don't return until the resize has actually happened,
// or 500ms have passed. // or 500ms have passed.
@ -969,15 +971,18 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
/* If set, hint "explicitly controls which UI orientations are allowed". */ /* 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_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
} else if (hint.contains("LandscapeRight")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hint.contains("LandscapeLeft")) { } else if (hint.contains("LandscapeLeft")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hint.contains("LandscapeRight")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
} }
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { /* exact match to 'Portrait' to distinguish with PortraitUpsideDown */
boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait");
if (contains_Portrait && hint.contains("PortraitUpsideDown")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (hint.contains("Portrait")) { } else if (contains_Portrait) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (hint.contains("PortraitUpsideDown")) { } else if (hint.contains("PortraitUpsideDown")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
@ -1090,7 +1095,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result, // thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
// we should stick to relative mode. // we should stick to relative mode.
// //
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) { if (Build.VERSION.SDK_INT < 27 /* Android 8.1 (O_MR1) */ && isDeXMode()) {
return false; return false;
} }
@ -1180,7 +1185,7 @@ 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 isDeXMode() { public static boolean isDeXMode() {
if (Build.VERSION.SDK_INT < 24) { if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
return false; return false;
} }
try { try {
@ -1617,7 +1622,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private final Runnable rehideSystemUi = new Runnable() { private final Runnable rehideSystemUi = new Runnable() {
@Override @Override
public void run() { public void run() {
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
@ -1670,7 +1675,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888); Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
++mLastCursorID; ++mLastCursorID;
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
try { try {
mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY)); mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY));
} catch (Exception e) { } catch (Exception e) {
@ -1686,7 +1691,7 @@ 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 void destroyCustomCursor(int cursorID) { public static void destroyCustomCursor(int cursorID) {
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
try { try {
mCursors.remove(cursorID); mCursors.remove(cursorID);
} catch (Exception e) { } catch (Exception e) {
@ -1700,7 +1705,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/ */
public static boolean setCustomCursor(int cursorID) { public static boolean setCustomCursor(int cursorID) {
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
try { try {
mSurface.setPointerIcon(mCursors.get(cursorID)); mSurface.setPointerIcon(mCursors.get(cursorID));
} catch (Exception e) { } catch (Exception e) {
@ -1755,7 +1760,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
cursor_type = 1002; //PointerIcon.TYPE_HAND; cursor_type = 1002; //PointerIcon.TYPE_HAND;
break; break;
} }
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
try { try {
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type)); mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
} catch (Exception e) { } catch (Exception e) {
@ -1769,7 +1774,7 @@ 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 void requestPermission(String permission, int requestCode) { public static void requestPermission(String permission, int requestCode) {
if (Build.VERSION.SDK_INT < 23) { if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
nativePermissionResult(requestCode, true); nativePermissionResult(requestCode, true);
return; return;
} }
@ -1798,7 +1803,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
i.setData(Uri.parse(url)); i.setData(Uri.parse(url));
int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK; int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
} else { } else {
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET; flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
@ -2002,6 +2007,18 @@ class SDLInputConnection extends BaseInputConnection {
@Override @Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) { public boolean deleteSurroundingText(int beforeLength, int afterLength) {
if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
if (beforeLength > 0 && afterLength == 0) {
// backspace(s)
while (beforeLength-- > 0) {
nativeGenerateScancodeForUnichar('\b');
}
return true;
}
}
if (!super.deleteSurroundingText(beforeLength, afterLength)) { if (!super.deleteSurroundingText(beforeLength, afterLength)) {
return false; return false;
} }

View File

@ -1,5 +1,8 @@
package org.libsdl.app; package org.libsdl.app;
import android.content.Context;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat; import android.media.AudioFormat;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.AudioRecord; import android.media.AudioRecord;
@ -8,34 +11,67 @@ import android.media.MediaRecorder;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
public class SDLAudioManager import java.util.Arrays;
{
public class SDLAudioManager {
protected static final String TAG = "SDLAudio"; protected static final String TAG = "SDLAudio";
protected static AudioTrack mAudioTrack; protected static AudioTrack mAudioTrack;
protected static AudioRecord mAudioRecord; protected static AudioRecord mAudioRecord;
protected static Context mContext;
private static final int[] NO_DEVICES = {};
private static AudioDeviceCallback mAudioDeviceCallback;
public static void initialize() { public static void initialize() {
mAudioTrack = null; mAudioTrack = null;
mAudioRecord = null; mAudioRecord = null;
mAudioDeviceCallback = null;
if(Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */)
{
mAudioDeviceCallback = new AudioDeviceCallback() {
@Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
Arrays.stream(addedDevices).forEach(deviceInfo -> addAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
}
@Override
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
Arrays.stream(removedDevices).forEach(deviceInfo -> removeAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
}
};
}
}
public static void setContext(Context context) {
mContext = context;
if (context != null) {
registerAudioDeviceCallback();
}
}
public static void release(Context context) {
unregisterAudioDeviceCallback(context);
} }
// Audio // Audio
protected static String getAudioFormatString(int audioFormat) { protected static String getAudioFormatString(int audioFormat) {
switch (audioFormat) { switch (audioFormat) {
case AudioFormat.ENCODING_PCM_8BIT: case AudioFormat.ENCODING_PCM_8BIT:
return "8-bit"; return "8-bit";
case AudioFormat.ENCODING_PCM_16BIT: case AudioFormat.ENCODING_PCM_16BIT:
return "16-bit"; return "16-bit";
case AudioFormat.ENCODING_PCM_FLOAT: case AudioFormat.ENCODING_PCM_FLOAT:
return "float"; return "float";
default: default:
return Integer.toString(audioFormat); return Integer.toString(audioFormat);
} }
} }
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) { protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
int channelConfig; int channelConfig;
int sampleSize; int sampleSize;
int frameSize; int frameSize;
@ -43,14 +79,14 @@ public class SDLAudioManager
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz"); Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
/* On older devices let's use known good settings */ /* On older devices let's use known good settings */
if (Build.VERSION.SDK_INT < 21) { if (Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
if (desiredChannels > 2) { if (desiredChannels > 2) {
desiredChannels = 2; desiredChannels = 2;
} }
} }
/* AudioTrack has sample rate limitation of 48000 (fixed in 5.0.2) */ /* AudioTrack has sample rate limitation of 48000 (fixed in 5.0.2) */
if (Build.VERSION.SDK_INT < 22) { if (Build.VERSION.SDK_INT < 22 /* Android 5.1 (LOLLIPOP_MR1) */) {
if (sampleRate < 8000) { if (sampleRate < 8000) {
sampleRate = 8000; sampleRate = 8000;
} else if (sampleRate > 48000) { } else if (sampleRate > 48000) {
@ -59,7 +95,7 @@ public class SDLAudioManager
} }
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) { if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
int minSDKVersion = (isCapture ? 23 : 21); int minSDKVersion = (isCapture ? 23 /* Android 6.0 (M) */ : 21 /* Android 5.0 (LOLLIPOP) */);
if (Build.VERSION.SDK_INT < minSDKVersion) { if (Build.VERSION.SDK_INT < minSDKVersion) {
audioFormat = AudioFormat.ENCODING_PCM_16BIT; audioFormat = AudioFormat.ENCODING_PCM_16BIT;
} }
@ -120,7 +156,7 @@ public class SDLAudioManager
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER; channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
break; break;
case 8: case 8:
if (Build.VERSION.SDK_INT >= 23) { if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
} else { } else {
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround"); Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
@ -201,6 +237,10 @@ public class SDLAudioManager
return null; return null;
} }
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
mAudioRecord.setPreferredDevice(getOutputAudioDeviceInfo(deviceId));
}
mAudioRecord.startRecording(); mAudioRecord.startRecording();
} }
@ -224,6 +264,10 @@ public class SDLAudioManager
return null; return null;
} }
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
mAudioTrack.setPreferredDevice(getInputAudioDeviceInfo(deviceId));
}
mAudioTrack.play(); mAudioTrack.play();
} }
@ -238,11 +282,73 @@ public class SDLAudioManager
return results; return results;
} }
private static AudioDeviceInfo getInputAudioDeviceInfo(int deviceId) {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
.findFirst()
.orElse(null);
} else {
return null;
}
}
private static AudioDeviceInfo getOutputAudioDeviceInfo(int deviceId) {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS))
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
.findFirst()
.orElse(null);
} else {
return null;
}
}
private static void registerAudioDeviceCallback() {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
audioManager.registerAudioDeviceCallback(mAudioDeviceCallback, null);
}
}
private static void unregisterAudioDeviceCallback(Context context) {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback);
}
}
/** /**
* This method is called by SDL using JNI. * This method is called by SDL using JNI.
*/ */
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) { public static int[] getAudioOutputDevices() {
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames); if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
} else {
return NO_DEVICES;
}
}
/**
* This method is called by SDL using JNI.
*/
public static int[] getAudioInputDevices() {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
} else {
return NO_DEVICES;
}
}
/**
* This method is called by SDL using JNI.
*/
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
} }
/** /**
@ -254,6 +360,11 @@ public class SDLAudioManager
return; return;
} }
if (android.os.Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
Log.e(TAG, "Attempted to make an incompatible audio call with uninitialized audio! (floating-point output is supported since Android 5.0 Lollipop)");
return;
}
for (int i = 0; i < buffer.length;) { for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING); int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
if (result > 0) { if (result > 0) {
@ -326,18 +437,22 @@ public class SDLAudioManager
/** /**
* This method is called by SDL using JNI. * This method is called by SDL using JNI.
*/ */
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) { public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames); return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
} }
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static int captureReadFloatBuffer(float[] buffer, boolean blocking) { public static int captureReadFloatBuffer(float[] buffer, boolean blocking) {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
return 0;
} else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
} }
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static int captureReadShortBuffer(short[] buffer, boolean blocking) { public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
if (Build.VERSION.SDK_INT < 23) { if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
return mAudioRecord.read(buffer, 0, buffer.length); return mAudioRecord.read(buffer, 0, buffer.length);
} else { } else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
@ -346,7 +461,7 @@ public class SDLAudioManager
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static int captureReadByteBuffer(byte[] buffer, boolean blocking) { public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
if (Build.VERSION.SDK_INT < 23) { if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
return mAudioRecord.read(buffer, 0, buffer.length); return mAudioRecord.read(buffer, 0, buffer.length);
} else { } else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
@ -391,4 +506,9 @@ public class SDLAudioManager
} }
public static native int nativeSetupJNI(); public static native int nativeSetupJNI();
public static native void removeAudioDevice(boolean isCapture, int deviceId);
public static native void addAudioDevice(boolean isCapture, int deviceId);
} }

View File

@ -24,7 +24,7 @@ public class SDLControllerManager
public static native int nativeAddJoystick(int device_id, String name, String desc, public static native int nativeAddJoystick(int device_id, String name, String desc,
int vendor_id, int product_id, int vendor_id, int product_id,
boolean is_accelerometer, int button_mask, boolean is_accelerometer, int button_mask,
int naxes, int nhats, int nballs); int naxes, int axis_mask, int nhats, int nballs);
public static native int nativeRemoveJoystick(int device_id); public static native int nativeRemoveJoystick(int device_id);
public static native int nativeAddHaptic(int device_id, String name); public static native int nativeAddHaptic(int device_id, String name);
public static native int nativeRemoveHaptic(int device_id); public static native int nativeRemoveHaptic(int device_id);
@ -42,7 +42,7 @@ public class SDLControllerManager
public static void initialize() { public static void initialize() {
if (mJoystickHandler == null) { if (mJoystickHandler == null) {
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
mJoystickHandler = new SDLJoystickHandler_API19(); mJoystickHandler = new SDLJoystickHandler_API19();
} else { } else {
mJoystickHandler = new SDLJoystickHandler_API16(); mJoystickHandler = new SDLJoystickHandler_API16();
@ -50,7 +50,7 @@ public class SDLControllerManager
} }
if (mHapticHandler == null) { if (mHapticHandler == null) {
if (Build.VERSION.SDK_INT >= 26) { if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
mHapticHandler = new SDLHapticHandler_API26(); mHapticHandler = new SDLHapticHandler_API26();
} else { } else {
mHapticHandler = new SDLHapticHandler(); mHapticHandler = new SDLHapticHandler();
@ -236,7 +236,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
mJoysticks.add(joystick); mJoysticks.add(joystick);
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc,
getVendorId(joystickDevice), getProductId(joystickDevice), false, getVendorId(joystickDevice), getProductId(joystickDevice), false,
getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0); getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, 0);
} }
} }
} }
@ -317,6 +317,9 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
public int getVendorId(InputDevice joystickDevice) { public int getVendorId(InputDevice joystickDevice) {
return 0; return 0;
} }
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
return -1;
}
public int getButtonMask(InputDevice joystickDevice) { public int getButtonMask(InputDevice joystickDevice) {
return -1; return -1;
} }
@ -334,6 +337,43 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
return joystickDevice.getVendorId(); return joystickDevice.getVendorId();
} }
@Override
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
// For compatibility, keep computing the axis mask like before,
// only really distinguishing 2, 4 and 6 axes.
int axis_mask = 0;
if (ranges.size() >= 2) {
// ((1 << SDL_GAMEPAD_AXIS_LEFTX) | (1 << SDL_GAMEPAD_AXIS_LEFTY))
axis_mask |= 0x0003;
}
if (ranges.size() >= 4) {
// ((1 << SDL_GAMEPAD_AXIS_RIGHTX) | (1 << SDL_GAMEPAD_AXIS_RIGHTY))
axis_mask |= 0x000c;
}
if (ranges.size() >= 6) {
// ((1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER) | (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER))
axis_mask |= 0x0030;
}
// Also add an indicator bit for whether the sorting order has changed.
// This serves to disable outdated gamecontrollerdb.txt mappings.
boolean have_z = false;
boolean have_past_z_before_rz = false;
for (InputDevice.MotionRange range : ranges) {
int axis = range.getAxis();
if (axis == MotionEvent.AXIS_Z) {
have_z = true;
} else if (axis > MotionEvent.AXIS_Z && axis < MotionEvent.AXIS_RZ) {
have_past_z_before_rz = true;
}
}
if (have_z && have_past_z_before_rz) {
// If both these exist, the compare() function changed sorting order.
// Set a bit to indicate this fact.
axis_mask |= 0x8000;
}
return axis_mask;
}
@Override @Override
public int getButtonMask(InputDevice joystickDevice) { public int getButtonMask(InputDevice joystickDevice) {
int button_mask = 0; int button_mask = 0;
@ -769,7 +809,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override @Override
public boolean supportsRelativeMouse() { public boolean supportsRelativeMouse() {
return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)); return (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */);
} }
@Override @Override
@ -779,7 +819,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override @Override
public boolean setRelativeMouseEnabled(boolean enabled) { public boolean setRelativeMouseEnabled(boolean enabled) {
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) { if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
if (enabled) { if (enabled) {
SDLActivity.getContentView().requestPointerCapture(); SDLActivity.getContentView().requestPointerCapture();
} else { } else {

View File

@ -116,7 +116,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
int nDeviceHeight = height; int nDeviceHeight = height;
try try
{ {
if (Build.VERSION.SDK_INT >= 17) { if (Build.VERSION.SDK_INT >= 17 /* Android 4.2 (JELLY_BEAN_MR1) */) {
DisplayMetrics realMetrics = new DisplayMetrics(); DisplayMetrics realMetrics = new DisplayMetrics();
mDisplay.getRealMetrics( realMetrics ); mDisplay.getRealMetrics( realMetrics );
nDeviceWidth = realMetrics.widthPixels; nDeviceWidth = realMetrics.widthPixels;
@ -163,7 +163,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
// Don't skip in MultiWindow. // Don't skip in MultiWindow.
if (skip) { if (skip) {
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
if (SDLActivity.mSingleton.isInMultiWindowMode()) { if (SDLActivity.mSingleton.isInMultiWindowMode()) {
Log.v("SDL", "Don't skip in Multi-Window"); Log.v("SDL", "Don't skip in Multi-Window");
skip = false; skip = false;

View File

@ -51,7 +51,7 @@ android {
// get precompiled deps // get precompiled deps
tasks.register('downloadDeps', Download) { tasks.register('downloadDeps', Download) {
def VERSION = "29052023" def VERSION = "02072023"
src "https://github.com/MultiCraft/deps_android/releases/download/$VERSION/deps_android.zip" src "https://github.com/MultiCraft/deps_android/releases/download/$VERSION/deps_android.zip"
dest new File(buildDir, 'deps.zip') dest new File(buildDir, 'deps.zip')
overwrite false overwrite false

View File

@ -5,9 +5,9 @@ APP_SHORT_COMMANDS := true
APP_MODULES := MultiCraft APP_MODULES := MultiCraft
ifdef NDEBUG ifdef NDEBUG
APP_CFLAGS := -Ofast -fvisibility=hidden -Wno-extra-tokens -D__FILE__=__FILE_NAME__ -Wno-builtin-macro-redefined APP_CFLAGS := -Ofast -fvisibility=hidden -fvisibility-inlines-hidden -Wno-extra-tokens -D__FILE__=__FILE_NAME__ -Wno-builtin-macro-redefined
else else
APP_CFLAGS := -g -D_DEBUG -O0 -fno-omit-frame-pointer APP_CFLAGS := -g -D_DEBUG -O1 -fno-omit-frame-pointer
endif endif
APP_CFLAGS += -fexceptions APP_CFLAGS += -fexceptions

View File

@ -77,11 +77,6 @@ extern "C" int SDL_main(int argc, char *argv[])
_Exit(0); _Exit(0);
} }
/**
* Handler for finished message box input
* Intentionally NOT in namespace porting
* ToDo: this doesn't work as expected, there's a workaround for it right now
*/
extern "C" { extern "C" {
JNIEXPORT void JNICALL Java_com_multicraft_game_GameActivity_pauseGame( JNIEXPORT void JNICALL Java_com_multicraft_game_GameActivity_pauseGame(
JNIEnv *env, jclass clazz) JNIEnv *env, jclass clazz)
@ -138,7 +133,7 @@ void initAndroid()
activityClass = findClass("com/multicraft/game/GameActivity"); activityClass = findClass("com/multicraft/game/GameActivity");
if (activityClass == nullptr) if (activityClass == nullptr)
errorstream << errorstream <<
"porting::initAndroid unable to find java game activity class" << "porting::initAndroid unable to find Java game activity class" <<
std::endl; std::endl;
#ifdef GPROF #ifdef GPROF
@ -158,15 +153,14 @@ void cleanupAndroid()
#endif #endif
} }
static std::string javaStringToUTF8(jstring js) static std::string readJavaString(jstring j_str)
{ {
std::string str; // Get string as a UTF-8 C string
// Get string as a UTF-8 c-string const char *c_str = jnienv->GetStringUTFChars(j_str, nullptr);
const char *c_str = jnienv->GetStringUTFChars(js, nullptr);
// Save it // Save it
str = c_str; std::string str(c_str);
// And free the c-string // And free the C string
jnienv->ReleaseStringUTFChars(js, c_str); jnienv->ReleaseStringUTFChars(j_str, c_str);
return str; return str;
} }
@ -191,7 +185,7 @@ static std::string getAndroidPath(
// Call getAbsolutePath // Call getAbsolutePath
auto js_path = (jstring) jnienv->CallObjectMethod(ob_file, mt_getAbsPath); auto js_path = (jstring) jnienv->CallObjectMethod(ob_file, mt_getAbsPath);
return javaStringToUTF8(js_path); return readJavaString(js_path);
} }
void initializePaths() void initializePaths()
@ -221,7 +215,7 @@ void showInputDialog(const std::string &hint, const std::string &current, int ed
"(Ljava/lang/String;Ljava/lang/String;I)V"); "(Ljava/lang/String;Ljava/lang/String;I)V");
FATAL_ERROR_IF(showdialog == nullptr, FATAL_ERROR_IF(showdialog == nullptr,
"porting::showInputDialog unable to find java show dialog method"); "porting::showInputDialog unable to find Java show dialog method");
jstring jhint = jnienv->NewStringUTF(hint.c_str()); jstring jhint = jnienv->NewStringUTF(hint.c_str());
jstring jcurrent = jnienv->NewStringUTF(current.c_str()); jstring jcurrent = jnienv->NewStringUTF(current.c_str());
@ -236,7 +230,7 @@ void openURIAndroid(const std::string &url)
"(Ljava/lang/String;)V"); "(Ljava/lang/String;)V");
FATAL_ERROR_IF(url_open == nullptr, FATAL_ERROR_IF(url_open == nullptr,
"porting::openURIAndroid unable to find java openURI method"); "porting::openURIAndroid unable to find Java openURI method");
jstring jurl = jnienv->NewStringUTF(url.c_str()); jstring jurl = jnienv->NewStringUTF(url.c_str());
jnienv->CallVoidMethod(activityObj, url_open, jurl); jnienv->CallVoidMethod(activityObj, url_open, jurl);
@ -248,7 +242,7 @@ int getInputDialogState()
"getDialogState", "()I"); "getDialogState", "()I");
FATAL_ERROR_IF(dialogstate == nullptr, FATAL_ERROR_IF(dialogstate == nullptr,
"porting::getInputDialogState unable to find java dialog state method"); "porting::getInputDialogState unable to find Java dialog state method");
return jnienv->CallIntMethod(activityObj, dialogstate); return jnienv->CallIntMethod(activityObj, dialogstate);
} }
@ -259,15 +253,10 @@ std::string getInputDialogValue()
"getDialogValue", "()Ljava/lang/String;"); "getDialogValue", "()Ljava/lang/String;");
FATAL_ERROR_IF(dialogvalue == nullptr, FATAL_ERROR_IF(dialogvalue == nullptr,
"porting::getInputDialogValue unable to find java dialog value method"); "porting::getInputDialogValue unable to find Java getDialogValue method");
jobject result = jnienv->CallObjectMethod(activityObj, dialogvalue); jobject result = jnienv->CallObjectMethod(activityObj, dialogvalue);
return readJavaString((jstring) result);
const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr);
std::string text(javachars);
jnienv->ReleaseStringUTFChars((jstring) result, javachars);
return text;
} }
float getTotalSystemMemory() float getTotalSystemMemory()
@ -289,7 +278,7 @@ void handleError(const std::string &errType, const std::string &err)
"handleError", "(Ljava/lang/String;)V"); "handleError", "(Ljava/lang/String;)V");
FATAL_ERROR_IF(report_err == nullptr, FATAL_ERROR_IF(report_err == nullptr,
"porting::handleError unable to find java handleError method"); "porting::handleError unable to find Java handleError method");
std::string errorMessage = errType + ": " + err; std::string errorMessage = errType + ": " + err;
jstring jerr = porting::getJniString(errorMessage); jstring jerr = porting::getJniString(errorMessage);
@ -302,7 +291,7 @@ void notifyServerConnect(bool is_multiplayer)
"notifyServerConnect", "(Z)V"); "notifyServerConnect", "(Z)V");
FATAL_ERROR_IF(notifyConnect == nullptr, FATAL_ERROR_IF(notifyConnect == nullptr,
"porting::notifyServerConnect unable to find java notifyServerConnect method"); "porting::notifyServerConnect unable to find Java notifyServerConnect method");
auto param = (jboolean) is_multiplayer; auto param = (jboolean) is_multiplayer;
@ -318,7 +307,7 @@ void notifyExitGame()
"notifyExitGame", "()V"); "notifyExitGame", "()V");
FATAL_ERROR_IF(notifyExit == nullptr, FATAL_ERROR_IF(notifyExit == nullptr,
"porting::notifyExitGame unable to find java notifyExitGame method"); "porting::notifyExitGame unable to find Java notifyExitGame method");
jnienv->CallVoidMethod(activityObj, notifyExit); jnienv->CallVoidMethod(activityObj, notifyExit);
@ -337,11 +326,12 @@ float getDisplayDensity()
"getDensity", "()F"); "getDensity", "()F");
FATAL_ERROR_IF(getDensity == nullptr, FATAL_ERROR_IF(getDensity == nullptr,
"porting::getDisplayDensity unable to find java getDensity method"); "porting::getDisplayDensity unable to find Java getDensity method");
value = jnienv->CallFloatMethod(activityObj, getDensity); value = jnienv->CallFloatMethod(activityObj, getDensity);
firstRun = false; firstRun = false;
} }
return value; return value;
} }
#endif // ndef SERVER #endif // ndef SERVER
@ -396,7 +386,7 @@ void upgrade(const std::string &item)
"upgrade", "(Ljava/lang/String;)V"); "upgrade", "(Ljava/lang/String;)V");
FATAL_ERROR_IF(upgradeGame == nullptr, FATAL_ERROR_IF(upgradeGame == nullptr,
"porting::upgradeGame unable to find java upgrade method"); "porting::upgrade unable to find Java upgrade method");
jstring jitem = jnienv->NewStringUTF(item.c_str()); jstring jitem = jnienv->NewStringUTF(item.c_str());
jnienv->CallVoidMethod(activityObj, upgradeGame, jitem); jnienv->CallVoidMethod(activityObj, upgradeGame, jitem);
@ -412,11 +402,12 @@ int getRoundScreen()
"getRoundScreen", "()I"); "getRoundScreen", "()I");
FATAL_ERROR_IF(getRadius == nullptr, FATAL_ERROR_IF(getRadius == nullptr,
"porting::getRadius unable to find java getRoundScreen method"); "porting::getRoundScreen unable to find Java getRoundScreen method");
radius = jnienv->CallIntMethod(activityObj, getRadius); radius = jnienv->CallIntMethod(activityObj, getRadius);
firstRun = false; firstRun = false;
} }
return radius; return radius;
} }
@ -426,11 +417,11 @@ std::string getSecretKey(const std::string &key)
"getSecretKey", "(Ljava/lang/String;)Ljava/lang/String;"); "getSecretKey", "(Ljava/lang/String;)Ljava/lang/String;");
FATAL_ERROR_IF(getKey == nullptr, FATAL_ERROR_IF(getKey == nullptr,
"porting::getSecretKey unable to find java getSecretKey method"); "porting::getSecretKey unable to find Java getSecretKey method");
jstring jkey = jnienv->NewStringUTF(key.c_str()); jstring jkey = jnienv->NewStringUTF(key.c_str());
auto result = (jstring) jnienv->CallObjectMethod(activityObj, getKey, jkey); auto result = (jstring) jnienv->CallObjectMethod(activityObj, getKey, jkey);
return javaStringToUTF8(result); return readJavaString(result);
} }
} }