Files
i-want-to-heal/android/app/src/main/java/com/warren/iwanttoheal/ControllerBridgeActivity.java
T

150 lines
5.1 KiB
Java

package com.warren.iwanttoheal;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.View;
import com.getcapacitor.BridgeActivity;
import java.io.File;
public abstract class ControllerBridgeActivity extends BridgeActivity {
public static final String EXTRA_INITIAL_URL = "com.warren.iwanttoheal.INITIAL_URL";
private static final long DPAD_THROTTLE_MS = 125;
private long lastDpadDispatchAt = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
clearWebViewServiceWorkers();
super.onCreate(savedInstanceState);
if (bridge != null) {
bridge.getWebView().clearCache(true);
}
loadIntentUrl();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
loadIntentUrl();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) enableImmersiveMode();
}
private void loadIntentUrl() {
if (bridge == null || getIntent() == null) return;
String initialUrl = getIntent().getStringExtra(EXTRA_INITIAL_URL);
if (initialUrl == null || initialUrl.isEmpty()) return;
bridge.getWebView().post(() -> bridge.getWebView().loadUrl(initialUrl));
}
private void enableImmersiveMode() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
);
}
private void clearWebViewServiceWorkers() {
File webViewData = new File(getApplicationInfo().dataDir, "app_webview");
deleteIfExists(new File(webViewData, "Default/Service Worker"));
deleteIfExists(new File(webViewData, "Service Worker"));
}
private void deleteIfExists(File file) {
if (!file.exists()) return;
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
deleteIfExists(child);
}
}
}
file.delete();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
String token = controllerToken(event.getKeyCode());
if (token == null || bridge == null) return super.dispatchKeyEvent(event);
if (event.getAction() == KeyEvent.ACTION_DOWN) {
boolean repeat = event.getRepeatCount() > 0;
if (isDpadToken(token) && shouldThrottleDpad()) return true;
String script =
"window.dispatchEvent(new CustomEvent('ashen-halls-native-controller',"
+ "{detail:{token:'" + token + "',repeat:" + repeat + "}}));";
bridge.getWebView().post(
() -> bridge.getWebView().evaluateJavascript(script, null)
);
}
return true;
}
private boolean shouldThrottleDpad() {
long now = SystemClock.uptimeMillis();
if (now - lastDpadDispatchAt < DPAD_THROTTLE_MS) return true;
lastDpadDispatchAt = now;
return false;
}
private boolean isDpadToken(String token) {
return token.equals("Button12")
|| token.equals("Button13")
|| token.equals("Button14")
|| token.equals("Button15");
}
private String controllerToken(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_BUTTON_A:
case KeyEvent.KEYCODE_ENTER:
return "Button0";
case KeyEvent.KEYCODE_BUTTON_B:
case KeyEvent.KEYCODE_BACK:
return "Button1";
case KeyEvent.KEYCODE_BUTTON_X:
return "Button2";
case KeyEvent.KEYCODE_BUTTON_Y:
return "Button3";
case KeyEvent.KEYCODE_BUTTON_L1:
return "Button4";
case KeyEvent.KEYCODE_BUTTON_R1:
return "Button5";
case KeyEvent.KEYCODE_BUTTON_L2:
return "Button6";
case KeyEvent.KEYCODE_BUTTON_R2:
return "Button7";
case KeyEvent.KEYCODE_BUTTON_SELECT:
return "Button8";
case KeyEvent.KEYCODE_BUTTON_START:
return "Button9";
case KeyEvent.KEYCODE_BUTTON_THUMBL:
return "Button10";
case KeyEvent.KEYCODE_BUTTON_THUMBR:
return "Button11";
case KeyEvent.KEYCODE_DPAD_UP:
return "Button12";
case KeyEvent.KEYCODE_DPAD_DOWN:
return "Button13";
case KeyEvent.KEYCODE_DPAD_LEFT:
return "Button14";
case KeyEvent.KEYCODE_DPAD_RIGHT:
return "Button15";
default:
return null;
}
}
}