Merge "[Device Controls] Handle taps correctly when the tile is in an inactive state." into sc-dev

This commit is contained in:
Caitlin Cassidy
2021-06-04 13:54:08 +00:00
committed by Android (Google) Code Review
2 changed files with 99 additions and 24 deletions

View File

@@ -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)
}
}
}

View File

@@ -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,21 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
fun testNoDialogWhenUnavailable() {
fun handleClick_unavailable_noActivityStarted() {
tile.click(null /* view */)
testableLooper.processAllMessages()
verify(activityStarter, never()).startActivity(any(), anyBoolean(),
any<ActivityLaunchAnimator.Controller>())
verifyZeroInteractions(activityStarter)
}
@Test
fun testDialogShowWhenAvailable() {
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()
@@ -281,18 +286,44 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click(null /* view */)
testableLooper.processAllMessages()
verify(activityStarter).startActivity(any(), eq(true) /* dismissShade */,
eq(null) as 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 testNoDialogWhenInactive() {
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()
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)
}
@Test
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"