Loading packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt +55 −27 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.biometrics.SensorLocationInternal import android.hardware.display.DisplayManager import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintSensorPropertiesInternal Loading Loading @@ -113,6 +114,7 @@ class SidefpsController @Inject constructor( orientationListener.enable() } } private var overlayOffsets: SensorLocationInternal = SensorLocationInternal.DEFAULT private val overlayViewParams = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, Loading Loading @@ -158,11 +160,19 @@ class SidefpsController @Inject constructor( val view = layoutInflater.inflate(R.layout.sidefps_view, null, false) val display = context.display!! val offsets = sensorProps.getLocation(display.uniqueId).let { location -> if (location == null) { Log.w(TAG, "No location specified for display: ${display.uniqueId}") } location ?: sensorProps.location } overlayOffsets = offsets val lottie = view.findViewById(R.id.sidefps_animation) as LottieAnimationView lottie.setAnimation(display.asSideFpsAnimation()) view.rotation = display.asSideFpsAnimationRotation() view.rotation = display.asSideFpsAnimationRotation(offsets.isYAligned()) updateOverlayParams(display, lottie.composition?.bounds ?: Rect()) lottie.setAnimation(display.asSideFpsAnimation(offsets.isYAligned())) lottie.addLottieOnCompositionLoadedListener { if (overlayView == view) { updateOverlayParams(display, it.bounds) Loading @@ -179,24 +189,37 @@ class SidefpsController @Inject constructor( val size = windowManager.maximumWindowMetrics.bounds val displayWidth = if (isPortrait) size.width() else size.height() val displayHeight = if (isPortrait) size.height() else size.width() val offsets = sensorProps.getLocation(display.uniqueId).let { location -> if (location == null) { Log.w(TAG, "No location specified for display: ${display.uniqueId}") } location ?: sensorProps.location } // ignore sensorLocationX and sensorRadius since it's assumed to be on the side // of the device and centered at sensorLocationY val (x, y) = when (display.rotation) { // ignore sensorRadius since it's assumed that the sensor is on the side and centered at // either sensorLocationX or sensorLocationY (both should not be set) val (x, y) = if (overlayOffsets.isYAligned()) { when (display.rotation) { Surface.ROTATION_90 -> Pair(overlayOffsets.sensorLocationY, 0) Surface.ROTATION_270 -> Pair( displayHeight - overlayOffsets.sensorLocationY - bounds.width(), displayWidth + bounds.height() ) Surface.ROTATION_180 -> Pair(0, displayHeight - overlayOffsets.sensorLocationY - bounds.height()) else -> Pair(displayWidth, overlayOffsets.sensorLocationY) } } else { when (display.rotation) { Surface.ROTATION_90 -> Pair(offsets.sensorLocationY, 0) Pair(0, displayWidth - overlayOffsets.sensorLocationX - bounds.height()) Surface.ROTATION_270 -> Pair(displayHeight - offsets.sensorLocationY - bounds.width(), displayWidth) Pair(displayWidth, overlayOffsets.sensorLocationX - bounds.height()) Surface.ROTATION_180 -> Pair(0, displayHeight - offsets.sensorLocationY - bounds.height()) Pair( displayWidth - overlayOffsets.sensorLocationX - bounds.width(), displayHeight ) else -> Pair(displayWidth, offsets.sensorLocationY) Pair(overlayOffsets.sensorLocationX, 0) } } overlayViewParams.x = x overlayViewParams.y = y Loading @@ -209,8 +232,10 @@ class SidefpsController @Inject constructor( // hide after a few seconds if the sensor is oriented down and there are // large overlapping system bars if ((context.display?.rotation == Surface.ROTATION_270) && windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar()) { val rotation = context.display?.rotation if (windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() && ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) || (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))) { overlayHideAnimator = view.animate() .alpha(0f) .setStartDelay(3_000) Loading Loading @@ -245,18 +270,21 @@ private fun ActivityTaskManager.topClass(): String = getTasks(1).firstOrNull()?.topActivity?.className ?: "" @RawRes private fun Display.asSideFpsAnimation(): Int = when (rotation) { Surface.ROTATION_0 -> R.raw.sfps_pulse Surface.ROTATION_180 -> R.raw.sfps_pulse else -> R.raw.sfps_pulse_landscape private fun Display.asSideFpsAnimation(yAligned: Boolean): Int = when (rotation) { Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse } private fun Display.asSideFpsAnimationRotation(): Float = when (rotation) { private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float = when (rotation) { Surface.ROTATION_90 -> if (yAligned) 0f else 180f Surface.ROTATION_180 -> 180f Surface.ROTATION_270 -> 180f Surface.ROTATION_270 -> if (yAligned) 180f else 0f else -> 0f } private fun SensorLocationInternal.isYAligned(): Boolean = sensorLocationY != 0 private fun Display.isPortrait(): Boolean = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt +99 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN import android.hardware.biometrics.SensorLocationInternal import android.hardware.biometrics.SensorProperties import android.hardware.display.DisplayManager import android.hardware.display.DisplayManagerGlobal Loading Loading @@ -52,6 +53,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.recents.OverviewProxyService import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -75,6 +77,12 @@ import org.mockito.junit.MockitoJUnit private const val DISPLAY_ID = 2 private const val SENSOR_ID = 1 private const val DISPLAY_SIZE_X = 800 private const val DISPLAY_SIZE_Y = 900 private val X_LOCATION = SensorLocationInternal("", 540, 0, 20) private val Y_LOCATION = SensorLocationInternal("", 0, 1500, 22) @SmallTest @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper Loading @@ -101,6 +109,8 @@ class SidefpsControllerTest : SysuiTestCase() { lateinit var handler: Handler @Captor lateinit var overlayCaptor: ArgumentCaptor<View> @Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> private val executor = FakeExecutor(FakeSystemClock()) private lateinit var overlayController: ISidefpsController Loading @@ -125,6 +135,17 @@ class SidefpsControllerTest : SysuiTestCase() { this } } `when`(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, DISPLAY_SIZE_X, DISPLAY_SIZE_Y), WindowInsets.CONSUMED) ) } private fun testWithDisplay( initInfo: DisplayInfo.() -> Unit = {}, locations: List<SensorLocationInternal> = listOf(X_LOCATION), windowInsets: WindowInsets = insetsForSmallNavbar(), block: () -> Unit ) { `when`(fingerprintManager.sensorPropertiesInternal).thenReturn( listOf( FingerprintSensorPropertiesInternal( Loading @@ -133,22 +154,21 @@ class SidefpsControllerTest : SysuiTestCase() { 5 /* maxEnrollmentsPerUser */, listOf() /* componentInfo */, FingerprintSensorProperties.TYPE_POWER_BUTTON, true /* resetLockoutRequiresHardwareAuthToken */ true /* resetLockoutRequiresHardwareAuthToken */, locations ) ) ) `when`(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), WindowInsets.CONSUMED) ) } private fun testWithDisplay(initInfo: DisplayInfo.() -> Unit = {}, block: () -> Unit) { val displayInfo = DisplayInfo() displayInfo.initInfo() val dmGlobal = mock(DisplayManagerGlobal::class.java) val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS) `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) `when`(windowManager.defaultDisplay).thenReturn(display) `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, DISPLAY_SIZE_X, DISPLAY_SIZE_Y), windowInsets) ) sideFpsController = SidefpsController( context.createDisplayContext(display), layoutInflater, fingerprintManager, Loading Loading @@ -244,29 +264,72 @@ class SidefpsControllerTest : SysuiTestCase() { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarOnY() = testWithDisplay( { rotation = Surface.ROTATION_0 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar90() = testWithDisplay({ rotation = Surface.ROTATION_90 }) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar90OnY() = testWithDisplay( { rotation = Surface.ROTATION_90 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar180() = testWithDisplay({ rotation = Surface.ROTATION_180 }) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarCollapsedDown() = testWithDisplay({ rotation = Surface.ROTATION_270 }) { `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), insetsForSmallNavbar()) ) fun showsWithTaskbar270OnY() = testWithDisplay( { rotation = Surface.ROTATION_270 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun hidesWithTaskbarDown() = testWithDisplay({ rotation = Surface.ROTATION_270 }) { `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), insetsForLargeNavbar()) ) fun showsWithTaskbarCollapsedDown() = testWithDisplay( { rotation = Surface.ROTATION_270 }, windowInsets = insetsForSmallNavbar() ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarCollapsedDownOnY() = testWithDisplay( { rotation = Surface.ROTATION_180 }, locations = listOf(Y_LOCATION), windowInsets = insetsForSmallNavbar() ) { hidesWithTaskbar(visible = true) } @Test fun hidesWithTaskbarDown() = testWithDisplay( { rotation = Surface.ROTATION_180 }, locations = listOf(X_LOCATION), windowInsets = insetsForLargeNavbar() ) { hidesWithTaskbar(visible = false) } @Test fun hidesWithTaskbarDownOnY() = testWithDisplay( { rotation = Surface.ROTATION_270 }, locations = listOf(Y_LOCATION), windowInsets = insetsForLargeNavbar() ) { hidesWithTaskbar(visible = false) } Loading @@ -281,6 +344,28 @@ class SidefpsControllerTest : SysuiTestCase() { verify(windowManager, never()).removeView(any()) verify(sidefpsView).visibility = if (visible) View.VISIBLE else View.GONE } @Test fun setsXAlign() = testWithDisplay { overlayController.show(SENSOR_ID, REASON_UNKNOWN) executor.runAllReady() verify(windowManager).addView(any(), overlayViewParamsCaptor.capture()) assertThat(overlayViewParamsCaptor.value.x).isEqualTo(X_LOCATION.sensorLocationX) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0) } @Test fun setYAlign() = testWithDisplay(locations = listOf(Y_LOCATION)) { overlayController.show(SENSOR_ID, REASON_UNKNOWN) executor.runAllReady() verify(windowManager).addView(any(), overlayViewParamsCaptor.capture()) assertThat(overlayViewParamsCaptor.value.x).isEqualTo(DISPLAY_SIZE_X) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(Y_LOCATION.sensorLocationY) } } private fun insetsForSmallNavbar() = insetsWithBottom(60) Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt +55 −27 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.biometrics.SensorLocationInternal import android.hardware.display.DisplayManager import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintSensorPropertiesInternal Loading Loading @@ -113,6 +114,7 @@ class SidefpsController @Inject constructor( orientationListener.enable() } } private var overlayOffsets: SensorLocationInternal = SensorLocationInternal.DEFAULT private val overlayViewParams = WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, Loading Loading @@ -158,11 +160,19 @@ class SidefpsController @Inject constructor( val view = layoutInflater.inflate(R.layout.sidefps_view, null, false) val display = context.display!! val offsets = sensorProps.getLocation(display.uniqueId).let { location -> if (location == null) { Log.w(TAG, "No location specified for display: ${display.uniqueId}") } location ?: sensorProps.location } overlayOffsets = offsets val lottie = view.findViewById(R.id.sidefps_animation) as LottieAnimationView lottie.setAnimation(display.asSideFpsAnimation()) view.rotation = display.asSideFpsAnimationRotation() view.rotation = display.asSideFpsAnimationRotation(offsets.isYAligned()) updateOverlayParams(display, lottie.composition?.bounds ?: Rect()) lottie.setAnimation(display.asSideFpsAnimation(offsets.isYAligned())) lottie.addLottieOnCompositionLoadedListener { if (overlayView == view) { updateOverlayParams(display, it.bounds) Loading @@ -179,24 +189,37 @@ class SidefpsController @Inject constructor( val size = windowManager.maximumWindowMetrics.bounds val displayWidth = if (isPortrait) size.width() else size.height() val displayHeight = if (isPortrait) size.height() else size.width() val offsets = sensorProps.getLocation(display.uniqueId).let { location -> if (location == null) { Log.w(TAG, "No location specified for display: ${display.uniqueId}") } location ?: sensorProps.location } // ignore sensorLocationX and sensorRadius since it's assumed to be on the side // of the device and centered at sensorLocationY val (x, y) = when (display.rotation) { // ignore sensorRadius since it's assumed that the sensor is on the side and centered at // either sensorLocationX or sensorLocationY (both should not be set) val (x, y) = if (overlayOffsets.isYAligned()) { when (display.rotation) { Surface.ROTATION_90 -> Pair(overlayOffsets.sensorLocationY, 0) Surface.ROTATION_270 -> Pair( displayHeight - overlayOffsets.sensorLocationY - bounds.width(), displayWidth + bounds.height() ) Surface.ROTATION_180 -> Pair(0, displayHeight - overlayOffsets.sensorLocationY - bounds.height()) else -> Pair(displayWidth, overlayOffsets.sensorLocationY) } } else { when (display.rotation) { Surface.ROTATION_90 -> Pair(offsets.sensorLocationY, 0) Pair(0, displayWidth - overlayOffsets.sensorLocationX - bounds.height()) Surface.ROTATION_270 -> Pair(displayHeight - offsets.sensorLocationY - bounds.width(), displayWidth) Pair(displayWidth, overlayOffsets.sensorLocationX - bounds.height()) Surface.ROTATION_180 -> Pair(0, displayHeight - offsets.sensorLocationY - bounds.height()) Pair( displayWidth - overlayOffsets.sensorLocationX - bounds.width(), displayHeight ) else -> Pair(displayWidth, offsets.sensorLocationY) Pair(overlayOffsets.sensorLocationX, 0) } } overlayViewParams.x = x overlayViewParams.y = y Loading @@ -209,8 +232,10 @@ class SidefpsController @Inject constructor( // hide after a few seconds if the sensor is oriented down and there are // large overlapping system bars if ((context.display?.rotation == Surface.ROTATION_270) && windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar()) { val rotation = context.display?.rotation if (windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() && ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) || (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))) { overlayHideAnimator = view.animate() .alpha(0f) .setStartDelay(3_000) Loading Loading @@ -245,18 +270,21 @@ private fun ActivityTaskManager.topClass(): String = getTasks(1).firstOrNull()?.topActivity?.className ?: "" @RawRes private fun Display.asSideFpsAnimation(): Int = when (rotation) { Surface.ROTATION_0 -> R.raw.sfps_pulse Surface.ROTATION_180 -> R.raw.sfps_pulse else -> R.raw.sfps_pulse_landscape private fun Display.asSideFpsAnimation(yAligned: Boolean): Int = when (rotation) { Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse } private fun Display.asSideFpsAnimationRotation(): Float = when (rotation) { private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float = when (rotation) { Surface.ROTATION_90 -> if (yAligned) 0f else 180f Surface.ROTATION_180 -> 180f Surface.ROTATION_270 -> 180f Surface.ROTATION_270 -> if (yAligned) 180f else 0f else -> 0f } private fun SensorLocationInternal.isYAligned(): Boolean = sensorLocationY != 0 private fun Display.isPortrait(): Boolean = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt +99 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN import android.hardware.biometrics.SensorLocationInternal import android.hardware.biometrics.SensorProperties import android.hardware.display.DisplayManager import android.hardware.display.DisplayManagerGlobal Loading Loading @@ -52,6 +53,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.recents.OverviewProxyService import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -75,6 +77,12 @@ import org.mockito.junit.MockitoJUnit private const val DISPLAY_ID = 2 private const val SENSOR_ID = 1 private const val DISPLAY_SIZE_X = 800 private const val DISPLAY_SIZE_Y = 900 private val X_LOCATION = SensorLocationInternal("", 540, 0, 20) private val Y_LOCATION = SensorLocationInternal("", 0, 1500, 22) @SmallTest @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper Loading @@ -101,6 +109,8 @@ class SidefpsControllerTest : SysuiTestCase() { lateinit var handler: Handler @Captor lateinit var overlayCaptor: ArgumentCaptor<View> @Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> private val executor = FakeExecutor(FakeSystemClock()) private lateinit var overlayController: ISidefpsController Loading @@ -125,6 +135,17 @@ class SidefpsControllerTest : SysuiTestCase() { this } } `when`(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, DISPLAY_SIZE_X, DISPLAY_SIZE_Y), WindowInsets.CONSUMED) ) } private fun testWithDisplay( initInfo: DisplayInfo.() -> Unit = {}, locations: List<SensorLocationInternal> = listOf(X_LOCATION), windowInsets: WindowInsets = insetsForSmallNavbar(), block: () -> Unit ) { `when`(fingerprintManager.sensorPropertiesInternal).thenReturn( listOf( FingerprintSensorPropertiesInternal( Loading @@ -133,22 +154,21 @@ class SidefpsControllerTest : SysuiTestCase() { 5 /* maxEnrollmentsPerUser */, listOf() /* componentInfo */, FingerprintSensorProperties.TYPE_POWER_BUTTON, true /* resetLockoutRequiresHardwareAuthToken */ true /* resetLockoutRequiresHardwareAuthToken */, locations ) ) ) `when`(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), WindowInsets.CONSUMED) ) } private fun testWithDisplay(initInfo: DisplayInfo.() -> Unit = {}, block: () -> Unit) { val displayInfo = DisplayInfo() displayInfo.initInfo() val dmGlobal = mock(DisplayManagerGlobal::class.java) val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS) `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) `when`(windowManager.defaultDisplay).thenReturn(display) `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, DISPLAY_SIZE_X, DISPLAY_SIZE_Y), windowInsets) ) sideFpsController = SidefpsController( context.createDisplayContext(display), layoutInflater, fingerprintManager, Loading Loading @@ -244,29 +264,72 @@ class SidefpsControllerTest : SysuiTestCase() { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarOnY() = testWithDisplay( { rotation = Surface.ROTATION_0 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar90() = testWithDisplay({ rotation = Surface.ROTATION_90 }) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar90OnY() = testWithDisplay( { rotation = Surface.ROTATION_90 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbar180() = testWithDisplay({ rotation = Surface.ROTATION_180 }) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarCollapsedDown() = testWithDisplay({ rotation = Surface.ROTATION_270 }) { `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), insetsForSmallNavbar()) ) fun showsWithTaskbar270OnY() = testWithDisplay( { rotation = Surface.ROTATION_270 }, locations = listOf(Y_LOCATION) ) { hidesWithTaskbar(visible = true) } @Test fun hidesWithTaskbarDown() = testWithDisplay({ rotation = Surface.ROTATION_270 }) { `when`(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(Rect(0, 0, 800, 800), insetsForLargeNavbar()) ) fun showsWithTaskbarCollapsedDown() = testWithDisplay( { rotation = Surface.ROTATION_270 }, windowInsets = insetsForSmallNavbar() ) { hidesWithTaskbar(visible = true) } @Test fun showsWithTaskbarCollapsedDownOnY() = testWithDisplay( { rotation = Surface.ROTATION_180 }, locations = listOf(Y_LOCATION), windowInsets = insetsForSmallNavbar() ) { hidesWithTaskbar(visible = true) } @Test fun hidesWithTaskbarDown() = testWithDisplay( { rotation = Surface.ROTATION_180 }, locations = listOf(X_LOCATION), windowInsets = insetsForLargeNavbar() ) { hidesWithTaskbar(visible = false) } @Test fun hidesWithTaskbarDownOnY() = testWithDisplay( { rotation = Surface.ROTATION_270 }, locations = listOf(Y_LOCATION), windowInsets = insetsForLargeNavbar() ) { hidesWithTaskbar(visible = false) } Loading @@ -281,6 +344,28 @@ class SidefpsControllerTest : SysuiTestCase() { verify(windowManager, never()).removeView(any()) verify(sidefpsView).visibility = if (visible) View.VISIBLE else View.GONE } @Test fun setsXAlign() = testWithDisplay { overlayController.show(SENSOR_ID, REASON_UNKNOWN) executor.runAllReady() verify(windowManager).addView(any(), overlayViewParamsCaptor.capture()) assertThat(overlayViewParamsCaptor.value.x).isEqualTo(X_LOCATION.sensorLocationX) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0) } @Test fun setYAlign() = testWithDisplay(locations = listOf(Y_LOCATION)) { overlayController.show(SENSOR_ID, REASON_UNKNOWN) executor.runAllReady() verify(windowManager).addView(any(), overlayViewParamsCaptor.capture()) assertThat(overlayViewParamsCaptor.value.x).isEqualTo(DISPLAY_SIZE_X) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(Y_LOCATION.sensorLocationY) } } private fun insetsForSmallNavbar() = insetsWithBottom(60) Loading