Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4314f1e authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[Media TTT] Allow swiping up to dismiss the chipbar.

Bug: 262584940
Test: with flag off, verify that you can't swipe up to dismiss the
chipbar
Test: with flag on, verify that starting a swipe around the chipbar area
and swiping up will dismiss the chipbar
Test: atest ChipbarCoordinatorTest SwipeChipbarAwayGestureHandlerTest
Change-Id: I8440b9b2d7d715981bbf8ee9e44d9202068d4a88

Change-Id: I38aa257855eacaaae6708c796f3f91ea4584342a
parent b7ec39e1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -341,6 +341,10 @@ object Flags {
    // TODO(b/263512203): Tracking Bug
    val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator", teamfood = true)

    // TODO(b/265813373): Tracking Bug
    val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE =
        unreleasedFlag(912, "media_ttt_dismiss_gesture", teamfood = true)

    // 1000 - dock
    val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")

+4 −0
Original line number Diff line number Diff line
@@ -30,4 +30,8 @@ class MediaTttFlags @Inject constructor(private val featureFlags: FeatureFlags)
    /** Check whether the flag for the receiver success state is enabled. */
    fun isMediaTttReceiverSuccessRippleEnabled(): Boolean =
        featureFlags.isEnabled(Flags.MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE)

    /** True if the media transfer chip can be dismissed via a gesture. */
    fun isMediaTttDismissGestureEnabled(): Boolean =
        featureFlags.isEnabled(Flags.MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE)
}
+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ constructor(
                    }
                },
            vibrationEffect = chipStateSender.transferStatus.vibrationEffect,
            allowSwipeToDismiss = true,
            windowTitle = MediaTttUtils.WINDOW_TITLE_SENDER,
            wakeReason = MediaTttUtils.WAKE_REASON_SENDER,
            timeoutMs = chipStateSender.timeout,
+3 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS
import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS
import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT
import androidx.annotation.CallSuper
import androidx.annotation.VisibleForTesting
import com.android.systemui.CoreStartable
import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Main
@@ -108,9 +109,10 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
     * Whenever the current view disappears, the next-priority view will be displayed if it's still
     * valid.
     */
    @VisibleForTesting
    internal val activeViews: MutableList<DisplayInfo> = mutableListOf()

    private fun getCurrentDisplayInfo(): DisplayInfo? {
    internal fun getCurrentDisplayInfo(): DisplayInfo? {
        return activeViews.getOrNull(0)
    }

+41 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ constructor(
    powerManager: PowerManager,
    private val falsingManager: FalsingManager,
    private val falsingCollector: FalsingCollector,
    private val swipeChipbarAwayGestureHandler: SwipeChipbarAwayGestureHandler?,
    private val viewUtil: ViewUtil,
    private val vibratorHelper: VibratorHelper,
    wakeLockBuilder: WakeLock.Builder,
@@ -105,6 +106,8 @@ constructor(
        commonWindowLayoutParams.apply { gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) }

    override fun updateView(newInfo: ChipbarInfo, currentView: ViewGroup) {
        updateGestureListening()

        logger.logViewUpdate(
            newInfo.windowTitle,
            newInfo.text.loadText(context),
@@ -228,6 +231,42 @@ constructor(
            includeMargins = true,
            onAnimationEnd,
        )

        updateGestureListening()
    }

    private fun updateGestureListening() {
        if (swipeChipbarAwayGestureHandler == null) {
            return
        }

        val currentDisplayInfo = getCurrentDisplayInfo()
        if (currentDisplayInfo != null && currentDisplayInfo.info.allowSwipeToDismiss) {
            swipeChipbarAwayGestureHandler.setViewFetcher { currentDisplayInfo.view }
            swipeChipbarAwayGestureHandler.addOnGestureDetectedCallback(TAG) {
                onSwipeUpGestureDetected()
            }
        } else {
            swipeChipbarAwayGestureHandler.resetViewFetcher()
            swipeChipbarAwayGestureHandler.removeOnGestureDetectedCallback(TAG)
        }
    }

    private fun onSwipeUpGestureDetected() {
        val currentDisplayInfo = getCurrentDisplayInfo()
        if (currentDisplayInfo == null) {
            logger.logSwipeGestureError(id = null, errorMsg = "No info is being displayed")
            return
        }
        if (!currentDisplayInfo.info.allowSwipeToDismiss) {
            logger.logSwipeGestureError(
                id = currentDisplayInfo.info.id,
                errorMsg = "This view prohibits swipe-to-dismiss",
            )
            return
        }
        removeView(currentDisplayInfo.info.id, SWIPE_UP_GESTURE_REASON)
        updateGestureListening()
    }

    private fun ViewGroup.getInnerView(): ViewGroup {
@@ -250,3 +289,5 @@ constructor(
private const val ANIMATION_IN_DURATION = 500L
private const val ANIMATION_OUT_DURATION = 250L
@IdRes private val INFO_TAG = R.id.tag_chipbar_info
private const val SWIPE_UP_GESTURE_REASON = "SWIPE_UP_GESTURE_DETECTED"
private const val TAG = "ChipbarCoordinator"
Loading