From b6e9d2fcc1dbfff69ca43f57691c780700fcb35f Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 24 Jan 2023 04:50:46 +0000 Subject: [PATCH] Make DeviceStateController generic Previously it was specific to fold-state, and used to notify a single client of fold-state changes. DeviceStateController is now generic and can be used (or modified) to cache, query, or receive callbacks for other state changes. Note that we are purposely removing the nested FoldStateListener class since it's a very thin layer and makes it unnecessarily complex when we add new functionality to DeviceStateController. A simple example would be DeviceStateController#getCurrentState() needing to access an inner FoldStateListener#getCurrentState(). Bug: 264499484 Test: atest DisplayRotationTests Test: atest DeviceStateControllerTests Change-Id: I81b0a61b52d74718fe1dee213a59509a44a9a920 --- core/res/res/values/config.xml | 20 ++++ core/res/res/values/symbols.xml | 2 + .../server/wm/DeviceStateController.java | 104 +++++++++------- .../com/android/server/wm/DisplayContent.java | 9 +- .../android/server/wm/DisplayRotation.java | 51 ++++---- .../server/wm/LetterboxUiController.java | 10 +- ...ysicalDisplaySwitchTransitionLauncher.java | 6 +- .../server/wm/DeviceStateControllerTests.java | 112 +++++++++--------- .../server/wm/DisplayRotationTests.java | 6 +- .../android/server/wm/SizeCompatTests.java | 6 +- 10 files changed, 179 insertions(+), 147 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a6be07d0b7803..d4b151dd82201 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -652,6 +652,16 @@ The default is false. --> false + + + + + @@ -672,6 +682,16 @@ --> + + + + + false diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index be9f6d2448ba3..50c4df783d000 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4015,8 +4015,10 @@ + + diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java index a6f855755192a..2e67399321a00 100644 --- a/services/core/java/com/android/server/wm/DeviceStateController.java +++ b/services/core/java/com/android/server/wm/DeviceStateController.java @@ -16,80 +16,92 @@ package com.android.server.wm; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.devicestate.DeviceStateManager; import android.os.Handler; import android.os.HandlerExecutor; +import com.android.internal.R; import com.android.internal.util.ArrayUtils; +import java.util.ArrayList; +import java.util.List; import java.util.function.Consumer; /** - * Class that registers callbacks with the {@link DeviceStateManager} and - * responds to fold state changes by forwarding such events to a delegate. + * Class that registers callbacks with the {@link DeviceStateManager} and responds to device + * changes. */ -final class DeviceStateController { +final class DeviceStateController implements DeviceStateManager.DeviceStateCallback { + + @NonNull private final DeviceStateManager mDeviceStateManager; - private final Context mContext; + @NonNull + private final int[] mOpenDeviceStates; + @NonNull + private final int[] mHalfFoldedDeviceStates; + @NonNull + private final int[] mFoldedDeviceStates; + @NonNull + private final int[] mRearDisplayDeviceStates; + @NonNull + private final List> mDeviceStateCallbacks = new ArrayList<>(); - private FoldStateListener mDeviceStateListener; + @Nullable + private DeviceState mLastDeviceState; - public enum FoldState { - UNKNOWN, OPEN, FOLDED, HALF_FOLDED + public enum DeviceState { + UNKNOWN, OPEN, FOLDED, HALF_FOLDED, REAR, } - DeviceStateController(Context context, Handler handler, Consumer delegate) { - mContext = context; - mDeviceStateManager = mContext.getSystemService(DeviceStateManager.class); + DeviceStateController(@NonNull Context context, @NonNull Handler handler) { + mDeviceStateManager = context.getSystemService(DeviceStateManager.class); + mOpenDeviceStates = context.getResources() + .getIntArray(R.array.config_openDeviceStates); + mHalfFoldedDeviceStates = context.getResources() + .getIntArray(R.array.config_halfFoldedDeviceStates); + mFoldedDeviceStates = context.getResources() + .getIntArray(R.array.config_foldedDeviceStates); + mRearDisplayDeviceStates = context.getResources() + .getIntArray(R.array.config_rearDisplayDeviceStates); + if (mDeviceStateManager != null) { - mDeviceStateListener = new FoldStateListener(mContext, delegate); - mDeviceStateManager - .registerCallback(new HandlerExecutor(handler), - mDeviceStateListener); + mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this); } } void unregisterFromDeviceStateManager() { - if (mDeviceStateListener != null) { - mDeviceStateManager.unregisterCallback(mDeviceStateListener); + if (mDeviceStateManager != null) { + mDeviceStateManager.unregisterCallback(this); } } - /** - * A listener for half-fold device state events that dispatches state changes to a delegate. - */ - static final class FoldStateListener implements DeviceStateManager.DeviceStateCallback { + void registerDeviceStateCallback(@NonNull Consumer callback) { + mDeviceStateCallbacks.add(callback); + } - private final int[] mHalfFoldedDeviceStates; - private final int[] mFoldedDeviceStates; - - @Nullable - private FoldState mLastResult; - private final Consumer mDelegate; - - FoldStateListener(Context context, Consumer delegate) { - mFoldedDeviceStates = context.getResources().getIntArray( - com.android.internal.R.array.config_foldedDeviceStates); - mHalfFoldedDeviceStates = context.getResources().getIntArray( - com.android.internal.R.array.config_halfFoldedDeviceStates); - mDelegate = delegate; + @Override + public void onStateChanged(int state) { + final DeviceState deviceState; + if (ArrayUtils.contains(mHalfFoldedDeviceStates, state)) { + deviceState = DeviceState.HALF_FOLDED; + } else if (ArrayUtils.contains(mFoldedDeviceStates, state)) { + deviceState = DeviceState.FOLDED; + } else if (ArrayUtils.contains(mRearDisplayDeviceStates, state)) { + deviceState = DeviceState.REAR; + } else if (ArrayUtils.contains(mOpenDeviceStates, state)) { + deviceState = DeviceState.OPEN; + } else { + deviceState = DeviceState.UNKNOWN; } - @Override - public void onStateChanged(int state) { - final boolean halfFolded = ArrayUtils.contains(mHalfFoldedDeviceStates, state); - FoldState result; - if (halfFolded) { - result = FoldState.HALF_FOLDED; - } else { - final boolean folded = ArrayUtils.contains(mFoldedDeviceStates, state); - result = folded ? FoldState.FOLDED : FoldState.OPEN; - } - if (mLastResult == null || !mLastResult.equals(result)) { - mLastResult = result; - mDelegate.accept(result); + if (mLastDeviceState == null || !mLastDeviceState.equals(deviceState)) { + mLastDeviceState = deviceState; + + for (Consumer callback : mDeviceStateCallbacks) { + callback.accept(mLastDeviceState); } } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 75d84eabd146c..5b2a3e33d01fe 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1125,14 +1125,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mWmService.mAtmService.getRecentTasks().getInputListener()); } + mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH); + mDisplayPolicy = new DisplayPolicy(mWmService, this); mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address); - mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH, - newFoldState -> { + final Consumer deviceStateConsumer = + (@NonNull DeviceStateController.DeviceState newFoldState) -> { mDisplaySwitchTransitionLauncher.foldStateChanged(newFoldState); mDisplayRotation.foldStateChanged(newFoldState); - }); + }; + mDeviceStateController.registerDeviceStateCallback(deviceStateConsumer); mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat( R.dimen.config_closeToSquareDisplayMaxAspectRatio); diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index e6d8b3db45647..a1e18cf75ae60 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -1573,7 +1573,7 @@ public class DisplayRotation { proto.end(token); } - boolean isDeviceInPosture(DeviceStateController.FoldState state, boolean isTabletop) { + boolean isDeviceInPosture(DeviceStateController.DeviceState state, boolean isTabletop) { if (mFoldController == null) return false; return mFoldController.isDeviceInPosture(state, isTabletop); } @@ -1585,10 +1585,10 @@ public class DisplayRotation { /** * Called by the DeviceStateManager callback when the device state changes. */ - void foldStateChanged(DeviceStateController.FoldState foldState) { + void foldStateChanged(DeviceStateController.DeviceState deviceState) { if (mFoldController != null) { synchronized (mLock) { - mFoldController.foldStateChanged(foldState); + mFoldController.foldStateChanged(deviceState); } } } @@ -1596,8 +1596,8 @@ public class DisplayRotation { private class FoldController { @Surface.Rotation private int mHalfFoldSavedRotation = -1; // No saved rotation - private DeviceStateController.FoldState mFoldState = - DeviceStateController.FoldState.UNKNOWN; + private DeviceStateController.DeviceState mDeviceState = + DeviceStateController.DeviceState.UNKNOWN; private boolean mInHalfFoldTransition = false; private final boolean mIsDisplayAlwaysSeparatingHinge; private final Set mTabletopRotations; @@ -1637,32 +1637,33 @@ public class DisplayRotation { R.bool.config_isDisplayHingeAlwaysSeparating); } - boolean isDeviceInPosture(DeviceStateController.FoldState state, boolean isTabletop) { - if (state != mFoldState) { + boolean isDeviceInPosture(DeviceStateController.DeviceState state, boolean isTabletop) { + if (state != mDeviceState) { return false; } - if (mFoldState == DeviceStateController.FoldState.HALF_FOLDED) { + if (mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED) { return !(isTabletop ^ mTabletopRotations.contains(mRotation)); } return true; } - DeviceStateController.FoldState getFoldState() { - return mFoldState; + DeviceStateController.DeviceState getFoldState() { + return mDeviceState; } boolean isSeparatingHinge() { - return mFoldState == DeviceStateController.FoldState.HALF_FOLDED - || (mFoldState == DeviceStateController.FoldState.OPEN + return mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED + || (mDeviceState == DeviceStateController.DeviceState.OPEN && mIsDisplayAlwaysSeparatingHinge); } boolean overrideFrozenRotation() { - return mFoldState == DeviceStateController.FoldState.HALF_FOLDED; + return mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED; } boolean shouldRevertOverriddenRotation() { - return mFoldState == DeviceStateController.FoldState.OPEN // When transitioning to open. + // When transitioning to open. + return mDeviceState == DeviceStateController.DeviceState.OPEN && mInHalfFoldTransition && mHalfFoldSavedRotation != -1 // Ignore if we've already reverted. && mUserRotationMode @@ -1676,30 +1677,30 @@ public class DisplayRotation { return savedRotation; } - void foldStateChanged(DeviceStateController.FoldState newState) { + void foldStateChanged(DeviceStateController.DeviceState newState) { ProtoLog.v(WM_DEBUG_ORIENTATION, "foldStateChanged: displayId %d, halfFoldStateChanged %s, " + "saved rotation: %d, mUserRotation: %d, mLastSensorRotation: %d, " + "mLastOrientation: %d, mRotation: %d", mDisplayContent.getDisplayId(), newState.name(), mHalfFoldSavedRotation, mUserRotation, mLastSensorRotation, mLastOrientation, mRotation); - if (mFoldState == DeviceStateController.FoldState.UNKNOWN) { - mFoldState = newState; + if (mDeviceState == DeviceStateController.DeviceState.UNKNOWN) { + mDeviceState = newState; return; } - if (newState == DeviceStateController.FoldState.HALF_FOLDED - && mFoldState != DeviceStateController.FoldState.HALF_FOLDED) { + if (newState == DeviceStateController.DeviceState.HALF_FOLDED + && mDeviceState != DeviceStateController.DeviceState.HALF_FOLDED) { // The device has transitioned to HALF_FOLDED state: save the current rotation and // update the device rotation. mHalfFoldSavedRotation = mRotation; - mFoldState = newState; + mDeviceState = newState; // Now mFoldState is set to HALF_FOLDED, the overrideFrozenRotation function will // return true, so rotation is unlocked. mService.updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */); } else { mInHalfFoldTransition = true; - mFoldState = newState; + mDeviceState = newState; // Tell the device to update its orientation. mService.updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */); @@ -1822,7 +1823,7 @@ public class DisplayRotation { final long mTimestamp = System.currentTimeMillis(); final int mHalfFoldSavedRotation; final boolean mInHalfFoldTransition; - final DeviceStateController.FoldState mFoldState; + final DeviceStateController.DeviceState mDeviceState; @Nullable final String mDisplayRotationCompatPolicySummary; Record(DisplayRotation dr, int fromRotation, int toRotation) { @@ -1852,11 +1853,11 @@ public class DisplayRotation { if (dr.mFoldController != null) { mHalfFoldSavedRotation = dr.mFoldController.mHalfFoldSavedRotation; mInHalfFoldTransition = dr.mFoldController.mInHalfFoldTransition; - mFoldState = dr.mFoldController.mFoldState; + mDeviceState = dr.mFoldController.mDeviceState; } else { mHalfFoldSavedRotation = NO_FOLD_CONTROLLER; mInHalfFoldTransition = false; - mFoldState = DeviceStateController.FoldState.UNKNOWN; + mDeviceState = DeviceStateController.DeviceState.UNKNOWN; } mDisplayRotationCompatPolicySummary = dc.mDisplayRotationCompatPolicy == null ? null @@ -1882,7 +1883,7 @@ public class DisplayRotation { pw.println(prefix + " halfFoldSavedRotation=" + mHalfFoldSavedRotation + " mInHalfFoldTransition=" + mInHalfFoldTransition - + " mFoldState=" + mFoldState); + + " mFoldState=" + mDeviceState); } if (mDisplayRotationCompatPolicySummary != null) { pw.println(prefix + mDisplayRotationCompatPolicySummary); diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 67e188fa90454..53195e27db910 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -533,7 +533,7 @@ final class LetterboxUiController { // Note that we check the task rather than the parent as with ActivityEmbedding the parent might // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is // actually fullscreen. - private boolean isDisplayFullScreenAndInPosture(DeviceStateController.FoldState state, + private boolean isDisplayFullScreenAndInPosture(DeviceStateController.DeviceState state, boolean isTabletop) { Task task = mActivityRecord.getTask(); return mActivityRecord.mDisplayContent != null @@ -559,7 +559,7 @@ final class LetterboxUiController { // Don't check resolved configuration because it may not be updated yet during // configuration change. boolean bookMode = isDisplayFullScreenAndInPosture( - DeviceStateController.FoldState.HALF_FOLDED, false /* isTabletop */); + DeviceStateController.DeviceState.HALF_FOLDED, false /* isTabletop */); return isHorizontalReachabilityEnabled(parentConfiguration) // Using the last global dynamic position to avoid "jumps" when moving // between apps or activities. @@ -571,7 +571,7 @@ final class LetterboxUiController { // Don't check resolved configuration because it may not be updated yet during // configuration change. boolean tabletopMode = isDisplayFullScreenAndInPosture( - DeviceStateController.FoldState.HALF_FOLDED, true /* isTabletop */); + DeviceStateController.DeviceState.HALF_FOLDED, true /* isTabletop */); return isVerticalReachabilityEnabled(parentConfiguration) // Using the last global dynamic position to avoid "jumps" when moving // between apps or activities. @@ -1087,7 +1087,7 @@ final class LetterboxUiController { int letterboxPositionForHorizontalReachability = getLetterboxConfiguration() .getLetterboxPositionForHorizontalReachability( isDisplayFullScreenAndInPosture( - DeviceStateController.FoldState.HALF_FOLDED, + DeviceStateController.DeviceState.HALF_FOLDED, false /* isTabletop */)); positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition( letterboxPositionForHorizontalReachability); @@ -1095,7 +1095,7 @@ final class LetterboxUiController { int letterboxPositionForVerticalReachability = getLetterboxConfiguration() .getLetterboxPositionForVerticalReachability( isDisplayFullScreenAndInPosture( - DeviceStateController.FoldState.HALF_FOLDED, + DeviceStateController.DeviceState.HALF_FOLDED, true /* isTabletop */)); positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition( letterboxPositionForVerticalReachability); diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java index 30bdc3477edf3..2edb082ab8df1 100644 --- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java +++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java @@ -51,10 +51,10 @@ public class PhysicalDisplaySwitchTransitionLauncher { /** * Called by the DeviceStateManager callback when the state changes. */ - void foldStateChanged(DeviceStateController.FoldState newFoldState) { + void foldStateChanged(DeviceStateController.DeviceState newDeviceState) { // Ignore transitions to/from half-folded. - if (newFoldState == DeviceStateController.FoldState.HALF_FOLDED) return; - mIsFolded = newFoldState == DeviceStateController.FoldState.FOLDED; + if (newDeviceState == DeviceStateController.DeviceState.HALF_FOLDED) return; + mIsFolded = newDeviceState == DeviceStateController.DeviceState.FOLDED; } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java index 86732c9a3f466..2a28ae29e692e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java @@ -16,13 +16,12 @@ package com.android.server.wm; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; import android.content.Context; import android.content.res.Resources; @@ -32,9 +31,10 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; +import com.android.internal.R; + import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; import java.util.function.Consumer; @@ -48,92 +48,76 @@ import java.util.function.Consumer; @Presubmit public class DeviceStateControllerTests { - private DeviceStateController.FoldStateListener mFoldStateListener; private DeviceStateController mTarget; private DeviceStateControllerBuilder mBuilder; private Context mMockContext; - private Handler mMockHandler; - private Resources mMockRes; private DeviceStateManager mMockDeviceStateManager; - - private Consumer mDelegate; - private DeviceStateController.FoldState mCurrentState = DeviceStateController.FoldState.UNKNOWN; + private DeviceStateController.DeviceState mCurrentState = + DeviceStateController.DeviceState.UNKNOWN; @Before public void setUp() { mBuilder = new DeviceStateControllerBuilder(); - mCurrentState = DeviceStateController.FoldState.UNKNOWN; + mCurrentState = DeviceStateController.DeviceState.UNKNOWN; } - private void initialize(boolean supportFold, boolean supportHalfFold) throws Exception { + private void initialize(boolean supportFold, boolean supportHalfFold) { mBuilder.setSupportFold(supportFold, supportHalfFold); - mDelegate = (newFoldState) -> { + Consumer delegate = (newFoldState) -> { mCurrentState = newFoldState; }; - mBuilder.setDelegate(mDelegate); + mBuilder.setDelegate(delegate); mBuilder.build(); - verifyFoldStateListenerRegistration(1); + verify(mMockDeviceStateManager).registerCallback(any(), any()); } @Test - public void testInitialization() throws Exception { + public void testInitialization() { initialize(true /* supportFold */, true /* supportHalfFolded */); - mFoldStateListener.onStateChanged(mUnfoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.OPEN); + mTarget.onStateChanged(mOpenDeviceStates[0]); + assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState); } @Test - public void testInitializationWithNoFoldSupport() throws Exception { + public void testInitializationWithNoFoldSupport() { initialize(false /* supportFold */, false /* supportHalfFolded */); - mFoldStateListener.onStateChanged(mFoldedStates[0]); + mTarget.onStateChanged(mFoldedStates[0]); // Note that the folded state is ignored. - assertEquals(mCurrentState, DeviceStateController.FoldState.OPEN); + assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); } @Test - public void testWithFoldSupported() throws Exception { + public void testWithFoldSupported() { initialize(true /* supportFold */, false /* supportHalfFolded */); - mFoldStateListener.onStateChanged(mUnfoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.OPEN); - mFoldStateListener.onStateChanged(mFoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.FOLDED); - mFoldStateListener.onStateChanged(mHalfFoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.OPEN); // Ignored + mTarget.onStateChanged(mOpenDeviceStates[0]); + assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState); + mTarget.onStateChanged(mFoldedStates[0]); + assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState); + mTarget.onStateChanged(mHalfFoldedStates[0]); + assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored } @Test - public void testWithHalfFoldSupported() throws Exception { + public void testWithHalfFoldSupported() { initialize(true /* supportFold */, true /* supportHalfFolded */); - mFoldStateListener.onStateChanged(mUnfoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.OPEN); - mFoldStateListener.onStateChanged(mFoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.FOLDED); - mFoldStateListener.onStateChanged(mHalfFoldedStates[0]); - assertEquals(mCurrentState, DeviceStateController.FoldState.HALF_FOLDED); + mTarget.onStateChanged(mOpenDeviceStates[0]); + assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState); + mTarget.onStateChanged(mFoldedStates[0]); + assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState); + mTarget.onStateChanged(mHalfFoldedStates[0]); + assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState); } - private final int[] mFoldedStates = {0}; - private final int[] mUnfoldedStates = {1}; + private final int[] mOpenDeviceStates = {1}; private final int[] mHalfFoldedStates = {2}; - - - private void verifyFoldStateListenerRegistration(int numOfInvocation) { - final ArgumentCaptor listenerCaptor = - ArgumentCaptor.forClass(DeviceStateController.FoldStateListener.class); - verify(mMockDeviceStateManager, times(numOfInvocation)).registerCallback( - any(), - listenerCaptor.capture()); - if (numOfInvocation > 0) { - mFoldStateListener = listenerCaptor.getValue(); - } - } + private final int[] mRearDisplayStates = {3}; private class DeviceStateControllerBuilder { private boolean mSupportFold = false; private boolean mSupportHalfFold = false; - private Consumer mDelegate; + private Consumer mDelegate; DeviceStateControllerBuilder setSupportFold( boolean supportFold, boolean supportHalfFold) { @@ -143,34 +127,44 @@ public class DeviceStateControllerTests { } DeviceStateControllerBuilder setDelegate( - Consumer delegate) { + Consumer delegate) { mDelegate = delegate; return this; } private void mockFold(boolean enableFold, boolean enableHalfFold) { + if (enableFold || enableHalfFold) { + when(mMockContext.getResources() + .getIntArray(R.array.config_openDeviceStates)) + .thenReturn(mOpenDeviceStates); + when(mMockContext.getResources() + .getIntArray(R.array.config_rearDisplayDeviceStates)) + .thenReturn(mRearDisplayStates); + } + if (enableFold) { - when(mMockContext.getResources().getIntArray( - com.android.internal.R.array.config_foldedDeviceStates)) + when(mMockContext.getResources() + .getIntArray(R.array.config_foldedDeviceStates)) .thenReturn(mFoldedStates); } if (enableHalfFold) { - when(mMockContext.getResources().getIntArray( - com.android.internal.R.array.config_halfFoldedDeviceStates)) + when(mMockContext.getResources() + .getIntArray(R.array.config_halfFoldedDeviceStates)) .thenReturn(mHalfFoldedStates); } } - private void build() throws Exception { + private void build() { mMockContext = mock(Context.class); - mMockRes = mock(Resources.class); - when(mMockContext.getResources()).thenReturn((mMockRes)); mMockDeviceStateManager = mock(DeviceStateManager.class); when(mMockContext.getSystemService(DeviceStateManager.class)) .thenReturn(mMockDeviceStateManager); + Resources mockRes = mock(Resources.class); + when(mMockContext.getResources()).thenReturn((mockRes)); mockFold(mSupportFold, mSupportHalfFold); - mMockHandler = mock(Handler.class); - mTarget = new DeviceStateController(mMockContext, mMockHandler, mDelegate); + Handler mockHandler = mock(Handler.class); + mTarget = new DeviceStateController(mMockContext, mockHandler); + mTarget.registerDeviceStateCallback(mDelegate); } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index 4ce43e1fc4690..f814608ed87ae 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -705,7 +705,7 @@ public class DisplayRotationTests { enableOrientationSensor(); - mTarget.foldStateChanged(DeviceStateController.FoldState.OPEN); + mTarget.foldStateChanged(DeviceStateController.DeviceState.OPEN); freezeRotation(Surface.ROTATION_270); mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_0)); @@ -715,7 +715,7 @@ public class DisplayRotationTests { SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0)); // ... until half-fold - mTarget.foldStateChanged(DeviceStateController.FoldState.HALF_FOLDED); + mTarget.foldStateChanged(DeviceStateController.DeviceState.HALF_FOLDED); assertTrue(waitForUiHandler()); verify(sMockWm).updateRotation(false, false); assertTrue(waitForUiHandler()); @@ -723,7 +723,7 @@ public class DisplayRotationTests { SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0)); // ... then transition back to flat - mTarget.foldStateChanged(DeviceStateController.FoldState.OPEN); + mTarget.foldStateChanged(DeviceStateController.DeviceState.OPEN); assertTrue(waitForUiHandler()); verify(sMockWm, atLeast(1)).updateRotation(false, false); assertTrue(waitForUiHandler()); diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index e5ff91f1ba373..e57201b009290 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -98,7 +98,7 @@ import androidx.test.filters.MediumTest; import com.android.internal.policy.SystemBarUtils; import com.android.internal.statusbar.LetterboxDetails; import com.android.server.statusbar.StatusBarManagerInternal; -import com.android.server.wm.DeviceStateController.FoldState; +import com.android.server.wm.DeviceStateController.DeviceState; import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; @@ -3059,9 +3059,9 @@ public class SizeCompatTests extends WindowTestsBase { private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) { final DisplayRotation r = mActivity.mDisplayContent.getDisplayRotation(); doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge(); - doReturn(false).when(r).isDeviceInPosture(any(FoldState.class), anyBoolean()); + doReturn(false).when(r).isDeviceInPosture(any(DeviceState.class), anyBoolean()); if (isHalfFolded) { - doReturn(true).when(r).isDeviceInPosture(FoldState.HALF_FOLDED, isTabletop); + doReturn(true).when(r).isDeviceInPosture(DeviceState.HALF_FOLDED, isTabletop); } mActivity.recomputeConfiguration(); }