diff options
| author | 2021-06-02 20:37:32 +0000 | |
|---|---|---|
| committer | 2021-06-03 19:27:55 +0000 | |
| commit | 9f6ddda4dfbd71f0f78230c145e559dea8e8460d (patch) | |
| tree | cc09c6afd375b868d403bb6d76ccc3914bbe2988 | |
| parent | 9766a0e7027527e4681d8eec399e94427eed5524 (diff) | |
[Device Controls] Handle taps correctly when the tile is in an inactive
state.
Test: Manual + new unit tests
Fixes: 189446872
Change-Id: Ia688a002c3d893bd61678f7572c0cb0f60e46105
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt | 39 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt | 84 |
2 files changed, 99 insertions, 24 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt index 2ab5a3a15205..6d3190ffa725 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt @@ -96,21 +96,32 @@ class DeviceControlsTile @Inject constructor( } override fun handleClick(view: View?) { - if (state.state == Tile.STATE_ACTIVE) { - mUiHandler.post { - val i = Intent().apply { - component = ComponentName(mContext, ControlsActivity::class.java) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) - putExtra(ControlsUiController.EXTRA_ANIMATE, true) - } - if (keyguardStateController.isUnlocked()) { - val animationController = view?.let { - ActivityLaunchAnimator.Controller.fromView(it) - } - mActivityStarter.startActivity(i, true /* dismissShade */, animationController) - } else { + if (state.state == Tile.STATE_UNAVAILABLE) { + return + } + + val intent = Intent().apply { + component = ComponentName(mContext, ControlsActivity::class.java) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) + putExtra(ControlsUiController.EXTRA_ANIMATE, true) + } + val animationController = view?.let { + ActivityLaunchAnimator.Controller.fromView(it) + } + + mUiHandler.post { + if (keyguardStateController.isUnlocked) { + mActivityStarter.startActivity( + intent, true /* dismissShade */, animationController) + } else { + if (state.state == Tile.STATE_ACTIVE) { mHost.collapsePanels() - mContext.startActivity(i) + // With an active tile, don't use ActivityStarter so that the activity is + // started without prompting keyguard unlock. + mContext.startActivity(intent) + } else { + mActivityStarter.postStartActivityDismissingKeyguard( + intent, 0 /* delay */, animationController) } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt index 580cd35459b9..6d1bbd9708ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt @@ -17,9 +17,9 @@ package com.android.systemui.qs.tiles import android.content.ComponentName -import android.os.Handler import android.content.Context import android.content.Intent +import android.os.Handler import android.provider.Settings import android.service.quicksettings.Tile import android.testing.AndroidTestingRunner @@ -52,14 +52,17 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.doNothing import org.mockito.Mockito.never +import org.mockito.Mockito.nullable import org.mockito.Mockito.spy import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations import java.util.Optional @@ -95,6 +98,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Captor private lateinit var listingCallbackCaptor: ArgumentCaptor<ControlsListingController.ControlsListingCallback> + @Captor + private lateinit var intentCaptor: ArgumentCaptor<Intent> private lateinit var testableLooper: TestableLooper private lateinit var tile: DeviceControlsTile @@ -259,21 +264,42 @@ class DeviceControlsTileTest : SysuiTestCase() { } @Test - fun testNoDialogWhenUnavailable() { + fun handleClick_unavailable_noActivityStarted() { + tile.click(null /* view */) + testableLooper.processAllMessages() + + verifyZeroInteractions(activityStarter) + } + + @Test + fun handleClick_availableAndLocked_activityStarted() { + verify(controlsListingController).observe( + any(LifecycleOwner::class.java), + capture(listingCallbackCaptor) + ) + `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) + `when`(keyguardStateController.isUnlocked).thenReturn(false) + + listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) + testableLooper.processAllMessages() + tile.click(null /* view */) testableLooper.processAllMessages() - verify(activityStarter, never()).startActivity(any(), anyBoolean(), - any<ActivityLaunchAnimator.Controller>()) + // The activity should be started right away and not require a keyguard dismiss. + verifyZeroInteractions(activityStarter) + verify(spiedContext).startActivity(intentCaptor.capture()) + assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test - fun testDialogShowWhenAvailable() { + fun handleClick_availableAndUnlocked_activityStarted() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) + `when`(keyguardStateController.isUnlocked).thenReturn(true) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() @@ -281,18 +307,23 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() - verify(activityStarter).startActivity(any(), eq(true) /* dismissShade */, - eq(null) as ActivityLaunchAnimator.Controller?) + verify(activityStarter, never()).postStartActivityDismissingKeyguard(any(), anyInt()) + verify(activityStarter).startActivity( + intentCaptor.capture(), + eq(true) /* dismissShade */, + nullable(ActivityLaunchAnimator.Controller::class.java)) + assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test - fun testNoDialogWhenInactive() { + fun handleClick_availableAfterUnlockAndIsLocked_keyguardDismissRequired() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) + `when`(keyguardStateController.isUnlocked).thenReturn(false) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() @@ -300,8 +331,39 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() - verify(activityStarter, never()).startActivity(any(), anyBoolean(), - any<ActivityLaunchAnimator.Controller>()) + verify(activityStarter, never()).startActivity( + any(), + anyBoolean() /* dismissShade */, + nullable(ActivityLaunchAnimator.Controller::class.java)) + verify(activityStarter).postStartActivityDismissingKeyguard( + intentCaptor.capture(), + anyInt(), + nullable(ActivityLaunchAnimator.Controller::class.java)) + assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) + } + + @Test + fun handleClick_availableAfterUnlockAndIsUnlocked_activityStarted() { + verify(controlsListingController).observe( + any(LifecycleOwner::class.java), + capture(listingCallbackCaptor) + ) + `when`(controlsComponent.getVisibility()) + .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) + `when`(keyguardStateController.isUnlocked).thenReturn(true) + + listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) + testableLooper.processAllMessages() + + tile.click(null /* view */) + testableLooper.processAllMessages() + + verify(activityStarter, never()).postStartActivityDismissingKeyguard(any(), anyInt()) + verify(activityStarter).startActivity( + intentCaptor.capture(), + eq(true) /* dismissShade */, + nullable(ActivityLaunchAnimator.Controller::class.java)) + assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } private fun createTile(): DeviceControlsTile { @@ -319,3 +381,5 @@ class DeviceControlsTileTest : SysuiTestCase() { ) } } + +private const val CONTROLS_ACTIVITY_CLASS_NAME = "com.android.systemui.controls.ui.ControlsActivity" |