161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung/* 261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * Copyright (C) 2017 The Android Open Source Project 361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * 461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * you may not use this file except in compliance with the License. 661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * You may obtain a copy of the License at 761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * 861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * 1061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * Unless required by applicable law or agreed to in writing, software 1161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 1261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * See the License for the specific language governing permissions and 1461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * limitations under the License. 1561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung */ 1661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 1761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungpackage com.android.server.am; 1861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 1961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 2061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 2161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 2261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 2361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static android.view.Display.DEFAULT_DISPLAY; 2461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 2561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static com.android.server.am.ActivityDisplay.POSITION_BOTTOM; 2661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 2761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport static org.junit.Assert.assertTrue; 2861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 2961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.app.ActivityManager.RunningTaskInfo; 3061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.content.ComponentName; 3161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.content.Context; 3261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.platform.test.annotations.Presubmit; 3361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.support.test.InstrumentationRegistry; 3461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.support.test.filters.MediumTest; 3561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.support.test.runner.AndroidJUnit4; 3661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport android.util.SparseArray; 3761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 3861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport org.junit.Before; 3961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport org.junit.Test; 4061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport org.junit.runner.RunWith; 4161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 4261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungimport java.util.ArrayList; 4361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 4461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung/** 4561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java 4661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung */ 4761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung@MediumTest 4861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung@Presubmit 4961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung@RunWith(AndroidJUnit4.class) 5061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chungpublic class RunningTasksTest extends ActivityTestsBase { 5161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 5261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung private Context mContext = InstrumentationRegistry.getContext(); 5361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung private ActivityManagerService mService; 5461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 5561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung private RunningTasks mRunningTasks; 5661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 5761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung @Before 5861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung @Override 5961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung public void setUp() throws Exception { 6061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung super.setUp(); 6161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 6261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung mService = createActivityManagerService(); 6361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung mRunningTasks = new RunningTasks(); 6461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 6561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 6661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung @Test 6761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung public void testCollectTasksByLastActiveTime() throws Exception { 6861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung // Create a number of stacks with tasks (of incrementing active time) 6961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final ActivityStackSupervisor supervisor = mService.mStackSupervisor; 7061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final SparseArray<ActivityDisplay> displays = new SparseArray<>(); 71343f65a43039036896a1d550c49f2f71fea5047cWinson Chung final ActivityDisplay display = new TestActivityDisplay(supervisor, DEFAULT_DISPLAY); 7261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung displays.put(DEFAULT_DISPLAY, display); 7361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 7461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final int numStacks = 2; 7561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) { 7661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final ActivityStack stack = new TestActivityStack(display, stackIndex, supervisor, 7761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true); 7861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung display.addChild(stack, POSITION_BOTTOM); 7961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 8061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 8161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final int numTasks = 10; 8261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung int activeTime = 0; 8361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung for (int i = 0; i < numTasks; i++) { 8461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung createTask(display.getChildAt(i % numStacks), ".Task" + i, i, activeTime++); 8561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 8661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 8761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung // Ensure that the latest tasks were returned in order of decreasing last active time, 8861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung // collected from all tasks across all the stacks 8961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final int numFetchTasks = 5; 9061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung ArrayList<RunningTaskInfo> tasks = new ArrayList<>(); 9161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, 9261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung displays, -1 /* callingUid */, true /* allowed */); 9361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung assertTrue(tasks.size() == numFetchTasks); 9461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung for (int i = 0; i < numFetchTasks; i++) { 9561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung assertTrue(tasks.get(i).id == (numTasks - i - 1)); 9661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 9761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 9861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung // Ensure that requesting more than the total number of tasks only returns the subset 9961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung // and does not crash 10061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung tasks.clear(); 10161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, 10261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung displays, -1 /* callingUid */, true /* allowed */); 10361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung assertTrue(tasks.size() == numTasks); 10461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung for (int i = 0; i < numTasks; i++) { 10561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung assertTrue(tasks.get(i).id == (numTasks - i - 1)); 10661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 10761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 10861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung 10961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung /** 11061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung * Create a task with a single activity in it, with the given last active time. 11161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung */ 11261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung private TaskRecord createTask(ActivityStack stack, String className, int taskId, 11361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung int lastActiveTime) { 11461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final TaskRecord task = new TaskBuilder(mService.mStackSupervisor) 11561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .setComponent(new ComponentName(mContext.getPackageName(), className)) 11661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .setTaskId(taskId) 11761c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .setStack(stack) 11861c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .build(); 11961c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung task.lastActiveTime = lastActiveTime; 12061c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung final ActivityRecord activity = new ActivityBuilder(mService) 12161c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .setTask(task) 12261c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity")) 12361c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung .build(); 12461c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung return task; 12561c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung } 12661c9e5a62933a9fe933ce5e6a4343cd0fbd8a532Winson Chung}