diff options
10 files changed, 179 insertions, 147 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a6be07d0b780..d4b151dd8220 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -652,6 +652,16 @@ The default is false. --> <bool name="config_lidControlsSleep">false</bool> + <!-- The device states (supplied by DeviceStateManager) that should be treated as open by the + device fold controller. Default is empty. --> + <integer-array name="config_openDeviceStates"> + <!-- Example: + <item>0</item> + <item>1</item> + <item>2</item> + --> + </integer-array> + <!-- The device states (supplied by DeviceStateManager) that should be treated as folded by the display fold controller. Default is empty. --> <integer-array name="config_foldedDeviceStates"> @@ -672,6 +682,16 @@ --> </integer-array> + <!-- The device states (supplied by DeviceStateManager) that should be treated as a rear display + state. Default is empty. --> + <integer-array name="config_rearDisplayDeviceStates"> + <!-- Example: + <item>0</item> + <item>1</item> + <item>2</item> + --> + </integer-array> + <!-- Indicates whether the window manager reacts to half-fold device states by overriding rotation. --> <bool name="config_windowManagerHalfFoldAutoRotateOverride">false</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 87e1924f8f85..f95b9cf022de 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4014,8 +4014,10 @@ <java-symbol type="integer" name="config_maxScanTasksForHomeVisibility" /> <!-- For Foldables --> + <java-symbol type="array" name="config_openDeviceStates" /> <java-symbol type="array" name="config_foldedDeviceStates" /> <java-symbol type="array" name="config_halfFoldedDeviceStates" /> + <java-symbol type="array" name="config_rearDisplayDeviceStates" /> <java-symbol type="bool" name="config_windowManagerHalfFoldAutoRotateOverride" /> <java-symbol type="array" name="config_deviceStatesOnWhichToWakeUp" /> <java-symbol type="array" name="config_deviceStatesOnWhichToSleep" /> diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java index a6f855755192..2e67399321a0 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<Consumer<DeviceState>> 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<FoldState> 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 { - - private final int[] mHalfFoldedDeviceStates; - private final int[] mFoldedDeviceStates; - - @Nullable - private FoldState mLastResult; - private final Consumer<FoldState> mDelegate; + void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback) { + mDeviceStateCallbacks.add(callback); + } - FoldStateListener(Context context, Consumer<FoldState> 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<DeviceState> 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 9af1b2bd40c6..740fd584839f 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<DeviceStateController.DeviceState> 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 e6d8b3db4564..a1e18cf75ae6 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<Integer> 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 73d1ff9d27d2..b67b74559e26 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -542,7 +542,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 @@ -568,7 +568,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. @@ -580,7 +580,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. @@ -1107,7 +1107,7 @@ final class LetterboxUiController { int letterboxPositionForHorizontalReachability = getLetterboxConfiguration() .getLetterboxPositionForHorizontalReachability( isDisplayFullScreenAndInPosture( - DeviceStateController.FoldState.HALF_FOLDED, + DeviceStateController.DeviceState.HALF_FOLDED, false /* isTabletop */)); positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition( letterboxPositionForHorizontalReachability); @@ -1115,7 +1115,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 30bdc3477edf..2edb082ab8df 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 86732c9a3f46..2a28ae29e692 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<DeviceStateController.FoldState> 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<DeviceStateController.DeviceState> 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<DeviceStateController.FoldStateListener> 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<DeviceStateController.FoldState> mDelegate; + private Consumer<DeviceStateController.DeviceState> mDelegate; DeviceStateControllerBuilder setSupportFold( boolean supportFold, boolean supportHalfFold) { @@ -143,34 +127,44 @@ public class DeviceStateControllerTests { } DeviceStateControllerBuilder setDelegate( - Consumer<DeviceStateController.FoldState> delegate) { + Consumer<DeviceStateController.DeviceState> 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 4ce43e1fc469..f814608ed87a 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 46d69d14f961..a09bb337d56f 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; @@ -3186,9 +3186,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(); } |