1 /* 2 * Copyright (C) 2020 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.car.carlauncher; 18 19 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 20 21 import static com.android.car.carlauncher.CarLauncher.TAG; 22 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; 23 24 import android.annotation.UiContext; 25 import android.app.ActivityTaskManager; 26 import android.app.TaskInfo; 27 import android.content.Context; 28 import android.util.Slog; 29 import android.window.TaskAppearedInfo; 30 31 import com.android.launcher3.icons.IconProvider; 32 import com.android.wm.shell.ShellTaskOrganizer; 33 import com.android.wm.shell.TaskView; 34 import com.android.wm.shell.TaskViewFactory; 35 import com.android.wm.shell.TaskViewFactoryController; 36 import com.android.wm.shell.common.HandlerExecutor; 37 import com.android.wm.shell.common.SyncTransactionQueue; 38 import com.android.wm.shell.common.TransactionPool; 39 import com.android.wm.shell.fullscreen.FullscreenTaskListener; 40 import com.android.wm.shell.startingsurface.StartingWindowController; 41 import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm; 42 43 import java.util.List; 44 import java.util.Optional; 45 import java.util.function.Consumer; 46 47 public final class TaskViewManager { 48 private static final boolean DBG = false; 49 50 private final Context mContext; 51 private final HandlerExecutor mExecutor; 52 private final TaskViewFactory mTaskViewFactory; 53 private final ShellTaskOrganizer mTaskOrganizer; 54 TaskViewManager(@iContext Context context, HandlerExecutor handlerExecutor)55 public TaskViewManager(@UiContext Context context, HandlerExecutor handlerExecutor) { 56 mContext = context; 57 mExecutor = handlerExecutor; 58 mTaskOrganizer = new ShellTaskOrganizer(mExecutor, mContext); 59 mTaskViewFactory = initWmShell(); 60 if (DBG) Slog.d(TAG, "TaskViewManager.create"); 61 } 62 initWmShell()63 private TaskViewFactory initWmShell() { 64 TransactionPool transactionPool = new TransactionPool(); 65 SyncTransactionQueue syncQueue = new SyncTransactionQueue(transactionPool, mExecutor); 66 FullscreenTaskListener fullscreenTaskListener = new FullscreenTaskListener(syncQueue, 67 Optional.empty()); 68 mTaskOrganizer.addListenerForType(fullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN); 69 StartingWindowController startingController = 70 new StartingWindowController(mContext, mExecutor, 71 new PhoneStartingWindowTypeAlgorithm(), new IconProvider(mContext), 72 transactionPool); 73 mTaskOrganizer.initStartingWindow(startingController); 74 List<TaskAppearedInfo> taskAppearedInfos = mTaskOrganizer.registerOrganizer(); 75 cleanUpExistingTaskViewTasks(taskAppearedInfos); 76 77 return new TaskViewFactoryController(mTaskOrganizer, mExecutor, syncQueue) 78 .asTaskViewFactory(); 79 } 80 release()81 void release() { 82 if (DBG) Slog.d(TAG, "TaskViewManager.release"); 83 mTaskOrganizer.unregisterOrganizer(); 84 } 85 createTaskView(Consumer<TaskView> onCreate)86 void createTaskView(Consumer<TaskView> onCreate) { 87 mTaskViewFactory.create(mContext, mExecutor, onCreate); 88 } 89 cleanUpExistingTaskViewTasks(List<TaskAppearedInfo> taskAppearedInfos)90 private static void cleanUpExistingTaskViewTasks(List<TaskAppearedInfo> taskAppearedInfos) { 91 ActivityTaskManager atm = ActivityTaskManager.getInstance(); 92 for (TaskAppearedInfo taskAppearedInfo : taskAppearedInfos) { 93 TaskInfo taskInfo = taskAppearedInfo.getTaskInfo(); 94 // Only TaskView tasks have WINDOWING_MODE_MULTI_WINDOW. 95 if (taskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) { 96 if (DBG) Slog.d(TAG, "Found the dangling task, removing: " + taskInfo.taskId); 97 atm.removeTask(taskInfo.taskId); 98 } 99 } 100 } 101 } 102