Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08bd3ea8 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #68002319: Allow current VoiceInteractionService to avoid...

...activity launch delays.

Activity manager now has a new private mechanism for other services
to report which apps are allowed to bypass the launch delay restriction,
which voice interaction service uses.

Test: manual

Bug: 68002319
Change-Id: I44e9b67411b5106b81e8363dc22d4e54caeb83c1
parent 1edf09c9
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -283,4 +283,15 @@ public abstract class ActivityManagerInternal {
     * @param token The IApplicationToken for the activity
     */
    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);
}
+93 −19
Original line number Diff line number Diff line
@@ -713,6 +713,12 @@ public class ActivityManagerService extends IActivityManager.Stub
    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 AppWarnings mAppWarnings;
@@ -2866,6 +2872,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    void onUserStoppedLocked(int userId) {
        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
        mAllowAppSwitchUids.remove(userId);
    }
    public void initPowerManagement() {
@@ -12605,6 +12612,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,
            int callingPid, int callingUid, String name) {
        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
@@ -12617,6 +12636,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        if (perm == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        if (checkAllowAppSwitchUid(sourceUid)) {
            return true;
        }
        // If the actual IPC caller is different from the logical source, then
        // also see if they are allowed to control app switches.
@@ -12627,6 +12649,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (perm == PackageManager.PERMISSION_GRANTED) {
                return true;
            }
            if (checkAllowAppSwitchUid(callingUid)) {
                return true;
            }
        }
        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
@@ -14903,6 +14928,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        boolean dumpVisibleStacksOnly = false;
        boolean dumpFocusedStackOnly = false;
        String dumpPackage = null;
        int dumpAppId = -1;
        int opti = 0;
        while (opti < args.length) {
@@ -14997,6 +15023,16 @@ public class ActivityManagerService extends IActivityManager.Stub
            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;
        // Is the caller requesting to dump a particular piece of data?
        if (opti < args.length) {
@@ -15104,7 +15140,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                            args.length - opti);
                }
                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)) {
                synchronized (this) {
@@ -15290,7 +15326,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (dumpAll) {
                    pw.println("-------------------------------------------------------------------------------");
                }
                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
            }
        } else {
@@ -15367,7 +15403,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (dumpAll) {
                    pw.println("-------------------------------------------------------------------------------");
                }
                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
            }
        }
        Binder.restoreCallingIdentity(origId);
@@ -15522,22 +15558,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) {
        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++) {
            UidRecord uidRec = uids.valueAt(i);
            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
                continue;
            }
            if (!printed) {
@@ -15584,7 +15610,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    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 printedAnything = false;
        int numPers = 0;
@@ -15662,13 +15688,14 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        if (mActiveUids.size() > 0) {
            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
                printedAnything = needSep = true;
            }
        }
        if (dumpAll) {
            if (mValidateUids.size() > 0) {
                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
                        needSep)) {
                    printedAnything = needSep = true;
                }
            }
@@ -15972,6 +15999,32 @@ public class ActivityManagerService extends IActivityManager.Stub
                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 (mAlwaysFinishActivities) {
                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
@@ -17950,7 +18003,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
            String[] emptyArgs = new String[] { };
            catPw.println();
            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
            catPw.println();
            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
                    false, null).dumpLocked();
@@ -24250,6 +24303,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);
                    }
                }
            }
        }
    }
    /**
+3 −0
Original line number Diff line number Diff line
@@ -427,8 +427,11 @@ public class VoiceInteractionManagerService extends SystemService {
                    if (hasComponent) {
                        mShortcutServiceInternal.setShortcutHostPackage(TAG,
                                serviceComponent.getPackageName(), mCurUser);
                        mAmInternal.setAllowAppSwitches(TAG,
                                serviceInfo.applicationInfo.uid, mCurUser);
                    } else {
                        mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser);
                        mAmInternal.setAllowAppSwitches(TAG, -1, mCurUser);
                    }
                }