From efbec5ac8b4039e20c68fbac47948b444a77605e 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 Merged-In: Ifb7f89e7fde47155eb987161fbbe30e7144103ab 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 8e149a98af0eb..b2ff01471e3a2 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; @@ -888,4 +889,17 @@ interface IWindowManager * @see android.window.WindowProviderService#getLaunchedDisplayId */ int getImeDisplayId(); + + /** + * 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 776a65db365f6..576fa83f81151 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; @@ -266,6 +267,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; @@ -755,6 +757,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; @@ -8759,4 +8766,22 @@ public class WindowManagerService extends IWindowManager.Stub : DEFAULT_DISPLAY; } } + + @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; + } }