1 /*
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 
17 package com.android.server.am;
18 
19 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21 
22 import android.app.ActivityManager.RunningTaskInfo;
23 import android.app.WindowConfiguration.ActivityType;
24 import android.app.WindowConfiguration.WindowingMode;
25 import android.util.SparseArray;
26 
27 import java.util.ArrayList;
28 import java.util.Comparator;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.TreeSet;
32 
33 /**
34  * Class for resolving the set of running tasks in the system.
35  */
36 class RunningTasks {
37 
38     // Comparator to sort by last active time (descending)
39     private static final Comparator<TaskRecord> LAST_ACTIVE_TIME_COMPARATOR =
40             (o1, o2) -> Long.signum(o2.lastActiveTime - o1.lastActiveTime);
41 
42     private final TaskRecord.TaskActivitiesReport mTmpReport =
43             new TaskRecord.TaskActivitiesReport();
44     private final TreeSet<TaskRecord> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR);
45     private final ArrayList<TaskRecord> mTmpStackTasks = new ArrayList<>();
46 
getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, SparseArray<ActivityDisplay> activityDisplays, int callingUid, boolean allowed)47     void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
48             @WindowingMode int ignoreWindowingMode, SparseArray<ActivityDisplay> activityDisplays,
49             int callingUid, boolean allowed) {
50         // Return early if there are no tasks to fetch
51         if (maxNum <= 0) {
52             return;
53         }
54 
55         // Gather all of the tasks across all of the tasks, and add them to the sorted set
56         mTmpSortedSet.clear();
57         mTmpStackTasks.clear();
58         final int numDisplays = activityDisplays.size();
59         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
60             final ActivityDisplay display = activityDisplays.valueAt(displayNdx);
61             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
62                 final ActivityStack stack = display.getChildAt(stackNdx);
63                 stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode,
64                         callingUid, allowed);
65                 for (int i = mTmpStackTasks.size() - 1; i >= 0; i--) {
66                     mTmpSortedSet.addAll(mTmpStackTasks);
67                 }
68             }
69         }
70 
71         // Take the first {@param maxNum} tasks and create running task infos for them
72         final Iterator<TaskRecord> iter = mTmpSortedSet.iterator();
73         while (iter.hasNext()) {
74             if (maxNum == 0) {
75                 break;
76             }
77 
78             final TaskRecord task = iter.next();
79             list.add(createRunningTaskInfo(task));
80             maxNum--;
81         }
82     }
83 
84     /**
85      * Constructs a {@link RunningTaskInfo} from a given {@param task}.
86      */
createRunningTaskInfo(TaskRecord task)87     private RunningTaskInfo createRunningTaskInfo(TaskRecord task) {
88         task.getNumRunningActivities(mTmpReport);
89 
90         final RunningTaskInfo ci = new RunningTaskInfo();
91         ci.id = task.taskId;
92         ci.stackId = task.getStackId();
93         ci.baseActivity = mTmpReport.base.intent.getComponent();
94         ci.topActivity = mTmpReport.top.intent.getComponent();
95         ci.lastActiveTime = task.lastActiveTime;
96         ci.description = task.lastDescription;
97         ci.numActivities = mTmpReport.numActivities;
98         ci.numRunning = mTmpReport.numRunning;
99         ci.supportsSplitScreenMultiWindow = task.supportsSplitScreenWindowingMode();
100         ci.resizeMode = task.mResizeMode;
101         ci.configuration.setTo(task.getConfiguration());
102         return ci;
103     }
104 }
105