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

Commit ff8c691d authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Create separate source of truth for display info

Create a separate class keeping track of display related
info, such as display layout, bounds and id. Make sure
its internal state gets updated as needed and other classes
such as PipSizeSpecHandler and PipBoundsState use it instead
of subscribing to display changes themselves.

Bug: 268390405

Test: atest WMShellUnitTests
Change-Id: I633ab09faa1ae3b5103078155e3781f3433ad1fc
Merged-In: I633ab09faa1ae3b5103078155e3781f3433ad1fc
parent a0c17af4
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
@@ -70,7 +71,7 @@ public abstract class TvPipModule {
            ShellInit shellInit,
            ShellController shellController,
            TvPipBoundsState tvPipBoundsState,
            PipSizeSpecHandler pipSizeSpecHandler,
            PipDisplayLayoutState pipDisplayLayoutState,
            TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
            TvPipBoundsController tvPipBoundsController,
            PipAppOpsListener pipAppOpsListener,
@@ -91,7 +92,7 @@ public abstract class TvPipModule {
                        shellInit,
                        shellController,
                        tvPipBoundsState,
                        pipSizeSpecHandler,
                        pipDisplayLayoutState,
                        tvPipBoundsAlgorithm,
                        tvPipBoundsController,
                        pipAppOpsListener,
@@ -141,14 +142,15 @@ public abstract class TvPipModule {
    @WMSingleton
    @Provides
    static TvPipBoundsState provideTvPipBoundsState(Context context,
            PipSizeSpecHandler pipSizeSpecHandler) {
        return new TvPipBoundsState(context, pipSizeSpecHandler);
            PipSizeSpecHandler pipSizeSpecHandler, PipDisplayLayoutState pipDisplayLayoutState) {
        return new TvPipBoundsState(context, pipSizeSpecHandler, pipDisplayLayoutState);
    }

    @WMSingleton
    @Provides
    static PipSizeSpecHandler providePipSizeSpecHelper(Context context) {
        return new PipSizeSpecHandler(context);
    static PipSizeSpecHandler providePipSizeSpecHelper(Context context,
            PipDisplayLayoutState pipDisplayLayoutState) {
        return new PipSizeSpecHandler(context, pipDisplayLayoutState);
    }

    // Handler needed for loadDrawableAsync() in PipControlsViewController
@@ -203,7 +205,7 @@ public abstract class TvPipModule {
            TvPipMenuController tvPipMenuController,
            SyncTransactionQueue syncTransactionQueue,
            TvPipBoundsState tvPipBoundsState,
            PipSizeSpecHandler pipSizeSpecHandler,
            PipDisplayLayoutState pipDisplayLayoutState,
            PipTransitionState pipTransitionState,
            TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
            PipAnimationController pipAnimationController,
@@ -215,7 +217,7 @@ public abstract class TvPipModule {
            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
            @ShellMainThread ShellExecutor mainExecutor) {
        return new TvPipTaskOrganizer(context,
                syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipSizeSpecHandler,
                syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipDisplayLayoutState,
                tvPipBoundsAlgorithm, tvPipMenuController, pipAnimationController,
                pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
                splitScreenControllerOptional, displayController, pipUiEventLogger,
+16 −13
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
@@ -344,6 +345,7 @@ public abstract class WMShellModule {
            PhonePipKeepClearAlgorithm pipKeepClearAlgorithm,
            PipBoundsState pipBoundsState,
            PipSizeSpecHandler pipSizeSpecHandler,
            PipDisplayLayoutState pipDisplayLayoutState,
            PipMotionHelper pipMotionHelper,
            PipMediaController pipMediaController,
            PhonePipMenuController phonePipMenuController,
@@ -360,18 +362,18 @@ public abstract class WMShellModule {
        return Optional.ofNullable(PipController.create(
                context, shellInit, shellCommandHandler, shellController,
                displayController, pipAnimationController, pipAppOpsListener, pipBoundsAlgorithm,
                pipKeepClearAlgorithm, pipBoundsState, pipSizeSpecHandler, pipMotionHelper,
                pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState,
                pipTouchHandler, pipTransitionController, windowManagerShellWrapper,
                taskStackListener, pipParamsChangedForwarder, displayInsetsController,
                oneHandedController, mainExecutor));
                pipKeepClearAlgorithm, pipBoundsState, pipSizeSpecHandler, pipDisplayLayoutState,
                pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer,
                pipTransitionState, pipTouchHandler, pipTransitionController,
                windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
                displayInsetsController, oneHandedController, mainExecutor));
    }

    @WMSingleton
    @Provides
    static PipBoundsState providePipBoundsState(Context context,
            PipSizeSpecHandler pipSizeSpecHandler) {
        return new PipBoundsState(context, pipSizeSpecHandler);
            PipSizeSpecHandler pipSizeSpecHandler, PipDisplayLayoutState pipDisplayLayoutState) {
        return new PipBoundsState(context, pipSizeSpecHandler, pipDisplayLayoutState);
    }

    @WMSingleton
@@ -388,8 +390,9 @@ public abstract class WMShellModule {

    @WMSingleton
    @Provides
    static PipSizeSpecHandler providePipSizeSpecHelper(Context context) {
        return new PipSizeSpecHandler(context);
    static PipSizeSpecHandler providePipSizeSpecHelper(Context context,
            PipDisplayLayoutState pipDisplayLayoutState) {
        return new PipSizeSpecHandler(context, pipDisplayLayoutState);
    }

    @WMSingleton
@@ -446,7 +449,7 @@ public abstract class WMShellModule {
            SyncTransactionQueue syncTransactionQueue,
            PipTransitionState pipTransitionState,
            PipBoundsState pipBoundsState,
            PipSizeSpecHandler pipSizeSpecHandler,
            PipDisplayLayoutState pipDisplayLayoutState,
            PipBoundsAlgorithm pipBoundsAlgorithm,
            PhonePipMenuController menuPhoneController,
            PipAnimationController pipAnimationController,
@@ -458,7 +461,7 @@ public abstract class WMShellModule {
            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
            @ShellMainThread ShellExecutor mainExecutor) {
        return new PipTaskOrganizer(context,
                syncTransactionQueue, pipTransitionState, pipBoundsState, pipSizeSpecHandler,
                syncTransactionQueue, pipTransitionState, pipBoundsState, pipDisplayLayoutState,
                pipBoundsAlgorithm, menuPhoneController, pipAnimationController,
                pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
                splitScreenControllerOptional, displayController, pipUiEventLogger,
@@ -477,12 +480,12 @@ public abstract class WMShellModule {
    static PipTransitionController providePipTransitionController(Context context,
            ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Transitions transitions,
            PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
            PipBoundsState pipBoundsState, PipSizeSpecHandler pipSizeSpecHandler,
            PipBoundsState pipBoundsState, PipDisplayLayoutState pipDisplayLayoutState,
            PipTransitionState pipTransitionState, PhonePipMenuController pipMenuController,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            Optional<SplitScreenController> splitScreenOptional) {
        return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
                pipBoundsState, pipSizeSpecHandler, pipTransitionState, pipMenuController,
                pipBoundsState, pipDisplayLayoutState, pipTransitionState, pipMenuController,
                pipBoundsAlgorithm, pipAnimationController, pipSurfaceTransactionHelper,
                splitScreenOptional);
    }
+6 −22
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.graphics.Rect;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Size;
import android.view.Display;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -77,6 +76,7 @@ public class PipBoundsState {
    private final @NonNull Rect mExpandedBounds = new Rect();
    private final @NonNull Rect mNormalMovementBounds = new Rect();
    private final @NonNull Rect mExpandedMovementBounds = new Rect();
    private final @NonNull PipDisplayLayoutState mPipDisplayLayoutState;
    private final Point mMaxSize = new Point();
    private final Point mMinSize = new Point();
    private final @NonNull Context mContext;
@@ -86,8 +86,6 @@ public class PipBoundsState {
    private @Nullable PipReentryState mPipReentryState;
    private final @Nullable PipSizeSpecHandler mPipSizeSpecHandler;
    private @Nullable ComponentName mLastPipComponentName;
    private int mDisplayId = Display.DEFAULT_DISPLAY;
    private final @NonNull DisplayLayout mDisplayLayout = new DisplayLayout();
    private final @NonNull MotionBoundsState mMotionBoundsState = new MotionBoundsState();
    private boolean mIsImeShowing;
    private int mImeHeight;
@@ -120,10 +118,12 @@ public class PipBoundsState {
    private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback;
    private List<Consumer<Rect>> mOnPipExclusionBoundsChangeCallbacks = new ArrayList<>();

    public PipBoundsState(@NonNull Context context, PipSizeSpecHandler pipSizeSpecHandler) {
    public PipBoundsState(@NonNull Context context, PipSizeSpecHandler pipSizeSpecHandler,
            PipDisplayLayoutState pipDisplayLayoutState) {
        mContext = context;
        reloadResources();
        mPipSizeSpecHandler = pipSizeSpecHandler;
        mPipDisplayLayoutState = pipDisplayLayoutState;
    }

    /** Reloads the resources. */
@@ -290,31 +290,16 @@ public class PipBoundsState {
        return mLastPipComponentName;
    }

    /** Get the current display id. */
    public int getDisplayId() {
        return mDisplayId;
    }

    /** Set the current display id for the associated display layout. */
    public void setDisplayId(int displayId) {
        mDisplayId = displayId;
    }

    /** Returns the display's bounds. */
    @NonNull
    public Rect getDisplayBounds() {
        return new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
    }

    /** Update the display layout. */
    public void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
        mDisplayLayout.set(displayLayout);
        return mPipDisplayLayoutState.getDisplayBounds();
    }

    /** Get a copy of the display layout. */
    @NonNull
    public DisplayLayout getDisplayLayout() {
        return new DisplayLayout(mDisplayLayout);
        return mPipDisplayLayoutState.getDisplayLayout();
    }

    @VisibleForTesting
@@ -568,7 +553,6 @@ public class PipBoundsState {
        pw.println(innerPrefix + "mExpandedMovementBounds=" + mExpandedMovementBounds);
        pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
        pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
        pw.println(innerPrefix + "mDisplayId=" + mDisplayId);
        pw.println(innerPrefix + "mStashedState=" + mStashedState);
        pw.println(innerPrefix + "mStashOffset=" + mStashOffset);
        pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 com.android.wm.shell.pip;

import android.content.Context;
import android.graphics.Rect;
import android.view.Surface;

import androidx.annotation.NonNull;

import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.dagger.WMSingleton;

import java.io.PrintWriter;

import javax.inject.Inject;

/**
 * Acts as a source of truth for display related information for PIP.
 */
@WMSingleton
public class PipDisplayLayoutState {
    private static final String TAG = PipDisplayLayoutState.class.getSimpleName();

    private Context mContext;
    private int mDisplayId;
    @NonNull private DisplayLayout mDisplayLayout;

    @Inject
    public PipDisplayLayoutState(Context context) {
        mContext = context;
        mDisplayLayout = new DisplayLayout();
    }

    /** Update the display layout. */
    public void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
        mDisplayLayout.set(displayLayout);
    }

    /** Get a copy of the display layout. */
    @NonNull
    public DisplayLayout getDisplayLayout() {
        return new DisplayLayout(mDisplayLayout);
    }

    /** Get the display bounds */
    @NonNull
    public Rect getDisplayBounds() {
        return new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
    }

    /**
     * Apply a rotation to this layout and its parameters.
     * @param targetRotation
     */
    public void rotateTo(@Surface.Rotation int targetRotation) {
        mDisplayLayout.rotateTo(mContext.getResources(), targetRotation);
    }

    /** Get the current display id */
    public int getDisplayId() {
        return mDisplayId;
    }

    /** Set the current display id for the associated display layout. */
    public void setDisplayId(int displayId) {
        mDisplayId = displayId;
    }

    /** Dumps internal state. */
    public void dump(PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + TAG);
        pw.println(innerPrefix + "mDisplayId=" + mDisplayId);
        pw.println(innerPrefix + "getDisplayBounds=" + getDisplayBounds());
    }
}
+10 −12
Original line number Diff line number Diff line
@@ -79,13 +79,11 @@ import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ScreenshotUtils;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
@@ -128,7 +126,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    private final Context mContext;
    private final SyncTransactionQueue mSyncTransactionQueue;
    private final PipBoundsState mPipBoundsState;
    private final PipSizeSpecHandler mPipSizeSpecHandler;
    private final PipDisplayLayoutState mPipDisplayLayoutState;
    private final PipBoundsAlgorithm mPipBoundsAlgorithm;
    private final @NonNull PipMenuController mPipMenuController;
    private final PipAnimationController mPipAnimationController;
@@ -316,7 +314,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            @NonNull SyncTransactionQueue syncTransactionQueue,
            @NonNull PipTransitionState pipTransitionState,
            @NonNull PipBoundsState pipBoundsState,
            @NonNull PipSizeSpecHandler pipSizeSpecHandler,
            @NonNull PipDisplayLayoutState pipDisplayLayoutState,
            @NonNull PipBoundsAlgorithm boundsHandler,
            @NonNull PipMenuController pipMenuController,
            @NonNull PipAnimationController pipAnimationController,
@@ -332,7 +330,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mSyncTransactionQueue = syncTransactionQueue;
        mPipTransitionState = pipTransitionState;
        mPipBoundsState = pipBoundsState;
        mPipSizeSpecHandler = pipSizeSpecHandler;
        mPipDisplayLayoutState = pipDisplayLayoutState;
        mPipBoundsAlgorithm = boundsHandler;
        mPipMenuController = pipMenuController;
        mPipTransitionController = pipTransitionController;
@@ -653,7 +651,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,

        // If the displayId of the task is different than what PipBoundsHandler has, then update
        // it. This is possible if we entered PiP on an external display.
        if (info.displayId != mPipBoundsState.getDisplayId()
        if (info.displayId != mPipDisplayLayoutState.getDisplayId()
                && mOnDisplayIdChangeCallback != null) {
            mOnDisplayIdChangeCallback.accept(info.displayId);
        }
@@ -1621,15 +1619,15 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        return animator;
    }

    /** Computes destination bounds in old rotation and returns source hint rect if available. */
    /** Computes destination bounds in old rotation and returns source hint rect if available.
     *
     * Note: updates the internal state of {@link PipDisplayLayoutState} by applying a rotation
     * transformation onto the display layout.
     */
    private @Nullable Rect computeRotatedBounds(int rotationDelta, int direction,
            Rect outDestinationBounds, Rect sourceHintRect) {
        if (direction == TRANSITION_DIRECTION_TO_PIP) {
            DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();

            layoutCopy.rotateTo(mContext.getResources(), mNextRotation);
            mPipBoundsState.setDisplayLayout(layoutCopy);
            mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
            mPipDisplayLayoutState.rotateTo(mNextRotation);

            final Rect displayBounds = mPipBoundsState.getDisplayBounds();
            outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
Loading