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

Commit d017fe35 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Add an inputconsumer override method for modern recents transitions" into sc-v2-dev

parents 0636af24 aeb52f75
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;

import android.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
@@ -66,6 +67,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.Set;
import java.util.function.Consumer;

@@ -99,6 +101,15 @@ final class InputMonitor {
     */
    private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();

    /**
     * Set when recents (overview) is active as part of a shell transition. While set, any focus
     * going to the recents activity will be redirected to the Recents input consumer. Since we
     * draw the live-tile above the recents activity, we also need to provide that activity as a
     * z-layering reference so that we can place the recents input consumer above it.
     */
    private WeakReference<ActivityRecord> mActiveRecentsActivity = null;
    private WeakReference<ActivityRecord> mActiveRecentsLayerRef = null;

    /**
     * Representation of a input consumer that the policy has added to the window manager to consume
     * input events going to windows below it.
@@ -394,6 +405,21 @@ final class InputMonitor {
        }
    }

    /**
     * Inform InputMonitor when recents is active so it can enable the recents input consumer.
     * @param activity The active recents activity. {@code null} means recents is not active.
     * @param layer An activity whose Z-layer is used as a reference for how to sort the consumer.
     */
    void setActiveRecents(@Nullable ActivityRecord activity, @Nullable ActivityRecord layer) {
        final boolean clear = activity == null;
        mActiveRecentsActivity = clear ? null : new WeakReference<>(activity);
        mActiveRecentsLayerRef = clear ? null : new WeakReference<>(layer);
    }

    private static <T> T getWeak(WeakReference<T> ref) {
        return ref != null ? ref.get() : null;
    }

    /**
     * Called when the current input focus changes.
     */
@@ -404,8 +430,10 @@ final class InputMonitor {
        if (recentsAnimationInputConsumer != null && focus != null) {
            final RecentsAnimationController recentsAnimationController =
                    mService.getRecentsAnimationController();
            final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
                    && recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord);
            final boolean shouldApplyRecentsInputConsumer = (recentsAnimationController != null
                    && recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord))
                    // Shell transitions doesn't use RecentsAnimationController
                    || getWeak(mActiveRecentsActivity) != null;
            if (shouldApplyRecentsInputConsumer) {
                requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
                        recentsAnimationInputConsumer.mName);
@@ -505,6 +533,14 @@ final class InputMonitor {
            mInDrag = inDrag;

            resetInputConsumers(mInputTransaction);
            // Update recents input consumer layer if active
            if (mAddRecentsAnimationInputConsumerHandle
                    && getWeak(mActiveRecentsActivity) != null) {
                final WindowContainer layer = getWeak(mActiveRecentsLayerRef);
                mRecentsAnimationInputConsumer.show(mInputTransaction,
                        layer != null ? layer : getWeak(mActiveRecentsActivity));
                mAddRecentsAnimationInputConsumerHandle = false;
            }
            mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);
            updateInputFocusRequest(mRecentsAnimationInputConsumer);

@@ -539,6 +575,7 @@ final class InputMonitor {

            final int privateFlags = w.mAttrs.privateFlags;

            // This only works for legacy transitions.
            if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
                if (recentsAnimationController.updateInputConsumerForApp(
                        mRecentsAnimationInputConsumer.mWindowHandle)) {
+60 −5
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
@@ -156,7 +159,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
    // TODO(b/188595497): remove when not needed.
    /** @see RecentsAnimationController#mNavigationBarAttachedToApp */
    private boolean mNavBarAttachedToApp = false;
    private int mNavBarDisplayId = INVALID_DISPLAY;
    private int mRecentsDisplayId = INVALID_DISPLAY;

    Transition(@TransitionType int type, @TransitionFlags int flags,
            TransitionController controller, BLASTSyncEngine syncEngine) {
@@ -176,6 +179,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        return mSyncId;
    }

    @TransitionFlags
    int getFlags() {
        return mFlags;
    }

    /**
     * Formally starts the transition. Participants can be collected before this is started,
     * but this won't consider itself ready until started -- even if all the participants have
@@ -407,6 +415,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        sendRemoteCallback(mClientAnimationFinishCallback);

        legacyRestoreNavigationBarFromApp();

        if (mRecentsDisplayId != INVALID_DISPLAY) {
            // Clean up input monitors (for recents)
            final DisplayContent dc =
                    mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
            dc.getInputMonitor().setActiveRecents(null /* activity */, null /* layer */);
        }
    }

    void abort() {
@@ -560,7 +575,43 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
        final DisplayContent dc =
                mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
        if (dc == null || !dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
        if (dc == null) return;
        mRecentsDisplayId = displayId;

        // Recents has an input-consumer to grab input from the "live tile" app. Set that up here
        final InputConsumerImpl recentsAnimationInputConsumer =
                dc.getInputMonitor().getInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
        if (recentsAnimationInputConsumer != null) {
            // find the top-most going-away activity and the recents activity. The top-most
            // is used as layer reference while the recents is used for registering the consumer
            // override.
            ActivityRecord recentsActivity = null;
            ActivityRecord topActivity = null;
            for (int i = 0; i < info.getChanges().size(); ++i) {
                final TransitionInfo.Change change = info.getChanges().get(i);
                if (change.getTaskInfo() == null) continue;
                final Task task = Task.fromWindowContainerToken(
                        info.getChanges().get(i).getTaskInfo().token);
                if (task == null) continue;
                final int activityType = change.getTaskInfo().topActivityType;
                final boolean isRecents = activityType == ACTIVITY_TYPE_HOME
                        || activityType == ACTIVITY_TYPE_RECENTS;
                if (isRecents && recentsActivity == null) {
                    recentsActivity = task.getTopVisibleActivity();
                } else if (!isRecents && topActivity == null) {
                    topActivity = task.getTopNonFinishingActivity();
                }
            }
            if (recentsActivity != null && topActivity != null) {
                recentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(
                        topActivity.getBounds());
                dc.getInputMonitor().setActiveRecents(recentsActivity, topActivity);
            }
        }

        // The rest of this function handles nav-bar reparenting

        if (!dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
                // Skip the case where the nav bar is controlled by fade rotation.
                || dc.getFadeRotationAnimationController() != null) {
            return;
@@ -587,7 +638,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
            return;
        }
        mNavBarAttachedToApp = true;
        mNavBarDisplayId = displayId;
        navWindow.mToken.cancelAnimation();
        final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction();
        final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl();
@@ -611,12 +661,17 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        if (!mNavBarAttachedToApp) return;
        mNavBarAttachedToApp = false;

        if (mRecentsDisplayId == INVALID_DISPLAY) {
            Slog.e(TAG, "Reparented navigation bar without a valid display");
            mRecentsDisplayId = DEFAULT_DISPLAY;
        }

        if (mController.mStatusBar != null) {
            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mNavBarDisplayId, true);
            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, true);
        }

        final DisplayContent dc =
                mController.mAtm.mRootWindowContainer.getDisplayContent(mNavBarDisplayId);
                mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
        final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
        if (navWindow == null) return;
        navWindow.setSurfaceTranslationY(0);