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

Commit 52a3bb48 authored by Bill Lin's avatar Bill Lin
Browse files

Integrate DisplayLayout for One handed mode

1) Handle rotation
2) Initialize DisplayLayout in dagger and update when
   onDisplayAdded() & onDisplayRemoved()
3) Refact OneHandedTouchHandler
4) Refact OneHandedBackgroundPanelOrganizer
5) Refact OneHandedDisplayAreaOrganizer

Test: atest WMShellUnitTests
Bug:182899148
Bug:182633327
Bug:183172404
Bug:183489178
Bug:183559944
Bug:183065937
Bug:183005910
Bug:183063280
Bug:183162084
Bug:181423645
Bug:177497107
Change-Id: Ie7a4fa97df5f6a3963a55bd507d36e026e971bab
parent 17ea6fca
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
@@ -34,8 +33,9 @@ import androidx.annotation.VisibleForTesting;

import com.android.internal.annotations.GuardedBy;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;

import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.Executor;

@@ -52,12 +52,15 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
    private final SurfaceSession mSurfaceSession = new SurfaceSession();
    private final float[] mColor;
    private final float mAlpha;
    private final Rect mRect;
    private final Executor mMainExecutor;
    private final Rect mDisplaySize;
    private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
            mSurfaceControlTransactionFactory;

    /**
     * The background to distinguish the boundary of translated windows and empty region when
     * one handed mode triggered.
     */
    private Rect mBkgBounds;
    @VisibleForTesting
    @GuardedBy("mLock")
    boolean mIsShowing;
@@ -82,15 +85,19 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
        mMainExecutor.execute(() -> removeBackgroundPanelLayer());
    }

    public OneHandedBackgroundPanelOrganizer(Context context, WindowManager windowManager,
            DisplayController displayController, Executor executor) {
    public OneHandedBackgroundPanelOrganizer(Context context, DisplayLayout displayLayout,
            Executor executor) {
        super(executor);
        mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();
        final Resources res = context.getResources();
        final float defaultRGB = res.getFloat(R.dimen.config_one_handed_background_rgb);
        mColor = new float[]{defaultRGB, defaultRGB, defaultRGB};
        mAlpha = res.getFloat(R.dimen.config_one_handed_background_alpha);
        mRect = new Rect(0, 0, mDisplaySize.width(), mDisplaySize.height());
        // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
        if (displayLayout.height() > displayLayout.width()) {
            mBkgBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height());
        } else {
            mBkgBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width());
        }
        mMainExecutor = executor;
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
    }
@@ -144,6 +151,7 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
            if (mBackgroundSurface == null) {
                mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession)
                        .setParent(mParentLeash)
                        .setBufferSize(mBkgBounds.width(), mBkgBounds.height())
                        .setColorLayer()
                        .setFormat(PixelFormat.RGBA_8888)
                        .setOpaque(false)
@@ -188,11 +196,19 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer

            SurfaceControl.Transaction transaction =
                    mSurfaceControlTransactionFactory.getTransaction();
            transaction.remove(mBackgroundSurface);
            transaction.apply();
            transaction.remove(mBackgroundSurface).apply();
            transaction.close();
            mBackgroundSurface = null;
            mIsShowing = false;
        }
    }

    void dump(@NonNull PrintWriter pw) {
        final String innerPrefix = "  ";
        pw.println(TAG + "states: ");
        pw.print(innerPrefix + "mIsShowing=");
        pw.println(mIsShowing);
        pw.print(innerPrefix + "mBkgBounds=");
        pw.println(mBkgBounds);
    }
}
+70 −42
Original line number Diff line number Diff line
@@ -17,10 +17,10 @@
package com.android.wm.shell.onehanded;

import static android.os.UserHandle.USER_CURRENT;
import static android.view.Display.DEFAULT_DISPLAY;

import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;

import android.Manifest;
import android.annotation.BinderThread;
import android.content.ComponentName;
import android.content.Context;
@@ -28,13 +28,13 @@ import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Slog;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -47,7 +47,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ExecutorUtils;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerCallback;
@@ -76,9 +76,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
    private boolean mLockedDisabled;
    private float mOffSetFraction;

    private final Context mContext;
    private Context mContext;

    private final AccessibilityManager mAccessibilityManager;
    private final DisplayController mDisplayController;
    private final OneHandedGestureHandler mGestureHandler;
    private final OneHandedSettingsUtil mOneHandedSettingsUtil;
    private final OneHandedTimeoutHandler mTimeoutHandler;
    private final OneHandedTouchHandler mTouchHandler;
@@ -89,10 +90,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
    private final ShellExecutor mMainExecutor;
    private final Handler mMainHandler;
    private final OneHandedImpl mImpl = new OneHandedImpl();
    private final WindowManager mWindowManager;

    private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
    private final AccessibilityManager mAccessibilityManager;
    private OneHandedGestureHandler mGestureHandler;
    private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;

    /**
@@ -100,8 +100,29 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
     */
    private final DisplayChangeController.OnDisplayChangingListener mRotationController =
            (display, fromRotation, toRotation, wct) -> {
                if (mDisplayAreaOrganizer != null) {
                    mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation, wct);
                if (!isInitialized()) {
                    return;
                }
                mDisplayAreaOrganizer.onRotateDisplay(mContext, toRotation, wct);
                mGestureHandler.onRotateDisplay(mDisplayAreaOrganizer.getDisplayLayout());
            };

    private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener =
            new DisplayController.OnDisplaysChangedListener() {
                @Override
                public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
                    if (displayId != DEFAULT_DISPLAY || !isInitialized()) {
                        return;
                    }
                    updateDisplayLayout(displayId);
                }

                @Override
                public void onDisplayAdded(int displayId) {
                    if (displayId != DEFAULT_DISPLAY || !isInitialized()) {
                        return;
                    }
                    updateDisplayLayout(displayId);
                }
            };

@@ -115,8 +136,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
            new AccessibilityManager.AccessibilityStateChangeListener() {
                @Override
                public void onAccessibilityStateChanged(boolean enabled) {
                    if (mOneHandedSettingsUtil == null) {
                        Slog.w(TAG, "mOneHandedSettingsUtil may not instantiate yet");
                    if (!isInitialized()) {
                        return;
                    }
                    if (enabled) {
@@ -147,6 +167,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                }
            };

    private boolean isInitialized() {
        if (mDisplayAreaOrganizer == null || mDisplayController == null
                || mGestureHandler == null || mOneHandedSettingsUtil == null) {
            Slog.w(TAG, "Components may not initialized yet!");
            return false;
        }
        return true;
    }

    /**
     * Creates {@link OneHandedController}, returns {@code null} if the feature is not supported.
@@ -154,8 +182,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
    @Nullable
    public static OneHandedController create(
            Context context, WindowManager windowManager, DisplayController displayController,
            TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger,
            ShellExecutor mainExecutor, Handler mainHandler) {
            DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener,
            UiEventLogger uiEventLogger, ShellExecutor mainExecutor, Handler mainHandler) {
        if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
            Slog.w(TAG, "Device doesn't support OneHanded feature");
            return null;
@@ -169,19 +197,17 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
                mainExecutor);
        OneHandedGestureHandler gestureHandler = new OneHandedGestureHandler(
                context, windowManager, displayController, ViewConfiguration.get(context),
                mainExecutor);
                context, displayLayout, ViewConfiguration.get(context), mainExecutor);
        OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer =
                new OneHandedBackgroundPanelOrganizer(context, windowManager, displayController,
                        mainExecutor);
                new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor);
        OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
                context, windowManager, animationController, tutorialHandler,
                context, displayLayout, animationController, tutorialHandler,
                oneHandedBackgroundPanelOrganizer, mainExecutor);
        OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil();
        OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger);
        IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
                ServiceManager.getService(Context.OVERLAY_SERVICE));
        return new OneHandedController(context, windowManager, displayController,
        return new OneHandedController(context, displayController,
                oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler,
                gestureHandler, settingsUtil, timeoutHandler, oneHandedUiEventsLogger,
                overlayManager, taskStackListener, mainExecutor, mainHandler);
@@ -189,7 +215,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>

    @VisibleForTesting
    OneHandedController(Context context,
            WindowManager windowManager,
            DisplayController displayController,
            OneHandedBackgroundPanelOrganizer backgroundPanelOrganizer,
            OneHandedDisplayAreaOrganizer displayAreaOrganizer,
@@ -205,7 +230,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
            Handler mainHandler) {
        mContext = context;
        mOneHandedSettingsUtil = settingsUtil;
        mWindowManager = windowManager;
        mBackgroundPanelOrganizer = backgroundPanelOrganizer;
        mDisplayAreaOrganizer = displayAreaOrganizer;
        mDisplayController = displayController;
@@ -218,6 +242,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        mOneHandedUiEventLogger = uiEventsLogger;
        mTaskStackListener = taskStackListener;

        mDisplayController.addDisplayWindowListener(mDisplaysChangedListener);
        final float offsetPercentageConfig = context.getResources().getFraction(
                R.fraction.config_one_handed_offset, 1, 1);
        final int sysPropPercentageConfig = SystemProperties.getInt(
@@ -297,8 +322,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
            Slog.d(TAG, "Temporary lock disabled");
            return;
        }
        final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation();
        if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) {
            Slog.w(TAG, "One handed mode only support portrait mode");
            return;
        }
        if (!mDisplayAreaOrganizer.isInOneHanded()) {
            final int yOffSet = Math.round(getDisplaySize().height() * mOffSetFraction);
            final int yOffSet = Math.round(
                    mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
            mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
            mTimeoutHandler.resetTimer();

@@ -371,6 +402,12 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
    }

    private void updateDisplayLayout(int displayId) {
        mDisplayAreaOrganizer.setDisplayLayout(
                mDisplayController.getDisplayLayout(displayId));
        mGestureHandler.onDisplayChanged(mDisplayAreaOrganizer.getDisplayLayout());
    }

    private ContentObserver getObserver(Runnable onChangeRunnable) {
        return new ContentObserver(mMainHandler) {
            @Override
@@ -454,24 +491,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_TIMEOUT_OUT));
    }

    /**
     * Query the current display real size from {@link WindowManager}
     *
     * @return {@link WindowManager#getCurrentWindowMetrics()#getBounds()}
     */
    private Rect getDisplaySize() {
        if (mWindowManager == null) {
            Slog.e(TAG, "WindowManager instance is null! Can not get display size!");
            return new Rect();
        }
        final Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
        if (displaySize.width() == 0 || displaySize.height() == 0) {
            Slog.e(TAG, "Display size error! width = " + displaySize.width()
                    + ", height = " + displaySize.height());
        }
        return displaySize;
    }

    @VisibleForTesting
    boolean isLockedDisabled() {
        return mLockedDisabled;
@@ -483,7 +502,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        }

        mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
        mGestureHandler.onOneHandedEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
        mGestureHandler.onGestureEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);

        if (!mIsOneHandedEnabled) {
            mDisplayAreaOrganizer.unregisterOrganizer();
@@ -532,10 +551,15 @@ public class OneHandedController implements RemoteCallable<OneHandedController>

    @VisibleForTesting
    void setLockedDisabled(boolean locked, boolean enabled) {
        if (enabled == mIsOneHandedEnabled) {
        final boolean isFeatureEnabled = mIsOneHandedEnabled || mIsSwipeToNotificationEnabled;

        if (enabled == isFeatureEnabled) {
            return;
        }
        mLockedDisabled = locked && !enabled;

        // Disabled gesture when keyguard ON
        mGestureHandler.onGestureEnabled(!mLockedDisabled && isFeatureEnabled);
    }

    private void onConfigChanged(Configuration newConfig) {
@@ -556,6 +580,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
        pw.print(innerPrefix + "mLockedDisabled=");
        pw.println(mLockedDisabled);

        if (mBackgroundPanelOrganizer != null) {
            mBackgroundPanelOrganizer.dump(pw);
        }

        if (mDisplayAreaOrganizer != null) {
            mDisplayAreaOrganizer.dump(pw);
        }
+40 −44
Original line number Diff line number Diff line
@@ -23,9 +23,7 @@ import android.content.Context;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
@@ -37,6 +35,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;

import java.io.PrintWriter;
@@ -58,7 +57,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION =
            "persist.debug.one_handed_translate_animation_duration";

    private final WindowManager mWindowManager;
    private DisplayLayout mDisplayLayout = new DisplayLayout();

    private final Rect mLastVisualDisplayBounds = new Rect();
    private final Rect mDefaultDisplayBounds = new Rect();

@@ -108,15 +108,15 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
     * Constructor of OneHandedDisplayAreaOrganizer
     */
    public OneHandedDisplayAreaOrganizer(Context context,
            WindowManager windowManager,
            DisplayLayout displayLayout,
            OneHandedAnimationController animationController,
            OneHandedTutorialHandler tutorialHandler,
            OneHandedBackgroundPanelOrganizer oneHandedBackgroundGradientOrganizer,
            ShellExecutor mainExecutor) {
        super(mainExecutor);
        mWindowManager = windowManager;
        mDisplayLayout.set(displayLayout);
        updateDisplayBounds();
        mAnimationController = animationController;
        mLastVisualDisplayBounds.set(getDisplayBounds());
        final int animationDurationConfig = context.getResources().getInteger(
                R.integer.config_one_handed_translate_animation_duration);
        mEnterExitAnimationDurationMs =
@@ -146,7 +146,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
            final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
            onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
        }
        mDefaultDisplayBounds.set(getDisplayBounds());
        updateDisplayBounds();
        return displayAreaInfos;
    }

@@ -157,30 +157,22 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    }

    /**
     * Handler for display rotation changes by below policy which
     * handles 90 degree display rotation changes {@link Surface.Rotation}.
     * Handler for display rotation changes by {@link DisplayLayout}
     *
     * @param fromRotation starting rotation of the display.
     * @param context       Any context
     * @param toRotation    target rotation of the display (after rotating).
     * @param wct           A task transaction {@link WindowContainerTransaction} from
     *                      {@link DisplayChangeController} to populate.
     */
    public void onRotateDisplay(int fromRotation, int toRotation, WindowContainerTransaction wct) {
        // Stop one handed without animation and reset cropped size immediately
        final Rect newBounds = new Rect(getDisplayBounds());
        // This diff rule will only filter the cases portrait <-> landscape
        final boolean isOrientationDiff = Math.abs(fromRotation - toRotation) % 2 == 1;

        if (isOrientationDiff) {
            // getDisplayBounds() will return window metrics bounds which dose not update to
            // corresponding display orientation yet, we have to manual rotate bounds
            newBounds.set(0, 0, newBounds.bottom, newBounds.right);
    public void onRotateDisplay(Context context, int toRotation, WindowContainerTransaction wct) {
        if (mDisplayLayout.rotation() == toRotation) {
            return;
        }
        mDisplayLayout.rotateTo(context.getResources(), toRotation);
        resetWindowsOffset(wct);
            mDefaultDisplayBounds.set(newBounds);
            mLastVisualDisplayBounds.set(newBounds);
        updateDisplayBounds();
        finishOffset(0, TRANSITION_DIRECTION_EXIT);
    }
    }

    /**
     * Offset the windows by a given offset on Y-axis, triggered also from screen rotation.
@@ -191,9 +183,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                mDefaultDisplayBounds.top + yOffset,
                mDefaultDisplayBounds.right,
                mDefaultDisplayBounds.bottom + yOffset);
        final Rect fromBounds = getLastVisualDisplayBounds() != null
                ? getLastVisualDisplayBounds()
                : mDefaultDisplayBounds;
        final Rect fromBounds = getLastVisualDisplayBounds();
        final int direction = yOffset > 0
                ? TRANSITION_DIRECTION_TRIGGER
                : TRANSITION_DIRECTION_EXIT;
@@ -219,7 +209,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        applyTransaction(wct);
    }

    private void resetWindowsOffset(WindowContainerTransaction wct) {
    @VisibleForTesting
    void resetWindowsOffset(WindowContainerTransaction wct) {
        final SurfaceControl.Transaction tx =
                mSurfaceControlTransactionFactory.getTransaction();
        mDisplayAreaTokenMap.forEach(
@@ -292,19 +283,19 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        return mLastVisualDisplayBounds;
    }

    @Nullable
    @VisibleForTesting
    Rect getDisplayBounds() {
        if (mWindowManager == null) {
            Slog.e(TAG, "WindowManager instance is null! Can not get display size!");
            return new Rect();
    @Nullable
    Rect getLastDisplayBounds() {
        return mLastVisualDisplayBounds;
    }
        final Rect displayBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        if (displayBounds.width() == 0 || displayBounds.height() == 0) {
            Slog.e(TAG, "Display size error! width = " + displayBounds.width()
                    + ", height = " + displayBounds.height());

    public DisplayLayout getDisplayLayout() {
        return mDisplayLayout;
    }
        return displayBounds;

    @VisibleForTesting
    void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
        mDisplayLayout.set(displayLayout);
    }

    @VisibleForTesting
@@ -312,6 +303,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        return mDisplayAreaTokenMap;
    }

    void updateDisplayBounds() {
        mDefaultDisplayBounds.set(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
        mLastVisualDisplayBounds.set(mDefaultDisplayBounds);
    }

    /**
     * Register transition callback
     */
@@ -324,13 +320,13 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
        pw.println(TAG + "states: ");
        pw.print(innerPrefix + "mIsInOneHanded=");
        pw.println(mIsInOneHanded);
        pw.print(innerPrefix + "mDisplayLayout.rotation()=");
        pw.println(mDisplayLayout.rotation());
        pw.print(innerPrefix + "mDisplayAreaTokenMap=");
        pw.println(mDisplayAreaTokenMap);
        pw.print(innerPrefix + "mDefaultDisplayBounds=");
        pw.println(mDefaultDisplayBounds);
        pw.print(innerPrefix + "mLastVisualDisplayBounds=");
        pw.println(mLastVisualDisplayBounds);
        pw.print(innerPrefix + "getDisplayBounds()=");
        pw.println(getDisplayBounds());
    }
}
+55 −65

File changed.

Preview size limit exceeded, changes collapsed.

+15 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED_BACKGROUND_
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.testing.AndroidTestingRunner;
@@ -35,6 +36,7 @@ import android.window.WindowContainerToken;
import androidx.test.filters.SmallTest;

import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;

import org.junit.Before;
import org.junit.Test;
@@ -48,7 +50,8 @@ import org.mockito.MockitoAnnotations;
public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
    private DisplayAreaInfo mDisplayAreaInfo;
    private Display mDisplay;
    private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
    private DisplayLayout mDisplayLayout;
    private OneHandedBackgroundPanelOrganizer mSpiedBackgroundPanelOrganizer;
    private WindowContainerToken mToken;
    private SurfaceControl mLeash;
    private TestableLooper mTestableLooper;
@@ -65,37 +68,38 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
        mToken = new WindowContainerToken(mMockRealToken);
        mLeash = new SurfaceControl();
        mDisplay = mContext.getDisplay();
        mDisplayLayout = new DisplayLayout(mContext, mDisplay);
        when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
        mDisplayAreaInfo = new DisplayAreaInfo(mToken, DEFAULT_DISPLAY,
                FEATURE_ONE_HANDED_BACKGROUND_PANEL);

        mBackgroundPanelOrganizer = new OneHandedBackgroundPanelOrganizer(mContext, mWindowManager,
                mMockDisplayController, Runnable::run);
        mSpiedBackgroundPanelOrganizer = spy(
                new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, Runnable::run));
    }

    @Test
    public void testOnDisplayAreaAppeared() {
        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mTestableLooper.processAllMessages();

        assertThat(mBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull();
        assertThat(mSpiedBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull();
    }

    @Test
    public void testShowBackgroundLayer() {
        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mBackgroundPanelOrganizer.showBackgroundPanelLayer();
        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mSpiedBackgroundPanelOrganizer.showBackgroundPanelLayer();
        mTestableLooper.processAllMessages();

        assertThat(mBackgroundPanelOrganizer.mIsShowing).isTrue();
        assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isTrue();
    }

    @Test
    public void testRemoveBackgroundLayer() {
        mBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mBackgroundPanelOrganizer.removeBackgroundPanelLayer();
        mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mSpiedBackgroundPanelOrganizer.removeBackgroundPanelLayer();
        mTestableLooper.processAllMessages();

        assertThat(mBackgroundPanelOrganizer.mIsShowing).isFalse();
        assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isFalse();
    }
}
Loading