feat(mmp): Hook 无心跳时自动唤醒或强停重开 TNG
领取台检测开启时,进程在跑但心跳过期会先进历史页唤醒,仍无效则 force-stop 重建 Hook。
This commit is contained in:
@@ -60,6 +60,9 @@ public class MmpClaimActivity extends MiracleGardenActivity<ActivityMmpClaimBind
|
|||||||
private boolean autoWatchWhileOpen = true;
|
private boolean autoWatchWhileOpen = true;
|
||||||
private boolean autoLaunchTngIfKilled = true;
|
private boolean autoLaunchTngIfKilled = true;
|
||||||
private long lastTngLaunchAt;
|
private long lastTngLaunchAt;
|
||||||
|
/** 0=未处理 1=已唤醒/进历史 2=已强停重开 */
|
||||||
|
private int hookRecoverStep;
|
||||||
|
private long lastHookRecoverAt;
|
||||||
private final Runnable watchRunnable = this::watchTngOnce;
|
private final Runnable watchRunnable = this::watchTngOnce;
|
||||||
/** null=检测中 true=通 false=不通 */
|
/** null=检测中 true=通 false=不通 */
|
||||||
private Boolean debugServerOk;
|
private Boolean debugServerOk;
|
||||||
@@ -342,13 +345,17 @@ public class MmpClaimActivity extends MiracleGardenActivity<ActivityMmpClaimBind
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean alive = TngProcessHelper.isRunning(this);
|
boolean alive = TngProcessHelper.isRunning(this);
|
||||||
if (autoWatchWhileOpen && !alive && autoLaunchTngIfKilled) {
|
if (autoWatchWhileOpen && autoLaunchTngIfKilled) {
|
||||||
long now = System.currentTimeMillis();
|
if (!alive) {
|
||||||
if (now - lastTngLaunchAt > 60_000L) {
|
long now = System.currentTimeMillis();
|
||||||
if (TngProcessHelper.launch(this)) {
|
if (now - lastTngLaunchAt > 60_000L) {
|
||||||
lastTngLaunchAt = now;
|
if (TngProcessHelper.launch(this)) {
|
||||||
Toast.makeText(this, "检测到 TNG 已退出,正在重新打开…", Toast.LENGTH_SHORT).show();
|
lastTngLaunchAt = now;
|
||||||
|
Toast.makeText(this, "检测到 TNG 已退出,正在重新打开…", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
maybeRecoverStaleHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateConnStatus();
|
updateConnStatus();
|
||||||
@@ -359,6 +366,63 @@ public class MmpClaimActivity extends MiracleGardenActivity<ActivityMmpClaimBind
|
|||||||
handler.postDelayed(watchRunnable, 12_000L);
|
handler.postDelayed(watchRunnable, 12_000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TNG 还在跑但 Hook 长时间无心跳:先唤醒/进历史页,仍无效再强停重开。
|
||||||
|
*/
|
||||||
|
private void maybeRecoverStaleHook() {
|
||||||
|
long hookAt = MmpHookStatus.lastAliveAt(this);
|
||||||
|
long age = hookAt > 0 ? System.currentTimeMillis() - hookAt : Long.MAX_VALUE;
|
||||||
|
if (age <= 3 * 60_000L) {
|
||||||
|
hookRecoverStep = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
boolean bounce = MmpLocalSettings.load(this)
|
||||||
|
.optBoolean("autoBounceHistoryOnDisconnect", true);
|
||||||
|
|
||||||
|
if (hookRecoverStep == 0) {
|
||||||
|
if (now - lastHookRecoverAt < 45_000L) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastHookRecoverAt = now;
|
||||||
|
hookRecoverStep = 1;
|
||||||
|
boolean ok = bounce
|
||||||
|
? TngProcessHelper.openMoneyPacketHistory(this)
|
||||||
|
: TngProcessHelper.launch(this);
|
||||||
|
if (ok) {
|
||||||
|
Toast.makeText(this, "Hook 无心跳,正在唤醒 TNG…", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hookRecoverStep == 1) {
|
||||||
|
if (now - lastHookRecoverAt < 90_000L) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 唤醒后仍无心跳 → 强停重建
|
||||||
|
lastHookRecoverAt = now;
|
||||||
|
hookRecoverStep = 2;
|
||||||
|
Toast.makeText(this, "仍无心跳,强制重启 TNG…", Toast.LENGTH_SHORT).show();
|
||||||
|
new Thread(() -> {
|
||||||
|
boolean ok = TngProcessHelper.forceStopAndLaunch(this);
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (ok) {
|
||||||
|
lastTngLaunchAt = System.currentTimeMillis();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "强制重启 TNG 失败", Toast.LENGTH_SHORT).show();
|
||||||
|
hookRecoverStep = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, "mmp-hook-recover").start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2 后隔 3 分钟仍无心跳,再重试一轮
|
||||||
|
if (now - lastHookRecoverAt > 3 * 60_000L) {
|
||||||
|
hookRecoverStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void pingDebugServer() {
|
private void pingDebugServer() {
|
||||||
lastDebugPingAt = System.currentTimeMillis();
|
lastDebugPingAt = System.currentTimeMillis();
|
||||||
MmpSettingsClient.pingHealth(ok -> runOnUiThread(() -> {
|
MmpSettingsClient.pingHealth(ok -> runOnUiThread(() -> {
|
||||||
@@ -405,7 +469,9 @@ public class MmpClaimActivity extends MiracleGardenActivity<ActivityMmpClaimBind
|
|||||||
}
|
}
|
||||||
|
|
||||||
String watchPart = autoWatchWhileOpen
|
String watchPart = autoWatchWhileOpen
|
||||||
? (autoLaunchTngIfKilled ? "检测:开(杀掉会拉起)" : "检测:开(不自动拉起)")
|
? (autoLaunchTngIfKilled
|
||||||
|
? "检测:开(退出/无心跳会拉起)"
|
||||||
|
: "检测:开(不自动拉起)")
|
||||||
: "检测:关";
|
: "检测:关";
|
||||||
|
|
||||||
String debugPart;
|
String debugPart;
|
||||||
|
|||||||
@@ -111,4 +111,45 @@ public final class TngProcessHelper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 打开红包历史页,触发 Hook onResume / 自动拉取 */
|
||||||
|
public static boolean openMoneyPacketHistory(Context context) {
|
||||||
|
if (context == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setClassName(TNG_PACKAGE,
|
||||||
|
"my.com.tngdigital.funding.moneypacket.create.ui.MoneyPacketHistoryActivity");
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
context.startActivity(intent);
|
||||||
|
Log.i(TAG, "opened MoneyPacketHistoryActivity");
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "open history fail, fallback launch: " + e.getMessage());
|
||||||
|
return launch(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 强制停止 TNG(优先 su) */
|
||||||
|
public static boolean forceStop(Context context) {
|
||||||
|
String out = shell("su -c am force-stop " + TNG_PACKAGE);
|
||||||
|
if (TextUtils.isEmpty(out)) {
|
||||||
|
out = shell("am force-stop " + TNG_PACKAGE);
|
||||||
|
}
|
||||||
|
Log.i(TAG, "force-stop TNG done");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 强停后再打开,用于 Hook 假死重建 */
|
||||||
|
public static boolean forceStopAndLaunch(Context context) {
|
||||||
|
forceStop(context);
|
||||||
|
try {
|
||||||
|
Thread.sleep(900L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
return launch(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user