From d95860a707c363cc51f3ad5c16cebe9affbceb3f Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Fri, 1 Oct 2021 16:08:00 +0200 Subject: [PATCH] Add API to allow SysUI/launcher to customize legacy task transition animations Launcher needs to be able to customize the task transition to: 1. set the background color during task transitions to the taskbar color when the taskbar is visible. and, temporarily, at least until tasks have rounded corners rather than being an overlay in the taskbar, we need: 2. a way to specify how much to crop the task by so that the task's rounded corners are visible above the taskbar during animation 3. a way to specify how much to crop the taskbar by so that the taskbar's rounded corners overlay is not visible over the tasks during the animation Test: None Bug: 200675009 Bug: 196387647 Change-Id: Ifb7f89e7fde47155eb987161fbbe30e7144103ab --- core/java/android/view/IWindowManager.aidl | 14 +++ .../java/android/view/TaskTransitionSpec.aidl | 20 ++++ .../java/android/view/TaskTransitionSpec.java | 91 +++++++++++++++++++ .../server/wm/WindowManagerService.java | 25 +++++ 4 files changed, 150 insertions(+) create mode 100644 core/java/android/view/TaskTransitionSpec.aidl create mode 100644 core/java/android/view/TaskTransitionSpec.java diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index f7d32d08c3821..2f8cadcaf517e 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -61,6 +61,7 @@ import android.view.InputChannel; import android.view.InputDevice; import android.view.IInputFilter; import android.view.AppTransitionAnimationSpec; +import android.view.TaskTransitionSpec; import android.view.WindowContentFrameStats; import android.view.WindowManager; import android.view.SurfaceControl; @@ -884,4 +885,17 @@ interface IWindowManager * @hide */ void setTaskSnapshotEnabled(boolean enabled); + + /** + * Customized the task transition animation with a task transition spec. + * + * @param spec the spec that will be used to customize the task animations + */ + void setTaskTransitionSpec(in TaskTransitionSpec spec); + + /** + * Clears any task transition spec that has been previously set and + * reverts to using the default task transition with no spec changes. + */ + void clearTaskTransitionSpec(); } diff --git a/core/java/android/view/TaskTransitionSpec.aidl b/core/java/android/view/TaskTransitionSpec.aidl new file mode 100644 index 0000000000000..08af15c3f9339 --- /dev/null +++ b/core/java/android/view/TaskTransitionSpec.aidl @@ -0,0 +1,20 @@ +/* +** Copyright 2021, 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.view; + +/** @hide */ +parcelable TaskTransitionSpec; diff --git a/core/java/android/view/TaskTransitionSpec.java b/core/java/android/view/TaskTransitionSpec.java new file mode 100644 index 0000000000000..e90d6e10f846f --- /dev/null +++ b/core/java/android/view/TaskTransitionSpec.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2021 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.view; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArraySet; + +import java.util.Set; + +/** + * Holds information about how to execute task transition animations. + * + * This class is intended to be used with IWindowManager.setTaskTransitionSpec methods when + * we want more customization over the way default task transitions are executed. + * + * @hide + */ +public class TaskTransitionSpec implements Parcelable { + /** + * The background color to use during task animations (override the default background color) + */ + public final int backgroundColor; + + /** + * TEMPORARY FIELD (b/202383002) + * TODO: Remove once we use surfaceflinger rounded corners on tasks rather than taskbar overlays + * + * A set of {@InsetsState.InternalInsetsType}s we want to use as the source to set the bounds + * of the task during the animation. Used to make sure that task animate above the taskbar. + * Will also be used to crop to the frame size of the inset source to the inset size to prevent + * the taskbar rounded corners overlay from being invisible during task transition animation. + */ + public final Set animationBoundInsets; + + public TaskTransitionSpec( + int backgroundColor, Set animationBoundInsets) { + this.backgroundColor = backgroundColor; + this.animationBoundInsets = animationBoundInsets; + } + + public TaskTransitionSpec(Parcel in) { + this.backgroundColor = in.readInt(); + + int animationBoundInsetsSize = in.readInt(); + this.animationBoundInsets = new ArraySet<>(animationBoundInsetsSize); + for (int i = 0; i < animationBoundInsetsSize; i++) { + this.animationBoundInsets.add(in.readInt()); + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(backgroundColor); + + dest.writeInt(animationBoundInsets.size()); + for (int insetType : animationBoundInsets) { + dest.writeInt(insetType); + } + } + + public static final @android.annotation.NonNull Parcelable.Creator + CREATOR = new Parcelable.Creator() { + public TaskTransitionSpec createFromParcel(Parcel in) { + return new TaskTransitionSpec(in); + } + + public TaskTransitionSpec[] newArray(int size) { + return new TaskTransitionSpec[size]; + } + }; +} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f11fa16557129..c5202dedb46cd 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.INPUT_CONSUMER; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; +import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.Manifest.permission.MANAGE_APP_TOKENS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; @@ -268,6 +269,7 @@ import android.view.ScrollCaptureResponse; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; +import android.view.TaskTransitionSpec; import android.view.View; import android.view.WindowContentFrameStats; import android.view.WindowInsets; @@ -756,6 +758,11 @@ public class WindowManagerService extends IWindowManager.Stub */ final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper()); + /** + * Used during task transitions to allow SysUI and launcher to customize task transitions. + */ + TaskTransitionSpec mTaskTransitionSpec; + boolean mHardKeyboardAvailable; WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; SettingsObserver mSettingsObserver; @@ -8714,4 +8721,22 @@ public class WindowManagerService extends IWindowManager.Stub public void setTaskSnapshotEnabled(boolean enabled) { mTaskSnapshotController.setTaskSnapshotEnabled(enabled); } + + @Override + public void setTaskTransitionSpec(TaskTransitionSpec spec) { + if (!checkCallingPermission(MANAGE_ACTIVITY_TASKS, "setTaskTransitionSpec()")) { + throw new SecurityException("Requires MANAGE_ACTIVITY_TASKS permission"); + } + + mTaskTransitionSpec = spec; + } + + @Override + public void clearTaskTransitionSpec() { + if (!checkCallingPermission(MANAGE_ACTIVITY_TASKS, "clearTaskTransitionSpec()")) { + throw new SecurityException("Requires MANAGE_ACTIVITY_TASKS permission"); + } + + mTaskTransitionSpec = null; + } }