Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b86a4ca6 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge "DeviceControlsTile deals with AVAILABLE_AFTER_UNLOCK" into sc-dev

parents 49c8eff6 5d39ba6e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2717,6 +2717,9 @@
    <!-- Controls dialog confirmation [CHAR LIMIT=30] -->
    <string name="controls_dialog_confirmation">Controls updated</string>

    <!-- Controls tile secondary label when device is locked and user does not want access to controls from lockscreen [CHAR LIMIT=20] -->
    <string name="controls_tile_locked">Device locked</string>

    <!-- Controls PIN entry dialog, switch to alphanumeric keyboard [CHAR LIMIT=100] -->
    <string name="controls_pin_use_alphanumeric">PIN contains letters or symbols</string>
    <!-- Controls PIN entry dialog, title [CHAR LIMIT=30] -->
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ class ControlsComponent @Inject constructor(
    }

    /**
     * @return true if controls are feature-enabled and have available services to serve controls
     * @return true if controls are feature-enabled and the user has the setting enabled
     */
    fun isEnabled() = featureEnabled && lazyControlsController.get().available

+13 −7
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ import com.android.internal.logging.MetricsLogger
import com.android.systemui.R
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsDialog
import com.android.systemui.dagger.qualifiers.Background
@@ -92,7 +92,7 @@ class DeviceControlsTile @Inject constructor(
    override fun isAvailable(): Boolean {
        return featureFlags.isKeyguardLayoutEnabled &&
                controlsLockscreen &&
                controlsComponent.getVisibility() != UNAVAILABLE
                controlsComponent.getControlsController().isPresent
    }

    override fun newTileState(): QSTile.State {
@@ -119,7 +119,7 @@ class DeviceControlsTile @Inject constructor(
    }

    override fun handleClick() {
        if (state.state != Tile.STATE_UNAVAILABLE) {
        if (state.state == Tile.STATE_ACTIVE) {
            mUiHandler.post {
                createDialog()
                controlsDialog?.show(controlsComponent.getControlsUiController().get())
@@ -129,15 +129,21 @@ class DeviceControlsTile @Inject constructor(

    override fun handleUpdateState(state: QSTile.State, arg: Any?) {
        state.label = tileLabel
        state.secondaryLabel = ""
        state.stateDescription = ""

        state.contentDescription = state.label
        state.icon = icon
        if (hasControlsApps.get()) {
            state.state = Tile.STATE_ACTIVE
        if (controlsComponent.isEnabled() && hasControlsApps.get()) {
            if (controlsDialog == null) {
                mUiHandler.post(this::createDialog)
            }
            if (controlsComponent.getVisibility() == AVAILABLE) {
                state.state = Tile.STATE_ACTIVE
                state.secondaryLabel = ""
            } else {
                state.state = Tile.STATE_INACTIVE
                state.secondaryLabel = mContext.getText(R.string.controls_tile_locked)
            }
            state.stateDescription = state.secondaryLabel
        } else {
            state.state = Tile.STATE_UNAVAILABLE
            dismissDialog()
+93 −38
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.controller.ControlsController
@@ -37,9 +36,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.settings.FakeSettings
@@ -49,7 +46,6 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -57,6 +53,7 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.Optional

@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -73,6 +70,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
    private lateinit var activityStarter: ActivityStarter
    @Mock
    private lateinit var qsLogger: QSLogger
    @Mock
    private lateinit var controlsComponent: ControlsComponent
    @Mock
    private lateinit var controlsUiController: ControlsUiController
@@ -96,54 +94,64 @@ class DeviceControlsTileTest : SysuiTestCase() {
    private lateinit var testableLooper: TestableLooper
    private lateinit var tile: DeviceControlsTile

    @Mock
    private lateinit var keyguardStateController: KeyguardStateController
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private lateinit var userTracker: UserTracker
    @Mock
    private lateinit var lockPatternUtils: LockPatternUtils
    @Mock
    private lateinit var secureSettings: SecureSettings
    private var featureEnabled = true

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        testableLooper = TestableLooper.get(this)
        secureSettings = FakeSettings()

        `when`(qsHost.context).thenReturn(mContext)
        `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
        `when`(controlsController.available).thenReturn(true)
        `when`(controlsComponent.isEnabled()).thenReturn(true)
        secureSettings.putInt(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 1)

        controlsComponent = ControlsComponent(
                true,
                mContext,
                { controlsController },
                { controlsUiController },
                { controlsListingController },
                lockPatternUtils,
                keyguardStateController,
                userTracker,
                secureSettings
        )
        setupControlsComponent()

        globalSettings = FakeSettings()

        globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 1)
        `when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(true)

        `when`(userTracker.userHandle.identifier).thenReturn(0)

        tile = createTile()
    }

    private fun setupControlsComponent() {
        `when`(controlsComponent.getControlsController()).thenAnswer {
            if (featureEnabled) {
                Optional.of(controlsController)
            } else {
                Optional.empty()
            }
        }

        `when`(controlsComponent.getControlsListingController()).thenAnswer {
            if (featureEnabled) {
                Optional.of(controlsListingController)
            } else {
                Optional.empty()
            }
        }

        `when`(controlsComponent.getControlsUiController()).thenAnswer {
            if (featureEnabled) {
                Optional.of(controlsUiController)
            } else {
                Optional.empty()
            }
        }
    }

    @Test
    fun testAvailable() {
        `when`(controlsController.available).thenReturn(true)
        assertThat(tile.isAvailable).isTrue()
    }

    @Test
    fun testNotAvailableFeature() {
        `when`(controlsController.available).thenReturn(true)
        `when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(false)

        assertThat(tile.isAvailable).isFalse()
@@ -151,24 +159,22 @@ class DeviceControlsTileTest : SysuiTestCase() {

    @Test
    fun testNotAvailableControls() {
        controlsComponent = ControlsComponent(
                false,
                mContext,
                { controlsController },
                { controlsUiController },
                { controlsListingController },
                lockPatternUtils,
                keyguardStateController,
                userTracker,
                secureSettings
        )
        featureEnabled = false
        tile = createTile()

        assertThat(tile.isAvailable).isFalse()
    }

    @Test
    fun testNotAvailableFlag() {
    fun testAvailableControlsSettingOff() {
        `when`(controlsController.available).thenReturn(false)

        tile = createTile()
        assertThat(tile.isAvailable).isTrue()
    }

    @Test
    fun testNotAvailableControlsLockscreenFlag() {
        globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 0)
        tile = createTile()

@@ -206,12 +212,27 @@ class DeviceControlsTileTest : SysuiTestCase() {
        assertThat(tile.state.state).isEqualTo(Tile.STATE_UNAVAILABLE)
    }

    @Test
    fun testStateUnavailableIfNotEnabled() {
        verify(controlsListingController).observe(
            any(LifecycleOwner::class.java),
            capture(listingCallbackCaptor)
        )
        `when`(controlsComponent.isEnabled()).thenReturn(false)

        listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
        testableLooper.processAllMessages()

        assertThat(tile.state.state).isEqualTo(Tile.STATE_UNAVAILABLE)
    }

    @Test
    fun testStateAvailableIfListings() {
        verify(controlsListingController).observe(
                any(LifecycleOwner::class.java),
                capture(listingCallbackCaptor)
        )
        `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)

        listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
        testableLooper.processAllMessages()
@@ -219,6 +240,21 @@ class DeviceControlsTileTest : SysuiTestCase() {
        assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE)
    }

    @Test
    fun testStateInactiveIfLocked() {
        verify(controlsListingController).observe(
            any(LifecycleOwner::class.java),
            capture(listingCallbackCaptor)
        )
        `when`(controlsComponent.getVisibility())
            .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)

        listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
        testableLooper.processAllMessages()

        assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
    }

    @Test
    fun testMoveBetweenStates() {
        verify(controlsListingController).observe(
@@ -249,6 +285,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
                any(LifecycleOwner::class.java),
                capture(listingCallbackCaptor)
        )
        `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)

        listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
        testableLooper.processAllMessages()
@@ -259,6 +296,24 @@ class DeviceControlsTileTest : SysuiTestCase() {
        verify(controlsDialog).show(controlsUiController)
    }

    @Test
    fun testNoDialogWhenInactive() {
        verify(controlsListingController).observe(
            any(LifecycleOwner::class.java),
            capture(listingCallbackCaptor)
        )
        `when`(controlsComponent.getVisibility())
            .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)

        listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
        testableLooper.processAllMessages()

        tile.click()
        testableLooper.processAllMessages()

        verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
    }

    @Test
    fun testDialogDismissedOnDestroy() {
        verify(controlsListingController).observe(