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

Commit 173f325f authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Fix accessibility for connected display status bar icon

Now it has a content description, and every time the green icon animates in "Display connected" is announced.

The icon is now selectable as well.

Fixes: 306525994
Fixes: 306522117
Fixes: 306527238
Test: SystemStatusAnimationSchedulerImplTest
Change-Id: I072daedb3e5873d640ae6da2ea319619a5bb32d1
parent 57cb73f2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3224,6 +3224,9 @@
    <!--- Label of the dismiss button of the dialog appearing when an external display is connected [CHAR LIMIT=NONE]-->
    <string name="dismiss_dialog">Dismiss</string>

    <!--- Content description of the connected display status bar icon that appears every time a display is connected [CHAR LIMIT=NONE]-->
    <string name="connected_display_icon_desc">Display connected</string>

    <!-- Title of the privacy dialog, shown for active / recent app usage of some phone sensors [CHAR LIMIT=30] -->
    <string name="privacy_dialog_title">Microphone &amp; Camera</string>
    <!-- Subtitle of the privacy dialog, shown for active / recent app usage of some phone sensors [CHAR LIMIT=NONE] -->
+8 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ interface StatusEvent {
    val showAnimation: Boolean
    val viewCreator: ViewCreator
    var contentDescription: String?
    /**
     * When true, an accessibility event with [contentDescription] is announced when the view
     * becomes visible.
     */
    val shouldAnnounceAccessibilityEvent: Boolean

    // Update this event with values from another event.
    fun updateFromEvent(other: StatusEvent?) {
@@ -76,6 +81,7 @@ class BatteryEvent(@IntRange(from = 0, to = 100) val batteryLevel: Int) : Status
    override var forceVisible = false
    override val showAnimation = true
    override var contentDescription: String? = ""
    override val shouldAnnounceAccessibilityEvent: Boolean = false

    override val viewCreator: ViewCreator = { context ->
        BatteryStatusChip(context).apply {
@@ -95,6 +101,7 @@ class ConnectedDisplayEvent : StatusEvent {
    override var forceVisible = false
    override val showAnimation = true
    override var contentDescription: String? = ""
    override val shouldAnnounceAccessibilityEvent: Boolean = true

    override val viewCreator: ViewCreator = { context ->
        ConnectedDisplayChip(context)
@@ -110,6 +117,7 @@ open class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEven
    override var contentDescription: String? = null
    override val priority = 100
    override var forceVisible = true
    override val shouldAnnounceAccessibilityEvent: Boolean = false
    var privacyItems: List<PrivacyItem> = listOf()
    private var privacyChip: OngoingPrivacyChip? = null

+5 −0
Original line number Diff line number Diff line
@@ -273,6 +273,11 @@ class SystemEventChipAnimationController @Inject constructor(
        })
    }

    /** Announces [contentDescriptions] for accessibility. */
    fun announceForAccessibility(contentDescriptions: String) {
        currentAnimatedView?.view?.announceForAccessibility(contentDescriptions)
    }

    private fun updateDimens(contentArea: Rect) {
        val lp = animationWindowView.layoutParams as FrameLayout.LayoutParams
        lp.height = contentArea.height()
+4 −1
Original line number Diff line number Diff line
@@ -100,9 +100,12 @@ constructor(
    }

    private fun startConnectedDisplayCollection() {
        val connectedDisplayEvent = ConnectedDisplayEvent().apply {
            contentDescription = context.getString(R.string.connected_display_icon_desc)
        }
        connectedDisplayCollectionJob =
                onDisplayConnectedFlow
                        .onEach { scheduler.onStatusEvent(ConnectedDisplayEvent()) }
                        .onEach { scheduler.onStatusEvent(connectedDisplayEvent) }
                        .launchIn(appScope)
    }

+7 −0
Original line number Diff line number Diff line
@@ -254,11 +254,18 @@ constructor(
        currentlyRunningAnimationJob =
            coroutineScope.launch {
                runChipAppearAnimation()
                announceForAccessibilityIfNeeded(event)
                delay(APPEAR_ANIMATION_DURATION + DISPLAY_LENGTH)
                runChipDisappearAnimation()
            }
    }

    private fun announceForAccessibilityIfNeeded(event: StatusEvent) {
        val description = event.contentDescription ?: return
        if (!event.shouldAnnounceAccessibilityEvent)  return
        chipAnimationController.announceForAccessibility(description)
    }

    /**
     * 1. Define a total budget for the chip animation (1500ms)
     * 2. Send out callbacks to listeners so that they can generate animations locally
Loading