Merge "[Chipbar] Have MediaTttSenderCoordinator be responsible for not hiding in certain cases." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
668aee06a1
@@ -47,6 +47,8 @@ constructor(
|
||||
private val uiEventLogger: MediaTttSenderUiEventLogger,
|
||||
) : CoreStartable {
|
||||
|
||||
private var displayedState: ChipStateSender? = null
|
||||
|
||||
private val commandQueueCallbacks =
|
||||
object : CommandQueue.Callbacks {
|
||||
override fun updateMediaTapToTransferSenderDisplay(
|
||||
@@ -84,8 +86,27 @@ constructor(
|
||||
uiEventLogger.logSenderStateChange(chipState)
|
||||
|
||||
if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
|
||||
chipbarCoordinator.removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER.name)
|
||||
// Return early if we're not displaying a chip anyway
|
||||
val currentDisplayedState = displayedState ?: return
|
||||
|
||||
val removalReason = ChipStateSender.FAR_FROM_RECEIVER.name
|
||||
if (
|
||||
currentDisplayedState.transferStatus == TransferStatus.IN_PROGRESS ||
|
||||
currentDisplayedState.transferStatus == TransferStatus.SUCCEEDED
|
||||
) {
|
||||
// Don't remove the chip if we're in progress or succeeded, since the user should
|
||||
// still be able to see the status of the transfer.
|
||||
logger.logRemovalBypass(
|
||||
removalReason,
|
||||
bypassReason = "transferStatus=${currentDisplayedState.transferStatus.name}"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
displayedState = null
|
||||
chipbarCoordinator.removeView(removalReason)
|
||||
} else {
|
||||
displayedState = chipState
|
||||
chipbarCoordinator.displayView(ChipSenderInfo(chipState, routeInfo, undoCallback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
|
||||
)
|
||||
cancelViewTimeout?.run()
|
||||
cancelViewTimeout = mainExecutor.executeDelayed(
|
||||
{ removeView(TemporaryDisplayRemovalReason.REASON_TIMEOUT) },
|
||||
{ removeView(REMOVAL_REASON_TIMEOUT) },
|
||||
timeout.toLong()
|
||||
)
|
||||
}
|
||||
@@ -175,9 +175,6 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
|
||||
*/
|
||||
fun removeView(removalReason: String) {
|
||||
val currentDisplayInfo = displayInfo ?: return
|
||||
if (shouldIgnoreViewRemoval(currentDisplayInfo.info, removalReason)) {
|
||||
return
|
||||
}
|
||||
|
||||
val currentView = currentDisplayInfo.view
|
||||
animateViewOut(currentView) { windowManager.removeView(currentView) }
|
||||
@@ -192,13 +189,6 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
|
||||
cancelViewTimeout?.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a view removal request should be ignored and false otherwise.
|
||||
*
|
||||
* Allows subclasses to keep the view visible for longer in certain circumstances.
|
||||
*/
|
||||
open fun shouldIgnoreViewRemoval(info: T, removalReason: String): Boolean = false
|
||||
|
||||
/**
|
||||
* A method implemented by subclasses to update [currentView] based on [newInfo].
|
||||
*/
|
||||
@@ -236,10 +226,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
|
||||
)
|
||||
}
|
||||
|
||||
object TemporaryDisplayRemovalReason {
|
||||
const val REASON_TIMEOUT = "TIMEOUT"
|
||||
const val REASON_SCREEN_TAP = "SCREEN_TAP"
|
||||
}
|
||||
private const val REMOVAL_REASON_TIMEOUT = "TIMEOUT"
|
||||
|
||||
private data class IconInfo(
|
||||
val iconName: String,
|
||||
|
||||
@@ -44,7 +44,6 @@ import com.android.systemui.media.taptotransfer.sender.MediaTttSenderUiEventLogg
|
||||
import com.android.systemui.media.taptotransfer.sender.TransferStatus
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.temporarydisplay.TemporaryDisplayRemovalReason
|
||||
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
|
||||
import com.android.systemui.temporarydisplay.TemporaryViewInfo
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
@@ -185,23 +184,6 @@ open class ChipbarCoordinator @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
override fun shouldIgnoreViewRemoval(info: ChipSenderInfo, removalReason: String): Boolean {
|
||||
// Don't remove the chip if we're in progress or succeeded, since the user should still be
|
||||
// able to see the status of the transfer. (But do remove it if it's finally timed out.)
|
||||
val transferStatus = info.state.transferStatus
|
||||
if (
|
||||
(transferStatus == TransferStatus.IN_PROGRESS ||
|
||||
transferStatus == TransferStatus.SUCCEEDED) &&
|
||||
removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT
|
||||
) {
|
||||
logger.logRemovalBypass(
|
||||
removalReason, bypassReason = "transferStatus=${transferStatus.name}"
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getTouchableRegion(view: View, outRect: Rect) {
|
||||
viewUtil.setRectToViewWindowLocation(view, outRect)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true)
|
||||
whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(1000)
|
||||
whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(TIMEOUT)
|
||||
|
||||
fakeClock = FakeSystemClock()
|
||||
fakeExecutor = FakeExecutor(fakeClock)
|
||||
@@ -316,7 +316,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() {
|
||||
fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayedButStillTimesOut() {
|
||||
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
|
||||
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
|
||||
routeInfo,
|
||||
@@ -332,10 +332,14 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayed() {
|
||||
fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() {
|
||||
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
|
||||
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
|
||||
routeInfo,
|
||||
@@ -351,10 +355,14 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayed() {
|
||||
fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() {
|
||||
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
|
||||
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
|
||||
routeInfo,
|
||||
@@ -370,10 +378,14 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayed() {
|
||||
fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() {
|
||||
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
|
||||
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
|
||||
routeInfo,
|
||||
@@ -389,6 +401,10 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
private fun getChipView(): ViewGroup {
|
||||
@@ -434,6 +450,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private const val OTHER_DEVICE_NAME = "My Tablet"
|
||||
private const val TIMEOUT = 10000
|
||||
|
||||
private val routeInfo =
|
||||
MediaRoute2Info.Builder("id", OTHER_DEVICE_NAME)
|
||||
|
||||
@@ -63,8 +63,6 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var powerManager: PowerManager
|
||||
|
||||
private var shouldIgnoreViewRemoval: Boolean = false
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
@@ -209,26 +207,6 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
|
||||
verify(windowManager, never()).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun removeView_shouldIgnoreRemovalFalse_viewRemoved() {
|
||||
shouldIgnoreViewRemoval = false
|
||||
underTest.displayView(getState())
|
||||
|
||||
underTest.removeView("reason")
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun removeView_shouldIgnoreRemovalTrue_viewNotRemoved() {
|
||||
shouldIgnoreViewRemoval = true
|
||||
underTest.displayView(getState())
|
||||
|
||||
underTest.removeView("reason")
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
}
|
||||
|
||||
private fun getState(name: String = "name") = ViewInfo(name)
|
||||
|
||||
private fun getConfigurationListener(): ConfigurationListener {
|
||||
@@ -267,10 +245,6 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
|
||||
mostRecentViewInfo = newInfo
|
||||
}
|
||||
|
||||
override fun shouldIgnoreViewRemoval(info: ViewInfo, removalReason: String): Boolean {
|
||||
return shouldIgnoreViewRemoval
|
||||
}
|
||||
|
||||
override fun getTouchableRegion(view: View, outRect: Rect) {
|
||||
outRect.setEmpty()
|
||||
}
|
||||
|
||||
@@ -434,92 +434,6 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
|
||||
assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverTriggeredThenRemoveView_viewStillDisplayed() {
|
||||
underTest.displayView(transferToReceiverTriggered())
|
||||
fakeClock.advanceTime(1000L)
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeExecutor.runAllReady()
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverTriggeredThenRemoveView_eventuallyTimesOut() {
|
||||
underTest.displayView(transferToReceiverTriggered())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceTriggeredThenRemoveView_viewStillDisplayed() {
|
||||
underTest.displayView(transferToThisDeviceTriggered())
|
||||
fakeClock.advanceTime(1000L)
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeExecutor.runAllReady()
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceTriggeredThenRemoveView_eventuallyTimesOut() {
|
||||
underTest.displayView(transferToThisDeviceTriggered())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverSucceededThenRemoveView_viewStillDisplayed() {
|
||||
underTest.displayView(transferToReceiverSucceeded())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeExecutor.runAllReady()
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToReceiverSucceededThenRemoveView_eventuallyTimesOut() {
|
||||
underTest.displayView(transferToReceiverSucceeded())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceSucceededThenRemoveView_viewStillDisplayed() {
|
||||
underTest.displayView(transferToThisDeviceSucceeded())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeExecutor.runAllReady()
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
verify(logger).logRemovalBypass(any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transferToThisDeviceSucceededThenRemoveView_eventuallyTimesOut() {
|
||||
underTest.displayView(transferToThisDeviceSucceeded())
|
||||
|
||||
underTest.removeView("fakeRemovalReason")
|
||||
fakeClock.advanceTime(TIMEOUT + 1L)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
|
||||
|
||||
private fun ViewGroup.getChipText(): String =
|
||||
|
||||
Reference in New Issue
Block a user