Loading core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Original line Diff line number Diff line Loading @@ -283,4 +283,15 @@ public abstract class ActivityManagerInternal { * @param token The IApplicationToken for the activity * @param token The IApplicationToken for the activity */ */ public abstract void setFocusedActivity(IBinder token); public abstract void setFocusedActivity(IBinder token); /** * Set a uid that is allowed to bypass stopped app switches, launching an app * whenever it wants. * * @param type Type of the caller -- unique string the caller supplies to identify itself * and disambiguate with other calles. * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type. * @param userId The user it is allowed for. */ public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId); } } services/core/java/com/android/server/am/ActivityManagerService.java +93 −19 Original line number Original line Diff line number Diff line Loading @@ -713,6 +713,12 @@ public class ActivityManagerService extends IActivityManager.Stub final UserController mUserController; final UserController mUserController; /** * Packages that are being allowed to perform unrestricted app switches. Mapping is * User -> Type -> uid. */ final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>(); final AppErrors mAppErrors; final AppErrors mAppErrors; final AppWarnings mAppWarnings; final AppWarnings mAppWarnings; Loading Loading @@ -2872,6 +2878,7 @@ public class ActivityManagerService extends IActivityManager.Stub void onUserStoppedLocked(int userId) { void onUserStoppedLocked(int userId) { mRecentTasks.unloadUserDataFromMemoryLocked(userId); mRecentTasks.unloadUserDataFromMemoryLocked(userId); mAllowAppSwitchUids.remove(userId); } } public void initPowerManagement() { public void initPowerManagement() { Loading Loading @@ -12611,6 +12618,18 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } boolean checkAllowAppSwitchUid(int uid) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid)); if (types != null) { for (int i = types.size() - 1; i >= 0; i--) { if (types.valueAt(i).intValue() == uid) { return true; } } } return false; } boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { int callingPid, int callingUid, String name) { if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { Loading @@ -12623,6 +12642,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (perm == PackageManager.PERMISSION_GRANTED) { if (perm == PackageManager.PERMISSION_GRANTED) { return true; return true; } } if (checkAllowAppSwitchUid(sourceUid)) { return true; } // If the actual IPC caller is different from the logical source, then // If the actual IPC caller is different from the logical source, then // also see if they are allowed to control app switches. // also see if they are allowed to control app switches. Loading @@ -12633,6 +12655,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (perm == PackageManager.PERMISSION_GRANTED) { if (perm == PackageManager.PERMISSION_GRANTED) { return true; return true; } } if (checkAllowAppSwitchUid(callingUid)) { return true; } } } Slog.w(TAG, name + " request from " + sourceUid + " stopped"); Slog.w(TAG, name + " request from " + sourceUid + " stopped"); Loading Loading @@ -14909,6 +14934,7 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpVisibleStacksOnly = false; boolean dumpVisibleStacksOnly = false; boolean dumpFocusedStackOnly = false; boolean dumpFocusedStackOnly = false; String dumpPackage = null; String dumpPackage = null; int dumpAppId = -1; int opti = 0; int opti = 0; while (opti < args.length) { while (opti < args.length) { Loading Loading @@ -15003,6 +15029,16 @@ public class ActivityManagerService extends IActivityManager.Stub return; return; } } if (dumpPackage != null) { try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( dumpPackage, 0); dumpAppId = UserHandle.getAppId(info.uid); } catch (NameNotFoundException e) { e.printStackTrace(); } } boolean more = false; boolean more = false; // Is the caller requesting to dump a particular piece of data? // Is the caller requesting to dump a particular piece of data? if (opti < args.length) { if (opti < args.length) { Loading Loading @@ -15110,7 +15146,7 @@ public class ActivityManagerService extends IActivityManager.Stub args.length - opti); args.length - opti); } } synchronized (this) { synchronized (this) { dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId); } } } else if ("oom".equals(cmd) || "o".equals(cmd)) { } else if ("oom".equals(cmd) || "o".equals(cmd)) { synchronized (this) { synchronized (this) { Loading Loading @@ -15296,7 +15332,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); } } } else { } else { Loading Loading @@ -15373,7 +15409,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); } } } } Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId); Loading Loading @@ -15528,22 +15564,12 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids, String header, boolean needSep) { String header, boolean needSep) { boolean printed = false; boolean printed = false; int whichAppId = -1; if (dumpPackage != null) { try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( dumpPackage, 0); whichAppId = UserHandle.getAppId(info.uid); } catch (NameNotFoundException e) { e.printStackTrace(); } } for (int i=0; i<uids.size(); i++) { for (int i=0; i<uids.size(); i++) { UidRecord uidRec = uids.valueAt(i); UidRecord uidRec = uids.valueAt(i); if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) { continue; continue; } } if (!printed) { if (!printed) { Loading Loading @@ -15590,7 +15616,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage) { int opti, boolean dumpAll, String dumpPackage, int dumpAppId) { boolean needSep = false; boolean needSep = false; boolean printedAnything = false; boolean printedAnything = false; int numPers = 0; int numPers = 0; Loading Loading @@ -15668,13 +15694,14 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (mActiveUids.size() > 0) { if (mActiveUids.size() > 0) { if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) { printedAnything = needSep = true; printedAnything = needSep = true; } } } } if (dumpAll) { if (dumpAll) { if (mValidateUids.size() > 0) { if (mValidateUids.size() > 0) { if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:", needSep)) { printedAnything = needSep = true; printedAnything = needSep = true; } } } } Loading Loading @@ -15978,6 +16005,32 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); } } } } if (mAllowAppSwitchUids.size() > 0) { boolean printed = false; for (int i = 0; i < mAllowAppSwitchUids.size(); i++) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i); for (int j = 0; j < types.size(); j++) { if (dumpPackage == null || UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) { if (needSep) { pw.println(); needSep = false; } if (!printed) { pw.println(" mAllowAppSwitchUids:"); printed = true; } pw.print(" User "); pw.print(mAllowAppSwitchUids.keyAt(i)); pw.print(": Type "); pw.print(types.keyAt(j)); pw.print(" = "); UserHandle.formatUid(pw, types.valueAt(j).intValue()); pw.println(); } } } } if (dumpPackage == null) { if (dumpPackage == null) { if (mAlwaysFinishActivities) { if (mAlwaysFinishActivities) { pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); Loading Loading @@ -17956,7 +18009,7 @@ public class ActivityManagerService extends IActivityManager.Stub PrintWriter catPw = new FastPrintWriter(catSw, false, 256); PrintWriter catPw = new FastPrintWriter(catSw, false, 256); String[] emptyArgs = new String[] { }; String[] emptyArgs = new String[] { }; catPw.println(); catPw.println(); dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1); catPw.println(); catPw.println(); mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, false, null).dumpLocked(); false, null).dumpLocked(); Loading Loading @@ -24256,6 +24309,27 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } } } @Override public void setAllowAppSwitches(@NonNull String type, int uid, int userId) { synchronized (ActivityManagerService.this) { if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId); if (types == null) { if (uid < 0) { return; } types = new ArrayMap<>(); mAllowAppSwitchUids.put(userId, types); } if (uid < 0) { types.remove(type); } else { types.put(type, uid); } } } } } } /** /** services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -427,8 +427,11 @@ public class VoiceInteractionManagerService extends SystemService { if (hasComponent) { if (hasComponent) { mShortcutServiceInternal.setShortcutHostPackage(TAG, mShortcutServiceInternal.setShortcutHostPackage(TAG, serviceComponent.getPackageName(), mCurUser); serviceComponent.getPackageName(), mCurUser); mAmInternal.setAllowAppSwitches(TAG, serviceInfo.applicationInfo.uid, mCurUser); } else { } else { mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser); mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser); mAmInternal.setAllowAppSwitches(TAG, -1, mCurUser); } } } } Loading Loading
core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Original line Diff line number Diff line Loading @@ -283,4 +283,15 @@ public abstract class ActivityManagerInternal { * @param token The IApplicationToken for the activity * @param token The IApplicationToken for the activity */ */ public abstract void setFocusedActivity(IBinder token); public abstract void setFocusedActivity(IBinder token); /** * Set a uid that is allowed to bypass stopped app switches, launching an app * whenever it wants. * * @param type Type of the caller -- unique string the caller supplies to identify itself * and disambiguate with other calles. * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type. * @param userId The user it is allowed for. */ public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId); } }
services/core/java/com/android/server/am/ActivityManagerService.java +93 −19 Original line number Original line Diff line number Diff line Loading @@ -713,6 +713,12 @@ public class ActivityManagerService extends IActivityManager.Stub final UserController mUserController; final UserController mUserController; /** * Packages that are being allowed to perform unrestricted app switches. Mapping is * User -> Type -> uid. */ final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>(); final AppErrors mAppErrors; final AppErrors mAppErrors; final AppWarnings mAppWarnings; final AppWarnings mAppWarnings; Loading Loading @@ -2872,6 +2878,7 @@ public class ActivityManagerService extends IActivityManager.Stub void onUserStoppedLocked(int userId) { void onUserStoppedLocked(int userId) { mRecentTasks.unloadUserDataFromMemoryLocked(userId); mRecentTasks.unloadUserDataFromMemoryLocked(userId); mAllowAppSwitchUids.remove(userId); } } public void initPowerManagement() { public void initPowerManagement() { Loading Loading @@ -12611,6 +12618,18 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } boolean checkAllowAppSwitchUid(int uid) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid)); if (types != null) { for (int i = types.size() - 1; i >= 0; i--) { if (types.valueAt(i).intValue() == uid) { return true; } } } return false; } boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { int callingPid, int callingUid, String name) { if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { Loading @@ -12623,6 +12642,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (perm == PackageManager.PERMISSION_GRANTED) { if (perm == PackageManager.PERMISSION_GRANTED) { return true; return true; } } if (checkAllowAppSwitchUid(sourceUid)) { return true; } // If the actual IPC caller is different from the logical source, then // If the actual IPC caller is different from the logical source, then // also see if they are allowed to control app switches. // also see if they are allowed to control app switches. Loading @@ -12633,6 +12655,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (perm == PackageManager.PERMISSION_GRANTED) { if (perm == PackageManager.PERMISSION_GRANTED) { return true; return true; } } if (checkAllowAppSwitchUid(callingUid)) { return true; } } } Slog.w(TAG, name + " request from " + sourceUid + " stopped"); Slog.w(TAG, name + " request from " + sourceUid + " stopped"); Loading Loading @@ -14909,6 +14934,7 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpVisibleStacksOnly = false; boolean dumpVisibleStacksOnly = false; boolean dumpFocusedStackOnly = false; boolean dumpFocusedStackOnly = false; String dumpPackage = null; String dumpPackage = null; int dumpAppId = -1; int opti = 0; int opti = 0; while (opti < args.length) { while (opti < args.length) { Loading Loading @@ -15003,6 +15029,16 @@ public class ActivityManagerService extends IActivityManager.Stub return; return; } } if (dumpPackage != null) { try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( dumpPackage, 0); dumpAppId = UserHandle.getAppId(info.uid); } catch (NameNotFoundException e) { e.printStackTrace(); } } boolean more = false; boolean more = false; // Is the caller requesting to dump a particular piece of data? // Is the caller requesting to dump a particular piece of data? if (opti < args.length) { if (opti < args.length) { Loading Loading @@ -15110,7 +15146,7 @@ public class ActivityManagerService extends IActivityManager.Stub args.length - opti); args.length - opti); } } synchronized (this) { synchronized (this) { dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId); } } } else if ("oom".equals(cmd) || "o".equals(cmd)) { } else if ("oom".equals(cmd) || "o".equals(cmd)) { synchronized (this) { synchronized (this) { Loading Loading @@ -15296,7 +15332,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); } } } else { } else { Loading Loading @@ -15373,7 +15409,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); } } } } Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId); Loading Loading @@ -15528,22 +15564,12 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids, String header, boolean needSep) { String header, boolean needSep) { boolean printed = false; boolean printed = false; int whichAppId = -1; if (dumpPackage != null) { try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( dumpPackage, 0); whichAppId = UserHandle.getAppId(info.uid); } catch (NameNotFoundException e) { e.printStackTrace(); } } for (int i=0; i<uids.size(); i++) { for (int i=0; i<uids.size(); i++) { UidRecord uidRec = uids.valueAt(i); UidRecord uidRec = uids.valueAt(i); if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) { continue; continue; } } if (!printed) { if (!printed) { Loading Loading @@ -15590,7 +15616,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage) { int opti, boolean dumpAll, String dumpPackage, int dumpAppId) { boolean needSep = false; boolean needSep = false; boolean printedAnything = false; boolean printedAnything = false; int numPers = 0; int numPers = 0; Loading Loading @@ -15668,13 +15694,14 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (mActiveUids.size() > 0) { if (mActiveUids.size() > 0) { if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) { printedAnything = needSep = true; printedAnything = needSep = true; } } } } if (dumpAll) { if (dumpAll) { if (mValidateUids.size() > 0) { if (mValidateUids.size() > 0) { if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:", needSep)) { printedAnything = needSep = true; printedAnything = needSep = true; } } } } Loading Loading @@ -15978,6 +16005,32 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); } } } } if (mAllowAppSwitchUids.size() > 0) { boolean printed = false; for (int i = 0; i < mAllowAppSwitchUids.size(); i++) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i); for (int j = 0; j < types.size(); j++) { if (dumpPackage == null || UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) { if (needSep) { pw.println(); needSep = false; } if (!printed) { pw.println(" mAllowAppSwitchUids:"); printed = true; } pw.print(" User "); pw.print(mAllowAppSwitchUids.keyAt(i)); pw.print(": Type "); pw.print(types.keyAt(j)); pw.print(" = "); UserHandle.formatUid(pw, types.valueAt(j).intValue()); pw.println(); } } } } if (dumpPackage == null) { if (dumpPackage == null) { if (mAlwaysFinishActivities) { if (mAlwaysFinishActivities) { pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); Loading Loading @@ -17956,7 +18009,7 @@ public class ActivityManagerService extends IActivityManager.Stub PrintWriter catPw = new FastPrintWriter(catSw, false, 256); PrintWriter catPw = new FastPrintWriter(catSw, false, 256); String[] emptyArgs = new String[] { }; String[] emptyArgs = new String[] { }; catPw.println(); catPw.println(); dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1); catPw.println(); catPw.println(); mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, false, null).dumpLocked(); false, null).dumpLocked(); Loading Loading @@ -24256,6 +24309,27 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } } } @Override public void setAllowAppSwitches(@NonNull String type, int uid, int userId) { synchronized (ActivityManagerService.this) { if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) { ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId); if (types == null) { if (uid < 0) { return; } types = new ArrayMap<>(); mAllowAppSwitchUids.put(userId, types); } if (uid < 0) { types.remove(type); } else { types.put(type, uid); } } } } } } /** /**
services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -427,8 +427,11 @@ public class VoiceInteractionManagerService extends SystemService { if (hasComponent) { if (hasComponent) { mShortcutServiceInternal.setShortcutHostPackage(TAG, mShortcutServiceInternal.setShortcutHostPackage(TAG, serviceComponent.getPackageName(), mCurUser); serviceComponent.getPackageName(), mCurUser); mAmInternal.setAllowAppSwitches(TAG, serviceInfo.applicationInfo.uid, mCurUser); } else { } else { mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser); mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser); mAmInternal.setAllowAppSwitches(TAG, -1, mCurUser); } } } } Loading