1 /* 2 * Copyright (C) 2024 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.wm.shell.taskview; 18 19 import android.annotation.Nullable; 20 import android.graphics.Rect; 21 import android.window.WindowContainerToken; 22 23 import java.lang.ref.WeakReference; 24 import java.util.ArrayList; 25 26 /** 27 * Keeps track of all TaskViews known by Shell. This is separated into its own object so that 28 * different TaskView managers can share state. 29 */ 30 public class TaskViewRepository { 31 /** 32 * The latest visibility and bounds state that has been requested for 33 * a {@link TaskViewTaskController}. 34 */ 35 public static class TaskViewState { 36 final WeakReference<TaskViewTaskController> mTaskView; 37 public boolean mVisible; 38 public Rect mBounds = new Rect(); 39 TaskViewState(TaskViewTaskController taskView)40 TaskViewState(TaskViewTaskController taskView) { 41 mTaskView = new WeakReference<>(taskView); 42 } 43 getTaskView()44 @Nullable public TaskViewTaskController getTaskView() { 45 return mTaskView.get(); 46 } 47 } 48 49 /** 50 * List of tracked TaskViews 51 */ 52 private final ArrayList<TaskViewState> mTaskViews = new ArrayList<>(); 53 findAndPrune(TaskViewTaskController tv)54 private int findAndPrune(TaskViewTaskController tv) { 55 for (int i = mTaskViews.size() - 1; i >= 0; --i) { 56 final TaskViewTaskController key = mTaskViews.get(i).mTaskView.get(); 57 if (key == null) { 58 mTaskViews.remove(i); 59 continue; 60 } 61 if (key != tv) continue; 62 return i; 63 } 64 return -1; 65 } 66 67 /** @return if the repository is tracking {@param tv}. */ contains(TaskViewTaskController tv)68 public boolean contains(TaskViewTaskController tv) { 69 return findAndPrune(tv) >= 0; 70 } 71 72 /** Start tracking {@param tv}. */ add(TaskViewTaskController tv)73 public void add(TaskViewTaskController tv) { 74 if (contains(tv)) return; 75 mTaskViews.add(new TaskViewState(tv)); 76 } 77 78 /** Remove {@param tv} from tracking. */ remove(TaskViewTaskController tv)79 public void remove(TaskViewTaskController tv) { 80 int idx = findAndPrune(tv); 81 if (idx < 0) return; 82 mTaskViews.remove(idx); 83 } 84 85 /** @return whether there are any TaskViews */ isEmpty()86 public boolean isEmpty() { 87 if (mTaskViews.isEmpty()) return true; 88 for (int i = mTaskViews.size() - 1; i >= 0; --i) { 89 if (mTaskViews.get(i).mTaskView.get() != null) continue; 90 mTaskViews.remove(i); 91 } 92 return mTaskViews.isEmpty(); 93 } 94 95 /** @return the state of {@param tv} if tracked, {@code null} otherwise. */ 96 @Nullable byTaskView(TaskViewTaskController tv)97 public TaskViewState byTaskView(TaskViewTaskController tv) { 98 int idx = findAndPrune(tv); 99 if (idx < 0) return null; 100 return mTaskViews.get(idx); 101 } 102 103 /** 104 * @return the state of the taskview containing {@param token} if tracked, 105 * {@code null} otherwise. 106 */ 107 @Nullable byToken(WindowContainerToken token)108 public TaskViewState byToken(WindowContainerToken token) { 109 for (int i = mTaskViews.size() - 1; i >= 0; --i) { 110 final TaskViewTaskController key = mTaskViews.get(i).mTaskView.get(); 111 if (key == null) { 112 mTaskViews.remove(i); 113 continue; 114 } 115 if (key.getTaskInfo() == null) continue; 116 if (key.getTaskInfo().token.equals(token)) { 117 return mTaskViews.get(i); 118 } 119 } 120 return null; 121 } 122 } 123