[Scummvm-git-logs] scummvm master -> c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6

lephilousophe noreply at scummvm.org
Tue Nov 12 21:40:08 UTC 2024


This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
76e69a770c ANDROID: Upgrade Gradle and Android Gradle Plugin
08f1383dc9 ANDROID: Use PointerIcon.TYPE_ARROW
fd3410ddd8 ANDROID: Align sections on 16K
5d58196643 ANDROID: Merge ScummVMEventsModern and ScummVMEventsBase
9a365241f9 ANDROID: Store the ScummVMActivity object in ScummVMEvents
5ea3ac6d51 ANDROID: Add support for predictive back gestures
a1393fac6b ANDROID: Target API level 35: Android 15 (Vanilla Ice Cream)
cc6a069c69 ANDROID: Rework the insets helper to handle cutouts and system bars
d9dcf93f65 ANDROID: Make ShortcutCreatorActivity edge-to-edge compliant
ac21b373e1 ANDROID: Make SplashActivity edge-to-edge compliant
c7584e6f7f ANDROID: Make custom shortcuts really custom


Commit: 76e69a770cbb40ec176babeaa0d18a2d91cec4ff
    https://github.com/scummvm/scummvm/commit/76e69a770cbb40ec176babeaa0d18a2d91cec4ff
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Upgrade Gradle and Android Gradle Plugin

Changed paths:
    dists/android/build.gradle
    dists/android/gradle/wrapper/gradle-wrapper.properties


diff --git a/dists/android/build.gradle b/dists/android/build.gradle
index b65e04c2812..ba262c63f3d 100644
--- a/dists/android/build.gradle
+++ b/dists/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:8.5.1'
+        classpath 'com.android.tools.build:gradle:8.7.2'
     }
 }
 
diff --git a/dists/android/gradle/wrapper/gradle-wrapper.properties b/dists/android/gradle/wrapper/gradle-wrapper.properties
index b82aa23a4f0..df97d72b8b9 100644
--- a/dists/android/gradle/wrapper/gradle-wrapper.properties
+++ b/dists/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME


Commit: 08f1383dc9ae230f5606ef6ade7bbc368809c56b
    https://github.com/scummvm/scummvm/commit/08f1383dc9ae230f5606ef6ade7bbc368809c56b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Use PointerIcon.TYPE_ARROW

PointerIcon.TYPE_DEFAULT is deprecated and has always been equal to
TYPE_ARROW.

Changed paths:
    backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java


diff --git a/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
index ff80eb7c1e4..42c9c6a82d3 100644
--- a/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
+++ b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
@@ -302,7 +302,7 @@ public class EditableSurfaceView extends SurfaceView {
 		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
 			// Android N (Nougat) is Android 7.0
 			//SurfaceView main_surface = findViewById(R.id.main_surface);
-			int type = show ? PointerIcon.TYPE_DEFAULT : PointerIcon.TYPE_NULL;
+			int type = show ? PointerIcon.TYPE_ARROW : PointerIcon.TYPE_NULL;
 			// https://stackoverflow.com/a/55482761
 			//Log.d(ScummVM.LOG_TAG, "captureMouse::showSystemMouseCursor3a");
 			setPointerIcon(PointerIcon.getSystemIcon(_context, type));
@@ -334,10 +334,10 @@ public class EditableSurfaceView extends SurfaceView {
 			if (_mouseIsInCapturedState) {
 				return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_NULL);
 			} else {
-				return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_DEFAULT);
+				return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_ARROW);
 			}
 		} else {
-			return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_DEFAULT);
+			return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_ARROW);
 		}
 	}
 


Commit: fd3410ddd84967406ec1e9ace7c918e323400234
    https://github.com/scummvm/scummvm/commit/fd3410ddd84967406ec1e9ace7c918e323400234
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Align sections on 16K

This is needed for the future Android devices making use of 16K pages

Changed paths:
    configure


diff --git a/configure b/configure
index 77011568651..482269b992b 100755
--- a/configure
+++ b/configure
@@ -3962,6 +3962,8 @@ case $_backend in
 		append_var INCLUDES '-I$(srcdir)/backends/platform/'$_backend
 		append_var CXXFLAGS "-Wa,--noexecstack"
 		append_var LDFLAGS "-Wl,-z,noexecstack"
+		# Newer Android devices will have 16K pages so we must be aligned
+		append_var LDFLAGS "-Wl,-z,max-page-size=16384"
 		# removed the following directive - was causing compilation issues when not also explicitly using --disable-mt32emu
 		# append_var INCLUDES "-isystem $ANDROID_NDK/sources/cxx-stl/system/include"
 		_sdl=no


Commit: 5d5819664334078a8f18bfcb2d5e8b5c67b0d9fb
    https://github.com/scummvm/scummvm/commit/5d5819664334078a8f18bfcb2d5e8b5c67b0d9fb
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Merge ScummVMEventsModern and ScummVMEventsBase

The split was done to allow to support versions before HONEYCOMB_MR1 but
we don't support these versions anymore.

Changed paths:
  A backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
  R backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
  R backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
    backends/platform/android/events.cpp
    backends/platform/android/org/scummvm/scummvm/MouseHelper.java
    backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index 6b6328671bc..65b0e96f970 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -48,7 +48,7 @@ static inline T scalef(T in, float numerator, float denominator) {
 	return static_cast<float>(in) * numerator / denominator;
 }
 
-// analog joystick axis id (for internal use) - Should match the logic in ScummVMEventsModern.java
+// analog joystick axis id (for internal use) - Should match the logic in ScummVMEvents.java
 enum {
 	// auxiliary movement axis bitflags
 	JE_JOY_AXIS_X_bf        = 0x01, // (0x01 << 0)
@@ -853,9 +853,9 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 		// arg2 = mouse y
 		// arg3 = AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_ACTION_UP, AMOTION_EVENT_ACTION_MOVE
 		// NOTE: Typically in a double tap event:
-		//       Before the ACTION_DOWN event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEventsBase's onDown())
-		//       and then a JE_TAP event (action UP) via ScummVMEventsBase's onSingleTapUp().
-		//       Before the ACTION_UP event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEventsBase's onDown()).
+		//       Before the ACTION_DOWN event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEvents's onDown())
+		//       and then a JE_TAP event (action UP) via ScummVMEvents's onSingleTapUp().
+		//       Before the ACTION_UP event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEvents's onDown()).
 //		LOGD("JE_DOUBLE_TAP - x: %d y: %d, arg3: %d", arg1, arg2, arg3);
 
 		ev0.type = Common::EVENT_MOUSEMOVE;
diff --git a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
index a8d2b1f6e8e..cde26ef1b41 100644
--- a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
+++ b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
@@ -182,18 +182,18 @@ public class MouseHelper implements View.OnHoverListener {
 	@SuppressLint("InlinedApi")
 	public boolean onMouseEvent(MotionEvent e, boolean hover) {
 
-		_scummvm.pushEvent(ScummVMEventsBase.JE_MOUSE_MOVE,
+		_scummvm.pushEvent(ScummVMEvents.JE_MOUSE_MOVE,
 			(int) e.getX(),
 			(int) e.getY(),
 			0,
 			0, 0, 0);
 
 		if (e.getActionMasked() == MotionEvent.ACTION_SCROLL) {
-			// The call is coming from ScummVMEventsModern, from a GenericMotionEvent (scroll wheel movement)
+			// The call is coming from ScummVMEvents, from a GenericMotionEvent (scroll wheel movement)
 			// TODO Do we want the JE_MOUSE_MOVE event too in this case?
-			int eventJEWheelUpDown = ScummVMEventsBase.JE_MOUSE_WHEEL_UP;
+			int eventJEWheelUpDown = ScummVMEvents.JE_MOUSE_WHEEL_UP;
 			if (e.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) {
-				eventJEWheelUpDown = ScummVMEventsBase.JE_MOUSE_WHEEL_DOWN;
+				eventJEWheelUpDown = ScummVMEvents.JE_MOUSE_WHEEL_DOWN;
 			}
 			//Log.d(ScummVM.LOG_TAG, "onMouseEvent Wheel Up/Down = " + eventJEWheelUpDown);
 			_scummvm.pushEvent(eventJEWheelUpDown,
@@ -217,31 +217,31 @@ public class MouseHelper implements View.OnHoverListener {
 			if (lmbDown) {
 				if (!_lmbPressed) {
 					// left mouse button was pressed just now
-					_scummvm.pushEvent(ScummVMEventsBase.JE_LMB_DOWN, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
+					_scummvm.pushEvent(ScummVMEvents.JE_LMB_DOWN, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
 				}
 
 				_lmbPressed = true;
 			} else {
 				if (_lmbPressed) {
 					// left mouse button was released just now
-					_scummvm.pushEvent(ScummVMEventsBase.JE_LMB_UP, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
+					_scummvm.pushEvent(ScummVMEvents.JE_LMB_UP, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
 				}
 
 				_lmbPressed = false;
 			}
 
-			_rmbPressed = handleButton(e, _rmbPressed, MotionEvent.BUTTON_SECONDARY, ScummVMEventsBase.JE_RMB_DOWN, ScummVMEventsBase.JE_RMB_UP);
-			_mmbPressed = handleButton(e, _mmbPressed, MotionEvent.BUTTON_TERTIARY, ScummVMEventsBase.JE_MMB_DOWN, ScummVMEventsBase.JE_MMB_UP);
-			_bmbPressed = handleButton(e, _bmbPressed, MotionEvent.BUTTON_BACK, ScummVMEventsBase.JE_BMB_DOWN, ScummVMEventsBase.JE_BMB_UP);
-			_fmbPressed = handleButton(e, _fmbPressed, MotionEvent.BUTTON_FORWARD, ScummVMEventsBase.JE_FMB_DOWN, ScummVMEventsBase.JE_FMB_UP);
+			_rmbPressed = handleButton(e, _rmbPressed, MotionEvent.BUTTON_SECONDARY, ScummVMEvents.JE_RMB_DOWN, ScummVMEvents.JE_RMB_UP);
+			_mmbPressed = handleButton(e, _mmbPressed, MotionEvent.BUTTON_TERTIARY, ScummVMEvents.JE_MMB_DOWN, ScummVMEvents.JE_MMB_UP);
+			_bmbPressed = handleButton(e, _bmbPressed, MotionEvent.BUTTON_BACK, ScummVMEvents.JE_BMB_DOWN, ScummVMEvents.JE_BMB_UP);
+			_fmbPressed = handleButton(e, _fmbPressed, MotionEvent.BUTTON_FORWARD, ScummVMEvents.JE_FMB_DOWN, ScummVMEvents.JE_FMB_UP);
 			// Lint warning for BUTTON_STYLUS... "
 			//  Field requires API level 23 (current min is 16): android.view.MotionEvent#BUTTON_STYLUS_PRIMARY"
 			//  Field requires API level 23 (current min is 16): android.view.MotionEvent#BUTTON_STYLUS_SECONDARY"
 			// We suppress it:
 			//
 			// https://stackoverflow.com/a/48588149
-			_srmbPressed = handleButton(e, _srmbPressed, MotionEvent.BUTTON_STYLUS_PRIMARY, ScummVMEventsBase.JE_RMB_DOWN, ScummVMEventsBase.JE_RMB_UP);
-			_smmbPressed = handleButton(e, _smmbPressed, MotionEvent.BUTTON_STYLUS_SECONDARY, ScummVMEventsBase.JE_MMB_DOWN, ScummVMEventsBase.JE_MMB_UP);
+			_srmbPressed = handleButton(e, _srmbPressed, MotionEvent.BUTTON_STYLUS_PRIMARY, ScummVMEvents.JE_RMB_DOWN, ScummVMEvents.JE_RMB_UP);
+			_smmbPressed = handleButton(e, _smmbPressed, MotionEvent.BUTTON_STYLUS_SECONDARY, ScummVMEvents.JE_MMB_DOWN, ScummVMEvents.JE_MMB_UP);
 		}
 		return true;
 	}
diff --git a/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java b/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
index 5aa81511063..ba896691198 100644
--- a/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
+++ b/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
@@ -1,9 +1,9 @@
 
 package org.scummvm.scummvm;
 
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MOUSE_WHEEL_DOWN;
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MOUSE_WHEEL_UP;
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MULTI;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MOUSE_WHEEL_DOWN;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MOUSE_WHEEL_UP;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MULTI;
 
 import android.os.Handler;
 import android.os.Looper;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index f56f63efd69..a792ea29654 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -610,13 +610,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			resId = R.drawable.ic_action_keyboard;
 		} else {
 			switch(touchMode) {
-			case ScummVMEventsBase.TOUCH_MODE_TOUCHPAD:
+			case ScummVMEvents.TOUCH_MODE_TOUCHPAD:
 				resId = R.drawable.ic_action_touchpad;
 				break;
-			case ScummVMEventsBase.TOUCH_MODE_MOUSE:
+			case ScummVMEvents.TOUCH_MODE_MOUSE:
 				resId = R.drawable.ic_action_mouse;
 				break;
-			case ScummVMEventsBase.TOUCH_MODE_GAMEPAD:
+			case ScummVMEvents.TOUCH_MODE_GAMEPAD:
 				resId = R.drawable.ic_action_gamepad;
 				break;
 			default:
@@ -663,7 +663,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		public void onClick(View v) {
 			runOnUiThread(new Runnable() {
 				public void run() {
-					_scummvm.pushEvent(ScummVMEventsBase.JE_MENU, 0, 0, 0, 0, 0, 0);
+					_scummvm.pushEvent(ScummVMEvents.JE_MENU, 0, 0, 0, 0, 0, 0);
 				}
 			});
 		}
@@ -900,7 +900,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	}
 
 	private MyScummVM _scummvm;
-	private ScummVMEventsBase _events;
+	private ScummVMEvents _events;
 	private MouseHelper _mouseHelper;
 	private Thread _scummvm_thread;
 
@@ -1031,11 +1031,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			//_mouseHelper.attach(_main_surface);
 		}
 
-		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
-			_events = new ScummVMEventsModern(this, _scummvm, _mouseHelper);
-		} else {
-			_events = new ScummVMEventsBase(this, _scummvm, _mouseHelper);
-		}
+		_events = new ScummVMEvents(this, _scummvm, _mouseHelper);
 
 		setupTouchModeBtn(_events.getTouchMode());
 
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
similarity index 63%
rename from backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
rename to backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 65f1fce55a3..8ba7614b172 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -9,6 +9,7 @@ import android.view.GestureDetector;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -17,7 +18,7 @@ import androidx.annotation.NonNull;
 
 import java.lang.ref.WeakReference;
 
-public class ScummVMEventsBase implements
+public class ScummVMEvents implements
 		android.view.View.OnKeyListener,
 		android.view.View.OnTouchListener,
 		android.view.GestureDetector.OnGestureListener,
@@ -64,6 +65,23 @@ public class ScummVMEventsBase implements
 	public static final int JOYSTICK_AXIS_MAX = 32767; // matches the definition in common/events of "const int16 JOYAXIS_MAX = 32767;"
 	public static final float JOYSTICK_AXIS_HAT_SCALE = 0.66f; // ie. 2/3 to be applied to JOYSTICK_AXIS_MAX
 
+	// auxiliary movement axis bitflags
+	// Also repeated (and used) in android's events.cpp (JE_JOYSTICK case)
+	private static final int JOYSTICK_AXIS_X_bf        = 0x01; // (0x01 << 0)
+	private static final int JOYSTICK_AXIS_Y_bf        = 0x02; // (0x01 << 1)
+	private static final int JOYSTICK_AXIS_HAT_X_bf    = 0x04; // (0x01 << 2)
+	private static final int JOYSTICK_AXIS_HAT_Y_bf    = 0x08; // (0x01 << 3)
+	private static final int JOYSTICK_AXIS_Z_bf        = 0x10; // (0x01 << 4)
+	private static final int JOYSTICK_AXIS_RZ_bf       = 0x20; // (0x01 << 5)
+	private static final int JOYSTICK_AXIS_LTRIGGER_bf = 0x40; // (0x01 << 6)
+	private static final int JOYSTICK_AXIS_RTRIGGER_bf = 0x80; // (0x01 << 7)
+
+	private static final int REPEAT_INTERVAL = 20; // ~50 keys per second
+	private static final int REPEAT_START_DELAY = 40;
+
+	private final float[] _repeatingJoystickCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+	private int _repeatingJoystickAxisIdBitFlags = 0x00;
+
 	final protected Context _context;
 	final protected ScummVM _scummvm;
 	final protected GestureDetector _gd;
@@ -80,18 +98,28 @@ public class ScummVMEventsBase implements
 	// https://stackoverflow.com/a/27826094
 	public static class ScummVMEventHandler extends Handler {
 
-		private final WeakReference<ScummVMEventsBase> mListenerReference;
+		private final WeakReference<ScummVMEvents> mListenerReference;
 
-		public ScummVMEventHandler(ScummVMEventsBase listener) {
+		public ScummVMEventHandler(ScummVMEvents listener) {
 			super(Looper.getMainLooper());
 			mListenerReference = new WeakReference<>(listener);
 		}
 
 		@Override
 		public synchronized void handleMessage(@NonNull Message msg) {
-			ScummVMEventsBase listener = mListenerReference.get();
+			ScummVMEvents listener = mListenerReference.get();
 			if(listener != null) {
-				listener.handleEVHMessage(msg);
+				switch (msg.what) {
+					case MSG_REPEAT:
+						if (listener.repeatMove(0, false)) {
+							Message repeat = Message.obtain(this, MSG_REPEAT);
+							sendMessageDelayed(repeat, REPEAT_INTERVAL);
+						}
+						break;
+					default:
+						listener.handleEVHMessage(msg);
+						break;
+				}
 			}
 		}
 
@@ -112,7 +140,7 @@ public class ScummVMEventsBase implements
 //		return new ScummVMEventHandler(this);
 //	}
 
-	public ScummVMEventsBase(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
+	public ScummVMEvents(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
 		_context = context;
 		_scummvm = scummvm;
 		// Careful, _mouseHelper can be null (if HoverListener is not available for the device API -- old devices, API < 9)
@@ -131,6 +159,7 @@ public class ScummVMEventsBase implements
 	final static int MSG_SMENU_LONG_PRESS = 1;
 	final static int MSG_SBACK_LONG_PRESS = 2;
 	final static int MSG_LONG_TOUCH_EVENT = 3;
+	final static int MSG_REPEAT = 4;
 
 	private void handleEVHMessage(final Message msg) {
 		if (msg.what == MSG_SMENU_LONG_PRESS) {
@@ -214,8 +243,63 @@ public class ScummVMEventsBase implements
 		return true;
 	}
 
-	public boolean onGenericMotionEvent(MotionEvent e) {
-		// we don't manage the GenericMotionEvent
+	public boolean onGenericMotionEvent(MotionEvent event) {
+		// TODO Make Use of MotionEvent.getToolType() ie. for handling TOOL_TYPE_FINGER/ TOOL_TYPE_MOUSE/ TOOL_TYPE_STYLUS/ TOOL_TYPE_UNKNOWN?
+		// Check that the event came from a joystick
+		if (((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK
+			 || (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0)) {
+			switch(event.getActionMasked()) {
+			case MotionEvent.ACTION_MOVE:
+				//InputDevice inputDevice = event.getDevice();
+				//Log.d(ScummVM.LOG_TAG, "JOYSTICK GENERIC MOTION: MOVE, Devname=" + inputDevice.getName() + " pid=" + inputDevice.getProductId() + " vid=" + inputDevice.getVendorId());
+				// NOTE In Android 12 (on some early version patch) support for PS5's DualSense broke, and the key mappings are messed up.
+				// This was fixed in another Android 12 patch, but not all devices got that. (eg Redmi 9 Pro does not have this update)
+				// Details about this here: https://stackoverflow.com/questions/68190869/dualshock-5-and-android
+				// Not much we can do about this.
+
+				// Process all historical movement samples in the batch
+				final int historySize = event.getHistorySize();
+
+				// Process the movements starting from the
+				// earliest historical position in the batch
+				for (int i = 0; i < historySize; ++i) {
+					// Process the event at historical position i
+					//Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m) hist: ");
+					processJoystickInput(event, i);
+				}
+
+				// Process the current movement sample in the batch (position -1)
+				//Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m): "  );
+				processJoystickInput(event, -1);
+				return true;
+
+			default:
+				break;
+			}
+		} else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+			//Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - onGenericMotionEvent(m) ");
+			//
+			// Check that the event might be a mouse scroll wheel (ACTION_SCROLL)
+			// Code inspired from https://stackoverflow.com/a/33086042
+			//
+			// NOTE Other GenericMotionEvent are also triggered for InputDevice of SOURCE_CLASS_POINTER (eg. physical mouse).
+			// These seem to be for button down/up events, which are handled along with pushing a JE_MOVE event
+			// in MouseHelper's onMouseEvent() called from onTouch().
+			switch (event.getActionMasked()) {
+			case MotionEvent.ACTION_SCROLL:
+				//Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - ACTION SCROLL");
+				// This action is not a touch event so it is delivered to
+				// View#onGenericMotionEvent(MotionEvent) rather than View#onTouchEvent(MotionEvent).
+				if (_mouseHelper != null) {
+					return _mouseHelper.onMouseEvent(event, false);
+				}
+				break;
+
+			default:
+				break;
+			}
+		}
+		//Log.d(ScummVM.LOG_TAG, "MOTION NOT HANDLED, source: " + event.getSource() + " event: "+ event.getActionMasked());
 		return false;
 	}
 
@@ -377,7 +461,7 @@ public class ScummVMEventsBase implements
 			//        or adjust the Pointer Speed setting from the "Control" tab.
 			// NOTE 2 Modern gamepads/ game controllers treat the "DPAD" cross buttons as HATs that produce movement events
 			// and *not* DPAD_UP/DOWN/LEFT/RIGHT button press events. Hence, for those controllers these DPAD key events won't be triggered.
-			// Those are handled in ScummVMEventsModern class within its onGenericMotionEvent() implementation.
+			// Those are handled within onGenericMotionEvent().
 			//
 			if ((e.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) {
 				type = JE_KEY;
@@ -718,4 +802,181 @@ public class ScummVMEventsBase implements
 //		Log.d(ScummVM.LOG_TAG, "onSingleTapConfirmed - double tap failed");
 		return true;
 	}
+
+	private static float getJoystickCenteredAxis(MotionEvent event, InputDevice device, int axisId, int historyPos) {
+		final InputDevice.MotionRange range = device.getMotionRange(axisId, event.getSource());
+		final int actionPointerIndex = event.getActionIndex();
+
+		// A joystick at rest does not always report an absolute position of
+		// (0,0). Use the getFlat() method to determine the range of values
+		// bounding the joystick axis center.
+		if (range != null) {
+			final float axisFlat = range.getFlat();
+			final float axisVal = (historyPos < 0) ? event.getAxisValue(range.getAxis(), actionPointerIndex) : event.getHistoricalAxisValue(range.getAxis(), actionPointerIndex, historyPos);
+
+			// Ignore axis values that are within the 'flat' region of the
+			// joystick axis center.
+			if (Math.abs(axisVal) > axisFlat) {
+//				Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") > " + axisFlat + " (flat) - raw val=" + axisVal);
+				// This value is already normalized in [-1.0, 1.0] (for sticks and "hats") or [0.0, 1.0] (for triggers)
+				return axisVal;
+			}
+//			else {
+//				Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") <= " + axisFlat  + "(flat) - raw val=" + axisVal);
+//			}
+		}
+//		else {
+//			Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + "- getCenteredAxis() range was null!");
+//		}
+		return 0;
+	}
+
+	private boolean repeatMove(final int axisBitFlags, boolean useArgumentAxis) {
+		// The argument axisFlags has flags set for the axis that have movement.
+		// Send pushEvents per axis (with bitflag set) as opposed to using a version of pushEvent with many arguments.
+		int axisBfs = axisBitFlags;
+		if (!useArgumentAxis) {
+			axisBfs = _repeatingJoystickAxisIdBitFlags;
+		}
+		for (int i = 0; i < _repeatingJoystickCenteredAxisValuesArray.length; ++i) {
+			if ((axisBfs & (0x01 <<  i)) != 0) {
+				_scummvm.pushEvent(JE_JOYSTICK, MotionEvent.ACTION_MOVE,
+				(int) (_repeatingJoystickCenteredAxisValuesArray[i] * JOYSTICK_AXIS_MAX),
+				0,
+				axisBfs & (0x01 <<  i), 0, 0);
+			}
+		}
+		return true;
+	}
+
+	private void processJoystickInput(MotionEvent event, int historyPos) {
+		InputDevice inputDevice = event.getDevice();
+
+//		// DEBUG LOGGING CODE
+//		final int actionPointerIndex = event.getActionIndex();
+//
+//		final int[] allAxisIdArray = {MotionEvent.AXIS_X, MotionEvent.AXIS_Y, MotionEvent.AXIS_Z,
+//		                        MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ,
+//		                        MotionEvent.AXIS_RTRIGGER, MotionEvent.AXIS_LTRIGGER,
+//		                        MotionEvent.AXIS_HAT_X, MotionEvent.AXIS_HAT_Y,
+//		                        MotionEvent.AXIS_WHEEL, MotionEvent.AXIS_VSCROLL, MotionEvent.AXIS_HSCROLL, MotionEvent.AXIS_SCROLL,
+//		                        MotionEvent.AXIS_RELATIVE_X, MotionEvent.AXIS_RELATIVE_Y, MotionEvent.AXIS_DISTANCE,
+//		                        MotionEvent.AXIS_THROTTLE, MotionEvent.AXIS_TILT, MotionEvent.AXIS_GAS, MotionEvent.AXIS_BRAKE, MotionEvent.AXIS_RUDDER,
+//		                        MotionEvent.AXIS_GENERIC_1, MotionEvent.AXIS_GENERIC_2, MotionEvent.AXIS_GENERIC_3, MotionEvent.AXIS_GENERIC_4,
+//		                        MotionEvent.AXIS_GENERIC_5, MotionEvent.AXIS_GENERIC_6, MotionEvent.AXIS_GENERIC_7, MotionEvent.AXIS_GENERIC_8,
+//		                        MotionEvent.AXIS_GENERIC_9, MotionEvent.AXIS_GENERIC_10, MotionEvent.AXIS_GENERIC_11, MotionEvent.AXIS_GENERIC_12,
+//		                        MotionEvent.AXIS_GENERIC_13, MotionEvent.AXIS_GENERIC_14, MotionEvent.AXIS_GENERIC_15, MotionEvent.AXIS_GENERIC_16};
+//
+//		// These correspond to our bitflags order for movement/repetition
+//		final String[] axisBitFlagIndexToString = {"LEFT_JOY_X", "LEFT_JOY_Y", "HAT_X", "HAT_Y", "RIGHT_JOY_X", "RIGHT_JOY_Y", "LEFT_TRIGGER", "RIGHT_TRIGGER"};
+//
+//		for (int i = 0; i < allAxisIdArray.length; ++i) {
+//			float axisVal = event.getAxisValue(allAxisIdArray[i], actionPointerIndex);
+//			if (Math.abs(axisVal) > 0.0f) {
+//				Log.d(ScummVM.LOG_TAG, "JOYSTICK MOTION ON AXIS: " + MotionEvent.axisToString(allAxisIdArray[i]) + " id: " + allAxisIdArray[i] + " for (raw): " + axisVal);
+//			}
+//		}
+//		// END OF DEBUG LOGGING CODE
+
+		// Scaling the HAT movement to 1/3 causes it to be filtered out by the backend (see backends/keymapper/hardware-input.cpp, method: findHardwareInput() )
+		// ie. "Ignore incomplete presses for remapping purposes" (lower than 1/2 of Common::JOYAXIS_MAX which is defined as 32767 in common/events.h)
+		// Hence we scale to 2/3 since hat axis is non-analog, and 100% of axis max is way too fast when used for cursor movement
+
+		// Calculate the distance(s) to move by - for each supported AXIS
+		// ie. the left control stick, hat switch, the right control stick, or the R/L triggers
+		// NOTE The order of entries in the moveDistanceArray array is important. It corresponds to our auxiliary movement axis bitflags values order
+		float[] centeredAxisValuesArray = {getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos),
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos),
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos),
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos),
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_LTRIGGER, historyPos),
+		                                   getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_RTRIGGER, historyPos)};
+
+		float currX    = 0.0f;
+		float absCurrX = 0.0f;
+		float currY    = 0.0f;
+		float absCurrY = 0.0f;
+		int stoppingMovementAxisIdBitFlags = 0;
+		int prevRepeatingAxisIdBitFlags = _repeatingJoystickAxisIdBitFlags;
+
+		for (int i = 0; i < centeredAxisValuesArray.length; ++i) {
+			currX = centeredAxisValuesArray[i];
+			absCurrX = Math.abs(currX);
+
+			// 0 - 5 (ie. 4+1) we deal with x-axis, y-axis together for LEFT STICK, HAT (DPAD), RIGHT STICK.
+			if (i < 5) {
+				currY = centeredAxisValuesArray[i+1];
+				absCurrY = Math.abs(currY);
+			}
+			// TODO Make this limit dependant on the ConfMan joystick_deadzone setting -- but avoid using frequent JNI to get the value
+			//      The virtual mouse already uses joystick_deadzone to handle input, along with the "kbdmouse_speed". (see backends/keymapper/virtual-mouse.cpp)
+			//      PSP also uses joystick_deadzone for its input so maybe we could do something similar. (see backends/platform/psp/input.cpp).
+			//      If this filtering goes to the native side (eg. in backends/platform/android/events.cpp) we'll still need to somehow update the repeating-axis bitflag.
+			if (absCurrX < 0.209f
+			    && (i >= 6 || absCurrY < 0.209f)) {
+				// When on all the axis for the current control (or the only axis) we have negligible movement that could still be greater than "flat" range,
+				// we do extra filter to stop repetition in order to avoid cases when Android does not send onGenericMotionEvent()
+				// for small x or y (while abs is still greater than range.getflat())!
+				// In such case we would end up with a slow moving "mouse" cursor - so we need this extra filter.
+
+				// If previously we had movement on at least one of the axis for the current control (or the only axis),
+				// then stop movement, reset values to 0 and clear pertinent repeating axis bitflags.
+				if ((prevRepeatingAxisIdBitFlags & (0x01 <<  i)) != 0
+				    || (i < 5 && (prevRepeatingAxisIdBitFlags & (0x01 << (i+1))) != 0)) {
+//					if (i < 5) {
+//						Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100) + " y=" + (int)(currY * 100));
+//					} else {
+//						Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100));
+//					}
+					// do the move, then signal the joystick has returned to center pos
+					stoppingMovementAxisIdBitFlags = 0;
+					_repeatingJoystickCenteredAxisValuesArray[i] = currX;
+					stoppingMovementAxisIdBitFlags |= (0x01 << i);
+					if (i < 5) {
+						_repeatingJoystickCenteredAxisValuesArray[i+1] = currY;
+						stoppingMovementAxisIdBitFlags |= (0x01 << (i+1));
+					}
+					repeatMove(stoppingMovementAxisIdBitFlags, true);
+
+					_repeatingJoystickCenteredAxisValuesArray[i] = 0.0f;
+					_repeatingJoystickAxisIdBitFlags &= ~(0x01 << i);
+					if (i < 5) {
+						_repeatingJoystickCenteredAxisValuesArray[i+1] = 0.0f;
+						_repeatingJoystickAxisIdBitFlags &= ~(0x01 << (i+1));
+					}
+					// This return-to-zero (center pos) is sent as an explicit extra event, so it's considered "movement" on the axis
+					repeatMove(stoppingMovementAxisIdBitFlags, true);
+				}
+			} else {
+				// Here we have significant movement on at least one of the axis for the current control (or the only axis).
+//				if (i < 5) {
+//					Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- update movement: x= " + (int)(currX * 100) + " y= " + (int)(currY * 100));
+//				} else {
+//					Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- update movement: x= " + (int)(currX * 100));
+//				}
+				// We update the axis values (for controls like sticks or hats we update both pertinent axis values here)
+				// and set the respective repetition bit flag(s).
+				_repeatingJoystickCenteredAxisValuesArray[i] = currX; // X AXIS
+				_repeatingJoystickAxisIdBitFlags |= (0x01 <<  i);
+				if (i < 5) {
+					_repeatingJoystickCenteredAxisValuesArray[i+1] = currY; // Y AXIS
+					_repeatingJoystickAxisIdBitFlags |= (0x01 <<  (i+1));
+				}
+			}
+			if (i < 5) ++i; // skip next index as we handled it already in this case
+		}
+
+		if (_repeatingJoystickAxisIdBitFlags == 0) {
+			// Only removeMessages() if all motions are supposed to stop, ie final moving stick/hat/trigger etc???
+			_handler.removeMessages(MSG_REPEAT);
+		} else if (prevRepeatingAxisIdBitFlags == 0) {
+			// Start repetition message sending (sendMessageDelayed)
+			Message msg = _handler.obtainMessage(MSG_REPEAT);
+			_handler.sendMessageDelayed(msg, REPEAT_START_DELAY);
+			repeatMove(_repeatingJoystickAxisIdBitFlags, true);
+		}
+	}
+
 }
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
deleted file mode 100644
index 0b6187c18ad..00000000000
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-
-import androidx.annotation.NonNull;
-
-import java.lang.ref.WeakReference;
-
-// A class that extends the basic ScummVMEventsBase, supporting Android APIs > HONEYCOMB_MR1 (API 12)
-public class ScummVMEventsModern extends ScummVMEventsBase {
-
-	private static final int MSG_REPEAT = 3;
-	private static final int REPEAT_INTERVAL = 20; // ~50 keys per second
-	private static final int REPEAT_START_DELAY = 40;
-
-	public ScummVMEventsModern(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
-		super(context, scummvm, mouseHelper);
-	}
-
-	// Custom handler code (to avoid mem leaks, see warning "This Handler Class Should Be Static Or Leaks Might Occur”) based on:
-	// https://stackoverflow.com/a/27826094
-	public static class ScummVMEventsModernHandler extends Handler {
-
-		private final WeakReference<ScummVMEventsModern> mListenerReference;
-
-		public ScummVMEventsModernHandler(ScummVMEventsModern listener) {
-			super(Looper.getMainLooper());
-			mListenerReference = new WeakReference<>(listener);
-		}
-
-		@Override
-		public synchronized void handleMessage(@NonNull Message msg) {
-			ScummVMEventsModern listener = mListenerReference.get();
-			if(listener != null) {
-				switch (msg.what) {
-					case MSG_REPEAT:
-						if (listener.repeatMove(0, false)) {
-							Message repeat = Message.obtain(this, MSG_REPEAT);
-							sendMessageDelayed(repeat, REPEAT_INTERVAL);
-						}
-						break;
-				}
-			}
-		}
-
-		public void clear() {
-			this.removeCallbacksAndMessages(null);
-		}
-	}
-
-	@Override
-	public void clearEventHandler() {
-		super.clearEventHandler();
-		mHandler.clear();
-	}
-
-	private final ScummVMEventsModernHandler mHandler = new ScummVMEventsModernHandler(this);
-	private final float[] repeatingCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
-
-	// auxiliary movement axis bitflags
-	// Also repeated (and used) in android's events.cpp (JE_JOYSTICK case)
-	private static final int AXIS_X_bf        = 0x01; // (0x01 << 0)
-	private static final int AXIS_Y_bf        = 0x02; // (0x01 << 1)
-	private static final int AXIS_HAT_X_bf    = 0x04; // (0x01 << 2)
-	private static final int AXIS_HAT_Y_bf    = 0x08; // (0x01 << 3)
-	private static final int AXIS_Z_bf        = 0x10; // (0x01 << 4)
-	private static final int AXIS_RZ_bf       = 0x20; // (0x01 << 5)
-	private static final int AXIS_LTRIGGER_bf = 0x40; // (0x01 << 6)
-	private static final int AXIS_RTRIGGER_bf = 0x80; // (0x01 << 7)
-
-	private int repeatingAxisIdBitFlags = 0x00;
-
-	private static float getCenteredAxis(MotionEvent event, InputDevice device, int axisId, int historyPos) {
-		final InputDevice.MotionRange range = device.getMotionRange(axisId, event.getSource());
-		final int actionPointerIndex = event.getActionIndex();
-
-		// A joystick at rest does not always report an absolute position of
-		// (0,0). Use the getFlat() method to determine the range of values
-		// bounding the joystick axis center.
-		if (range != null) {
-			final float axisFlat = range.getFlat();
-			final float axisVal = (historyPos < 0) ? event.getAxisValue(range.getAxis(), actionPointerIndex) : event.getHistoricalAxisValue(range.getAxis(), actionPointerIndex, historyPos);
-
-			// Ignore axis values that are within the 'flat' region of the
-			// joystick axis center.
-			if (Math.abs(axisVal) > axisFlat) {
-//				Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") > " + axisFlat + " (flat) - raw val=" + axisVal);
-				// This value is already normalized in [-1.0, 1.0] (for sticks and "hats") or [0.0, 1.0] (for triggers)
-				return axisVal;
-			}
-//			else {
-//				Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") <= " + axisFlat  + "(flat) - raw val=" + axisVal);
-//			}
-		}
-//		else {
-//			Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + "- getCenteredAxis() range was null!");
-//		}
-		return 0;
-	}
-
-	private void removeMessages() {
-		if (mHandler != null) {
-			mHandler.removeMessages(MSG_REPEAT);
-		}
-	}
-
-	private boolean repeatMove(final int axisBitFlags, boolean useArgumentAxis) {
-		// The argument axisFlags has flags set for the axis that have movement.
-		// Send pushEvents per axis (with bitflag set) as opposed to using a version of pushEvent with many arguments.
-		int axisBfs = axisBitFlags;
-		if (!useArgumentAxis) {
-			axisBfs = repeatingAxisIdBitFlags;
-		}
-		for (int i = 0; i < repeatingCenteredAxisValuesArray.length; ++i) {
-			if ((axisBfs & (0x01 <<  i)) != 0) {
-				_scummvm.pushEvent(JE_JOYSTICK, MotionEvent.ACTION_MOVE,
-				(int) (repeatingCenteredAxisValuesArray[i] * JOYSTICK_AXIS_MAX),
-				0,
-				axisBfs & (0x01 <<  i), 0, 0);
-			}
-		}
-		return true;
-	}
-
-	private void processJoystickInput(MotionEvent event, int historyPos) {
-		InputDevice inputDevice = event.getDevice();
-
-//		// DEBUG LOGGING CODE
-//		final int actionPointerIndex = event.getActionIndex();
-//
-//		final int[] allAxisIdArray = {MotionEvent.AXIS_X, MotionEvent.AXIS_Y, MotionEvent.AXIS_Z,
-//		                        MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ,
-//		                        MotionEvent.AXIS_RTRIGGER, MotionEvent.AXIS_LTRIGGER,
-//		                        MotionEvent.AXIS_HAT_X, MotionEvent.AXIS_HAT_Y,
-//		                        MotionEvent.AXIS_WHEEL, MotionEvent.AXIS_VSCROLL, MotionEvent.AXIS_HSCROLL, MotionEvent.AXIS_SCROLL,
-//		                        MotionEvent.AXIS_RELATIVE_X, MotionEvent.AXIS_RELATIVE_Y, MotionEvent.AXIS_DISTANCE,
-//		                        MotionEvent.AXIS_THROTTLE, MotionEvent.AXIS_TILT, MotionEvent.AXIS_GAS, MotionEvent.AXIS_BRAKE, MotionEvent.AXIS_RUDDER,
-//		                        MotionEvent.AXIS_GENERIC_1, MotionEvent.AXIS_GENERIC_2, MotionEvent.AXIS_GENERIC_3, MotionEvent.AXIS_GENERIC_4,
-//		                        MotionEvent.AXIS_GENERIC_5, MotionEvent.AXIS_GENERIC_6, MotionEvent.AXIS_GENERIC_7, MotionEvent.AXIS_GENERIC_8,
-//		                        MotionEvent.AXIS_GENERIC_9, MotionEvent.AXIS_GENERIC_10, MotionEvent.AXIS_GENERIC_11, MotionEvent.AXIS_GENERIC_12,
-//		                        MotionEvent.AXIS_GENERIC_13, MotionEvent.AXIS_GENERIC_14, MotionEvent.AXIS_GENERIC_15, MotionEvent.AXIS_GENERIC_16};
-//
-//		// These correspond to our bitflags order for movement/repetition
-//		final String[] axisBitFlagIndexToString = {"LEFT_JOY_X", "LEFT_JOY_Y", "HAT_X", "HAT_Y", "RIGHT_JOY_X", "RIGHT_JOY_Y", "LEFT_TRIGGER", "RIGHT_TRIGGER"};
-//
-//		for (int i = 0; i < allAxisIdArray.length; ++i) {
-//			float axisVal = event.getAxisValue(allAxisIdArray[i], actionPointerIndex);
-//			if (Math.abs(axisVal) > 0.0f) {
-//				Log.d(ScummVM.LOG_TAG, "JOYSTICK MOTION ON AXIS: " + MotionEvent.axisToString(allAxisIdArray[i]) + " id: " + allAxisIdArray[i] + " for (raw): " + axisVal);
-//			}
-//		}
-//		// END OF DEBUG LOGGING CODE
-
-		// Scaling the HAT movement to 1/3 causes it to be filtered out by the backend (see backends/keymapper/hardware-input.cpp, method: findHardwareInput() )
-		// ie. "Ignore incomplete presses for remapping purposes" (lower than 1/2 of Common::JOYAXIS_MAX which is defined as 32767 in common/events.h)
-		// Hence we scale to 2/3 since hat axis is non-analog, and 100% of axis max is way too fast when used for cursor movement
-
-		// Calculate the distance(s) to move by - for each supported AXIS
-		// ie. the left control stick, hat switch, the right control stick, or the R/L triggers
-		// NOTE The order of entries in the moveDistanceArray array is important. It corresponds to our auxiliary movement axis bitflags values order
-		float[] centeredAxisValuesArray = {getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos),
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos),
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos),
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos),
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_LTRIGGER, historyPos),
-		                                   getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RTRIGGER, historyPos)};
-
-		float currX    = 0.0f;
-		float absCurrX = 0.0f;
-		float currY    = 0.0f;
-		float absCurrY = 0.0f;
-		int stoppingMovementAxisIdBitFlags = 0;
-		int prevRepeatingAxisIdBitFlags = repeatingAxisIdBitFlags;
-
-		for (int i = 0; i < centeredAxisValuesArray.length; ++i) {
-			currX = centeredAxisValuesArray[i];
-			absCurrX = Math.abs(currX);
-
-			// 0 - 5 (ie. 4+1) we deal with x-axis, y-axis together for LEFT STICK, HAT (DPAD), RIGHT STICK.
-			if (i < 5) {
-				currY = centeredAxisValuesArray[i+1];
-				absCurrY = Math.abs(currY);
-			}
-			// TODO Make this limit dependant on the ConfMan joystick_deadzone setting -- but avoid using frequent JNI to get the value
-			//      The virtual mouse already uses joystick_deadzone to handle input, along with the "kbdmouse_speed". (see backends/keymapper/virtual-mouse.cpp)
-			//      PSP also uses joystick_deadzone for its input so maybe we could do something similar. (see backends/platform/psp/input.cpp).
-			//      If this filtering goes to the native side (eg. in backends/platform/android/events.cpp) we'll still need to somehow update the repeating-axis bitflag.
-			if (absCurrX < 0.209f
-			    && (i >= 6 || absCurrY < 0.209f)) {
-				// When on all the axis for the current control (or the only axis) we have negligible movement that could still be greater than "flat" range,
-				// we do extra filter to stop repetition in order to avoid cases when Android does not send onGenericMotionEvent()
-				// for small x or y (while abs is still greater than range.getflat())!
-				// In such case we would end up with a slow moving "mouse" cursor - so we need this extra filter.
-
-				// If previously we had movement on at least one of the axis for the current control (or the only axis),
-				// then stop movement, reset values to 0 and clear pertinent repeating axis bitflags.
-				if ((prevRepeatingAxisIdBitFlags & (0x01 <<  i)) != 0
-				    || (i < 5 && (prevRepeatingAxisIdBitFlags & (0x01 << (i+1))) != 0)) {
-//					if (i < 5) {
-//						Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100) + " y=" + (int)(currY * 100));
-//					} else {
-//						Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100));
-//					}
-					// do the move, then signal the joystick has returned to center pos
-					stoppingMovementAxisIdBitFlags = 0;
-					repeatingCenteredAxisValuesArray[i] = currX;
-					stoppingMovementAxisIdBitFlags |= (0x01 << i);
-					if (i < 5) {
-						repeatingCenteredAxisValuesArray[i+1] = currY;
-						stoppingMovementAxisIdBitFlags |= (0x01 << (i+1));
-					}
-					repeatMove(stoppingMovementAxisIdBitFlags, true);
-
-					repeatingCenteredAxisValuesArray[i] = 0.0f;
-					repeatingAxisIdBitFlags &= ~(0x01 << i);
-					if (i < 5) {
-						repeatingCenteredAxisValuesArray[i+1] = 0.0f;
-						repeatingAxisIdBitFlags &= ~(0x01 << (i+1));
-					}
-					// This return-to-zero (center pos) is sent as an explicit extra event, so it's considered "movement" on the axis
-					repeatMove(stoppingMovementAxisIdBitFlags, true);
-				}
-			} else {
-				// Here we have significant movement on at least one of the axis for the current control (or the only axis).
-//				if (i < 5) {
-//					Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- update movement: x= " + (int)(currX * 100) + " y= " + (int)(currY * 100));
-//				} else {
-//					Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- update movement: x= " + (int)(currX * 100));
-//				}
-				// We update the axis values (for controls like sticks or hats we update both pertinent axis values here)
-				// and set the respective repetition bit flag(s).
-				repeatingCenteredAxisValuesArray[i] = currX; // X AXIS
-				repeatingAxisIdBitFlags |= (0x01 <<  i);
-				if (i < 5) {
-					repeatingCenteredAxisValuesArray[i+1] = currY; // Y AXIS
-					repeatingAxisIdBitFlags |= (0x01 <<  (i+1));
-				}
-			}
-			if (i < 5) ++i; // skip next index as we handled it already in this case
-		}
-
-		if (repeatingAxisIdBitFlags == 0) {
-			// Only removeMessages() if all motions are supposed to stop, ie final moving stick/hat/trigger etc???
-			removeMessages();
-		} else if (prevRepeatingAxisIdBitFlags == 0) {
-			// Start repetition message sending (sendMessageDelayed)
-			Message msg = mHandler.obtainMessage(MSG_REPEAT);
-			mHandler.sendMessageDelayed(msg, REPEAT_START_DELAY);
-			repeatMove(repeatingAxisIdBitFlags, true);
-		}
-	}
-
-	@Override
-	public boolean onGenericMotionEvent(MotionEvent event) {
-		// TODO Make Use of MotionEvent.getToolType() ie. for handling TOOL_TYPE_FINGER/ TOOL_TYPE_MOUSE/ TOOL_TYPE_STYLUS/ TOOL_TYPE_UNKNOWN?
-		// Check that the event came from a joystick
-		if (((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK
-			 || (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0)) {
-			switch(event.getActionMasked()) {
-			case MotionEvent.ACTION_MOVE:
-				//InputDevice inputDevice = event.getDevice();
-				//Log.d(ScummVM.LOG_TAG, "JOYSTICK GENERIC MOTION: MOVE, Devname=" + inputDevice.getName() + " pid=" + inputDevice.getProductId() + " vid=" + inputDevice.getVendorId());
-				// NOTE In Android 12 (on some early version patch) support for PS5's DualSense broke, and the key mappings are messed up.
-				// This was fixed in another Android 12 patch, but not all devices got that. (eg Redmi 9 Pro does not have this update)
-				// Details about this here: https://stackoverflow.com/questions/68190869/dualshock-5-and-android
-				// Not much we can do about this.
-
-				// Process all historical movement samples in the batch
-				final int historySize = event.getHistorySize();
-
-				// Process the movements starting from the
-				// earliest historical position in the batch
-				for (int i = 0; i < historySize; ++i) {
-					// Process the event at historical position i
-					//Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m) hist: ");
-					processJoystickInput(event, i);
-				}
-
-				// Process the current movement sample in the batch (position -1)
-				//Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m): "  );
-				processJoystickInput(event, -1);
-				return true;
-
-			default:
-				break;
-			}
-		} else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-			//Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - onGenericMotionEvent(m) ");
-			//
-			// Check that the event might be a mouse scroll wheel (ACTION_SCROLL)
-			// Code inspired from https://stackoverflow.com/a/33086042
-			//
-			// NOTE Other GenericMotionEvent are also triggered for InputDevice of SOURCE_CLASS_POINTER (eg. physical mouse).
-			// These seem to be for button down/up events, which are handled along with pushing a JE_MOVE event
-			// in MouseHelper's onMouseEvent() called from ScummVMEventsBase onTouch().
-			switch (event.getActionMasked()) {
-			case MotionEvent.ACTION_SCROLL:
-				//Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - ACTION SCROLL");
-				// This action is not a touch event so it is delivered to
-				// View#onGenericMotionEvent(MotionEvent) rather than View#onTouchEvent(MotionEvent).
-				if (_mouseHelper != null) {
-					return _mouseHelper.onMouseEvent(event, false);
-				}
-				break;
-
-			default:
-				break;
-			}
-		}
-		//Log.d(ScummVM.LOG_TAG, "MOTION NOT HANDLED, source: " + event.getSource() + " event: "+ event.getActionMasked());
-		// this basically returns false since the super just returns false
-		return super.onGenericMotionEvent(event);
-	}
-}


Commit: 9a365241f9fb3449b1e5a59d3fe872530d4d6fc4
    https://github.com/scummvm/scummvm/commit/9a365241f9fb3449b1e5a59d3fe872530d4d6fc4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Store the ScummVMActivity object in ScummVMEvents

This avoids unsafe casts and makes things cleaner.

Changed paths:
    backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java


diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 8ba7614b172..f0937085ba9 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -1,6 +1,5 @@
 package org.scummvm.scummvm;
 
-import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -82,7 +81,7 @@ public class ScummVMEvents implements
 	private final float[] _repeatingJoystickCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
 	private int _repeatingJoystickAxisIdBitFlags = 0x00;
 
-	final protected Context _context;
+	final protected ScummVMActivity _activity;
 	final protected ScummVM _scummvm;
 	final protected GestureDetector _gd;
 	final protected int _longPressTimeout;
@@ -140,15 +139,15 @@ public class ScummVMEvents implements
 //		return new ScummVMEventHandler(this);
 //	}
 
-	public ScummVMEvents(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
-		_context = context;
+	public ScummVMEvents(ScummVMActivity activity, ScummVM scummvm, MouseHelper mouseHelper) {
+		_activity = activity;
 		_scummvm = scummvm;
 		// Careful, _mouseHelper can be null (if HoverListener is not available for the device API -- old devices, API < 9)
 		_mouseHelper = mouseHelper;
 
 		_multitouchHelper = new MultitouchHelper(_scummvm);
 
-		_gd = new GestureDetector(context, this);
+		_gd = new GestureDetector(activity, this);
 		_gd.setOnDoubleTapListener(this);
 		_gd.setIsLongpressEnabled(false);
 
@@ -166,11 +165,11 @@ public class ScummVMEvents implements
 			// this toggles the android keyboard (see showVirtualKeyboard() in ScummVMActivity.java)
 			// when menu key is long-pressed
 //			InputMethodManager imm = (InputMethodManager)
-//				_context.getSystemService(Context.INPUT_METHOD_SERVICE);
+//				_activity.getSystemService(Context.INPUT_METHOD_SERVICE);
 //
 //			if (imm != null)
 //				imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
-			((ScummVMActivity) _context).toggleScreenKeyboard();
+			_activity.toggleScreenKeyboard();
 		} else if (msg.what == MSG_SBACK_LONG_PRESS) {
 			_scummvm.pushEvent(JE_SYS_KEY,
 			                   KeyEvent.ACTION_DOWN,
@@ -360,8 +359,8 @@ public class ScummVMEvents implements
 					return true;
 				} else if (action == KeyEvent.ACTION_UP) {
 					// Hide keyboard
-					if (((ScummVMActivity) _context).isScreenKeyboardShown()) {
-						((ScummVMActivity) _context).hideScreenKeyboard();
+					if (_activity.isScreenKeyboardShown()) {
+						_activity.hideScreenKeyboard();
 					}
 					return true;
 				}
@@ -626,13 +625,13 @@ public class ScummVMEvents implements
 //		}
 
 		if (ScummVMActivity.keyboardWithoutTextInputShown
-		    && ((ScummVMActivity) _context).isScreenKeyboardShown()
-		    && ((ScummVMActivity) _context).getScreenKeyboard().getY() <= event.getY() ) {
-			event.offsetLocation(-((ScummVMActivity) _context).getScreenKeyboard().getX(), -((ScummVMActivity) _context).getScreenKeyboard().getY());
+		    && _activity.isScreenKeyboardShown()
+		    && _activity.getScreenKeyboard().getY() <= event.getY() ) {
+			event.offsetLocation(-_activity.getScreenKeyboard().getX(), -_activity.getScreenKeyboard().getY());
 			// TODO maybe call the onTouchEvent of something else here?
-			((ScummVMActivity) _context).getScreenKeyboard().onTouchEvent(event);
+			_activity.getScreenKeyboard().onTouchEvent(event);
 			// correct the offset for continuing handling the event
-			event.offsetLocation(((ScummVMActivity) _context).getScreenKeyboard().getX(), ((ScummVMActivity) _context).getScreenKeyboard().getY());
+			event.offsetLocation(_activity.getScreenKeyboard().getX(), _activity.getScreenKeyboard().getY());
 		}
 
 		if (_mouseHelper != null) {


Commit: 5ea3ac6d514c5e7825848d74baf2371529e9b567
    https://github.com/scummvm/scummvm/commit/5ea3ac6d514c5e7825848d74baf2371529e9b567
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Add support for predictive back gestures

This should make the code future proof.
With this flag enabled, the KEYCODE_BACK event is never sent through
the onKey callback but using a dedicated callback.

Changed paths:
    backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
    dists/android/AndroidManifest.xml


diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index f0937085ba9..e2e93137de2 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -12,8 +12,11 @@ import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 
 import java.lang.ref.WeakReference;
 
@@ -127,6 +130,18 @@ public class ScummVMEvents implements
 		}
 	}
 
+	@RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU)
+	private class OnBackInvoked implements OnBackInvokedCallback {
+		@Override
+		public void onBackInvoked() {
+			//Log.d(ScummVM.LOG_TAG,"Sending back key");
+			ScummVMEvents.this._scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK,
+					0, 0, 0, 0);
+			ScummVMEvents.this._scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK,
+					0, 0, 0, 0);
+		}
+	}
+
 	final private ScummVMEventHandler _handler = new ScummVMEventHandler(this);
 
 //	/**
@@ -153,6 +168,10 @@ public class ScummVMEvents implements
 
 		_doubleTapMode = false;
 		_longPressTimeout = ViewConfiguration.getLongPressTimeout();
+
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+			activity.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, new OnBackInvoked());
+		}
 	}
 
 	final static int MSG_SMENU_LONG_PRESS = 1;
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index 07b2de9765b..5aef1b46948 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -41,6 +41,7 @@
 		android:allowBackup="true"
 		android:appCategory="game"
 		android:description="@string/app_desc"
+		android:enableOnBackInvokedCallback="true"
 		android:icon="@mipmap/scummvm"
 		android:label="@string/app_name${nameSuffix}"
 		android:requestLegacyExternalStorage="true">


Commit: a1393fac6b1ad8795ed00d3d529d43db244adf86
    https://github.com/scummvm/scummvm/commit/a1393fac6b1ad8795ed00d3d529d43db244adf86
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Target API level 35: Android 15 (Vanilla Ice Cream)

Changed paths:
    dists/android/build.gradle


diff --git a/dists/android/build.gradle b/dists/android/build.gradle
index ba262c63f3d..501837dfc5e 100644
--- a/dists/android/build.gradle
+++ b/dists/android/build.gradle
@@ -30,7 +30,7 @@ tasks.withType(JavaCompile).configureEach {
 apply plugin: 'com.android.application'
 
 android {
-    compileSdk 34
+    compileSdk 35
     ndkVersion "23.2.8568313"
 
     namespace "org.scummvm.scummvm"
@@ -41,7 +41,7 @@ android {
         base.archivesName = "ScummVM"
 
         minSdkVersion 16
-        targetSdkVersion 34
+        targetSdkVersion 35
 
         versionName "2.9.0"
         versionCode 2090001


Commit: cc6a069c69aac3cab84753cdffefd7563f8d7a57
    https://github.com/scummvm/scummvm/commit/cc6a069c69aac3cab84753cdffefd7563f8d7a57
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Rework the insets helper to handle cutouts and system bars

Also fix copy paste bugs and linting errors from Android Studio.

Changed paths:
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
    backends/platform/android/org/scummvm/scummvm/ScummVM.java


diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index af0c104250e..c8808bbc7dc 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -138,7 +138,7 @@ const JNINativeMethod JNI::_natives[] = {
 		(void *)JNI::syncVirtkeyboardState },
 	{ "setPause", "(Z)V",
 		(void *)JNI::setPause },
-	{ "systemInsetsUpdated", "([I)V",
+	{ "systemInsetsUpdated", "([I[I[I)V",
 		(void *)JNI::systemInsetsUpdated },
 	{ "getNativeVersionInfo", "()Ljava/lang/String;",
 		(void *)JNI::getNativeVersionInfo }
@@ -968,10 +968,11 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
 	}
 }
 
-void JNI::systemInsetsUpdated(JNIEnv *env, jobject self, jintArray insets) {
-	assert(env->GetArrayLength(insets) == ARRAYSIZE(gestures_insets));
+void JNI::systemInsetsUpdated(JNIEnv *env, jobject self, jintArray gestureInsets, jintArray systemInsets, jintArray cutoutInsets) {
+	assert(env->GetArrayLength(gestureInsets) == ARRAYSIZE(gestures_insets));
 
-	env->GetIntArrayRegion(insets, 0, ARRAYSIZE(gestures_insets), gestures_insets);
+	// TODO: handle systemInsets and cutoutInsets
+	env->GetIntArrayRegion(gestureInsets, 0, ARRAYSIZE(gestures_insets), gestures_insets);
 }
 
 jstring JNI::getNativeVersionInfo(JNIEnv *env, jobject self) {
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 8b50dab0371..3ceb3f76f04 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -196,7 +196,7 @@ private:
 	static void syncVirtkeyboardState(JNIEnv *env, jobject self, jboolean newState);
 	static void setPause(JNIEnv *env, jobject self, jboolean value);
 
-	static void systemInsetsUpdated(JNIEnv *env, jobject self, jintArray insets);
+	static void systemInsetsUpdated(JNIEnv *env, jobject self, jintArray gestureInsets, jintArray systemInsets, jintArray cutoutInsets);
 
 	static jstring getNativeVersionInfo(JNIEnv *env, jobject self);
 	static jstring convertToJString(JNIEnv *env, const Common::U32String &str);
diff --git a/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java b/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
index 07fbea39686..2d0dc9414db 100644
--- a/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
+++ b/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
@@ -16,6 +16,7 @@ import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioTrack;
+import android.view.DisplayCutout;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowInsets;
@@ -83,7 +84,7 @@ class CompatHelpers {
 
 	static class SystemInsets {
 		public interface SystemInsetsListener {
-			void systemInsetsUpdated(int insets[]);
+			void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets);
 		}
 
 		public static void registerSystemInsetsListener(View v, SystemInsetsListener l) {
@@ -91,34 +92,87 @@ class CompatHelpers {
 				v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerR(l));
 			} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
 				v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerQ(l));
-			} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH) {
-				v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerKitKatW(l));
+			} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
+				v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerP(l));
+			} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+				v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerLollipop(l));
 			} else {
 				// Not available
-				int[] insets = new int[] { 0, 0, 0, 0 };
-				l.systemInsetsUpdated(insets);
+				int[] gestureInsets = new int[] { 0, 0, 0, 0 };
+				int[] systemInsets = new int[] { 0, 0, 0, 0 };
+				int[] cutoutInsets = new int[] { 0, 0, 0, 0 };
+				l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
+			}
+		}
+
+		@RequiresApi(android.os.Build.VERSION_CODES.LOLLIPOP)
+		@SuppressWarnings("deprecation")
+		private static class OnApplyWindowInsetsListenerLollipop implements View.OnApplyWindowInsetsListener {
+			final private SystemInsetsListener l;
+
+			public OnApplyWindowInsetsListenerLollipop(SystemInsetsListener l) {
+				this.l = l;
+			}
+
+			@Override
+			public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
+				// No system gestures inset before Android Q
+				int[] gestureInsets = new int[] {
+					insets.getStableInsetLeft(),
+					insets.getStableInsetTop(),
+					insets.getStableInsetRight(),
+					insets.getStableInsetBottom()
+				};
+				int[] systemInsets = new int[] {
+					insets.getSystemWindowInsetLeft(),
+					insets.getSystemWindowInsetTop(),
+					insets.getSystemWindowInsetRight(),
+					insets.getSystemWindowInsetBottom()
+				};
+				// No cutouts before Android P
+				int[] cutoutInsets = new int[] { 0, 0, 0, 0 };
+				l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
+				return v.onApplyWindowInsets(insets);
 			}
 		}
 
-		@RequiresApi(android.os.Build.VERSION_CODES.KITKAT_WATCH)
+		@RequiresApi(android.os.Build.VERSION_CODES.P)
 		@SuppressWarnings("deprecation")
-		private static class OnApplyWindowInsetsListenerKitKatW implements View.OnApplyWindowInsetsListener {
-			private SystemInsetsListener l;
+		private static class OnApplyWindowInsetsListenerP implements View.OnApplyWindowInsetsListener {
+			final private SystemInsetsListener l;
 
-			public OnApplyWindowInsetsListenerKitKatW(SystemInsetsListener l) {
+			public OnApplyWindowInsetsListenerP(SystemInsetsListener l) {
 				this.l = l;
 			}
 
 			@Override
 			public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
 				// No system gestures inset before Android Q
-				int[] insetsArray = new int[] {
+				int[] gestureInsets = new int[] {
 					insets.getStableInsetLeft(),
 					insets.getStableInsetTop(),
 					insets.getStableInsetRight(),
 					insets.getStableInsetBottom()
 				};
-				l.systemInsetsUpdated(insetsArray);
+				int[] systemInsets = new int[] {
+					insets.getSystemWindowInsetLeft(),
+					insets.getSystemWindowInsetTop(),
+					insets.getSystemWindowInsetRight(),
+					insets.getSystemWindowInsetBottom()
+				};
+				int[] cutoutInsets;
+				DisplayCutout cutout = insets.getDisplayCutout();
+				if (cutout == null) {
+					cutoutInsets = new int[] { 0, 0, 0, 0 };
+				} else {
+					cutoutInsets = new int[] {
+						cutout.getSafeInsetLeft(),
+						cutout.getSafeInsetTop(),
+						cutout.getSafeInsetRight(),
+						cutout.getSafeInsetBottom()
+					};
+				}
+				l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
 				return v.onApplyWindowInsets(insets);
 			}
 		}
@@ -126,7 +180,7 @@ class CompatHelpers {
 		@RequiresApi(android.os.Build.VERSION_CODES.Q)
 		@SuppressWarnings("deprecation")
 		private static class OnApplyWindowInsetsListenerQ implements View.OnApplyWindowInsetsListener {
-			private SystemInsetsListener l;
+			final private SystemInsetsListener l;
 
 			public OnApplyWindowInsetsListenerQ(SystemInsetsListener l) {
 				this.l = l;
@@ -134,22 +188,40 @@ class CompatHelpers {
 
 			@Override
 			public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
-				Insets insetsStruct = insets.getStableInsets();
-				int[] insetsArray = new int[] {
+				Insets insetsStruct = insets.getSystemGestureInsets();
+				int[] gestureInsets = new int[] {
+					insetsStruct.left,
+					insetsStruct.top,
+					insetsStruct.right,
+					insetsStruct.bottom,
+				};
+				insetsStruct = insets.getSystemWindowInsets();
+				int[] systemInsets = new int[] {
 					insetsStruct.left,
 					insetsStruct.top,
 					insetsStruct.right,
 					insetsStruct.bottom,
 				};
-				l.systemInsetsUpdated(insetsArray);
+				int[] cutoutInsets;
+				DisplayCutout cutout = insets.getDisplayCutout();
+				if (cutout == null) {
+					cutoutInsets = new int[] { 0, 0, 0, 0 };
+				} else {
+					cutoutInsets = new int[] {
+						cutout.getSafeInsetLeft(),
+						cutout.getSafeInsetTop(),
+						cutout.getSafeInsetRight(),
+						cutout.getSafeInsetBottom()
+					};
+				}
+				l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
 				return v.onApplyWindowInsets(insets);
 			}
 		}
 
 		@RequiresApi(android.os.Build.VERSION_CODES.R)
-		@SuppressWarnings("deprecation")
 		private static class OnApplyWindowInsetsListenerR implements View.OnApplyWindowInsetsListener {
-			private SystemInsetsListener l;
+			final private SystemInsetsListener l;
 
 			public OnApplyWindowInsetsListenerR(SystemInsetsListener l) {
 				this.l = l;
@@ -158,13 +230,32 @@ class CompatHelpers {
 			@Override
 			public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
 				Insets insetsStruct = insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemGestures());
-				int[] insetsArray = new int[] {
+				int[] gestureInsets = new int[] {
 					insetsStruct.left,
 					insetsStruct.top,
 					insetsStruct.right,
 					insetsStruct.bottom,
 				};
-				l.systemInsetsUpdated(insetsArray);
+				insetsStruct = insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
+				int[] systemInsets = new int[] {
+					insetsStruct.left,
+					insetsStruct.top,
+					insetsStruct.right,
+					insetsStruct.bottom,
+				};
+				int[] cutoutInsets;
+				DisplayCutout cutout = insets.getDisplayCutout();
+				if (cutout == null) {
+					cutoutInsets = new int[] { 0, 0, 0, 0 };
+				} else {
+					cutoutInsets = new int[] {
+						cutout.getSafeInsetLeft(),
+						cutout.getSafeInsetTop(),
+						cutout.getSafeInsetRight(),
+						cutout.getSafeInsetBottom()
+					};
+				}
+				l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
 				return v.onApplyWindowInsets(insets);
 			}
 		}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index d8891cf2ad5..ced347e1ee3 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -71,7 +71,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback,
 
 	// CompatHelpers.WindowInsets.SystemInsetsListener interface
 	@Override
-	final public native void systemInsetsUpdated(int insets[]);
+	final public native void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets);
 
 	// Callbacks from C++ peer instance
 	abstract protected void getDPI(float[] values);


Commit: d9dcf93f658fea2d5b09963cf5ef9e53cc9173c7
    https://github.com/scummvm/scummvm/commit/d9dcf93f658fea2d5b09963cf5ef9e53cc9173c7
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Make ShortcutCreatorActivity edge-to-edge compliant

Changed paths:
  A dists/android/res/values-v21/themes.xml
  A dists/android/res/values-v30/themes.xml
    backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
    dists/android/res/layout/shortcut_creator_activity.xml
    dists/android/res/values/themes.xml


diff --git a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
index 814a35b0d92..6ffb42a75d8 100644
--- a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
@@ -26,6 +26,7 @@ import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -50,7 +51,7 @@ import java.util.List;
 import java.util.Map;
 
 
-public class ShortcutCreatorActivity extends Activity {
+public class ShortcutCreatorActivity extends Activity implements CompatHelpers.SystemInsets.SystemInsetsListener  {
 	final protected static String LOG_TAG = "ShortcutCreatorActivity";
 
 	private IconsCache _cache;
@@ -91,6 +92,8 @@ public class ShortcutCreatorActivity extends Activity {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.shortcut_creator_activity);
 
+		CompatHelpers.SystemInsets.registerSystemInsetsListener(findViewById(R.id.shortcut_creator_root), this);
+
 		// We are only here to create a shortcut
 		if (!Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) {
 			finish();
@@ -154,6 +157,16 @@ public class ShortcutCreatorActivity extends Activity {
 		setResult(RESULT_CANCELED);
 	}
 
+	@Override
+	public void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets) {
+		LinearLayout root = findViewById(R.id.shortcut_creator_root);
+		// Ignore bottom as we have our list which can overflow
+		root.setPadding(
+			Math.max(systemInsets[0], cutoutInsets[0]),
+			Math.max(systemInsets[1], cutoutInsets[1]),
+			Math.max(systemInsets[2], cutoutInsets[2]), 0);
+	}
+
 	static private FileInputStream openFile(File path) {
 		 try {
 			return new FileInputStream(path);
diff --git a/dists/android/res/layout/shortcut_creator_activity.xml b/dists/android/res/layout/shortcut_creator_activity.xml
index b1d2e160f9e..21a5452020c 100644
--- a/dists/android/res/layout/shortcut_creator_activity.xml
+++ b/dists/android/res/layout/shortcut_creator_activity.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	xmlns:tools="http://schemas.android.com/tools"
+	android:id="@+id/shortcut_creator_root"
 	android:layout_width="match_parent"
 	android:layout_height="match_parent"
 	android:orientation="vertical"
diff --git a/dists/android/res/values-v21/themes.xml b/dists/android/res/values-v21/themes.xml
new file mode 100644
index 00000000000..2094d8d62c5
--- /dev/null
+++ b/dists/android/res/values-v21/themes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
+		<item name="android:windowTranslucentStatus">true</item>
+		<item name="android:windowTranslucentNavigation">true</item>
+	</style>
+</resources>
diff --git a/dists/android/res/values-v30/themes.xml b/dists/android/res/values-v30/themes.xml
new file mode 100644
index 00000000000..e8e96c57c8e
--- /dev/null
+++ b/dists/android/res/values-v30/themes.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
+		<item name="android:windowLayoutInDisplayCutoutMode">always</item>
+	</style>
+</resources>
diff --git a/dists/android/res/values/themes.xml b/dists/android/res/values/themes.xml
index 8e553cfb4fb..1cb7de54a0b 100644
--- a/dists/android/res/values/themes.xml
+++ b/dists/android/res/values/themes.xml
@@ -14,6 +14,16 @@
 	<style name="ShortcutCreatorThemeBase" parent="@android:style/Theme.DeviceDefault">
 	</style>
 
-	<style name="ShortcutCreatorTheme" parent="ShortcutCreatorThemeBase">
+	<style name="ShortcutCreatorTheme_v11" parent="ShortcutCreatorThemeBase">
+		<item name="android:windowActionBar">false</item>
+		<item name="android:windowNoTitle">true</item>
+	</style>
+
+	<style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
+	</style>
+	<style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
+	</style>
+
+	<style name="ShortcutCreatorTheme" parent="ShortcutCreatorTheme_v30">
 	</style>
 </resources>


Commit: ac21b373e1fe760d33b444855040d326ec5e93a8
    https://github.com/scummvm/scummvm/commit/ac21b373e1fe760d33b444855040d326ec5e93a8
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Make SplashActivity edge-to-edge compliant

Changed paths:
    dists/android/res/values-v21/themes.xml
    dists/android/res/values-v30/themes.xml
    dists/android/res/values/themes.xml


diff --git a/dists/android/res/values-v21/themes.xml b/dists/android/res/values-v21/themes.xml
index 2094d8d62c5..355580da9de 100644
--- a/dists/android/res/values-v21/themes.xml
+++ b/dists/android/res/values-v21/themes.xml
@@ -1,5 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+	<style name="SplashTheme_v21" parent="SplashThemeBase">
+		<item name="android:windowTranslucentStatus">true</item>
+		<item name="android:windowTranslucentNavigation">true</item>
+	</style>
+
 	<style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
 		<item name="android:windowTranslucentStatus">true</item>
 		<item name="android:windowTranslucentNavigation">true</item>
diff --git a/dists/android/res/values-v30/themes.xml b/dists/android/res/values-v30/themes.xml
index e8e96c57c8e..72015e6ad4d 100644
--- a/dists/android/res/values-v30/themes.xml
+++ b/dists/android/res/values-v30/themes.xml
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+	<style name="SplashTheme_v30" parent="SplashTheme_v21">
+		<item name="android:windowLayoutInDisplayCutoutMode">always</item>
+	</style>
+
 	<style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
 		<item name="android:windowLayoutInDisplayCutoutMode">always</item>
 	</style>
diff --git a/dists/android/res/values/themes.xml b/dists/android/res/values/themes.xml
index 1cb7de54a0b..e3835a388ab 100644
--- a/dists/android/res/values/themes.xml
+++ b/dists/android/res/values/themes.xml
@@ -6,7 +6,15 @@
 		<item name="keyboardViewStyle">@style/View.CustomKeyboard</item>
 	</style>
 
-	<style name="SplashTheme" parent="AppTheme">
+	<style name="SplashThemeBase" parent="AppTheme">
+	</style>
+
+	<style name="SplashTheme_v21" parent="SplashThemeBase">
+	</style>
+	<style name="SplashTheme_v30" parent="SplashTheme_v21">
+	</style>
+
+	<style name="SplashTheme" parent="SplashTheme_v30">
 		<item name="android:windowBackground">@drawable/splash</item>
 	</style>
 


Commit: c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6
    https://github.com/scummvm/scummvm/commit/c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00

Commit Message:
ANDROID: Make custom shortcuts really custom

Before this change, the user may not have been able to set its own label
if a shortcut with the same name already existed.

Changed paths:
    backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java


diff --git a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
index 6ffb42a75d8..b0931031024 100644
--- a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
@@ -256,9 +256,14 @@ public class ShortcutCreatorActivity extends Activity implements CompatHelpers.S
 			builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
 				dialog.dismiss();
 
+				String label = desc.getText().toString();
+				// Generate an id which depends on the user description
+				// Without this, if the user changes the description but already has the same shortcut (also in the dynamic ones), the other label will be reused
+				String shortcutId = game.getTarget() + String.format("-%08x", label.hashCode());
+
 				Intent shortcut = new Intent(Intent.ACTION_MAIN, Uri.fromParts("scummvm", game.getTarget(), null),
 					ShortcutCreatorActivity.this, SplashActivity.class);
-				Intent result = CompatHelpers.ShortcutCreator.createShortcutResultIntent(ShortcutCreatorActivity.this, game.getTarget(), shortcut,
+				Intent result = CompatHelpers.ShortcutCreator.createShortcutResultIntent(ShortcutCreatorActivity.this, shortcutId, shortcut,
 					desc.getText().toString(), icon, R.drawable.ic_no_game_icon);
 				setResult(RESULT_OK, result);
 




More information about the Scummvm-git-logs mailing list