Merge "[Device Controls] Handle taps correctly when the tile is in an inactive state." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d4c8951618
@@ -96,21 +96,32 @@ class DeviceControlsTile @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handleClick(view: View?) {
|
override fun handleClick(view: View?) {
|
||||||
if (state.state == Tile.STATE_ACTIVE) {
|
if (state.state == Tile.STATE_UNAVAILABLE) {
|
||||||
mUiHandler.post {
|
return
|
||||||
val i = Intent().apply {
|
}
|
||||||
|
|
||||||
|
val intent = Intent().apply {
|
||||||
component = ComponentName(mContext, ControlsActivity::class.java)
|
component = ComponentName(mContext, ControlsActivity::class.java)
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
putExtra(ControlsUiController.EXTRA_ANIMATE, true)
|
putExtra(ControlsUiController.EXTRA_ANIMATE, true)
|
||||||
}
|
}
|
||||||
if (keyguardStateController.isUnlocked()) {
|
|
||||||
val animationController = view?.let {
|
val animationController = view?.let {
|
||||||
ActivityLaunchAnimator.Controller.fromView(it)
|
ActivityLaunchAnimator.Controller.fromView(it)
|
||||||
}
|
}
|
||||||
mActivityStarter.startActivity(i, true /* dismissShade */, animationController)
|
|
||||||
|
mUiHandler.post {
|
||||||
|
if (keyguardStateController.isUnlocked) {
|
||||||
|
mActivityStarter.startActivity(
|
||||||
|
intent, true /* dismissShade */, animationController)
|
||||||
} else {
|
} else {
|
||||||
|
if (state.state == Tile.STATE_ACTIVE) {
|
||||||
mHost.collapsePanels()
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
package com.android.systemui.qs.tiles
|
package com.android.systemui.qs.tiles
|
||||||
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.os.Handler
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Handler
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.service.quicksettings.Tile
|
import android.service.quicksettings.Tile
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
@@ -52,14 +52,17 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentCaptor
|
import org.mockito.ArgumentCaptor
|
||||||
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.ArgumentMatchers.anyBoolean
|
import org.mockito.ArgumentMatchers.anyBoolean
|
||||||
import org.mockito.Captor
|
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.doNothing
|
import org.mockito.Mockito.doNothing
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
|
import org.mockito.Mockito.nullable
|
||||||
import org.mockito.Mockito.spy
|
import org.mockito.Mockito.spy
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.verifyZeroInteractions
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
@@ -95,6 +98,8 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
|||||||
@Captor
|
@Captor
|
||||||
private lateinit var listingCallbackCaptor:
|
private lateinit var listingCallbackCaptor:
|
||||||
ArgumentCaptor<ControlsListingController.ControlsListingCallback>
|
ArgumentCaptor<ControlsListingController.ControlsListingCallback>
|
||||||
|
@Captor
|
||||||
|
private lateinit var intentCaptor: ArgumentCaptor<Intent>
|
||||||
|
|
||||||
private lateinit var testableLooper: TestableLooper
|
private lateinit var testableLooper: TestableLooper
|
||||||
private lateinit var tile: DeviceControlsTile
|
private lateinit var tile: DeviceControlsTile
|
||||||
@@ -259,21 +264,21 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNoDialogWhenUnavailable() {
|
fun handleClick_unavailable_noActivityStarted() {
|
||||||
tile.click(null /* view */)
|
tile.click(null /* view */)
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
verify(activityStarter, never()).startActivity(any(), anyBoolean(),
|
verifyZeroInteractions(activityStarter)
|
||||||
any<ActivityLaunchAnimator.Controller>())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDialogShowWhenAvailable() {
|
fun handleClick_availableAndLocked_activityStarted() {
|
||||||
verify(controlsListingController).observe(
|
verify(controlsListingController).observe(
|
||||||
any(LifecycleOwner::class.java),
|
any(LifecycleOwner::class.java),
|
||||||
capture(listingCallbackCaptor)
|
capture(listingCallbackCaptor)
|
||||||
)
|
)
|
||||||
`when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
|
`when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
|
||||||
|
`when`(keyguardStateController.isUnlocked).thenReturn(false)
|
||||||
|
|
||||||
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
|
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
@@ -281,18 +286,44 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
|||||||
tile.click(null /* view */)
|
tile.click(null /* view */)
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
verify(activityStarter).startActivity(any(), eq(true) /* dismissShade */,
|
// The activity should be started right away and not require a keyguard dismiss.
|
||||||
eq(null) as ActivityLaunchAnimator.Controller?)
|
verifyZeroInteractions(activityStarter)
|
||||||
|
verify(spiedContext).startActivity(intentCaptor.capture())
|
||||||
|
assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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(
|
verify(controlsListingController).observe(
|
||||||
any(LifecycleOwner::class.java),
|
any(LifecycleOwner::class.java),
|
||||||
capture(listingCallbackCaptor)
|
capture(listingCallbackCaptor)
|
||||||
)
|
)
|
||||||
`when`(controlsComponent.getVisibility())
|
`when`(controlsComponent.getVisibility())
|
||||||
.thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
|
.thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
|
||||||
|
`when`(keyguardStateController.isUnlocked).thenReturn(false)
|
||||||
|
|
||||||
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
|
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
@@ -300,8 +331,39 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
|||||||
tile.click(null /* view */)
|
tile.click(null /* view */)
|
||||||
testableLooper.processAllMessages()
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
verify(activityStarter, never()).startActivity(any(), anyBoolean(),
|
verify(activityStarter, never()).startActivity(
|
||||||
any<ActivityLaunchAnimator.Controller>())
|
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 {
|
private fun createTile(): DeviceControlsTile {
|
||||||
@@ -319,3 +381,5 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val CONTROLS_ACTIVITY_CLASS_NAME = "com.android.systemui.controls.ui.ControlsActivity"
|
||||||
|
|||||||
Reference in New Issue
Block a user