Skip to content

Commit

Permalink
Added InputMethod check
Browse files Browse the repository at this point in the history
  • Loading branch information
Nep-Timeline committed Sep 10, 2024
1 parent b8b265f commit 6b2170f
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 1 deletion.
14 changes: 13 additions & 1 deletion app/src/main/java/nep/timeline/cirno/entity/AppRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.Data;
import nep.timeline.cirno.CommonConstants;
import nep.timeline.cirno.configs.checkers.AppConfigs;
import nep.timeline.cirno.utils.InputMethodData;
import nep.timeline.cirno.utils.PKGUtils;
import nep.timeline.cirno.virtuals.ProcessRecord;

Expand All @@ -30,7 +31,7 @@ public AppRecord(ApplicationInfo applicationInfo) {
}

public boolean isSystem() {
return packageName == null || PKGUtils.isSystemApp(applicationInfo) || AppConfigs.isWhiteApp(packageName, userId) || CommonConstants.isWhitelistApps(packageName);
return packageName == null || equals(InputMethodData.currentInputMethodApp) || PKGUtils.isSystemApp(applicationInfo) || AppConfigs.isWhiteApp(packageName, userId) || CommonConstants.isWhitelistApps(packageName);
}

public String getPackageNameWithUser() {
Expand All @@ -43,4 +44,15 @@ public void reset() {
this.frozen = false;
this.appState = new AppState(this);
}

@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (obj instanceof AppRecord appRecord)
return getUserId() == appRecord.getUserId() && getPackageName().equals(appRecord.getPackageName());
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package nep.timeline.cirno.hooks.android.input;

import android.os.Build;
import android.view.inputmethod.InputMethodInfo;

import java.util.Map;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import nep.timeline.cirno.entity.AppRecord;
import nep.timeline.cirno.framework.AbstractMethodHook;
import nep.timeline.cirno.framework.MethodHook;
import nep.timeline.cirno.services.ActivityManagerService;
import nep.timeline.cirno.services.AppService;
import nep.timeline.cirno.services.FreezerService;
import nep.timeline.cirno.threads.FreezerHandler;
import nep.timeline.cirno.utils.InputMethodData;

public class InputMethodManagerService extends MethodHook {
public InputMethodManagerService(ClassLoader classLoader) {
super(classLoader);
}

@Override
public String getTargetClass() {
return "com.android.server.inputmethod.InputMethodManagerService";
}

@Override
public String getTargetMethod() {
return "setInputMethodLocked";
}

@Override
public Object[] getTargetParam() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU)
return new Object[] { String.class, int.class, int.class };
return new Object[] { String.class, int.class };
}

@Override
public XC_MethodHook getTargetHook() {
return new AbstractMethodHook() {
@Override
protected void beforeMethod(MethodHookParam param) {
String id = (String) param.args[0];
if (id == null)
return;

Object settings = XposedHelpers.getObjectField(param.thisObject, "mSettings");

synchronized (InputMethodData.class) {
if (InputMethodData.instance == null) {
InputMethodData.instance = param.thisObject;
if (settings != null) {
Object map = XposedHelpers.getObjectField(settings, "mMethodMap");
if (map != null) {
if (map.getClass().getTypeName().equals("com.android.server.inputmethod.InputMethodMap"))
InputMethodData.inputMethods = (Map<String, InputMethodInfo>) XposedHelpers.getObjectField(map, "mMap");
else
InputMethodData.inputMethods = (Map<String, InputMethodInfo>) map;
}
else
InputMethodData.inputMethods = null;
}
else
InputMethodData.inputMethods = null;
}

Map<String, InputMethodInfo> inputMethodMap = InputMethodData.inputMethods;
if (inputMethodMap == null)
return;

InputMethodInfo inputMethodInfo = inputMethodMap.get(id);

if (inputMethodInfo != null && !inputMethodInfo.equals(InputMethodData.currentInputMethodInfo)) {
InputMethodData.currentInputMethodInfo = inputMethodInfo;
AppRecord appRecord = AppService.get(inputMethodInfo.getPackageName(), (settings == null) ? ActivityManagerService.getCurrentOrTargetUserId() : (int) XposedHelpers.callMethod(settings, "getUserId"));
if (appRecord != InputMethodData.currentInputMethodApp) {
AppRecord oldApp = InputMethodData.currentInputMethodApp;
InputMethodData.currentInputMethodApp = appRecord;
if (appRecord != null)
FreezerService.thaw(appRecord);
if (oldApp != null)
FreezerHandler.sendFreezeMessage(oldApp, 3000);
}
}
}
}
};
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/nep/timeline/cirno/master/AndroidHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import nep.timeline.cirno.hooks.android.binder.SamsungBinderTransHook;
import nep.timeline.cirno.hooks.android.broadcast.BroadcastDeliveryHook;
import nep.timeline.cirno.hooks.android.broadcast.BroadcastSkipHook;
import nep.timeline.cirno.hooks.android.input.InputMethodManagerService;
import nep.timeline.cirno.hooks.android.network.NetworkManagerHook;
import nep.timeline.cirno.hooks.android.process.ProcessAddHook;
import nep.timeline.cirno.hooks.android.process.ProcessRemoveHook;
Expand All @@ -23,6 +24,8 @@ public static void start(ClassLoader classLoader) {
FileObserver fileObserver = new ConfigFileObserver();
fileObserver.startWatching();

// InputMethod
new InputMethodManagerService(classLoader);
// Network
new NetworkManagerHook(classLoader);
// Alarms
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public static ApplicationInfo getApplicationInfo(String packageName, int userId)
return null;
}

public static int getCurrentOrTargetUserId() {
return (int) XposedHelpers.callMethod(XposedHelpers.getObjectField(instance, "mUserController"), "getCurrentOrTargetUserId");
}

public static String[] getPackagesForUid(int uid) {
Context context = getContext();

Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/nep/timeline/cirno/utils/InputMethodData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nep.timeline.cirno.utils;

import android.view.inputmethod.InputMethodInfo;

import java.util.HashMap;
import java.util.Map;

import nep.timeline.cirno.entity.AppRecord;

public class InputMethodData {
public static volatile Object instance;
public static Map<String, InputMethodInfo> inputMethods = new HashMap<>();
public static InputMethodInfo currentInputMethodInfo;
public static AppRecord currentInputMethodApp;
}

0 comments on commit 6b2170f

Please sign in to comment.