Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4ca5286 authored by Vadim Caen's avatar Vadim Caen
Browse files

Server infrastructure for back nav animation (BackNav 1/n)

This CL introduces the BackNavigationController that gathers the
required data to be passed to WMShell to create the back animation

These data are passed via the BackNavigationInfo Parcelable.

The CL also containes a basic screenshoting mechanism as a temporary
solution until a proper screenshoting infrastructure is created
(b/207481538).

Test: atest BackNavigationControllerTests
Bug: 131727607
Change-Id: Ibd7fc78e590794daf35f7718ddfa53e7f439813b
parent 86608e36
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationAdapter;
import android.window.IWindowOrganizerController;
import android.window.BackNavigationInfo;
import android.window.SplashScreenView;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
@@ -346,7 +347,8 @@ interface IActivityTaskManager {
    void setRunningRemoteTransitionDelegate(in IApplicationThread caller);

    /**
     * Prepare the back preview in the server
     * Prepare the back navigation in the server. This setups the leashed for sysui to animate
     * the back gesture and returns the data needed for the animation.
     */
    void startBackPreview(IRemoteAnimationRunner runner);
    android.window.BackNavigationInfo startBackNavigation();
}
+3 −18
Original line number Diff line number Diff line
@@ -14,24 +14,9 @@
 * limitations under the License.
 */

package com.android.server.wm;

import android.os.SystemProperties;

/**
 * Controller to handle actions related to the back gesture on the server side.
 */
public class BackGestureController {

    private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";

    public static boolean isEnabled() {
        return SystemProperties.getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
    }
package android.window;

/**
     * Start a remote animation the back gesture.
 * @hide
 */
    public void startBackPreview() {
    }
}
parcelable BackNavigationInfo;
 No newline at end of file
+242 −0
Original line number Diff line number Diff line
/*
 * 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.window;

import static java.util.Objects.requireNonNull;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.hardware.HardwareBuffer;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteCallback;
import android.view.SurfaceControl;

/**
 * Information to be sent to SysUI about a back event.
 *
 * @hide
 */
public final class BackNavigationInfo implements Parcelable {

    /**
     * The target of the back navigation is undefined.
     */
    public static final int TYPE_UNDEFINED = -1;

    /**
     * Navigating back will close the currently visible dialog
     */
    public static final int TYPE_DIALOG_CLOSE = 0;

    /**
     * Navigating back will bring the user back to the home screen
     */
    public static final int TYPE_RETURN_TO_HOME = 1;

    /**
     * Navigating back will bring the user to the previous activity in the same Task
     */
    public static final int TYPE_CROSS_ACTIVITY = 2;

    /**
     * Navigating back will bring the user to the previous activity in the previous Task
     */
    public static final int TYPE_CROSS_TASK = 3;

    /**
     * Defines the type of back destinations a back even can lead to. This is used to define the
     * type of animation that need to be run on SystemUI.
     */
    @IntDef(prefix = "TYPE_", value = {
            TYPE_UNDEFINED,
            TYPE_DIALOG_CLOSE,
            TYPE_RETURN_TO_HOME,
            TYPE_CROSS_ACTIVITY,
            TYPE_CROSS_TASK})
    @interface BackTargetType {
    }

    private final int mType;
    @Nullable
    private final SurfaceControl mDepartingWindowContainer;
    @Nullable
    private final SurfaceControl mScreenshotSurface;
    @Nullable
    private final HardwareBuffer mScreenshotBuffer;
    @Nullable
    private final RemoteCallback mRemoteCallback;
    @Nullable
    private final WindowConfiguration mTaskWindowConfiguration;

    /**
     * Create a new {@link BackNavigationInfo} instance.
     *
     * @param type  The {@link BackTargetType} of the destination (what will be displayed after
     *              the back action)
     * @param topWindowLeash      The leash to animate away the current topWindow. The consumer
     *                            of the leash is responsible for removing it.
     * @param screenshotSurface The screenshot of the previous activity to be displayed.
     * @param screenshotBuffer      A buffer containing a screenshot used to display the activity.
     *                            See {@link  #getScreenshotHardwareBuffer()} for information
     *                            about nullity.
     * @param taskWindowConfiguration The window configuration of the Task being animated
     *                            beneath.
     * @param onBackNavigationDone   The callback to be called once the client is done with the back
     *                           preview.
     */
    public BackNavigationInfo(@BackTargetType int type,
            @Nullable SurfaceControl topWindowLeash,
            @Nullable SurfaceControl screenshotSurface,
            @Nullable HardwareBuffer screenshotBuffer,
            @Nullable WindowConfiguration taskWindowConfiguration,
            @NonNull RemoteCallback onBackNavigationDone) {
        mType = type;
        mDepartingWindowContainer = topWindowLeash;
        mScreenshotSurface = screenshotSurface;
        mScreenshotBuffer = screenshotBuffer;
        mTaskWindowConfiguration = taskWindowConfiguration;
        mRemoteCallback = onBackNavigationDone;
    }

    private BackNavigationInfo(@NonNull Parcel in) {
        mType = in.readInt();
        mDepartingWindowContainer = in.readTypedObject(SurfaceControl.CREATOR);
        mScreenshotSurface = in.readTypedObject(SurfaceControl.CREATOR);
        mScreenshotBuffer = in.readTypedObject(HardwareBuffer.CREATOR);
        mTaskWindowConfiguration = in.readTypedObject(WindowConfiguration.CREATOR);
        mRemoteCallback = requireNonNull(in.readTypedObject(RemoteCallback.CREATOR));
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mType);
        dest.writeTypedObject(mDepartingWindowContainer, flags);
        dest.writeTypedObject(mScreenshotSurface, flags);
        dest.writeTypedObject(mScreenshotBuffer, flags);
        dest.writeTypedObject(mTaskWindowConfiguration, flags);
        dest.writeTypedObject(mRemoteCallback, flags);
    }

    /**
     * Returns the type of back navigation that is about to happen.
     * @see BackTargetType
     */
    public @BackTargetType int getType() {
        return mType;
    }

    /**
     * Returns a leash to the top window container that needs to be animated. This can be null if
     * the back animation is controlled by the application.
     */
    @Nullable
    public SurfaceControl getDepartingWindowContainer() {
        return mDepartingWindowContainer;
    }

    /**
     *  Returns the {@link SurfaceControl} that should be used to display a screenshot of the
     *  previous activity.
     */
    @Nullable
    public SurfaceControl getScreenshotSurface() {
        return mScreenshotSurface;
    }

    /**
     * Returns the {@link HardwareBuffer} containing the screenshot the activity about to be
     * shown. This can be null if one of the following conditions is met:
     * <ul>
     *     <li>The screenshot is not available
     *     <li> The previous activity is the home screen ( {@link  #TYPE_RETURN_TO_HOME}
     *     <li> The current window is a dialog ({@link  #TYPE_DIALOG_CLOSE}
     *     <li> The back animation is controlled by the application
     * </ul>
     */
    @Nullable
    public HardwareBuffer getScreenshotHardwareBuffer() {
        return mScreenshotBuffer;
    }

    /**
     * Returns the {@link WindowConfiguration} of the current task. This is null when the top
     * application is controlling the back animation.
     */
    @Nullable
    public WindowConfiguration getTaskWindowConfiguration() {
        return mTaskWindowConfiguration;
    }

    /**
     * Callback to be called when the back preview is finished in order to notify the server that
     * it can clean up the resources created for the animation.
     */
    public void onBackNavigationFinished() {
        mRemoteCallback.sendResult(null);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<BackNavigationInfo> CREATOR = new Creator<BackNavigationInfo>() {
        @Override
        public BackNavigationInfo createFromParcel(Parcel in) {
            return new BackNavigationInfo(in);
        }

        @Override
        public BackNavigationInfo[] newArray(int size) {
            return new BackNavigationInfo[size];
        }
    };

    @Override
    public String toString() {
        return "BackNavigationInfo{"
                + "mType=" + typeToString(mType) + " (" + mType + ")"
                + ", mDepartingWindowContainer=" + mDepartingWindowContainer
                + ", mScreenshotSurface=" + mScreenshotSurface
                + ", mTaskWindowConfiguration= " + mTaskWindowConfiguration
                + ", mScreenshotBuffer=" + mScreenshotBuffer
                + ", mRemoteCallback=" + mRemoteCallback
                + '}';
    }

    /**
     * Translates the {@link BackNavigationInfo} integer type to its String representation
     */
    public static String typeToString(@BackTargetType int type) {
        switch (type) {
            case  TYPE_UNDEFINED:
                return "TYPE_UNDEFINED";
            case TYPE_DIALOG_CLOSE:
                return "TYPE_DIALOG_CLOSE";
            case TYPE_RETURN_TO_HOME:
                return "TYPE_RETURN_TO_HOME";
            case TYPE_CROSS_ACTIVITY:
                return "TYPE_CROSS_ACTIVITY";
            case TYPE_CROSS_TASK:
                return "TYPE_CROSS_TASK";
        }
        return String.valueOf(type);
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ public enum ProtoLogGroup implements IProtoLogGroup {
    WM_DEBUG_LAYER_MIRRORING(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
            Consts.TAG_WM),
    WM_DEBUG_WALLPAPER(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
    WM_DEBUG_BACK_PREVIEW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
            "CoreBackPreview"),
    TEST_GROUP(true, true, false, "WindowManagerProtoLogTest");

    private final boolean mEnabled;
+27 −30
Original line number Diff line number Diff line
@@ -103,18 +103,6 @@
      "group": "WM_DEBUG_STATES",
      "at": "com\/android\/server\/wm\/TaskFragment.java"
    },
    "-2002500255": {
      "message": "Defer removing snapshot surface in %dms",
      "level": "VERBOSE",
      "group": "WM_DEBUG_STARTING_WINDOW",
      "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
    },
    "-1991255017": {
      "message": "Drawing snapshot surface sizeMismatch=%b",
      "level": "VERBOSE",
      "group": "WM_DEBUG_STARTING_WINDOW",
      "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
    },
    "-1980468143": {
      "message": "DisplayArea appeared name=%s",
      "level": "VERBOSE",
@@ -745,6 +733,12 @@
      "group": "WM_DEBUG_BOOT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-1343787701": {
      "message": "startBackNavigation task=%s, topRunningActivity=%s",
      "level": "DEBUG",
      "group": "WM_DEBUG_BACK_PREVIEW",
      "at": "com\/android\/server\/wm\/BackNavigationController.java"
    },
    "-1340540100": {
      "message": "Creating SnapshotStartingData",
      "level": "VERBOSE",
@@ -1597,12 +1591,6 @@
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "-405536909": {
      "message": "Removing snapshot surface",
      "level": "VERBOSE",
      "group": "WM_DEBUG_STARTING_WINDOW",
      "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
    },
    "-401282500": {
      "message": "destroyIfPossible: r=%s destroy returned removed=%s",
      "level": "DEBUG",
@@ -1867,6 +1855,12 @@
      "group": "WM_DEBUG_STATES",
      "at": "com\/android\/server\/wm\/Task.java"
    },
    "-134091882": {
      "message": "Screenshotting Activity %s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_BACK_PREVIEW",
      "at": "com\/android\/server\/wm\/TaskFragment.java"
    },
    "-124316973": {
      "message": "Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
      "level": "VERBOSE",
@@ -1951,6 +1945,12 @@
      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
      "at": "com\/android\/server\/wm\/WindowContainer.java"
    },
    "-23020844": {
      "message": "Back: Reset surfaces",
      "level": "DEBUG",
      "group": "WM_DEBUG_BACK_PREVIEW",
      "at": "com\/android\/server\/wm\/BackNavigationController.java"
    },
    "-21399771": {
      "message": "activity %s already destroying, skipping request with reason:%s",
      "level": "VERBOSE",
@@ -2005,12 +2005,6 @@
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "44438983": {
      "message": "performLayout: Activity exiting now removed %s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ADD_REMOVE",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "45285419": {
      "message": "startingWindow was set but startingSurface==null, couldn't remove",
      "level": "VERBOSE",
@@ -3271,12 +3265,6 @@
      "group": "WM_DEBUG_LAYER_MIRRORING",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "1417601133": {
      "message": "Enqueueing ADD_STARTING",
      "level": "VERBOSE",
      "group": "WM_DEBUG_STARTING_WINDOW",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "1422781269": {
      "message": "Resuming rotation after re-position",
      "level": "DEBUG",
@@ -3397,6 +3385,12 @@
      "group": "WM_DEBUG_APP_TRANSITIONS",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "1554795024": {
      "message": "Previous Activity is %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_BACK_PREVIEW",
      "at": "com\/android\/server\/wm\/BackNavigationController.java"
    },
    "1557732761": {
      "message": "For Intent %s bringing to top: %s",
      "level": "DEBUG",
@@ -3924,6 +3918,9 @@
    "WM_DEBUG_APP_TRANSITIONS_ANIM": {
      "tag": "WindowManager"
    },
    "WM_DEBUG_BACK_PREVIEW": {
      "tag": "CoreBackPreview"
    },
    "WM_DEBUG_BOOT": {
      "tag": "WindowManager"
    },
Loading