Merge "Ensure side fingerprint sensor overlay shows above all other content." into sc-v2-dev
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.biometrics
|
package com.android.systemui.biometrics
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorListenerAdapter
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
@@ -33,6 +35,8 @@ import android.view.Gravity
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewPropertyAnimator
|
||||||
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.annotation.RawRes
|
import androidx.annotation.RawRes
|
||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
@@ -42,6 +46,7 @@ import com.android.internal.annotations.VisibleForTesting
|
|||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
|
import com.android.systemui.recents.OverviewProxyService
|
||||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -56,9 +61,10 @@ class SidefpsController @Inject constructor(
|
|||||||
private val layoutInflater: LayoutInflater,
|
private val layoutInflater: LayoutInflater,
|
||||||
fingerprintManager: FingerprintManager?,
|
fingerprintManager: FingerprintManager?,
|
||||||
private val windowManager: WindowManager,
|
private val windowManager: WindowManager,
|
||||||
@Main mainExecutor: DelayableExecutor,
|
overviewProxyService: OverviewProxyService,
|
||||||
displayManager: DisplayManager,
|
displayManager: DisplayManager,
|
||||||
@Main handler: Handler
|
@Main mainExecutor: DelayableExecutor,
|
||||||
|
@Main private val handler: Handler
|
||||||
) {
|
) {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
|
val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
|
||||||
@@ -74,15 +80,33 @@ class SidefpsController @Inject constructor(
|
|||||||
BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
|
BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
|
||||||
) { onOrientationChanged() }
|
) { onOrientationChanged() }
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
val overviewProxyListener = object : OverviewProxyService.OverviewProxyListener {
|
||||||
|
override fun onTaskbarStatusUpdated(visible: Boolean, stashed: Boolean) {
|
||||||
|
overlayView?.let { view ->
|
||||||
|
handler.postDelayed({ updateOverlayVisibility(view) }, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val animationDuration =
|
||||||
|
context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
|
||||||
|
|
||||||
|
private var overlayHideAnimator: ViewPropertyAnimator? = null
|
||||||
|
|
||||||
private var overlayView: View? = null
|
private var overlayView: View? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field?.let { oldView ->
|
field?.let { oldView ->
|
||||||
windowManager.removeView(oldView)
|
windowManager.removeView(oldView)
|
||||||
orientationListener.disable()
|
orientationListener.disable()
|
||||||
}
|
}
|
||||||
|
overlayHideAnimator?.cancel()
|
||||||
|
overlayHideAnimator = null
|
||||||
|
|
||||||
field = value
|
field = value
|
||||||
field?.let { newView ->
|
field?.let { newView ->
|
||||||
windowManager.addView(newView, overlayViewParams)
|
windowManager.addView(newView, overlayViewParams)
|
||||||
|
updateOverlayVisibility(newView)
|
||||||
orientationListener.enable()
|
orientationListener.enable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,11 +114,8 @@ class SidefpsController @Inject constructor(
|
|||||||
private val overlayViewParams = WindowManager.LayoutParams(
|
private val overlayViewParams = WindowManager.LayoutParams(
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||||
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
|
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
|
||||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
|
||||||
or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
|
||||||
or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
|
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
).apply {
|
).apply {
|
||||||
title = TAG
|
title = TAG
|
||||||
@@ -121,6 +142,7 @@ class SidefpsController @Inject constructor(
|
|||||||
|
|
||||||
override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
|
override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
|
||||||
})
|
})
|
||||||
|
overviewProxyService.addCallback(overviewProxyListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onOrientationChanged() {
|
private fun onOrientationChanged() {
|
||||||
@@ -176,6 +198,33 @@ class SidefpsController @Inject constructor(
|
|||||||
overlayViewParams.x = x
|
overlayViewParams.x = x
|
||||||
overlayViewParams.y = y
|
overlayViewParams.y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateOverlayVisibility(view: View) {
|
||||||
|
if (view != overlayView) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()) {
|
||||||
|
overlayHideAnimator = view.animate()
|
||||||
|
.alpha(0f)
|
||||||
|
.setStartDelay(3_000)
|
||||||
|
.setDuration(animationDuration)
|
||||||
|
.setListener(object : AnimatorListenerAdapter() {
|
||||||
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
|
view.visibility = View.GONE
|
||||||
|
overlayHideAnimator = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
overlayHideAnimator?.cancel()
|
||||||
|
overlayHideAnimator = null
|
||||||
|
view.alpha = 1f
|
||||||
|
view.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BiometricOverlayConstants.ShowReason
|
@BiometricOverlayConstants.ShowReason
|
||||||
@@ -200,6 +249,9 @@ private fun Display.asSideFpsAnimationRotation(): Float = when (rotation) {
|
|||||||
private fun Display.isPortrait(): Boolean =
|
private fun Display.isPortrait(): Boolean =
|
||||||
rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
|
rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
|
||||||
|
|
||||||
|
private fun WindowInsets.hasBigNavigationBar(): Boolean =
|
||||||
|
getInsets(WindowInsets.Type.navigationBars()).bottom >= 70
|
||||||
|
|
||||||
private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
|
private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
|
||||||
fun update() {
|
fun update() {
|
||||||
val c = context.getColor(R.color.biometric_dialog_accent)
|
val c = context.getColor(R.color.biometric_dialog_accent)
|
||||||
|
|||||||
@@ -583,7 +583,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
|
|
||||||
mCoreLayoutParams = new WindowManager.LayoutParams(
|
mCoreLayoutParams = new WindowManager.LayoutParams(
|
||||||
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
|
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
|
||||||
getCoreLayoutParamFlags(),
|
Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
|
||||||
PixelFormat.TRANSLUCENT);
|
PixelFormat.TRANSLUCENT);
|
||||||
mCoreLayoutParams.setTitle(TAG);
|
mCoreLayoutParams.setTitle(TAG);
|
||||||
mCoreLayoutParams.setFitInsetsTypes(0);
|
mCoreLayoutParams.setFitInsetsTypes(0);
|
||||||
@@ -616,13 +616,6 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCoreLayoutParamFlags() {
|
|
||||||
return WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
|
||||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private FingerprintSensorPropertiesInternal findFirstUdfps() {
|
private FingerprintSensorPropertiesInternal findFirstUdfps() {
|
||||||
for (FingerprintSensorPropertiesInternal props :
|
for (FingerprintSensorPropertiesInternal props :
|
||||||
@@ -685,7 +678,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
final int paddingX = animation != null ? animation.getPaddingX() : 0;
|
final int paddingX = animation != null ? animation.getPaddingX() : 0;
|
||||||
final int paddingY = animation != null ? animation.getPaddingY() : 0;
|
final int paddingY = animation != null ? animation.getPaddingY() : 0;
|
||||||
|
|
||||||
mCoreLayoutParams.flags = getCoreLayoutParamFlags();
|
mCoreLayoutParams.flags = Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS;
|
||||||
if (animation != null && animation.listenForTouchesOutsideView()) {
|
if (animation != null && animation.listenForTouchesOutsideView()) {
|
||||||
mCoreLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
|
mCoreLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import android.hardware.biometrics.SensorPropertiesInternal;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
|
||||||
@@ -46,6 +47,13 @@ public class Utils {
|
|||||||
public static final int CREDENTIAL_PATTERN = 2;
|
public static final int CREDENTIAL_PATTERN = 2;
|
||||||
public static final int CREDENTIAL_PASSWORD = 3;
|
public static final int CREDENTIAL_PASSWORD = 3;
|
||||||
|
|
||||||
|
/** Base set of layout flags for fingerprint overlay widgets. */
|
||||||
|
public static final int FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS =
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
|
@IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
|
||||||
@interface CredentialType {}
|
@interface CredentialType {}
|
||||||
@@ -55,11 +63,6 @@ public class Utils {
|
|||||||
/ DisplayMetrics.DENSITY_DEFAULT);
|
/ DisplayMetrics.DENSITY_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float pixelsToDp(Context context, float pixels) {
|
|
||||||
return pixels / ((float) context.getResources().getDisplayMetrics().densityDpi
|
|
||||||
/ DisplayMetrics.DENSITY_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view) {
|
static void notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view) {
|
||||||
if (!am.isEnabled()) {
|
if (!am.isEnabled()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.biometrics
|
package com.android.systemui.biometrics
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.graphics.Insets
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
|
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
|
import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
|
||||||
@@ -33,7 +35,9 @@ import android.view.Display
|
|||||||
import android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
|
import android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
|
||||||
import android.view.DisplayInfo
|
import android.view.DisplayInfo
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Surface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewPropertyAnimator
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.WindowMetrics
|
import android.view.WindowMetrics
|
||||||
@@ -41,6 +45,7 @@ import androidx.test.filters.SmallTest
|
|||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.recents.OverviewProxyService
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@@ -53,6 +58,8 @@ import org.mockito.Captor
|
|||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import org.mockito.Mockito.any
|
import org.mockito.Mockito.any
|
||||||
|
import org.mockito.Mockito.anyFloat
|
||||||
|
import org.mockito.Mockito.anyLong
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.reset
|
import org.mockito.Mockito.reset
|
||||||
@@ -81,6 +88,8 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
@Mock
|
@Mock
|
||||||
lateinit var displayManager: DisplayManager
|
lateinit var displayManager: DisplayManager
|
||||||
@Mock
|
@Mock
|
||||||
|
lateinit var overviewProxyService: OverviewProxyService
|
||||||
|
@Mock
|
||||||
lateinit var handler: Handler
|
lateinit var handler: Handler
|
||||||
@Captor
|
@Captor
|
||||||
lateinit var overlayCaptor: ArgumentCaptor<View>
|
lateinit var overlayCaptor: ArgumentCaptor<View>
|
||||||
@@ -91,9 +100,23 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
|
context.addMockSystemService(DisplayManager::class.java, displayManager)
|
||||||
|
context.addMockSystemService(WindowManager::class.java, windowManager)
|
||||||
|
|
||||||
`when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
|
`when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
|
||||||
`when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
|
`when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
|
||||||
.thenReturn(mock(LottieAnimationView::class.java))
|
.thenReturn(mock(LottieAnimationView::class.java))
|
||||||
|
with(mock(ViewPropertyAnimator::class.java)) {
|
||||||
|
`when`(sidefpsView.animate()).thenReturn(this)
|
||||||
|
`when`(alpha(anyFloat())).thenReturn(this)
|
||||||
|
`when`(setStartDelay(anyLong())).thenReturn(this)
|
||||||
|
`when`(setDuration(anyLong())).thenReturn(this)
|
||||||
|
`when`(setListener(any())).thenAnswer {
|
||||||
|
(it.arguments[0] as Animator.AnimatorListener)
|
||||||
|
.onAnimationEnd(mock(Animator::class.java))
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
`when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
|
`when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
|
||||||
listOf(
|
listOf(
|
||||||
FingerprintSensorPropertiesInternal(
|
FingerprintSensorPropertiesInternal(
|
||||||
@@ -106,30 +129,33 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
`when`(windowManager.defaultDisplay).thenReturn(
|
|
||||||
Display(
|
|
||||||
DisplayManagerGlobal.getInstance(),
|
|
||||||
DISPLAY_ID,
|
|
||||||
DisplayInfo(),
|
|
||||||
DEFAULT_DISPLAY_ADJUSTMENTS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
`when`(windowManager.maximumWindowMetrics).thenReturn(
|
`when`(windowManager.maximumWindowMetrics).thenReturn(
|
||||||
WindowMetrics(Rect(0, 0, 800, 800), WindowInsets.CONSUMED)
|
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)
|
||||||
|
|
||||||
sideFpsController = SidefpsController(
|
sideFpsController = SidefpsController(
|
||||||
mContext, layoutInflater, fingerprintManager, windowManager, executor,
|
context.createDisplayContext(display), layoutInflater, fingerprintManager,
|
||||||
displayManager, handler
|
windowManager, overviewProxyService, displayManager, executor, handler
|
||||||
)
|
)
|
||||||
|
|
||||||
overlayController = ArgumentCaptor.forClass(ISidefpsController::class.java).apply {
|
overlayController = ArgumentCaptor.forClass(ISidefpsController::class.java).apply {
|
||||||
verify(fingerprintManager).setSidefpsController(capture())
|
verify(fingerprintManager).setSidefpsController(capture())
|
||||||
}.value
|
}.value
|
||||||
|
|
||||||
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSubscribesToOrientationChangesWhenShowingOverlay() {
|
fun testSubscribesToOrientationChangesWhenShowingOverlay() = testWithDisplay {
|
||||||
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
@@ -141,7 +167,7 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShowsAndHides() {
|
fun testShowsAndHides() = testWithDisplay {
|
||||||
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
@@ -156,7 +182,7 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShowsOnce() {
|
fun testShowsOnce() = testWithDisplay {
|
||||||
repeat(5) {
|
repeat(5) {
|
||||||
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
@@ -167,7 +193,7 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testHidesOnce() {
|
fun testHidesOnce() = testWithDisplay {
|
||||||
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
@@ -181,10 +207,64 @@ class SidefpsControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIgnoredForKeyguard() {
|
fun testIgnoredForKeyguard() = testWithDisplay {
|
||||||
overlayController.show(SENSOR_ID, REASON_AUTH_KEYGUARD)
|
testIgnoredFor(REASON_AUTH_KEYGUARD)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testIgnoredFor(reason: Int) {
|
||||||
|
overlayController.show(SENSOR_ID, reason)
|
||||||
|
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
verify(windowManager, never()).addView(any(), any())
|
verify(windowManager, never()).addView(any(), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun showsWithTaskbar() = testWithDisplay({ rotation = Surface.ROTATION_0 }) {
|
||||||
|
hidesWithTaskbar(visible = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun showsWithTaskbar90() = testWithDisplay({ rotation = Surface.ROTATION_90 }) {
|
||||||
|
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())
|
||||||
|
)
|
||||||
|
hidesWithTaskbar(visible = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hidesWithTaskbarDown() = testWithDisplay({ rotation = Surface.ROTATION_270 }) {
|
||||||
|
`when`(windowManager.currentWindowMetrics).thenReturn(
|
||||||
|
WindowMetrics(Rect(0, 0, 800, 800), insetsForLargeNavbar())
|
||||||
|
)
|
||||||
|
hidesWithTaskbar(visible = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hidesWithTaskbar(visible: Boolean) {
|
||||||
|
overlayController.show(SENSOR_ID, REASON_UNKNOWN)
|
||||||
|
executor.runAllReady()
|
||||||
|
|
||||||
|
sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(true, false)
|
||||||
|
executor.runAllReady()
|
||||||
|
|
||||||
|
verify(windowManager).addView(any(), any())
|
||||||
|
verify(windowManager, never()).removeView(any())
|
||||||
|
verify(sidefpsView).visibility = if (visible) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun insetsForSmallNavbar() = insetsWithBottom(60)
|
||||||
|
private fun insetsForLargeNavbar() = insetsWithBottom(100)
|
||||||
|
private fun insetsWithBottom(bottom: Int) = WindowInsets.Builder()
|
||||||
|
.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, bottom))
|
||||||
|
.build()
|
||||||
Reference in New Issue
Block a user