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

Commit 3f0e59ac authored by Winson Chung's avatar Winson Chung
Browse files

Formalize recents component in the system

- Add resource for recents component which can be overridden in an overlay
- Allow the static recents component access to APIs which would otherwise
  require privileged permissions
- Remove some unused TV recents code

Bug: 67864419
Test: com.android.server.am.RecentTasksTest
Test: #testNotRecentsComponent_denyApiAccess
Test: #testRecentsComponent_allowApiAccessWithoutPermissions

Change-Id: Ia4939b7d443a6058ab4bb41d8c194eb4611cbf80
parent 61c9e5a6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    public static final int ACTIVITY_TYPE_STANDARD = 1;
    /** Home/Launcher activity type. */
    public static final int ACTIVITY_TYPE_HOME = 2;
    /** Recents/Overview activity type. */
    /** Recents/Overview activity type. There is only one activity with this type in the system. */
    public static final int ACTIVITY_TYPE_RECENTS = 3;
    /** Assistant activity type. */
    public static final int ACTIVITY_TYPE_ASSISTANT = 4;
+4 −0
Original line number Diff line number Diff line
@@ -2356,6 +2356,10 @@
         property. If this is false, then the following recents config flags are ignored. -->
    <bool name="config_hasRecents">true</bool>

    <!-- Component name for the activity that will be presenting the Recents UI, which will receive
         special permissions for API related to fetching and presenting recent tasks. -->
    <string name="config_recentsComponentName" translatable="false">com.android.systemui/.recents.RecentsActivity</string>

    <!-- The minimum number of visible recent tasks to be presented to the user through the
         SystemUI. Can be -1 if there is no minimum limit. -->
    <integer name="config_minNumVisibleRecentTasks_grid">-1</integer>
+1 −0
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@
  <java-symbol type="bool" name="config_enableMultiUserUI"/>
  <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
  <java-symbol type="bool" name="config_hasRecents" />
  <java-symbol type="string" name="config_recentsComponentName" />
  <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" />
  <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" />
  <java-symbol type="integer" name="config_minNumVisibleRecentTasks_grid" />
+0 −5
Original line number Diff line number Diff line
@@ -302,11 +302,6 @@ public class RecentsTransitionHelper {
     */
    private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task,
            final TaskStackView stackView, int windowingMode, int activityType, Rect windowRect) {
        if (activityType == ACTIVITY_TYPE_RECENTS || activityType == ACTIVITY_TYPE_HOME
                || windowingMode == WINDOWING_MODE_PINNED) {
            return null;
        }

        // Calculate the offscreen task rect (for tasks that are not backed by views)
        TaskView taskView = stackView.getChildViewForTask(task);
        TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
+69 −42
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
@@ -672,7 +673,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    /**
     * List of intents that were used to start the most recent tasks.
     */
    final RecentTasks mRecentTasks;
    private final RecentTasks mRecentTasks;
    /**
     * For addAppTask: cached of the last activity component that was added.
@@ -2771,7 +2772,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mTaskChangeNotificationController =
                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
        mActivityStarter = new ActivityStarter(this);
        mRecentTasks = new RecentTasks(this, mStackSupervisor);
        mRecentTasks = createRecentTasks();
        mStackSupervisor.setRecentTasks(mRecentTasks);
        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
@@ -2817,6 +2818,14 @@ public class ActivityManagerService extends IActivityManager.Stub
        return new ActivityStackSupervisor(this, mHandler.getLooper());
    }
    protected RecentTasks createRecentTasks() {
        return new RecentTasks(this, mStackSupervisor);
    }
    RecentTasks getRecentTasks() {
        return mRecentTasks;
    }
    public void setSystemServiceManager(SystemServiceManager mgr) {
        mSystemServiceManager = mgr;
    }
@@ -3152,6 +3161,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            synchronized (this) {
                final ActivityStack stack = mStackSupervisor.getStack(stackId);
                if (stack == null) {
                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
                    return;
                }
                final ActivityRecord r = stack.topRunningActivityLocked();
@@ -3188,7 +3198,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    /** Sets the task stack listener that gets callbacks when a task stack changes. */
    @Override
    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "registerTaskStackListener()");
        mTaskChangeNotificationController.registerTaskStackListener(listener);
    }
@@ -3197,7 +3208,8 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @Override
    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "unregisterTaskStackListener()");
         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
     }
@@ -4875,12 +4887,9 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: startActivityFromRecents called without " +
                    START_TASKS_FROM_RECENTS;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
                "startActivityFromRecents()");
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -8332,9 +8341,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    /**
     * This can be called with or without the global lock held.
     */
    int checkComponentPermission(String permission, int pid, int uid,
            int owningUid, boolean exported) {
        if (pid == MY_PID) {
@@ -8408,6 +8414,15 @@ public class ActivityManagerService extends IActivityManager.Stub
        throw new SecurityException(msg);
    }
    /**
     * This can be called with or without the global lock held.
     */
    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
            enforceCallingPermission(permission, func);
        }
    }
    /**
     * Determine if UID is holding permissions required to access {@link Uri} in
     * the given {@link ProviderInfo}. Final permission checking is always done
@@ -9797,6 +9812,11 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
        if (mRecentTasks.isCallerRecents(callingUid)) {
            // Always allow the recents component to get tasks
            return true;
        }
        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
        if (!allowed) {
@@ -9844,8 +9864,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public ActivityManager.TaskDescription getTaskDescription(int id) {
        synchronized (this) {
            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                    "getTaskDescription()");
            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
            if (tr != null) {
@@ -10039,7 +10058,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void cancelTaskWindowTransition(int taskId) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "cancelTaskWindowTransition()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10058,7 +10078,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void cancelTaskThumbnailTransition(int taskId) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "cancelTaskThumbnailTransition()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10077,7 +10098,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
        final long ident = Binder.clearCallingIdentity();
        try {
            final TaskRecord task;
@@ -10130,12 +10151,13 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void removeStack(int stackId) {
        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
                final ActivityStack stack = mStackSupervisor.getStack(stackId);
                if (stack == null) {
                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
                    return;
                }
                if (!stack.isActivityTypeStandardOrUndefined()) {
@@ -10155,7 +10177,8 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @Override
    public void removeStacksInWindowingModes(int[] windowingModes) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksInWindowingModes()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "removeStacksInWindowingModes()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
@@ -10168,7 +10191,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void removeStacksWithActivityTypes(int[] activityTypes) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksWithActivityTypes()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "removeStacksWithActivityTypes()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
@@ -10197,7 +10221,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public boolean removeTask(int taskId) {
        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
@@ -10374,7 +10398,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
@@ -10410,7 +10434,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
        synchronized (this) {
            long ident = Binder.clearCallingIdentity();
            try {
@@ -10461,7 +10485,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
            Rect initialBounds) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
        synchronized (this) {
            long ident = Binder.clearCallingIdentity();
            try {
@@ -10500,12 +10524,16 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @Override
    public void dismissSplitScreenMode(boolean toTop) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
                final ActivityStack stack =
                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
                if (stack == null) {
                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
                    return;
                }
                if (toTop) {
                    mStackSupervisor.resizeStackLocked(stack, null /* destBounds */,
                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
@@ -10528,14 +10556,14 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @Override
    public void dismissPip(boolean animate, int animationDuration) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
                final PinnedActivityStack stack =
                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
                if (stack == null) {
                    Slog.w(TAG, "dismissPip: pinned stack not found.");
                    return;
                }
                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
@@ -10565,7 +10593,8 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @Override
    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "moveTopActivityToPinnedStack()");
        synchronized (this) {
            if (!mSupportsPictureInPicture) {
                throw new IllegalStateException("moveTopActivityToPinnedStack:"
@@ -10584,13 +10613,14 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
            boolean preserveWindows, boolean animate, int animationDuration) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
                if (animate) {
                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
                    if (stack == null) {
                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
                        return;
                    }
                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
@@ -10619,8 +10649,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
            Rect tempDockedTaskInsetBounds,
            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                "resizeDockedStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10635,8 +10664,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                "resizePinnedStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10695,7 +10723,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public List<StackInfo> getAllStackInfos() {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -10708,7 +10736,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public StackInfo getStackInfo(int windowingMode, int activityType) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -11869,8 +11897,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void appNotRespondingViaProvider(IBinder connection) {
        enforceCallingPermission(
                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
        final ContentProviderConnection conn = (ContentProviderConnection) connection;
        if (conn == null) {
@@ -18133,8 +18160,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    // =========================================================
    @Override
    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
            int flags) {
    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
        enforceNotIsolatedCaller("getServices");
        final int callingUid = Binder.getCallingUid();
@@ -20078,7 +20104,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public StackInfo getFocusedStackInfo() throws RemoteException {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
@@ -20118,7 +20144,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    // TODO: API should just be about changing windowing modes...
    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
                "moveTasksToFullscreenStack()");
        synchronized (this) {
            final long origId = Binder.clearCallingIdentity();
            try {
Loading