blob: 5783713b17b1d3f5cbd65cdc0cf6b9f7dd302987 [file] [log] [blame]
Winson Chung61c9e5a2017-10-11 10:39:32 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Winson Chung61c9e5a2017-10-11 10:39:32 -070018
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090019import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
21
Winson Chung61c9e5a2017-10-11 10:39:32 -070022import android.app.ActivityManager.RunningTaskInfo;
23import android.app.WindowConfiguration.ActivityType;
24import android.app.WindowConfiguration.WindowingMode;
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090025import android.os.UserHandle;
Nicholas Sauer3f9249f2019-09-10 20:23:41 -070026import android.util.ArraySet;
Winson Chung61c9e5a2017-10-11 10:39:32 -070027
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090028import com.android.internal.util.function.pooled.PooledConsumer;
29import com.android.internal.util.function.pooled.PooledLambda;
30
Winson Chung61c9e5a2017-10-11 10:39:32 -070031import java.util.ArrayList;
32import java.util.Comparator;
33import java.util.Iterator;
34import java.util.List;
35import java.util.TreeSet;
36
37/**
38 * Class for resolving the set of running tasks in the system.
39 */
40class RunningTasks {
41
42 // Comparator to sort by last active time (descending)
Louis Changcdec0802019-11-11 11:45:07 +080043 private static final Comparator<Task> LAST_ACTIVE_TIME_COMPARATOR =
Winson Chung61c9e5a2017-10-11 10:39:32 -070044 (o1, o2) -> Long.signum(o2.lastActiveTime - o1.lastActiveTime);
45
Louis Changcdec0802019-11-11 11:45:07 +080046 private final TreeSet<Task> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR);
47 private final ArrayList<Task> mTmpStackTasks = new ArrayList<>();
Winson Chung61c9e5a2017-10-11 10:39:32 -070048
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090049 private int mCallingUid;
50 private int mUserId;
51 private boolean mCrossUser;
52 private ArraySet<Integer> mProfileIds;
53 private boolean mAllowed;
54 private int mIgnoreActivityType;
55 private int mIgnoreWindowingMode;
56 private ActivityStack mTopDisplayFocusStack;
57
Winson Chung61c9e5a2017-10-11 10:39:32 -070058 void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090059 @WindowingMode int ignoreWindowingMode, RootActivityContainer root,
Nicholas Sauer3f9249f2019-09-10 20:23:41 -070060 int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
Winson Chung39072852017-11-01 17:09:48 -070061 // Return early if there are no tasks to fetch
62 if (maxNum <= 0) {
63 return;
64 }
Winson Chung61c9e5a2017-10-11 10:39:32 -070065
66 // Gather all of the tasks across all of the tasks, and add them to the sorted set
67 mTmpSortedSet.clear();
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090068 mCallingUid = callingUid;
69 mUserId = UserHandle.getUserId(callingUid);
70 mCrossUser = crossUser;
71 mProfileIds = profileIds;
72 mAllowed = allowed;
73 mIgnoreActivityType = ignoreActivityType;
74 mIgnoreWindowingMode = ignoreWindowingMode;
75 mTopDisplayFocusStack = root.getTopDisplayFocusedStack();
76
77 final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
78 PooledLambda.__(Task.class));
79 root.mRootWindowContainer.forAllTasks(c, false);
80 c.recycle();
Winson Chung61c9e5a2017-10-11 10:39:32 -070081
82 // Take the first {@param maxNum} tasks and create running task infos for them
Louis Changcdec0802019-11-11 11:45:07 +080083 final Iterator<Task> iter = mTmpSortedSet.iterator();
Winson Chung61c9e5a2017-10-11 10:39:32 -070084 while (iter.hasNext()) {
85 if (maxNum == 0) {
86 break;
87 }
88
Louis Changcdec0802019-11-11 11:45:07 +080089 final Task task = iter.next();
Winson Chung61c9e5a2017-10-11 10:39:32 -070090 list.add(createRunningTaskInfo(task));
91 maxNum--;
92 }
93 }
94
Wale Ogunwale85fb19a2019-12-05 10:41:05 +090095 private void processTask(Task task) {
96 if (task.getTopNonFinishingActivity() == null) {
97 // Skip if there are no activities in the task
98 return;
99 }
100 if (task.effectiveUid != mCallingUid) {
101 if (task.mUserId != mUserId && !mCrossUser && !mProfileIds.contains(task.mUserId)) {
102 // Skip if the caller does not have cross user permission or cannot access
103 // the task's profile
104 return;
105 }
106 if (!mAllowed && !task.isActivityTypeHome()) {
107 // Skip if the caller isn't allowed to fetch this task, except for the home
108 // task which we always return.
109 return;
110 }
111 }
112 if (mIgnoreActivityType != ACTIVITY_TYPE_UNDEFINED
113 && task.getActivityType() == mIgnoreActivityType) {
114 // Skip ignored activity type
115 return;
116 }
117 if (mIgnoreWindowingMode != WINDOWING_MODE_UNDEFINED
118 && task.getWindowingMode() == mIgnoreWindowingMode) {
119 // Skip ignored windowing mode
120 return;
121 }
122
123 final ActivityStack stack = task.getStack();
124 if (stack == mTopDisplayFocusStack && stack.getTopMostTask() == task) {
125 // For the focused stack top task, update the last stack active time so that it can be
126 // used to determine the order of the tasks (it may not be set for newly created tasks)
127 task.touchActiveTime();
128 }
129
130 mTmpSortedSet.add(task);
131 }
132
133 /** Constructs a {@link RunningTaskInfo} from a given {@param task}. */
Louis Changcdec0802019-11-11 11:45:07 +0800134 private RunningTaskInfo createRunningTaskInfo(Task task) {
Winson Chungabfdcce2018-07-02 17:23:33 -0700135 final RunningTaskInfo rti = new RunningTaskInfo();
Mark Renoufc808f062019-02-07 15:20:37 -0500136 task.fillTaskInfo(rti);
Winson Chungabfdcce2018-07-02 17:23:33 -0700137 // Fill in some deprecated values
138 rti.id = rti.taskId;
139 return rti;
Winson Chung61c9e5a2017-10-11 10:39:32 -0700140 }
141}