Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java +26 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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) Loading Loading @@ -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); } } libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +70 −42 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; /** Loading @@ -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); } }; Loading @@ -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) { Loading Loading @@ -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. Loading @@ -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; Loading @@ -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); Loading @@ -189,7 +215,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> @VisibleForTesting OneHandedController(Context context, WindowManager windowManager, DisplayController displayController, OneHandedBackgroundPanelOrganizer backgroundPanelOrganizer, OneHandedDisplayAreaOrganizer displayAreaOrganizer, Loading @@ -205,7 +230,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> Handler mainHandler) { mContext = context; mOneHandedSettingsUtil = settingsUtil; mWindowManager = windowManager; mBackgroundPanelOrganizer = backgroundPanelOrganizer; mDisplayAreaOrganizer = displayAreaOrganizer; mDisplayController = displayController; Loading @@ -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( Loading Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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) { Loading @@ -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); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +40 −44 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 = Loading Loading @@ -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; } Loading @@ -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. Loading @@ -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; Loading @@ -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( Loading Loading @@ -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 Loading @@ -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 */ Loading @@ -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()); } } libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java +55 −65 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java +15 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java +26 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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) Loading Loading @@ -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); } }
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +70 −42 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; /** Loading @@ -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); } }; Loading @@ -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) { Loading Loading @@ -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. Loading @@ -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; Loading @@ -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); Loading @@ -189,7 +215,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> @VisibleForTesting OneHandedController(Context context, WindowManager windowManager, DisplayController displayController, OneHandedBackgroundPanelOrganizer backgroundPanelOrganizer, OneHandedDisplayAreaOrganizer displayAreaOrganizer, Loading @@ -205,7 +230,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> Handler mainHandler) { mContext = context; mOneHandedSettingsUtil = settingsUtil; mWindowManager = windowManager; mBackgroundPanelOrganizer = backgroundPanelOrganizer; mDisplayAreaOrganizer = displayAreaOrganizer; mDisplayController = displayController; Loading @@ -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( Loading Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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) { Loading @@ -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); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +40 −44 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 = Loading Loading @@ -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; } Loading @@ -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. Loading @@ -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; Loading @@ -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( Loading Loading @@ -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 Loading @@ -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 */ Loading @@ -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()); } }
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java +55 −65 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java +15 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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(); } }