package com.lody.virtual.client.hook.patchs.am; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ServiceInfo; import android.os.Handler; import android.os.IBinder; import android.os.Message; import com.lody.virtual.client.VClientImpl; import com.lody.virtual.client.core.VirtualCore; import com.lody.virtual.client.interfaces.Injectable; import com.lody.virtual.client.ipc.VActivityManager; import com.lody.virtual.helper.proto.StubActivityRecord; import com.lody.virtual.helper.utils.ComponentUtils; import com.lody.virtual.helper.utils.Reflect; import com.lody.virtual.helper.utils.VLog; import mirror.android.app.ActivityManagerNative; import mirror.android.app.ActivityThread; import mirror.android.app.IActivityManager; /** * @author Lody * @see Handler.Callback */ public class HCallbackHook implements Handler.Callback, Injectable { public static final int LAUNCH_ACTIVITY = ActivityThread.H.LAUNCH_ACTIVITY.get(); public static final int CREATE_SERVICE = ActivityThread.H.CREATE_SERVICE.get(); private static final String TAG = HCallbackHook.class.getSimpleName(); private static final HCallbackHook sCallback = new HCallbackHook(); private boolean mCalling = false; private Handler.Callback otherCallback; private HCallbackHook() { } public static HCallbackHook getDefault() { return sCallback; } private static Handler getH() { return ActivityThread.mH.get(VirtualCore.mainThread()); } private static Handler.Callback getHCallback() { try { Handler handler = getH(); return mirror.android.os.Handler.mCallback.get(handler); } catch (Throwable e) { e.printStackTrace(); } return null; } @Override public boolean handleMessage(Message msg) { if (!mCalling) { mCalling = true; try { if (LAUNCH_ACTIVITY == msg.what) { if (!handleLaunchActivity(msg)) { return true; } } else if (CREATE_SERVICE == msg.what) { if (!VClientImpl.get().isBound()) { ServiceInfo info = Reflect.on(msg.obj).get("info"); VClientImpl.get().bindApplication(info.packageName, info.processName); } } if (otherCallback != null) { boolean desired = otherCallback.handleMessage(msg); mCalling = false; return desired; } else { mCalling = false; } } finally { mCalling = false; } } return false; } private boolean handleLaunchActivity(Message msg) { Object r = msg.obj; Intent stubIntent = ActivityThread.ActivityClientRecord.intent.get(r); StubActivityRecord saveInstance = new StubActivityRecord(stubIntent); if (saveInstance.intent == null) { return true; } Intent intent = saveInstance.intent; ComponentName caller = saveInstance.caller; IBinder token = ActivityThread.ActivityClientRecord.token.get(r); ActivityInfo info = saveInstance.info; if (VClientImpl.get().getToken() == null) { VActivityManager.get().processRestarted(info.packageName, info.processName, saveInstance.userId); getH().sendMessageAtFrontOfQueue(Message.obtain(msg)); return false; } if (!VClientImpl.get().isBound()) { VClientImpl.get().bindApplication(info.packageName, info.processName); getH().sendMessageAtFrontOfQueue(Message.obtain(msg)); return false; } int taskId = IActivityManager.getTaskForActivity.call( ActivityManagerNative.getDefault.call(), token, false ); VActivityManager.get().onActivityCreate(ComponentUtils.toComponentName(info), caller, token, info, intent, ComponentUtils.getTaskAffinity(info), taskId, info.launchMode, info.flags); ClassLoader appClassLoader = VClientImpl.get().getClassLoader(info.applicationInfo); intent.setExtrasClassLoader(appClassLoader); ActivityThread.ActivityClientRecord.intent.set(r, intent); ActivityThread.ActivityClientRecord.activityInfo.set(r, info); return true; } @Override public void inject() throws Throwable { otherCallback = getHCallback(); mirror.android.os.Handler.mCallback.set(getH(), this); } @Override public boolean isEnvBad() { Handler.Callback callback = getHCallback(); boolean envBad = callback != this; if (callback != null && envBad) { VLog.d(TAG, "HCallback has bad, other callback = " + callback); } return envBad; } }