package com.lody.virtual.client.hook.patchs.appops;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import com.lody.virtual.client.hook.base.PatchBinderDelegate;
import com.lody.virtual.client.hook.base.ReplaceLastPkgHook;
import com.lody.virtual.client.hook.base.StaticHook;
import java.lang.reflect.Method;
import mirror.android.os.ServiceManager;
import mirror.com.android.internal.app.IAppOpsService;
/**
* @author Lody
*
* Fuck the AppOpsService.
*
* @see android.app.AppOpsManager
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public class AppOpsManagerPatch extends PatchBinderDelegate {
public AppOpsManagerPatch() {
super(IAppOpsService.Stub.TYPE, Context.APP_OPS_SERVICE);
}
@Override
protected void onBindHooks() {
super.onBindHooks();
addHook(new BaseHook("checkOperation", 1, 2));
addHook(new BaseHook("noteOperation", 1, 2));
addHook(new BaseHook("startOperation", 2, 3));
addHook(new BaseHook("finishOperation", 2, 3));
addHook(new BaseHook("startWatchingMode", -1, 1));
addHook(new BaseHook("checkPackage", 0, 1));
addHook(new BaseHook("getOpsForPackage", 0, 1));
addHook(new BaseHook("setMode", 1, 2));
addHook(new BaseHook("checkAudioOperation", 2, 3));
addHook(new BaseHook("setAudioRestriction", 2, -1));
addHook(new BaseHook("noteProxyOperation", 2, 3));
addHook(new ReplaceLastPkgHook("resetAllModes"));
}
private class BaseHook extends StaticHook {
final int pkgIndex;
final int uidIndex;
BaseHook(String name, int uidIndex, int pkgIndex) {
super(name);
this.pkgIndex = pkgIndex;
this.uidIndex = uidIndex;
}
@Override
public boolean beforeCall(Object who, Method method, Object... args) {
if (pkgIndex != -1 && args.length > pkgIndex && args[pkgIndex] instanceof String) {
args[pkgIndex] = getHostPkg();
}
if (uidIndex != -1 && args[uidIndex] instanceof Integer) {
args[uidIndex] = getRealUid();
}
return true;
}
}
}