package com.android.systemui.shade import android.content.Context import android.content.res.Resources import android.graphics.Rect import android.testing.AndroidTestingRunner import android.view.DisplayCutout import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.battery.BatteryMeterView import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnit @SmallTest @RunWith(AndroidTestingRunner::class) class QsBatteryModeControllerTest : SysuiTestCase() { private companion object { val CENTER_TOP_CUTOUT: DisplayCutout = mock().also { whenever(it.boundingRectTop).thenReturn(Rect(10, 0, 20, 10)) } const val MOTION_LAYOUT_MAX_FRAME = 100 const val QQS_START_FRAME = 14 const val QS_END_FRAME = 58 } @JvmField @Rule val mockitoRule = MockitoJUnit.rule()!! @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider @Mock private lateinit var mockedContext: Context @Mock private lateinit var mockedResources: Resources private lateinit var controller: QsBatteryModeController // under test @Before fun setup() { whenever(mockedContext.resources).thenReturn(mockedResources) whenever(mockedResources.getInteger(R.integer.fade_in_start_frame)).thenReturn(QS_END_FRAME) whenever(mockedResources.getInteger(R.integer.fade_out_complete_frame)) .thenReturn(QQS_START_FRAME) controller = QsBatteryModeController(mockedContext, insetsProvider) } @Test fun returnsMODE_ONforQqsWithCenterCutout() { assertThat( controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction()) ) .isEqualTo(BatteryMeterView.MODE_ON) } @Test fun returnsMODE_ESTIMATEforQsWithCenterCutout() { assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction())) .isEqualTo(BatteryMeterView.MODE_ESTIMATE) } @Test fun returnsMODE_ONforQqsWithCornerCutout() { whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true) assertThat( controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction()) ) .isEqualTo(BatteryMeterView.MODE_ESTIMATE) } @Test fun returnsMODE_ESTIMATEforQsWithCornerCutout() { whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true) assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction())) .isEqualTo(BatteryMeterView.MODE_ESTIMATE) } @Test fun returnsNullInBetween() { assertThat( controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.nextFrameToFraction()) ) .isNull() assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.prevFrameToFraction())) .isNull() } private fun Int.prevFrameToFraction(): Float = (this - 1) / MOTION_LAYOUT_MAX_FRAME.toFloat() private fun Int.nextFrameToFraction(): Float = (this + 1) / MOTION_LAYOUT_MAX_FRAME.toFloat() }