1
0
Fork 0

11th attempt to fix the Priviliged options crash: constant heartbeat checks while we are visible

This commit is contained in:
sspanak 2025-06-23 14:54:51 +03:00 committed by Dimo Karaivanov
parent 98eac9da51
commit 525f6fbf65
2 changed files with 42 additions and 13 deletions

View file

@ -28,6 +28,7 @@ public class TraditionalT9 extends MainViewHandler {
@NonNull private final Handler backgroundTasks = new Handler(Looper.getMainLooper());
@NonNull private final Handler zombieDetector = new Handler(Looper.getMainLooper());
@NonNull private final Handler heartbeatDetector = new Handler(Looper.getMainLooper());
private boolean isDead = false;
private int zombieChecks = 0;
@ -131,12 +132,17 @@ public class TraditionalT9 extends MainViewHandler {
@Override
protected boolean onStart(EditorInfo field) {
AppHacks.onStart(settings, field);
if (zombieChecks == 0 && !SystemSettings.isTT9Selected(this)) {
if (SystemSettings.isTT9Selected(this)) {
startHeartbeatCheck();
} else {
if (zombieChecks == 0) {
startZombieCheck();
}
return false;
}
AppHacks.onStart(settings, field);
if (isDead || !super.onStart(field)) {
setStatusIcon(mInputMode, mLanguage);
return false;
@ -188,6 +194,8 @@ public class TraditionalT9 extends MainViewHandler {
if (zombieChecks == 0) {
startZombieCheck();
}
stopHeartbeatCheck();
}
@ -207,10 +215,31 @@ public class TraditionalT9 extends MainViewHandler {
/**
* On Android 11+ the IME is sometimes not killed when the user switches to a different one.
* Here we attempt to detect if we are disabled, then hide and kill ourselves.
* On Android 11+ onStop() and onDestroy() are sometimes not called when the user switches to a
* different IME. Here we attempt to detect if we are disabled, then hide and kill ourselves.
*/
protected void startZombieCheck() {
private void startHeartbeatCheck() {
if (!SystemSettings.isTT9Selected(this)) {
onZombie();
} else if (!isDead && !InputModeKind.isPassthrough(mInputMode)) {
heartbeatDetector.postDelayed(this::startHeartbeatCheck, SettingsStore.ZOMBIE_HEARTBEAT_INTERVAL);
Logger.v(LOG_TAG, "===> Heart is beating");
}
}
private void stopHeartbeatCheck() {
if (!DeviceInfo.AT_LEAST_ANDROID_10 || heartbeatDetector.hasCallbacks(this::startHeartbeatCheck)) {
heartbeatDetector.removeCallbacksAndMessages(null);
Logger.d(LOG_TAG, "===> Heartbeat check stopped");
}
}
/**
* Similar to the heartbeat check, but detects if we are on when invisible or after re-init.
*/
private void startZombieCheck() {
if (zombieChecks > 0 && !SystemSettings.isTT9Selected(this)) {
zombieChecks = 0;
onZombie();
@ -226,7 +255,7 @@ public class TraditionalT9 extends MainViewHandler {
}
protected void onZombie() {
private void onZombie() {
if (isDead) {
Logger.w(LOG_TAG, "===> Already dead. Cannot kill self.");
return;
@ -241,13 +270,12 @@ public class TraditionalT9 extends MainViewHandler {
protected void cleanUp() {
stopHeartbeatCheck();
zombieDetector.removeCallbacksAndMessages(null);
zombieChecks = SettingsStore.ZOMBIE_CHECK_MAX;
backgroundTasks.removeCallbacksAndMessages(null);
super.cleanUp();
setInputField(null);
backgroundTasks.removeCallbacksAndMessages(null);
zombieChecks = SettingsStore.ZOMBIE_CHECK_MAX;
zombieDetector.removeCallbacksAndMessages(null);
LanguageCollection.destroy();
DataStore.destroy();
Logger.d(LOG_TAG, "===> Final cleanup completed");
}

View file

@ -43,8 +43,9 @@ public class SettingsStore extends SettingsHotkeys {
public final static int WORD_FREQUENCY_NORMALIZATION_DIVIDER = 100; // normalized frequency = WORD_FREQUENCY_MAX / WORD_FREQUENCY_NORMALIZATION_DIVIDER
public final static int WORD_PAIR_MAX = 1000;
public final static int WORD_PAIR_MAX_WORD_LENGTH = 6;
public final static int ZOMBIE_CHECK_INTERVAL = 1500; // ms
public final static int ZOMBIE_CHECK_INTERVAL = 5000; // ms
public final static int ZOMBIE_CHECK_MAX = 2;
public final static int ZOMBIE_HEARTBEAT_INTERVAL = 2000; // ms
/************* hacks *************/
public final static int PREFERENCES_CLICK_DEBOUNCE_TIME = 250; // ms