package com.lody.virtual.client.ipc; import android.app.Activity; import android.app.IServiceConnection; import android.app.Notification; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ProviderInfo; import android.os.Bundle; import android.os.IBinder; import android.os.IInterface; import android.os.RemoteException; import com.lody.virtual.client.core.VirtualCore; import com.lody.virtual.client.env.VirtualRuntime; import com.lody.virtual.helper.compat.ActivityManagerCompat; import com.lody.virtual.helper.utils.ComponentUtils; import com.lody.virtual.os.VUserHandle; import com.lody.virtual.remote.AppTaskInfo; import com.lody.virtual.remote.PendingIntentData; import com.lody.virtual.remote.PendingResultData; import com.lody.virtual.remote.VParceledListSlice; import com.lody.virtual.server.IActivityManager; import com.lody.virtual.server.interfaces.IProcessObserver; import java.util.HashMap; import java.util.List; import java.util.Map; import mirror.android.app.ActivityThread; import mirror.android.content.ContentProviderNative; /** * @author Lody */ public class VActivityManager { private static final VActivityManager sAM = new VActivityManager(); private final Map<IBinder, ActivityClientRecord> mActivities = new HashMap<IBinder, ActivityClientRecord>(6); private IActivityManager mRemote; public static VActivityManager get() { return sAM; } public IActivityManager getService() { if (mRemote == null) { synchronized (VActivityManager.class) { if (mRemote == null) { final Object remote = getRemoteInterface(); mRemote = LocalProxyUtils.genProxy(IActivityManager.class, remote); } } } return mRemote; } private Object getRemoteInterface() { return IActivityManager.Stub .asInterface(ServiceManagerNative.getService(ServiceManagerNative.ACTIVITY)); } public int startActivity(Intent intent, ActivityInfo info, IBinder resultTo, Bundle options, String resultWho, int requestCode, int userId) { try { return getService().startActivity(intent, info, resultTo, options, resultWho, requestCode, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int startActivities(Intent[] intents, String[] resolvedTypes, IBinder token, Bundle options, int userId) { try { return getService().startActivities(intents, resolvedTypes, token, options, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int startActivity(Intent intent, int userId) { if (userId < 0) { return ActivityManagerCompat.START_NOT_CURRENT_USER_ACTIVITY; } ActivityInfo info = VirtualCore.get().resolveActivityInfo(intent, userId); if (info == null) { return ActivityManagerCompat.START_INTENT_NOT_RESOLVED; } return startActivity(intent, info, null, null, null, 0, userId); } public ActivityClientRecord onActivityCreate(ComponentName component, ComponentName caller, IBinder token, ActivityInfo info, Intent intent, String affinity, int taskId, int launchMode, int flags) { ActivityClientRecord r = new ActivityClientRecord(); r.info = info; mActivities.put(token, r); try { getService().onActivityCreated(component, caller, token, intent, affinity, taskId, launchMode, flags); } catch (RemoteException e) { e.printStackTrace(); } return r; } public ActivityClientRecord getActivityRecord(IBinder token) { synchronized (mActivities) { return token == null ? null : mActivities.get(token); } } public void onActivityResumed(Activity activity) { IBinder token = mirror.android.app.Activity.mToken.get(activity); try { getService().onActivityResumed(VUserHandle.myUserId(), token); } catch (RemoteException e) { e.printStackTrace(); } } public boolean onActivityDestroy(IBinder token) { mActivities.remove(token); try { return getService().onActivityDestroyed(VUserHandle.myUserId(), token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public AppTaskInfo getTaskInfo(int taskId) { try { return getService().getTaskInfo(taskId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public ComponentName getCallingActivity(IBinder token) { try { return getService().getCallingActivity(VUserHandle.myUserId(), token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public String getCallingPackage(IBinder token) { try { return getService().getCallingPackage(VUserHandle.myUserId(), token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public String getPackageForToken(IBinder token) { try { return getService().getPackageForToken(VUserHandle.myUserId(), token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public ComponentName getActivityForToken(IBinder token) { try { return getService().getActivityClassForToken(VUserHandle.myUserId(), token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public ComponentName startService(IInterface caller, Intent service, String resolvedType, int userId) { try { return getService().startService(caller != null ? caller.asBinder() : null, service, resolvedType, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int stopService(IInterface caller, Intent service, String resolvedType) { try { return getService().stopService(caller != null ? caller.asBinder() : null, service, resolvedType, VUserHandle.myUserId()); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public boolean stopServiceToken(ComponentName className, IBinder token, int startId) { try { return getService().stopServiceToken(className, token, startId, VUserHandle.myUserId()); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean keepNotification) { try { getService().setServiceForeground(className, token, id, notification, keepNotification, VUserHandle.myUserId()); } catch (RemoteException e) { e.printStackTrace(); } } public int bindService(IBinder caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { try { return getService().bindService(caller, token, service, resolvedType, connection, flags, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public boolean unbindService(IServiceConnection connection) { try { return getService().unbindService(connection, VUserHandle.myUserId()); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void unbindFinished(IBinder token, Intent service, boolean doRebind) { try { getService().unbindFinished(token, service, doRebind, VUserHandle.myUserId()); } catch (RemoteException e) { e.printStackTrace(); } } public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { try { getService().serviceDoneExecuting(token, type, startId, res, VUserHandle.myUserId()); } catch (RemoteException e) { e.printStackTrace(); } } public IBinder peekService(Intent service, String resolvedType) { try { return getService().peekService(service, resolvedType, VUserHandle.myUserId()); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void publishService(IBinder token, Intent intent, IBinder service) { try { getService().publishService(token, intent, service, VUserHandle.myUserId()); } catch (RemoteException e) { e.printStackTrace(); } } public VParceledListSlice getServices(int maxNum, int flags) { try { return getService().getServices(maxNum, flags, VUserHandle.myUserId()); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void processRestarted(String packageName, String processName, int userId) { try { getService().processRestarted(packageName, processName, userId); } catch (RemoteException e) { e.printStackTrace(); } } public String getAppProcessName(int pid) { try { return getService().getAppProcessName(pid); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public String getInitialPackage(int pid) { try { return getService().getInitialPackage(pid); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public boolean isAppProcess(String processName) { try { return getService().isAppProcess(processName); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void handleApplicationCrash() { try { getService().handleApplicationCrash(); } catch (RemoteException e) { e.printStackTrace(); } } public void killAllApps() { try { getService().killAllApps(); } catch (RemoteException e) { e.printStackTrace(); } } public void killApplicationProcess(String procName, int uid) { try { getService().killApplicationProcess(procName, uid); } catch (RemoteException e) { e.printStackTrace(); } } public void registerProcessObserver(IProcessObserver observer) { try { getService().registerProcessObserver(observer); } catch (RemoteException e) { e.printStackTrace(); } } public void killAppByPkg(String pkg, int userId) { try { getService().killAppByPkg(pkg, userId); } catch (RemoteException e) { e.printStackTrace(); } } public void unregisterProcessObserver(IProcessObserver observer) { try { getService().unregisterProcessObserver(observer); } catch (RemoteException e) { e.printStackTrace(); } } public void appDoneExecuting() { try { getService().appDoneExecuting(); } catch (RemoteException e) { e.printStackTrace(); } } public List<String> getProcessPkgList(int pid) { try { return getService().getProcessPkgList(pid); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public boolean isAppPid(int pid) { try { return getService().isAppPid(pid); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int getUidByPid(int pid) { try { return getService().getUidByPid(pid); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int getSystemPid() { try { return getService().getSystemPid(); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void sendActivityResult(IBinder resultTo, String resultWho, int requestCode) { ActivityClientRecord r = mActivities.get(resultTo); if (r != null && r.activity != null) { Object mainThread = VirtualCore.mainThread(); ActivityThread.sendActivityResult.call(mainThread, resultTo, resultWho, requestCode, 0, null); } } public IInterface acquireProviderClient(int userId, ProviderInfo info) throws RemoteException { return ContentProviderNative.asInterface.call(getService().acquireProviderClient(userId, info)); } public PendingIntentData getPendingIntent(IBinder binder) throws RemoteException { return getService().getPendingIntent(binder); } public void addPendingIntent(IBinder binder, String creator) throws RemoteException { getService().addPendingIntent(binder, creator); } public void removePendingIntent(IBinder binder) throws RemoteException { getService().removePendingIntent(binder); } public void finishActivity(IBinder token) { ActivityClientRecord r = getActivityRecord(token); if (r != null) { Activity activity = r.activity; while (true) { // We shouldn't use Activity.getParent(), // because It may be overwritten. Activity parent = mirror.android.app.Activity.mParent.get(activity); if (parent == null) { break; } activity = parent; } // We shouldn't use Activity.isFinishing(), // because It may be overwritten. if (!mirror.android.app.Activity.mFinished.get(activity)) { int resultCode = mirror.android.app.Activity.mResultCode.get(activity); Intent resultData = mirror.android.app.Activity.mResultData.get(activity); ActivityManagerCompat.finishActivity(token, resultCode, resultData); mirror.android.app.Activity.mFinished.set(activity, true); } } } public boolean isAppRunning(String packageName, int userId) { try { return getService().isAppRunning(packageName, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public int initProcess(String packageName, String processName, int userId) { try { return getService().initProcess(packageName, processName, userId); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void sendBroadcast(Intent intent, int userId) { Intent newIntent = ComponentUtils.redirectBroadcastIntent(intent, userId); if (newIntent != null) { VirtualCore.get().getContext().sendBroadcast(newIntent); } } public boolean isVAServiceToken(IBinder token) { try { return getService().isVAServiceToken(token); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } public void broadcastFinish(PendingResultData res) { try { getService().broadcastFinish(res); } catch (RemoteException e) { VirtualRuntime.crash(e); } } public String getPackageForIntentSender(IBinder binder) { try { return getService().getPackageForIntentSender(binder); } catch (RemoteException e) { return VirtualRuntime.crash(e); } } }