1 /* 2 * Copyright (C) 2018 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.wm; 18 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 20 import static com.android.server.wm.RunningTasks.FLAG_ALLOWED; 21 import static com.android.server.wm.RunningTasks.FLAG_CROSS_USERS; 22 import static com.android.server.wm.RunningTasks.FLAG_KEEP_INTENT_EXTRA; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertNotNull; 28 import static org.junit.Assert.assertTrue; 29 30 import android.app.ActivityManager.RunningTaskInfo; 31 import android.content.ComponentName; 32 import android.os.Bundle; 33 import android.platform.test.annotations.Presubmit; 34 import android.util.ArraySet; 35 36 import androidx.test.filters.MediumTest; 37 38 import com.google.common.truth.Correspondence; 39 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 44 import java.util.ArrayList; 45 46 /** 47 * Build/Install/Run: 48 * atest WmTests:RunningTasksTest 49 */ 50 @MediumTest 51 @Presubmit 52 @RunWith(WindowTestRunner.class) 53 public class RunningTasksTest extends WindowTestsBase { 54 55 private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>(); 56 private static final Correspondence<RunningTaskInfo, Integer> TASKINFO_HAS_ID = 57 Correspondence.transforming((RunningTaskInfo t) -> t.taskId, "has id"); 58 59 60 private RunningTasks mRunningTasks; 61 62 @Before setUp()63 public void setUp() throws Exception { 64 mRunningTasks = new RunningTasks(); 65 } 66 67 @Test testTaskInfo_expectNoExtrasByDefault()68 public void testTaskInfo_expectNoExtrasByDefault() { 69 final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); 70 final int numTasks = 10; 71 for (int i = 0; i < numTasks; i++) { 72 final Task stack = new TaskBuilder(mSupervisor) 73 .setDisplay(display) 74 .setOnTop(true) 75 .build(); 76 final Bundle data = new Bundle(); 77 data.putInt("key", 100); 78 createTask(stack, ".Task" + i, i, data); 79 } 80 81 final int numFetchTasks = 5; 82 final ArrayList<RunningTaskInfo> tasks = new ArrayList<>(); 83 mRunningTasks.getTasks(numFetchTasks, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, 84 mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); 85 assertThat(tasks).hasSize(numFetchTasks); 86 for (int i = 0; i < tasks.size(); i++) { 87 final Bundle extras = tasks.get(i).baseIntent.getExtras(); 88 assertTrue(extras == null || extras.isEmpty()); 89 } 90 } 91 92 @Test testTaskInfo_expectExtrasWithKeepExtraFlag()93 public void testTaskInfo_expectExtrasWithKeepExtraFlag() { 94 final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); 95 final int numTasks = 10; 96 for (int i = 0; i < numTasks; i++) { 97 final Task stack = new TaskBuilder(mSupervisor) 98 .setDisplay(display) 99 .setOnTop(true) 100 .build(); 101 final Bundle data = new Bundle(); 102 data.putInt("key", 100); 103 createTask(stack, ".Task" + i, i, data); 104 } 105 106 final int numFetchTasks = 5; 107 final ArrayList<RunningTaskInfo> tasks = new ArrayList<>(); 108 mRunningTasks.getTasks(numFetchTasks, tasks, 109 FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, 110 mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); 111 assertThat(tasks).hasSize(numFetchTasks); 112 for (int i = 0; i < tasks.size(); i++) { 113 final Bundle extras = tasks.get(i).baseIntent.getExtras(); 114 assertNotNull(extras); 115 assertEquals(100, extras.getInt("key")); 116 } 117 } 118 119 @Test testGetTasksSortByFocusAndVisibility()120 public void testGetTasksSortByFocusAndVisibility() { 121 final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); 122 final Task stack = new TaskBuilder(mSupervisor) 123 .setDisplay(display) 124 .setOnTop(true) 125 .build(); 126 127 final int numTasks = 10; 128 final ArrayList<Task> tasks = new ArrayList<>(); 129 for (int i = 0; i < numTasks; i++) { 130 final Task task = createTask(stack, ".Task" + i, i, null); 131 doReturn(false).when(task).isVisible(); 132 tasks.add(task); 133 } 134 135 final Task focusedTask = tasks.get(numTasks - 1); 136 doReturn(true).when(focusedTask).isVisible(); 137 display.mFocusedApp = focusedTask.getTopNonFinishingActivity(); 138 139 final Task visibleTaskTop = tasks.get(numTasks - 2); 140 doReturn(true).when(visibleTaskTop).isVisible(); 141 142 final Task visibleTaskBottom = tasks.get(numTasks - 3); 143 doReturn(true).when(visibleTaskBottom).isVisible(); 144 145 // Ensure that the focused Task is on top, visible tasks below, then invisible tasks. 146 final int numFetchTasks = 5; 147 final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>(); 148 mRunningTasks.getTasks(numFetchTasks, fetchTasks, 149 FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, 150 mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); 151 assertThat(fetchTasks).hasSize(numFetchTasks); 152 for (int i = 0; i < numFetchTasks; i++) { 153 assertEquals(numTasks - i - 1, fetchTasks.get(i).id); 154 } 155 156 // Ensure that requesting more than the total number of tasks only returns the subset 157 // and does not crash 158 fetchTasks.clear(); 159 mRunningTasks.getTasks(100, fetchTasks, 160 FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, 161 mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); 162 assertThat(fetchTasks).hasSize(numTasks); 163 for (int i = 0; i < numTasks; i++) { 164 assertEquals(numTasks - i - 1, fetchTasks.get(i).id); 165 } 166 } 167 168 /** 169 * Create a task with a single activity in it. 170 */ createTask(Task stack, String className, int taskId, Bundle extras)171 private Task createTask(Task stack, String className, int taskId, Bundle extras) { 172 final Task task = new TaskBuilder(mAtm.mTaskSupervisor) 173 .setComponent(new ComponentName(mContext.getPackageName(), className)) 174 .setTaskId(taskId) 175 .setParentTask(stack) 176 .build(); 177 final ActivityRecord activity = new ActivityBuilder(mAtm) 178 .setTask(task) 179 .setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity")) 180 .setIntentExtras(extras) 181 .build(); 182 task.intent = activity.intent; 183 return task; 184 } 185 186 @Test testMultipleDisplays()187 public void testMultipleDisplays() { 188 final DisplayContent display0 = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); 189 final DisplayContent display1 = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); 190 final int numTasks = 10; 191 final ArrayList<Task> tasks = new ArrayList<>(); 192 for (int i = 0; i < numTasks; i++) { 193 final Task stack = new TaskBuilder(mSupervisor) 194 .setDisplay(i % 2 == 0 ? display0 : display1) 195 .setOnTop(true) 196 .build(); 197 final Task task = createTask(stack, ".Task" + i, i, null); 198 tasks.add(task); 199 } 200 201 final int numFetchTasks = numTasks; 202 final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>(); 203 204 mRunningTasks.getTasks(numFetchTasks, fetchTasks, 205 FLAG_ALLOWED | FLAG_CROSS_USERS, 206 mAtm.getRecentTasks(), display0, -1 /* callingUid */, PROFILE_IDS); 207 assertThat(fetchTasks).hasSize(numTasks / 2); 208 assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID) 209 .containsExactly(0, 2, 4, 6, 8); 210 211 fetchTasks.clear(); 212 mRunningTasks.getTasks(numFetchTasks, fetchTasks, 213 FLAG_ALLOWED | FLAG_CROSS_USERS, 214 mAtm.getRecentTasks(), display1, -1 /* callingUid */, PROFILE_IDS); 215 assertThat(fetchTasks).hasSize(numTasks / 2); 216 assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID) 217 .containsExactly(1, 3, 5, 7, 9); 218 219 fetchTasks.clear(); 220 mRunningTasks.getTasks(numFetchTasks, fetchTasks, 221 FLAG_ALLOWED | FLAG_CROSS_USERS, 222 mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); 223 assertThat(fetchTasks).hasSize(numTasks); 224 assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID) 225 .containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); 226 } 227 } 228