package biz.bokhorst.xprivacy; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; public class XActivityManager extends XHook { private Methods mMethod; private String mClassName; private static final String cClassName = "android.app.ActivityManager"; private static Map<String, String> mapIntentRestriction = new HashMap<String, String>(); static { mapIntentRestriction.put(Intent.ACTION_VIEW, PrivacyManager.cView); } private XActivityManager(Methods method, String restrictionName, String className) { super(restrictionName, method.name().replace("Srv_", ""), method.name()); mMethod = method; if (className == null) mClassName = "com.android.server.am.ActivityManagerService"; else mClassName = className; } public String getClassName() { return mClassName; } // @formatter:off // public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags) // public List<RunningAppProcessInfo> getRunningAppProcesses() // public List<RunningServiceInfo> getRunningServices(int maxNum) // public List<RunningTaskInfo> getRunningTasks(int maxNum) // frameworks/base/core/java/android/app/ActivityManager.java // http://developer.android.com/reference/android/app/ActivityManager.html // public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) // public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() // public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) // public List<RunningTaskInfo> getTasks(int maxNum, int flags, IThumbnailReceiver receiver) // public int startActivities(IApplicationThread caller, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId) // public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, String profileFile, ParcelFileDescriptor profileFd, Bundle options) // public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, String profileFile,ParcelFileDescriptor profileFd, Bundle options, int userId) // public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) // public int startActivityWithConfig(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration newConfig, Bundle options, int userId) // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/com/android/server/am/ActivityManagerService.java // public int startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options, int userId) // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/android/accounts/IAccountManager.java/ // @formatter:on // @formatter:off private enum Methods { getRecentTasks, getRunningAppProcesses, getRunningServices, getRunningTasks, Srv_getRecentTasks, Srv_getRunningAppProcesses, Srv_getServices, Srv_getTasks, Srv_startActivities, Srv_startActivity, Srv_startActivityAsCaller, Srv_startActivityAsUser, Srv_startActivityAndWait, Srv_startActivityWithConfig }; // @formatter:on public static List<XHook> getInstances(String className, boolean server) { List<XHook> listHook = new ArrayList<XHook>(); if (!cClassName.equals(className)) { if (className == null) className = cClassName; for (Methods act : Methods.values()) if (act.name().startsWith("Srv_")) { if (server) if (act.name().startsWith("Srv_start")) listHook.add(new XActivityManager(act, null, null)); else listHook.add(new XActivityManager(act, PrivacyManager.cSystem, null)); } else if (!server) listHook.add(new XActivityManager(act, PrivacyManager.cSystem, className)); } return listHook; } @Override protected void before(XParam param) throws Throwable { switch (mMethod) { case getRecentTasks: case getRunningAppProcesses: case getRunningServices: case getRunningTasks: case Srv_getRecentTasks: case Srv_getRunningAppProcesses: case Srv_getServices: case Srv_getTasks: break; case Srv_startActivities: if (param.args.length > 2 && param.args[2] instanceof Intent[]) { List<Intent> listIntent = new ArrayList<Intent>(); for (Intent intent : (Intent[]) param.args[2]) if (!isRestricted(param, intent)) listIntent.add(intent); if (listIntent.size() == 0) param.setResult(0); // ActivityManager.START_SUCCESS else param.args[2] = listIntent.toArray(new Intent[0]); } break; case Srv_startActivity: case Srv_startActivityAsCaller: case Srv_startActivityAsUser: case Srv_startActivityWithConfig: if (param.args.length > 2 && param.args[2] instanceof Intent) { Intent intent = (Intent) param.args[2]; if (isRestricted(param, intent)) param.setResult(0); // ActivityManager.START_SUCCESS } break; case Srv_startActivityAndWait: if (param.args.length > 2 && param.args[2] instanceof Intent) { Intent intent = (Intent) param.args[2]; if (isRestricted(param, intent)) { Class<?> cWaitResult = Class.forName("android.app.IActivityManager.WaitResult"); Field fWho = cWaitResult.getDeclaredField("who"); Class<?> we = this.getClass(); ComponentName component = new ComponentName(we.getPackage().getName(), we.getName()); Object waitResult = cWaitResult.getConstructor().newInstance(); fWho.set(waitResult, component); param.setResult(waitResult); } } break; } } @Override protected void after(XParam param) throws Throwable { switch (mMethod) { case getRecentTasks: case Srv_getRecentTasks: if (param.getResult() != null && isRestricted(param)) param.setResult(new ArrayList<ActivityManager.RecentTaskInfo>()); break; case getRunningAppProcesses: case Srv_getRunningAppProcesses: if (param.getResult() != null && isRestricted(param)) param.setResult(new ArrayList<ActivityManager.RunningAppProcessInfo>()); break; case getRunningServices: case Srv_getServices: if (param.getResult() != null && isRestricted(param)) param.setResult(new ArrayList<ActivityManager.RunningServiceInfo>()); break; case getRunningTasks: case Srv_getTasks: if (param.getResult() != null && isRestricted(param)) param.setResult(new ArrayList<ActivityManager.RunningTaskInfo>()); break; case Srv_startActivities: case Srv_startActivity: case Srv_startActivityAsCaller: case Srv_startActivityAsUser: case Srv_startActivityAndWait: case Srv_startActivityWithConfig: break; } } // Helper methods private boolean isRestricted(XParam param, Intent intent) throws Throwable { String action = intent.getAction(); if (mapIntentRestriction.containsKey(action)) { String restrictionName = mapIntentRestriction.get(action); if (Intent.ACTION_VIEW.equals(action)) { Uri uri = intent.getData(); if (uri != null) return isRestrictedExtra(param, restrictionName, "Srv_" + action, uri.toString()); } else return isRestricted(param, restrictionName, "Srv_" + action); } return false; } }