Android build v1.1.7

This commit is contained in:
Warren H
2026-06-30 14:23:45 -04:00
parent df6306fe7a
commit 5b8c32dc41
6 changed files with 321 additions and 37 deletions
@@ -7,19 +7,27 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import com.getcapacitor.BridgeActivity;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public abstract class ControllerBridgeActivity extends BridgeActivity {
public static final String EXTRA_INITIAL_URL = "com.warren.iwanttoheal.INITIAL_URL";
private static final String PREFS_NAME = "com.warren.iwanttoheal.performance";
private static final String CACHE_CLEARED_VERSION_KEY = "webview_cache_cleared_version";
private static final float AXIS_DEAD_ZONE = 0.45f;
private static final long DPAD_THROTTLE_MS = 55;
private final long[] lastDpadDispatchAt = new long[16];
private final Set<String> activeMotionTokens = new HashSet<>();
private final Map<String, Long> lastMotionDispatchAt = new HashMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -140,19 +148,98 @@ public abstract class ControllerBridgeActivity extends BridgeActivity {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
boolean repeat = event.getRepeatCount() > 0;
if (isDpadToken(token) && shouldThrottleDpad(token)) return true;
String script =
"window.dispatchEvent(new CustomEvent('ashen-halls-native-controller',"
+ "{detail:{token:'" + token + "',repeat:" + repeat + "}}));";
bridge.getWebView().post(
() -> {
bridge.getWebView().requestFocus();
bridge.getWebView().evaluateJavascript(script, null);
}
);
dispatchNativeControllerToken(token, repeat);
}
return true;
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
if (
bridge == null
|| event.getActionMasked() != MotionEvent.ACTION_MOVE
|| !isControllerMotionEvent(event)
) {
return super.dispatchGenericMotionEvent(event);
}
Set<String> currentTokens = new HashSet<>();
addAxisTokens(
currentTokens,
event.getAxisValue(MotionEvent.AXIS_HAT_X),
"Button14",
"Button15"
);
addAxisTokens(
currentTokens,
event.getAxisValue(MotionEvent.AXIS_HAT_Y),
"Button12",
"Button13"
);
addAxisTokens(
currentTokens,
event.getAxisValue(MotionEvent.AXIS_X),
"Axis0-",
"Axis0+"
);
addAxisTokens(
currentTokens,
event.getAxisValue(MotionEvent.AXIS_Y),
"Axis1-",
"Axis1+"
);
boolean hadMotionTokens = !activeMotionTokens.isEmpty();
long now = SystemClock.uptimeMillis();
for (String token : currentTokens) {
boolean repeat = activeMotionTokens.contains(token);
long lastDispatchAt = lastMotionDispatchAt.containsKey(token)
? lastMotionDispatchAt.get(token)
: 0L;
if (!repeat || now - lastDispatchAt >= DPAD_THROTTLE_MS) {
dispatchNativeControllerToken(token, repeat);
lastMotionDispatchAt.put(token, now);
}
}
activeMotionTokens.clear();
activeMotionTokens.addAll(currentTokens);
if (currentTokens.isEmpty() && !hadMotionTokens) {
return super.dispatchGenericMotionEvent(event);
}
return true;
}
private boolean isControllerMotionEvent(MotionEvent event) {
int source = event.getSource();
return (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK
|| (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
|| (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
}
private void addAxisTokens(
Set<String> tokens,
float value,
String negativeToken,
String positiveToken
) {
if (value <= -AXIS_DEAD_ZONE) tokens.add(negativeToken);
if (value >= AXIS_DEAD_ZONE) tokens.add(positiveToken);
}
private void dispatchNativeControllerToken(String token, boolean repeat) {
if (bridge == null || bridge.getWebView() == null) return;
String script =
"window.dispatchEvent(new CustomEvent('ashen-halls-native-controller',"
+ "{detail:{token:'" + token + "',repeat:" + repeat + "}}));";
bridge.getWebView().post(
() -> {
bridge.getWebView().requestFocus();
bridge.getWebView().evaluateJavascript(script, null);
}
);
}
private boolean shouldThrottleDpad(String token) {
int buttonIndex = Integer.parseInt(token.substring("Button".length()));
long now = SystemClock.uptimeMillis();
@@ -171,10 +258,13 @@ public abstract class ControllerBridgeActivity extends BridgeActivity {
private String controllerToken(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_BUTTON_A:
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_NUMPAD_ENTER:
return "Button0";
case KeyEvent.KEYCODE_BUTTON_B:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_ESCAPE:
return "Button1";
case KeyEvent.KEYCODE_BUTTON_X:
return "Button2";