Merge "[Media TTT] Adding Haptics" into tm-qpr-dev

This commit is contained in:
Michael Mikhail
2022-10-21 23:58:51 +00:00
committed by Android (Google) Code Review
7 changed files with 70 additions and 15 deletions

View File

@@ -159,7 +159,8 @@ constructor(
null null
} }
} }
} },
vibrationEffect = chipStateSender.transferStatus.vibrationEffect,
) )
} }

View File

@@ -16,16 +16,36 @@
package com.android.systemui.media.taptotransfer.sender package com.android.systemui.media.taptotransfer.sender
/** Represents the different possible transfer states that we could be in. */ import android.os.VibrationEffect
enum class TransferStatus {
/**
* Represents the different possible transfer states that we could be in and the vibration effects
* that come with updating transfer states.
*
* @property vibrationEffect an optional vibration effect when the transfer status is changed.
*/
enum class TransferStatus(
val vibrationEffect: VibrationEffect? = null,
) {
/** The transfer hasn't started yet. */ /** The transfer hasn't started yet. */
NOT_STARTED, NOT_STARTED(
vibrationEffect =
VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1.0f, 0)
.compose()
),
/** The transfer is currently ongoing but hasn't completed yet. */ /** The transfer is currently ongoing but hasn't completed yet. */
IN_PROGRESS, IN_PROGRESS(
vibrationEffect =
VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 1.0f, 0)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.7f, 70)
.compose(),
),
/** The transfer has completed successfully. */ /** The transfer has completed successfully. */
SUCCEEDED, SUCCEEDED,
/** The transfer has completed with a failure. */ /** The transfer has completed with a failure. */
FAILED, FAILED(vibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK)),
/** The device is too far away to do a transfer. */ /** The device is too far away to do a transfer. */
TOO_FAR, TOO_FAR,
} }

View File

@@ -42,6 +42,7 @@ import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.media.taptotransfer.common.MediaTttUtils
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger
import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.concurrency.DelayableExecutor
@@ -79,6 +80,7 @@ open class ChipbarCoordinator @Inject constructor(
private val falsingManager: FalsingManager, private val falsingManager: FalsingManager,
private val falsingCollector: FalsingCollector, private val falsingCollector: FalsingCollector,
private val viewUtil: ViewUtil, private val viewUtil: ViewUtil,
private val vibratorHelper: VibratorHelper,
) : TemporaryViewDisplayController<ChipbarInfo, MediaTttLogger>( ) : TemporaryViewDisplayController<ChipbarInfo, MediaTttLogger>(
context, context,
logger, logger,
@@ -154,6 +156,11 @@ open class ChipbarCoordinator @Inject constructor(
).contentDescription = ).contentDescription =
"${newInfo.startIcon.contentDescription.loadContentDescription(context)} " + "${newInfo.startIcon.contentDescription.loadContentDescription(context)} " +
"${newInfo.text.loadText(context)}" "${newInfo.text.loadText(context)}"
// ---- Haptics ----
newInfo.vibrationEffect?.let {
vibratorHelper.vibrate(it)
}
} }
override fun animateViewIn(view: ViewGroup) { override fun animateViewIn(view: ViewGroup) {

View File

@@ -16,6 +16,7 @@
package com.android.systemui.temporarydisplay.chipbar package com.android.systemui.temporarydisplay.chipbar
import android.os.VibrationEffect
import android.view.View import android.view.View
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
@@ -29,11 +30,13 @@ import com.android.systemui.temporarydisplay.TemporaryViewInfo
* @property text the text to display. * @property text the text to display.
* @property endItem an optional end item to display at the end of the chipbar (on the right in LTR * @property endItem an optional end item to display at the end of the chipbar (on the right in LTR
* locales; on the left in RTL locales). * locales; on the left in RTL locales).
* @property vibrationEffect an optional vibration effect when the chipbar is displayed
*/ */
data class ChipbarInfo( data class ChipbarInfo(
val startIcon: Icon, val startIcon: Icon,
val text: Text, val text: Text,
val endItem: ChipbarEndItem?, val endItem: ChipbarEndItem?,
val vibrationEffect: VibrationEffect? = null,
) : TemporaryViewInfo ) : TemporaryViewInfo
/** The possible items to display at the end of the chipbar. */ /** The possible items to display at the end of the chipbar. */

View File

@@ -22,6 +22,7 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.media.MediaRoute2Info import android.media.MediaRoute2Info
import android.os.PowerManager import android.os.PowerManager
import android.os.VibrationEffect
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.testing.TestableLooper import android.testing.TestableLooper
import android.view.View import android.view.View
@@ -41,6 +42,7 @@ import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator
@@ -81,10 +83,10 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Mock private lateinit var logger: MediaTttLogger @Mock private lateinit var logger: MediaTttLogger
@Mock private lateinit var mediaTttFlags: MediaTttFlags @Mock private lateinit var mediaTttFlags: MediaTttFlags
@Mock private lateinit var packageManager: PackageManager @Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var powerManager: PowerManager @Mock private lateinit var powerManager: PowerManager
@Mock private lateinit var viewUtil: ViewUtil @Mock private lateinit var viewUtil: ViewUtil
@Mock private lateinit var windowManager: WindowManager @Mock private lateinit var windowManager: WindowManager
@Mock private lateinit var vibratorHelper: VibratorHelper
private lateinit var chipbarCoordinator: ChipbarCoordinator private lateinit var chipbarCoordinator: ChipbarCoordinator
private lateinit var commandQueueCallback: CommandQueue.Callbacks private lateinit var commandQueueCallback: CommandQueue.Callbacks
private lateinit var fakeAppIconDrawable: Drawable private lateinit var fakeAppIconDrawable: Drawable
@@ -129,6 +131,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
falsingManager, falsingManager,
falsingCollector, falsingCollector,
viewUtil, viewUtil,
vibratorHelper,
) )
chipbarCoordinator.start() chipbarCoordinator.start()
@@ -182,9 +185,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -203,9 +206,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -224,9 +227,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.VISIBLE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.VISIBLE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -245,9 +248,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.VISIBLE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.VISIBLE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -265,9 +268,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
.isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText()) .isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText())
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
verify(vibratorHelper, never()).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -335,9 +338,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
.isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText()) .isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText())
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id)
verify(vibratorHelper, never()).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -408,9 +411,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test
@@ -429,9 +432,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
assertThat(uiEventLoggerFake.eventId(0)) assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id)
verify(vibratorHelper).vibrate(any<VibrationEffect>())
} }
@Test @Test

View File

@@ -17,6 +17,7 @@
package com.android.systemui.temporarydisplay.chipbar package com.android.systemui.temporarydisplay.chipbar
import android.os.PowerManager import android.os.PowerManager
import android.os.VibrationEffect
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.testing.TestableLooper import android.testing.TestableLooper
import android.view.View import android.view.View
@@ -36,6 +37,7 @@ import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
@@ -66,6 +68,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
@Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var falsingCollector: FalsingCollector @Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var viewUtil: ViewUtil @Mock private lateinit var viewUtil: ViewUtil
@Mock private lateinit var vibratorHelper: VibratorHelper
private lateinit var fakeClock: FakeSystemClock private lateinit var fakeClock: FakeSystemClock
private lateinit var fakeExecutor: FakeExecutor private lateinit var fakeExecutor: FakeExecutor
private lateinit var uiEventLoggerFake: UiEventLoggerFake private lateinit var uiEventLoggerFake: UiEventLoggerFake
@@ -92,6 +95,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
falsingManager, falsingManager,
falsingCollector, falsingCollector,
viewUtil, viewUtil,
vibratorHelper,
) )
underTest.start() underTest.start()
} }
@@ -272,6 +276,20 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
assertThat(isClicked).isTrue() assertThat(isClicked).isTrue()
} }
@Test
fun displayView_vibrationEffect_doubleClickEffect() {
underTest.displayView(
ChipbarInfo(
Icon.Resource(R.id.check_box, null),
Text.Loaded("text"),
endItem = null,
vibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK),
)
)
verify(vibratorHelper).vibrate(VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK))
}
@Test @Test
fun updateView_viewUpdated() { fun updateView_viewUpdated() {
// First, display a view // First, display a view

View File

@@ -25,6 +25,7 @@ import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger
import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.view.ViewUtil import com.android.systemui.util.view.ViewUtil
@@ -41,6 +42,7 @@ class FakeChipbarCoordinator(
falsingManager: FalsingManager, falsingManager: FalsingManager,
falsingCollector: FalsingCollector, falsingCollector: FalsingCollector,
viewUtil: ViewUtil, viewUtil: ViewUtil,
vibratorHelper: VibratorHelper,
) : ) :
ChipbarCoordinator( ChipbarCoordinator(
context, context,
@@ -53,6 +55,7 @@ class FakeChipbarCoordinator(
falsingManager, falsingManager,
falsingCollector, falsingCollector,
viewUtil, viewUtil,
vibratorHelper,
) { ) {
override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) { override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {
// Just bypass the animation in tests // Just bypass the animation in tests