1 /* 2 * Copyright (C) 2023 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 android.car.app; 18 19 import android.annotation.Nullable; 20 import android.app.ActivityManager; 21 import android.view.SurfaceControl; 22 23 import java.util.Iterator; 24 import java.util.LinkedHashMap; 25 26 /** 27 * Methods in this class ar not thread safe and the caller should hold the lock before calling them. 28 */ 29 final class RootTaskStackManager { 30 private ActivityManager.RunningTaskInfo mRootTask; 31 private final LinkedHashMap<Integer, ActivityManager.RunningTaskInfo> mChildrenTaskStack = 32 new LinkedHashMap<>(); 33 taskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash)34 void taskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { 35 // The first call to onTaskAppeared() is always for the root-task. 36 if (mRootTask == null) { 37 mRootTask = taskInfo; 38 return; 39 } 40 41 mChildrenTaskStack.put(taskInfo.taskId, taskInfo); 42 } 43 taskInfoChanged(ActivityManager.RunningTaskInfo taskInfo)44 void taskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { 45 if (mRootTask == null || mRootTask.taskId == taskInfo.taskId) { 46 return; 47 } 48 if (taskInfo.isVisible() && mChildrenTaskStack.containsKey(taskInfo.taskId)) { 49 // Remove the task and insert again so that it jumps to the end of 50 // the queue. 51 mChildrenTaskStack.remove(taskInfo.taskId); 52 mChildrenTaskStack.put(taskInfo.taskId, taskInfo); 53 } 54 } 55 taskVanished(ActivityManager.RunningTaskInfo taskInfo)56 void taskVanished(ActivityManager.RunningTaskInfo taskInfo) { 57 if (mRootTask == null || mRootTask.taskId == taskInfo.taskId) { 58 return; 59 } 60 61 if (mChildrenTaskStack.containsKey(taskInfo.taskId)) { 62 mChildrenTaskStack.remove(taskInfo.taskId); 63 } 64 } 65 66 @Nullable getTopTask()67 ActivityManager.RunningTaskInfo getTopTask() { 68 if (mChildrenTaskStack.isEmpty()) { 69 return null; 70 } 71 ActivityManager.RunningTaskInfo topTask = null; 72 Iterator<ActivityManager.RunningTaskInfo> iterator = mChildrenTaskStack.values().iterator(); 73 while (iterator.hasNext()) { 74 topTask = iterator.next(); 75 } 76 return topTask; 77 } 78 } 79