[Chipbar] Rename "chip" -> "view" in the generic

TemporaryViewDisplayController (and other affected places).

Bug: 245610654
Test: media.taptotransfer tests
Test: temporarydisplay tests
Test: verify media ttt chip still works
Change-Id: Ib59a5b8a70435ddc02a4ab0c74edfb07e7a3176e
This commit is contained in:
Caitlin Shkuratov
2022-09-07 22:25:28 +00:00
parent 935167436b
commit e221b76ff9
7 changed files with 212 additions and 213 deletions

View File

@@ -116,18 +116,18 @@ class MediaTttChipControllerReceiver @Inject constructor(
uiEventLogger.logReceiverStateChange(chipState)
if (chipState == ChipStateReceiver.FAR_FROM_SENDER) {
removeChip(removalReason = ChipStateReceiver.FAR_FROM_SENDER::class.simpleName!!)
removeView(removalReason = ChipStateReceiver.FAR_FROM_SENDER::class.simpleName!!)
return
}
if (appIcon == null) {
displayChip(ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appName))
displayView(ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appName))
return
}
appIcon.loadDrawableAsync(
context,
Icon.OnDrawableLoadedListener { drawable ->
displayChip(ChipReceiverInfo(routeInfo, drawable, appName))
displayView(ChipReceiverInfo(routeInfo, drawable, appName))
},
// Notify the listener on the main handler since the listener will update
// the UI.
@@ -135,19 +135,19 @@ class MediaTttChipControllerReceiver @Inject constructor(
)
}
override fun updateChipView(newChipInfo: ChipReceiverInfo, currentChipView: ViewGroup) {
super.updateChipView(newChipInfo, currentChipView)
override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
super.updateView(newInfo, currentView)
val iconName = setIcon(
currentChipView,
newChipInfo.routeInfo.clientPackageName,
newChipInfo.appIconDrawableOverride,
newChipInfo.appNameOverride
currentView,
newInfo.routeInfo.clientPackageName,
newInfo.appIconDrawableOverride,
newInfo.appNameOverride
)
currentChipView.contentDescription = iconName
currentView.contentDescription = iconName
}
override fun animateChipIn(chipView: ViewGroup) {
val appIconView = chipView.requireViewById<View>(R.id.app_icon)
override fun animateViewIn(view: ViewGroup) {
val appIconView = view.requireViewById<View>(R.id.app_icon)
appIconView.animate()
.translationYBy(-1 * getTranslationAmount().toFloat())
.setDuration(30.frames)
@@ -157,8 +157,8 @@ class MediaTttChipControllerReceiver @Inject constructor(
.setDuration(5.frames)
.start()
// Using withEndAction{} doesn't apply a11y focus when screen is unlocked.
appIconView.postOnAnimation { chipView.requestAccessibilityFocus() }
startRipple(chipView.requireViewById(R.id.ripple))
appIconView.postOnAnimation { view.requestAccessibilityFocus() }
startRipple(view.requireViewById(R.id.ripple))
}
override fun getIconSize(isAppIcon: Boolean): Int? =

View File

@@ -120,7 +120,7 @@ enum class ChipStateSender(
// state, but that may take too long to go through the binder and the user may be
// confused ast o why the UI hasn't changed yet. So, we immediately change the UI
// here.
controllerSender.displayChip(
controllerSender.displayView(
ChipSenderInfo(
TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, undoCallback
)
@@ -155,7 +155,7 @@ enum class ChipStateSender(
// state, but that may take too long to go through the binder and the user may be
// confused as to why the UI hasn't changed yet. So, we immediately change the UI
// here.
controllerSender.displayChip(
controllerSender.displayView(
ChipSenderInfo(
TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, undoCallback
)

View File

@@ -103,53 +103,52 @@ class MediaTttChipControllerSender @Inject constructor(
uiEventLogger.logSenderStateChange(chipState)
if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
removeChip(removalReason = ChipStateSender.FAR_FROM_RECEIVER::class.simpleName!!)
removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER::class.simpleName!!)
} else {
displayChip(ChipSenderInfo(chipState, routeInfo, undoCallback))
displayView(ChipSenderInfo(chipState, routeInfo, undoCallback))
}
}
/** Displays the chip view for the given state. */
override fun updateChipView(
newChipInfo: ChipSenderInfo,
currentChipView: ViewGroup
override fun updateView(
newInfo: ChipSenderInfo,
currentView: ViewGroup
) {
super.updateChipView(newChipInfo, currentChipView)
super.updateView(newInfo, currentView)
val chipState = newChipInfo.state
val chipState = newInfo.state
// App icon
val iconName = setIcon(currentChipView, newChipInfo.routeInfo.clientPackageName)
val iconName = setIcon(currentView, newInfo.routeInfo.clientPackageName)
// Text
val otherDeviceName = newChipInfo.routeInfo.name.toString()
val otherDeviceName = newInfo.routeInfo.name.toString()
val chipText = chipState.getChipTextString(context, otherDeviceName)
currentChipView.requireViewById<TextView>(R.id.text).text = chipText
currentView.requireViewById<TextView>(R.id.text).text = chipText
// Loading
currentChipView.requireViewById<View>(R.id.loading).visibility =
currentView.requireViewById<View>(R.id.loading).visibility =
chipState.isMidTransfer.visibleIfTrue()
// Undo
val undoView = currentChipView.requireViewById<View>(R.id.undo)
val undoView = currentView.requireViewById<View>(R.id.undo)
val undoClickListener = chipState.undoClickListener(
this, newChipInfo.routeInfo, newChipInfo.undoCallback, uiEventLogger
this, newInfo.routeInfo, newInfo.undoCallback, uiEventLogger
)
undoView.setOnClickListener(undoClickListener)
undoView.visibility = (undoClickListener != null).visibleIfTrue()
// Failure
currentChipView.requireViewById<View>(R.id.failure_icon).visibility =
currentView.requireViewById<View>(R.id.failure_icon).visibility =
chipState.isTransferFailure.visibleIfTrue()
// For accessibility
currentChipView.requireViewById<ViewGroup>(
currentView.requireViewById<ViewGroup>(
R.id.media_ttt_sender_chip_inner
).contentDescription = "$iconName $chipText"
}
override fun animateChipIn(chipView: ViewGroup) {
val chipInnerView = chipView.requireViewById<ViewGroup>(R.id.media_ttt_sender_chip_inner)
override fun animateViewIn(view: ViewGroup) {
val chipInnerView = view.requireViewById<ViewGroup>(R.id.media_ttt_sender_chip_inner)
ViewHierarchyAnimator.animateAddition(
chipInnerView,
ViewHierarchyAnimator.Hotspot.TOP,
@@ -162,14 +161,14 @@ class MediaTttChipControllerSender @Inject constructor(
)
}
override fun removeChip(removalReason: String) {
override fun removeView(removalReason: String) {
// Don't remove the chip if we're mid-transfer since the user should still be able to
// see the status of the transfer. (But do remove it if it's finally timed out.)
if (chipInfo?.state?.isMidTransfer == true &&
if (info?.state?.isMidTransfer == true &&
removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT) {
return
}
super.removeChip(removalReason)
super.removeView(removalReason)
}
private fun Boolean.visibleIfTrue(): Int {

View File

@@ -44,11 +44,11 @@ import com.android.systemui.util.concurrency.DelayableExecutor
/**
* A generic controller that can temporarily display a new view in a new window.
*
* Subclasses need to override and implement [updateChipView], which is where they can control what
* Subclasses need to override and implement [updateView], which is where they can control what
* gets displayed to the user.
*
* The generic type T is expected to contain all the information necessary for the subclasses to
* display the chip in a certain state, since they receive <T> in [updateChipView].
* display the view in a certain state, since they receive <T> in [updateView].
*
* TODO(b/245610654): Remove all the media-specific logic from this class.
*/
@@ -60,7 +60,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo>(
private val accessibilityManager: AccessibilityManager,
private val configurationController: ConfigurationController,
private val powerManager: PowerManager,
@LayoutRes private val chipLayoutRes: Int,
@LayoutRes private val viewLayoutRes: Int,
) {
/**
* Window layout params that will be used as a starting point for the [windowLayoutParams] of
@@ -85,31 +85,31 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo>(
*/
internal abstract val windowLayoutParams: WindowManager.LayoutParams
/** The chip view currently being displayed. Null if the chip is not being displayed. */
private var chipView: ViewGroup? = null
/** The view currently being displayed. Null if the view is not being displayed. */
private var view: ViewGroup? = null
/** The chip info currently being displayed. Null if the chip is not being displayed. */
internal var chipInfo: T? = null
/** The info currently being displayed. Null if the view is not being displayed. */
internal var info: T? = null
/** A [Runnable] that, when run, will cancel the pending timeout of the chip. */
private var cancelChipViewTimeout: Runnable? = null
/** A [Runnable] that, when run, will cancel the pending timeout of the view. */
private var cancelViewTimeout: Runnable? = null
/**
* Displays the chip with the provided [newChipInfo].
* Displays the view with the provided [newInfo].
*
* This method handles inflating and attaching the view, then delegates to [updateChipView] to
* display the correct information in the chip.
* This method handles inflating and attaching the view, then delegates to [updateView] to
* display the correct information in the view.
*/
fun displayChip(newChipInfo: T) {
val currentChipView = chipView
fun displayView(newInfo: T) {
val currentView = view
if (currentChipView != null) {
updateChipView(newChipInfo, currentChipView)
if (currentView != null) {
updateView(newInfo, currentView)
} else {
// The chip is new, so set up all our callbacks and inflate the view
// The view is new, so set up all our callbacks and inflate the view
configurationController.addCallback(displayScaleListener)
// Wake the screen if necessary so the user will see the chip. (Per b/239426653, we want
// the chip to show over the dream state, so we should only wake up if the screen is
// Wake the screen if necessary so the user will see the view. (Per b/239426653, we want
// the view to show over the dream state, so we should only wake up if the screen is
// completely off.)
if (!powerManager.isScreenOn) {
powerManager.wakeUp(
@@ -119,79 +119,79 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo>(
)
}
inflateAndUpdateChip(newChipInfo)
inflateAndUpdateView(newInfo)
}
// Cancel and re-set the chip timeout each time we get a new state.
// Cancel and re-set the view timeout each time we get a new state.
val timeout = accessibilityManager.getRecommendedTimeoutMillis(
newChipInfo.getTimeoutMs().toInt(),
// Not all chips have controls so FLAG_CONTENT_CONTROLS might be superfluous, but
newInfo.getTimeoutMs().toInt(),
// Not all views have controls so FLAG_CONTENT_CONTROLS might be superfluous, but
// include it just to be safe.
FLAG_CONTENT_ICONS or FLAG_CONTENT_TEXT or FLAG_CONTENT_CONTROLS
)
cancelChipViewTimeout?.run()
cancelChipViewTimeout = mainExecutor.executeDelayed(
{ removeChip(TemporaryDisplayRemovalReason.REASON_TIMEOUT) },
cancelViewTimeout?.run()
cancelViewTimeout = mainExecutor.executeDelayed(
{ removeView(TemporaryDisplayRemovalReason.REASON_TIMEOUT) },
timeout.toLong()
)
}
/** Inflates a new chip view, updates it with [newChipInfo], and adds the view to the window. */
private fun inflateAndUpdateChip(newChipInfo: T) {
val newChipView = LayoutInflater
/** Inflates a new view, updates it with [newInfo], and adds the view to the window. */
private fun inflateAndUpdateView(newInfo: T) {
val newView = LayoutInflater
.from(context)
.inflate(chipLayoutRes, null) as ViewGroup
chipView = newChipView
updateChipView(newChipInfo, newChipView)
windowManager.addView(newChipView, windowLayoutParams)
animateChipIn(newChipView)
.inflate(viewLayoutRes, null) as ViewGroup
view = newView
updateView(newInfo, newView)
windowManager.addView(newView, windowLayoutParams)
animateViewIn(newView)
}
/** Removes then re-inflates the chip. */
private fun reinflateChip() {
val currentChipInfo = chipInfo
if (chipView == null || currentChipInfo == null) { return }
/** Removes then re-inflates the view. */
private fun reinflateView() {
val currentInfo = info
if (view == null || currentInfo == null) { return }
windowManager.removeView(chipView)
inflateAndUpdateChip(currentChipInfo)
windowManager.removeView(view)
inflateAndUpdateView(currentInfo)
}
private val displayScaleListener = object : ConfigurationController.ConfigurationListener {
override fun onDensityOrFontScaleChanged() {
reinflateChip()
reinflateView()
}
}
/**
* Hides the chip.
* Hides the view.
*
* @param removalReason a short string describing why the chip was removed (timeout, state
* @param removalReason a short string describing why the view was removed (timeout, state
* change, etc.)
*/
open fun removeChip(removalReason: String) {
if (chipView == null) { return }
open fun removeView(removalReason: String) {
if (view == null) { return }
logger.logChipRemoval(removalReason)
configurationController.removeCallback(displayScaleListener)
windowManager.removeView(chipView)
chipView = null
chipInfo = null
// No need to time the chip out since it's already gone
cancelChipViewTimeout?.run()
windowManager.removeView(view)
view = null
info = null
// No need to time the view out since it's already gone
cancelViewTimeout?.run()
}
/**
* A method implemented by subclasses to update [currentChipView] based on [newChipInfo].
* A method implemented by subclasses to update [currentView] based on [newInfo].
*/
@CallSuper
open fun updateChipView(newChipInfo: T, currentChipView: ViewGroup) {
chipInfo = newChipInfo
open fun updateView(newInfo: T, currentView: ViewGroup) {
info = newInfo
}
/**
* A method that can be implemented by subclcasses to do custom animations for when the chip
* A method that can be implemented by subclasses to do custom animations for when the view
* appears.
*/
open fun animateChipIn(chipView: ViewGroup) {}
open fun animateViewIn(view: ViewGroup) {}
/**
* Returns the size that the icon should be, or null if no size override is needed.
@@ -209,12 +209,12 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo>(
* @return the content description of the icon.
*/
internal fun setIcon(
currentChipView: ViewGroup,
currentView: ViewGroup,
appPackageName: String?,
appIconDrawableOverride: Drawable? = null,
appNameOverride: CharSequence? = null,
): CharSequence {
val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
val appIconView = currentView.requireViewById<CachingIconView>(R.id.app_icon)
val iconInfo = getIconInfo(appPackageName)
getIconSize(iconInfo.isAppIcon)?.let { size ->

View File

@@ -178,7 +178,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
@Test
fun setIcon_isAppIcon_usesAppIconSize() {
controllerReceiver.displayChip(getChipReceiverInfo())
controllerReceiver.displayView(getChipReceiverInfo())
val chipView = getChipView()
controllerReceiver.setIcon(chipView, PACKAGE_NAME)
@@ -194,7 +194,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
@Test
fun setIcon_notAppIcon_usesGenericIconSize() {
controllerReceiver.displayChip(getChipReceiverInfo())
controllerReceiver.displayView(getChipReceiverInfo())
val chipView = getChipView()
controllerReceiver.setIcon(chipView, appPackageName = null)

View File

@@ -305,7 +305,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun almostCloseToStartCast_appIcon_deviceName_noLoadingIcon_noUndo_noFailureIcon() {
val state = almostCloseToStartCast()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -321,7 +321,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun almostCloseToEndCast_appIcon_deviceName_noLoadingIcon_noUndo_noFailureIcon() {
val state = almostCloseToEndCast()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -337,7 +337,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToReceiverTriggered_appIcon_loadingIcon_noUndo_noFailureIcon() {
val state = transferToReceiverTriggered()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -353,7 +353,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToThisDeviceTriggered_appIcon_loadingIcon_noUndo_noFailureIcon() {
val state = transferToThisDeviceTriggered()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -369,7 +369,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToReceiverSucceeded_appIcon_deviceName_noLoadingIcon_noFailureIcon() {
val state = transferToReceiverSucceeded()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -383,7 +383,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToReceiverSucceeded_nullUndoRunnable_noUndo() {
controllerSender.displayChip(transferToReceiverSucceeded(undoCallback = null))
controllerSender.displayView(transferToReceiverSucceeded(undoCallback = null))
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
@@ -394,7 +394,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val undoCallback = object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
}
controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
@@ -410,7 +410,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
}
}
controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
getChipView().getUndoButton().performClick()
assertThat(undoCallbackCalled).isTrue()
@@ -421,7 +421,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val undoCallback = object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
}
controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
getChipView().getUndoButton().performClick()
@@ -436,7 +436,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToThisDeviceSucceeded_appIcon_deviceName_noLoadingIcon_noFailureIcon() {
val state = transferToThisDeviceSucceeded()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -450,7 +450,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToThisDeviceSucceeded_nullUndoRunnable_noUndo() {
controllerSender.displayChip(transferToThisDeviceSucceeded(undoCallback = null))
controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback = null))
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
@@ -461,7 +461,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val undoCallback = object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
}
controllerSender.displayChip(transferToThisDeviceSucceeded(undoCallback))
controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
@@ -477,7 +477,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
}
}
controllerSender.displayChip(transferToThisDeviceSucceeded(undoCallback))
controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
getChipView().getUndoButton().performClick()
assertThat(undoCallbackCalled).isTrue()
@@ -488,7 +488,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
val undoCallback = object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
}
controllerSender.displayChip(transferToThisDeviceSucceeded(undoCallback))
controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
getChipView().getUndoButton().performClick()
@@ -503,7 +503,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToReceiverFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
val state = transferToReceiverFailed()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -519,7 +519,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToThisDeviceFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
val state = transferToThisDeviceFailed()
controllerSender.displayChip(state)
controllerSender.displayView(state)
val chipView = getChipView()
assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -534,24 +534,24 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun changeFromAlmostCloseToStartToTransferTriggered_loadingIconAppears() {
controllerSender.displayChip(almostCloseToStartCast())
controllerSender.displayChip(transferToReceiverTriggered())
controllerSender.displayView(almostCloseToStartCast())
controllerSender.displayView(transferToReceiverTriggered())
assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
}
@Test
fun changeFromTransferTriggeredToTransferSucceeded_loadingIconDisappears() {
controllerSender.displayChip(transferToReceiverTriggered())
controllerSender.displayChip(transferToReceiverSucceeded())
controllerSender.displayView(transferToReceiverTriggered())
controllerSender.displayView(transferToReceiverSucceeded())
assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.GONE)
}
@Test
fun changeFromTransferTriggeredToTransferSucceeded_undoButtonAppears() {
controllerSender.displayChip(transferToReceiverTriggered())
controllerSender.displayChip(
controllerSender.displayView(transferToReceiverTriggered())
controllerSender.displayView(
transferToReceiverSucceeded(
object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
@@ -564,26 +564,26 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun changeFromTransferSucceededToAlmostCloseToStart_undoButtonDisappears() {
controllerSender.displayChip(transferToReceiverSucceeded())
controllerSender.displayChip(almostCloseToStartCast())
controllerSender.displayView(transferToReceiverSucceeded())
controllerSender.displayView(almostCloseToStartCast())
assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE)
}
@Test
fun changeFromTransferTriggeredToTransferFailed_failureIconAppears() {
controllerSender.displayChip(transferToReceiverTriggered())
controllerSender.displayChip(transferToReceiverFailed())
controllerSender.displayView(transferToReceiverTriggered())
controllerSender.displayView(transferToReceiverFailed())
assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
}
@Test
fun transferToReceiverTriggeredThenRemoveChip_chipStillDisplayed() {
controllerSender.displayChip(transferToReceiverTriggered())
fun transferToReceiverTriggeredThenRemoveView_viewStillDisplayed() {
controllerSender.displayView(transferToReceiverTriggered())
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
controllerSender.removeView("fakeRemovalReason")
fakeExecutor.runAllReady()
verify(windowManager, never()).removeView(any())
@@ -592,9 +592,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToReceiverTriggeredThenFarFromReceiver_eventuallyTimesOut() {
val state = transferToReceiverTriggered()
controllerSender.displayChip(state)
controllerSender.displayView(state)
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
controllerSender.removeView("fakeRemovalReason")
fakeClock.advanceTime(TIMEOUT + 1L)
@@ -602,11 +602,11 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
}
@Test
fun transferToThisDeviceTriggeredThenRemoveChip_chipStillDisplayed() {
controllerSender.displayChip(transferToThisDeviceTriggered())
fun transferToThisDeviceTriggeredThenRemoveView_viewStillDisplayed() {
controllerSender.displayView(transferToThisDeviceTriggered())
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
controllerSender.removeView("fakeRemovalReason")
fakeExecutor.runAllReady()
verify(windowManager, never()).removeView(any())
@@ -615,9 +615,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
@Test
fun transferToThisDeviceTriggeredThenFarFromReceiver_eventuallyTimesOut() {
val state = transferToThisDeviceTriggered()
controllerSender.displayChip(state)
controllerSender.displayView(state)
fakeClock.advanceTime(1000L)
controllerSender.removeChip("fakeRemovalReason")
controllerSender.removeView("fakeRemovalReason")
fakeClock.advanceTime(TIMEOUT + 1L)

View File

@@ -107,43 +107,43 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
}
@Test
fun displayChip_chipAdded() {
underTest.displayChip(getState())
fun displayView_viewAdded() {
underTest.displayView(getState())
verify(windowManager).addView(any(), any())
}
@Test
fun displayChip_screenOff_screenWakes() {
fun displayView_screenOff_screenWakes() {
whenever(powerManager.isScreenOn).thenReturn(false)
underTest.displayChip(getState())
underTest.displayView(getState())
verify(powerManager).wakeUp(any(), any(), any())
}
@Test
fun displayChip_screenAlreadyOn_screenNotWoken() {
fun displayView_screenAlreadyOn_screenNotWoken() {
whenever(powerManager.isScreenOn).thenReturn(true)
underTest.displayChip(getState())
underTest.displayView(getState())
verify(powerManager, never()).wakeUp(any(), any(), any())
}
@Test
fun displayChip_twice_chipNotAddedTwice() {
underTest.displayChip(getState())
fun displayView_twice_viewNotAddedTwice() {
underTest.displayView(getState())
reset(windowManager)
underTest.displayChip(getState())
underTest.displayView(getState())
verify(windowManager, never()).addView(any(), any())
}
@Test
fun displayChip_chipDoesNotDisappearsBeforeTimeout() {
fun displayView_viewDoesNotDisappearsBeforeTimeout() {
val state = getState()
underTest.displayChip(state)
underTest.displayView(state)
reset(windowManager)
fakeClock.advanceTime(TIMEOUT_MS - 1)
@@ -152,9 +152,9 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
}
@Test
fun displayChip_chipDisappearsAfterTimeout() {
fun displayView_viewDisappearsAfterTimeout() {
val state = getState()
underTest.displayChip(state)
underTest.displayView(state)
reset(windowManager)
fakeClock.advanceTime(TIMEOUT_MS + 1)
@@ -163,176 +163,176 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
}
@Test
fun displayChip_calledAgainBeforeTimeout_timeoutReset() {
// First, display the chip
fun displayView_calledAgainBeforeTimeout_timeoutReset() {
// First, display the view
val state = getState()
underTest.displayChip(state)
underTest.displayView(state)
// After some time, re-display the chip
// After some time, re-display the view
val waitTime = 1000L
fakeClock.advanceTime(waitTime)
underTest.displayChip(getState())
underTest.displayView(getState())
// Wait until the timeout for the first display would've happened
fakeClock.advanceTime(TIMEOUT_MS - waitTime + 1)
// Verify we didn't hide the chip
// Verify we didn't hide the view
verify(windowManager, never()).removeView(any())
}
@Test
fun displayChip_calledAgainBeforeTimeout_eventuallyTimesOut() {
// First, display the chip
fun displayView_calledAgainBeforeTimeout_eventuallyTimesOut() {
// First, display the view
val state = getState()
underTest.displayChip(state)
underTest.displayView(state)
// After some time, re-display the chip
// After some time, re-display the view
fakeClock.advanceTime(1000L)
underTest.displayChip(getState())
underTest.displayView(getState())
// Ensure we still hide the chip eventually
// Ensure we still hide the view eventually
fakeClock.advanceTime(TIMEOUT_MS + 1)
verify(windowManager).removeView(any())
}
@Test
fun displayScaleChange_chipReinflatedWithMostRecentState() {
underTest.displayChip(getState(name = "First name"))
underTest.displayChip(getState(name = "Second name"))
fun displayScaleChange_viewReinflatedWithMostRecentState() {
underTest.displayView(getState(name = "First name"))
underTest.displayView(getState(name = "Second name"))
reset(windowManager)
getConfigurationListener().onDensityOrFontScaleChanged()
verify(windowManager).removeView(any())
verify(windowManager).addView(any(), any())
assertThat(underTest.mostRecentChipInfo?.name).isEqualTo("Second name")
assertThat(underTest.mostRecentViewInfo?.name).isEqualTo("Second name")
}
@Test
fun removeChip_chipRemovedAndRemovalLogged() {
// First, add the chip
underTest.displayChip(getState())
fun removeView_viewRemovedAndRemovalLogged() {
// First, add the view
underTest.displayView(getState())
// Then, remove it
val reason = "test reason"
underTest.removeChip(reason)
underTest.removeView(reason)
verify(windowManager).removeView(any())
verify(logger).logChipRemoval(reason)
}
@Test
fun removeChip_noAdd_viewNotRemoved() {
underTest.removeChip("reason")
fun removeView_noAdd_viewNotRemoved() {
underTest.removeView("reason")
verify(windowManager, never()).removeView(any())
}
@Test
fun setIcon_nullAppIconDrawableAndNullPackageName_stillHasIcon() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(chipView, appPackageName = null, appIconDrawableOverride = null)
underTest.setIcon(view, appPackageName = null, appIconDrawableOverride = null)
assertThat(chipView.getAppIconView().drawable).isNotNull()
assertThat(view.getAppIconView().drawable).isNotNull()
}
@Test
fun setIcon_nullAppIconDrawableAndInvalidPackageName_stillHasIcon() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(
chipView, appPackageName = "fakePackageName", appIconDrawableOverride = null
view, appPackageName = "fakePackageName", appIconDrawableOverride = null
)
assertThat(chipView.getAppIconView().drawable).isNotNull()
assertThat(view.getAppIconView().drawable).isNotNull()
}
@Test
fun setIcon_nullAppIconDrawable_iconIsFromPackageName() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(chipView, PACKAGE_NAME, appIconDrawableOverride = null, null)
underTest.setIcon(view, PACKAGE_NAME, appIconDrawableOverride = null, null)
assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconFromPackageName)
assertThat(view.getAppIconView().drawable).isEqualTo(appIconFromPackageName)
}
@Test
fun setIcon_hasAppIconDrawable_iconIsDrawable() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
val drawable = context.getDrawable(R.drawable.ic_alarm)!!
underTest.setIcon(chipView, PACKAGE_NAME, drawable, null)
underTest.setIcon(view, PACKAGE_NAME, drawable, null)
assertThat(chipView.getAppIconView().drawable).isEqualTo(drawable)
assertThat(view.getAppIconView().drawable).isEqualTo(drawable)
}
@Test
fun setIcon_nullAppNameAndNullPackageName_stillHasContentDescription() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(chipView, appPackageName = null, appNameOverride = null)
underTest.setIcon(view, appPackageName = null, appNameOverride = null)
assertThat(chipView.getAppIconView().contentDescription.toString()).isNotEmpty()
assertThat(view.getAppIconView().contentDescription.toString()).isNotEmpty()
}
@Test
fun setIcon_nullAppNameAndInvalidPackageName_stillHasContentDescription() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(
chipView, appPackageName = "fakePackageName", appNameOverride = null
view, appPackageName = "fakePackageName", appNameOverride = null
)
assertThat(chipView.getAppIconView().contentDescription.toString()).isNotEmpty()
assertThat(view.getAppIconView().contentDescription.toString()).isNotEmpty()
}
@Test
fun setIcon_nullAppName_iconContentDescriptionIsFromPackageName() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(chipView, PACKAGE_NAME, null, appNameOverride = null)
underTest.setIcon(view, PACKAGE_NAME, null, appNameOverride = null)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_NAME)
assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME)
}
@Test
fun setIcon_hasAppName_iconContentDescriptionIsAppNameOverride() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
val appName = "Override App Name"
underTest.setIcon(chipView, PACKAGE_NAME, null, appName)
underTest.setIcon(view, PACKAGE_NAME, null, appName)
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(appName)
assertThat(view.getAppIconView().contentDescription).isEqualTo(appName)
}
@Test
fun setIcon_iconSizeMatchesGetIconSize() {
underTest.displayChip(getState())
val chipView = getChipView()
underTest.displayView(getState())
val view = getView()
underTest.setIcon(chipView, PACKAGE_NAME)
chipView.measure(
underTest.setIcon(view, PACKAGE_NAME)
view.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(ICON_SIZE)
assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(ICON_SIZE)
assertThat(view.getAppIconView().measuredWidth).isEqualTo(ICON_SIZE)
assertThat(view.getAppIconView().measuredHeight).isEqualTo(ICON_SIZE)
}
private fun getState(name: String = "name") = ChipInfo(name)
private fun getState(name: String = "name") = ViewInfo(name)
private fun getChipView(): ViewGroup {
private fun getView(): ViewGroup {
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
verify(windowManager).addView(viewCaptor.capture(), any())
return viewCaptor.value as ViewGroup
@@ -354,7 +354,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
powerManager: PowerManager,
) : TemporaryViewDisplayController<ChipInfo>(
) : TemporaryViewDisplayController<ViewInfo>(
context,
logger,
windowManager,
@@ -364,17 +364,17 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
powerManager,
R.layout.media_ttt_chip,
) {
var mostRecentChipInfo: ChipInfo? = null
var mostRecentViewInfo: ViewInfo? = null
override val windowLayoutParams = commonWindowLayoutParams
override fun updateChipView(newChipInfo: ChipInfo, currentChipView: ViewGroup) {
super.updateChipView(newChipInfo, currentChipView)
mostRecentChipInfo = newChipInfo
override fun updateView(newInfo: ViewInfo, currentView: ViewGroup) {
super.updateView(newInfo, currentView)
mostRecentViewInfo = newInfo
}
override fun getIconSize(isAppIcon: Boolean): Int = ICON_SIZE
}
inner class ChipInfo(val name: String) : TemporaryViewInfo {
inner class ViewInfo(val name: String) : TemporaryViewInfo {
override fun getTimeoutMs() = 1L
}
}