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

Commit 51f86a15 authored by Alejandro Nijamkin's avatar Alejandro Nijamkin Committed by Ale Nijamkin
Browse files

Fixes RTL bug in quick affordance slot tabs.

When rendering with a right-to-left language, we shouldn't flip the
order of the slot names; this way, the "right" slot tab remains on the
right and the "left" slot tab remains on the left, regardless of the
layout direction of the current locale.

Fix: 276477249
Test: included unit test
Test: manually verified that "Left shortcut" is always on the left and
"Right shortcut" is always on the right, regardless of the direction of
the current system language (used Hebrew to verify).

Change-Id: Ibcffff3b4f26231c78299fd8afe4a16fe5cb1b11
parent 5be8ccc6
Loading
Loading
Loading
Loading
+25 −25
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.data.repository

import android.content.Context
import android.os.UserHandle
import android.util.LayoutDirection
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -113,30 +114,6 @@ constructor(
                initialValue = emptyMap(),
            )

    private val _slotPickerRepresentations: List<KeyguardSlotPickerRepresentation> by lazy {
        fun parseSlot(unparsedSlot: String): Pair<String, Int> {
            val split = unparsedSlot.split(SLOT_CONFIG_DELIMITER)
            check(split.size == 2)
            val slotId = split[0]
            val slotCapacity = split[1].toInt()
            return slotId to slotCapacity
        }

        val unparsedSlots =
            appContext.resources.getStringArray(R.array.config_keyguardQuickAffordanceSlots)

        val seenSlotIds = mutableSetOf<String>()
        unparsedSlots.mapNotNull { unparsedSlot ->
            val (slotId, slotCapacity) = parseSlot(unparsedSlot)
            check(!seenSlotIds.contains(slotId)) { "Duplicate slot \"$slotId\"!" }
            seenSlotIds.add(slotId)
            KeyguardSlotPickerRepresentation(
                id = slotId,
                maxSelectedAffordances = slotCapacity,
            )
        }
    }

    init {
        legacySettingSyncer.startSyncing()
        dumpManager.registerDumpable("KeyguardQuickAffordances", Dumpster())
@@ -211,7 +188,30 @@ constructor(
     * each slot and select which affordance(s) is/are installed in each slot on the keyguard.
     */
    fun getSlotPickerRepresentations(): List<KeyguardSlotPickerRepresentation> {
        return _slotPickerRepresentations
        fun parseSlot(unparsedSlot: String): Pair<String, Int> {
            val split = unparsedSlot.split(SLOT_CONFIG_DELIMITER)
            check(split.size == 2)
            val slotId = split[0]
            val slotCapacity = split[1].toInt()
            return slotId to slotCapacity
        }

        val unparsedSlots =
            appContext.resources.getStringArray(R.array.config_keyguardQuickAffordanceSlots)
        if (appContext.resources.configuration.layoutDirection == LayoutDirection.RTL) {
            unparsedSlots.reverse()
        }

        val seenSlotIds = mutableSetOf<String>()
        return unparsedSlots.mapNotNull { unparsedSlot ->
            val (slotId, slotCapacity) = parseSlot(unparsedSlot)
            check(!seenSlotIds.contains(slotId)) { "Duplicate slot \"$slotId\"!" }
            seenSlotIds.add(slotId)
            KeyguardSlotPickerRepresentation(
                id = slotId,
                maxSelectedAffordances = slotCapacity,
            )
        }
    }

    private inner class Dumpster : Dumpable {
+36 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
@@ -67,6 +68,7 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {

    @Before
    fun setUp() {
        context.resources.configuration.setLayoutDirection(Locale.US)
        config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
        config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
        val testDispatcher = StandardTestDispatcher()
@@ -221,6 +223,40 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
            )
    }

    @Test
    fun getSlotPickerRepresentations_rightToLeft_slotsReversed() {
        context.resources.configuration.setLayoutDirection(Locale("he", "IL"))
        val slot1 = "slot1"
        val slot2 = "slot2"
        val slot3 = "slot3"
        context.orCreateTestableResources.addOverride(
            R.array.config_keyguardQuickAffordanceSlots,
            arrayOf(
                "$slot1:2",
                "$slot2:4",
                "$slot3:5",
            ),
        )

        assertThat(underTest.getSlotPickerRepresentations())
            .isEqualTo(
                listOf(
                    KeyguardSlotPickerRepresentation(
                        id = slot3,
                        maxSelectedAffordances = 5,
                    ),
                    KeyguardSlotPickerRepresentation(
                        id = slot2,
                        maxSelectedAffordances = 4,
                    ),
                    KeyguardSlotPickerRepresentation(
                        id = slot1,
                        maxSelectedAffordances = 2,
                    ),
                )
            )
    }

    @Test
    fun `selections for secondary user`() =
        testScope.runTest {