333 lines
12 KiB
Java
333 lines
12 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2020 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.window;
|
||
|
|
||
|
import android.annotation.BinderThread;
|
||
|
import android.annotation.CallSuper;
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.Nullable;
|
||
|
import android.annotation.RequiresPermission;
|
||
|
import android.annotation.SuppressLint;
|
||
|
import android.annotation.TestApi;
|
||
|
import android.app.ActivityManager;
|
||
|
import android.app.CameraCompatTaskInfo.CameraCompatControlState;
|
||
|
import android.os.IBinder;
|
||
|
import android.os.RemoteException;
|
||
|
import android.view.SurfaceControl;
|
||
|
|
||
|
import com.android.internal.annotations.VisibleForTesting;
|
||
|
|
||
|
import java.util.List;
|
||
|
import java.util.concurrent.Executor;
|
||
|
|
||
|
/**
|
||
|
* Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
|
||
|
* @hide
|
||
|
*/
|
||
|
@TestApi
|
||
|
public class TaskOrganizer extends WindowOrganizer {
|
||
|
|
||
|
private final ITaskOrganizerController mTaskOrganizerController;
|
||
|
// Callbacks WM Core are posted on this executor if it isn't null, otherwise direct calls are
|
||
|
// made on the incoming binder call.
|
||
|
private final Executor mExecutor;
|
||
|
|
||
|
public TaskOrganizer() {
|
||
|
this(null /*taskOrganizerController*/, null /*executor*/);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@VisibleForTesting
|
||
|
public TaskOrganizer(ITaskOrganizerController taskOrganizerController, Executor executor) {
|
||
|
mExecutor = executor != null ? executor : Runnable::run;
|
||
|
mTaskOrganizerController = taskOrganizerController != null
|
||
|
? taskOrganizerController : getController();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Register a TaskOrganizer to manage tasks as they enter a supported windowing mode.
|
||
|
*
|
||
|
* @return a list of the tasks that should be managed by the organizer, not including tasks
|
||
|
* created via {@link #createRootTask}.
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@CallSuper
|
||
|
@NonNull
|
||
|
public List<TaskAppearedInfo> registerOrganizer() {
|
||
|
try {
|
||
|
return mTaskOrganizerController.registerTaskOrganizer(mInterface).getList();
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Unregisters a previously registered task organizer. */
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@CallSuper
|
||
|
public void unregisterOrganizer() {
|
||
|
try {
|
||
|
mTaskOrganizerController.unregisterTaskOrganizer(mInterface);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called when a Task is starting and the system would like to show a UI to indicate that an
|
||
|
* application is starting. The client is responsible to add/remove the starting window if it
|
||
|
* has create a starting window for the Task.
|
||
|
*
|
||
|
* @param info The information about the Task that's available
|
||
|
* @hide
|
||
|
*/
|
||
|
@BinderThread
|
||
|
public void addStartingWindow(@NonNull StartingWindowInfo info) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the Task want to remove the starting window.
|
||
|
* @param removalInfo The information used to remove the starting window.
|
||
|
* @hide
|
||
|
*/
|
||
|
@BinderThread
|
||
|
public void removeStartingWindow(@NonNull StartingWindowRemovalInfo removalInfo) {}
|
||
|
|
||
|
/**
|
||
|
* Called when the Task want to copy the splash screen.
|
||
|
*/
|
||
|
@BinderThread
|
||
|
public void copySplashScreenView(int taskId) {}
|
||
|
|
||
|
/**
|
||
|
* Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
|
||
|
* removed the splash screen view.
|
||
|
* @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
|
||
|
* @see SplashScreenView#remove()
|
||
|
*/
|
||
|
@BinderThread
|
||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called when a task with the registered windowing mode can be controlled by this task
|
||
|
* organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
|
||
|
* to show this task.
|
||
|
*/
|
||
|
@BinderThread
|
||
|
public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo,
|
||
|
@NonNull SurfaceControl leash) {}
|
||
|
|
||
|
@BinderThread
|
||
|
public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
|
||
|
|
||
|
@BinderThread
|
||
|
public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
|
||
|
|
||
|
@BinderThread
|
||
|
public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
|
||
|
|
||
|
/** @hide */
|
||
|
@BinderThread
|
||
|
public void onImeDrawnOnTask(int taskId) {}
|
||
|
|
||
|
/**
|
||
|
* Creates a persistent root task in WM for a particular windowing-mode.
|
||
|
* @param displayId The display to create the root task on.
|
||
|
* @param windowingMode Windowing mode to put the root task in.
|
||
|
* @param launchCookie Launch cookie to associate with the task so that is can be identified
|
||
|
* when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
|
||
|
* @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
|
||
|
* @hide
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
|
||
|
boolean removeWithTaskOrganizer) {
|
||
|
try {
|
||
|
mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie,
|
||
|
removeWithTaskOrganizer);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a persistent root task in WM for a particular windowing-mode.
|
||
|
* @param displayId The display to create the root task on.
|
||
|
* @param windowingMode Windowing mode to put the root task in.
|
||
|
* @param launchCookie Launch cookie to associate with the task so that is can be identified
|
||
|
* when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@Nullable
|
||
|
public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
|
||
|
createRootTask(displayId, windowingMode, launchCookie, false /* removeWithTaskOrganizer */);
|
||
|
}
|
||
|
|
||
|
/** Deletes a persistent root task in WM */
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
public boolean deleteRootTask(@NonNull WindowContainerToken task) {
|
||
|
try {
|
||
|
return mTaskOrganizerController.deleteRootTask(task);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Gets direct child tasks (ordered from top-to-bottom) */
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@Nullable
|
||
|
@SuppressLint("NullableCollection")
|
||
|
public List<ActivityManager.RunningTaskInfo> getChildTasks(
|
||
|
@NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
|
||
|
try {
|
||
|
return mTaskOrganizerController.getChildTasks(parent, activityTypes);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Gets all root tasks on a display (ordered from top-to-bottom) */
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@Nullable
|
||
|
@SuppressLint("NullableCollection")
|
||
|
public List<ActivityManager.RunningTaskInfo> getRootTasks(
|
||
|
int displayId, @NonNull int[] activityTypes) {
|
||
|
try {
|
||
|
return mTaskOrganizerController.getRootTasks(displayId, activityTypes);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Get the {@link WindowContainerToken} of the task which contains the current ime target */
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
@Nullable
|
||
|
public WindowContainerToken getImeTarget(int display) {
|
||
|
try {
|
||
|
return mTaskOrganizerController.getImeTarget(display);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Requests that the given task organizer is notified when back is pressed on the root activity
|
||
|
* of one of its controlled tasks.
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task,
|
||
|
boolean interceptBackPressed) {
|
||
|
try {
|
||
|
mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Restarts the top activity in the given task by killing its process if it is visible.
|
||
|
* @hide
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
public void restartTaskTopActivityProcessIfVisible(@NonNull WindowContainerToken task) {
|
||
|
try {
|
||
|
mTaskOrganizerController.restartTaskTopActivityProcessIfVisible(task);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates a state of camera compat control for stretched issues in the viewfinder.
|
||
|
* @hide
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
public void updateCameraCompatControlState(@NonNull WindowContainerToken task,
|
||
|
@CameraCompatControlState int state) {
|
||
|
try {
|
||
|
mTaskOrganizerController.updateCameraCompatControlState(task, state);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the executor to run callbacks on.
|
||
|
* @hide
|
||
|
*/
|
||
|
@NonNull
|
||
|
public Executor getExecutor() {
|
||
|
return mExecutor;
|
||
|
}
|
||
|
|
||
|
private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
|
||
|
@Override
|
||
|
public void addStartingWindow(StartingWindowInfo windowInfo) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(windowInfo));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.removeStartingWindow(removalInfo));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void copySplashScreenView(int taskId) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onAppSplashScreenViewRemoved(taskId));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onTaskVanished(taskInfo));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onTaskInfoChanged(info));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onBackPressedOnTaskRoot(info));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onImeDrawnOnTask(int taskId) {
|
||
|
mExecutor.execute(() -> TaskOrganizer.this.onImeDrawnOnTask(taskId));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
|
||
|
private ITaskOrganizerController getController() {
|
||
|
try {
|
||
|
return getWindowOrganizerController().getTaskOrganizerController();
|
||
|
} catch (RemoteException e) {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|