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

Commit 78feb3d5 authored by George Lin's avatar George Lin
Browse files

Expose sysui runtime values to wallpaper picker (2/2)

Test: Manually tested
Fixes: 379348167
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: I6a0f5b0b3401e9def56c0d13db0c135aec067b7d
parent ef60e0f7
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.database.ContentObserver
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.annotation.DrawableRes
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
@@ -59,6 +60,11 @@ interface CustomizationProviderClient {
    /** Returns the list of flags. */
    suspend fun queryFlags(): List<Flag>

    /**
     * Returns [Bundle] where the keys are from [CustomizationProviderContract.RuntimeValuesTable]
     */
    suspend fun queryRuntimeValues(): Bundle

    /**
     * Returns [Flow] for observing the collection of slots.
     *
@@ -73,6 +79,13 @@ interface CustomizationProviderClient {
     */
    fun observeFlags(): Flow<List<Flag>>

    /**
     * Returns [Flow] for observing the variables from the System UI.
     *
     * @see [queryRuntimeValues]
     */
    fun observeRuntimeValues(): Flow<Bundle>

    /**
     * Returns all available affordances supported by the device, regardless of current slot
     * placement.
@@ -262,6 +275,30 @@ class CustomizationProviderClientImpl(
        } ?: emptyList()
    }

    override suspend fun queryRuntimeValues(): Bundle {
        return withContext(backgroundDispatcher) {
            Bundle().apply {
                context.contentResolver
                    .query(Contract.RuntimeValuesTable.URI, null, null, null, null)
                    ?.use { cursor ->
                        val nameColumnIndex =
                            cursor.getColumnIndex(Contract.FlagsTable.Columns.NAME)
                        val valueColumnIndex =
                            cursor.getColumnIndex(Contract.FlagsTable.Columns.VALUE)
                        if (nameColumnIndex >= 0 && valueColumnIndex >= 0) {
                            while (cursor.moveToNext()) {
                                when (val name = cursor.getString(nameColumnIndex)) {
                                    Contract.RuntimeValuesTable.KEY_IS_SHADE_LAYOUT_WIDE -> {
                                        putBoolean(name, cursor.getInt(valueColumnIndex) == 1)
                                    }
                                }
                            }
                        }
                    }
            }
        }
    }

    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
        return observeUri(Contract.LockScreenQuickAffordances.SlotTable.URI).map { querySlots() }
    }
@@ -270,6 +307,10 @@ class CustomizationProviderClientImpl(
        return observeUri(Contract.FlagsTable.URI).map { queryFlags() }
    }

    override fun observeRuntimeValues(): Flow<Bundle> {
        return observeUri(Contract.RuntimeValuesTable.URI).map { queryRuntimeValues() }
    }

    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
        return withContext(backgroundDispatcher) {
            context.contentResolver
+23 −0
Original line number Diff line number Diff line
@@ -198,4 +198,27 @@ object CustomizationProviderContract {
            const val VALUE = "value"
        }
    }

    object RuntimeValuesTable {
        const val TABLE_NAME = "runtime_values"
        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()

        /**
         * This key corresponds to an Int value, where `1` means `true` and `0` means `false`.
         *
         * Whether the shade layout should be wide (true) or narrow (false).
         *
         * In a wide layout, notifications and quick settings each take up only half the screen
         * width (whether they are shown at the same time or not). In a narrow layout, they can each
         * be as wide as the entire screen.
         */
        const val KEY_IS_SHADE_LAYOUT_WIDE = "is_shade_layout_wide"

        object Columns {
            /** String. Unique ID for the value. */
            const val NAME = "name"
            /** Type depends on the key name. */
            const val VALUE = "value"
        }
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.shared.customization.data.content

import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -64,11 +65,13 @@ class FakeCustomizationProviderClient(
                value = true,
            )
        ),
    runtimeValues: Bundle = Bundle(),
) : CustomizationProviderClient {

    private val slots = MutableStateFlow(slots)
    private val affordances = MutableStateFlow(affordances)
    private val flags = MutableStateFlow(flags)
    private val runtimeValues = MutableStateFlow(runtimeValues)

    private val selections = MutableStateFlow<Map<String, List<String>>>(emptyMap())

@@ -93,6 +96,10 @@ class FakeCustomizationProviderClient(
        return flags.value
    }

    override suspend fun queryRuntimeValues(): Bundle {
        return runtimeValues.value
    }

    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
        return slots.asStateFlow()
    }
@@ -101,6 +108,10 @@ class FakeCustomizationProviderClient(
        return flags.asStateFlow()
    }

    override fun observeRuntimeValues(): Flow<Bundle> {
        return runtimeValues.asStateFlow()
    }

    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
        return affordances.value
    }
@@ -147,6 +158,10 @@ class FakeCustomizationProviderClient(
            }
    }

    fun setRuntimeValues(runtimeValues: Bundle) {
        this.runtimeValues.value = runtimeValues
    }

    fun setSlotCapacity(slotId: String, capacity: Int) {
        slots.value =
            slots.value.toMutableList().apply {
+29 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCall
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -44,6 +45,7 @@ class CustomizationProvider :
    ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {

    @Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
    @Inject lateinit var shadeModeInteractor: ShadeModeInteractor
    @Inject lateinit var previewManager: KeyguardRemotePreviewManager
    @Inject @Main lateinit var mainDispatcher: CoroutineDispatcher

@@ -73,6 +75,11 @@ class CustomizationProvider :
                MATCH_CODE_ALL_SELECTIONS,
            )
            addURI(Contract.AUTHORITY, Contract.FlagsTable.TABLE_NAME, MATCH_CODE_ALL_FLAGS)
            addURI(
                Contract.AUTHORITY,
                Contract.RuntimeValuesTable.TABLE_NAME,
                MATCH_CODE_ALL_RUNTIME_VALUES,
            )
        }

    override fun onCreate(): Boolean {
@@ -94,7 +101,8 @@ class CustomizationProvider :
                MATCH_CODE_ALL_SLOTS,
                MATCH_CODE_ALL_AFFORDANCES,
                MATCH_CODE_ALL_FLAGS,
                MATCH_CODE_ALL_SELECTIONS -> "vnd.android.cursor.dir/vnd."
                MATCH_CODE_ALL_SELECTIONS,
                MATCH_CODE_ALL_RUNTIME_VALUES -> "vnd.android.cursor.dir/vnd."
                else -> null
            }

@@ -113,6 +121,7 @@ class CustomizationProvider :
                        Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME
                    )
                MATCH_CODE_ALL_FLAGS -> Contract.FlagsTable.TABLE_NAME
                MATCH_CODE_ALL_RUNTIME_VALUES -> Contract.RuntimeValuesTable.TABLE_NAME
                else -> null
            }

@@ -146,6 +155,7 @@ class CustomizationProvider :
                MATCH_CODE_ALL_SLOTS -> querySlots()
                MATCH_CODE_ALL_SELECTIONS -> querySelections()
                MATCH_CODE_ALL_FLAGS -> queryFlags()
                MATCH_CODE_ALL_RUNTIME_VALUES -> queryRuntimeValues()
                else -> null
            }
        }
@@ -334,6 +344,23 @@ class CustomizationProvider :
            }
    }

    private fun queryRuntimeValues(): Cursor {
        return MatrixCursor(
                arrayOf(
                    Contract.RuntimeValuesTable.Columns.NAME,
                    Contract.RuntimeValuesTable.Columns.VALUE,
                )
            )
            .apply {
                addRow(
                    arrayOf(
                        Contract.RuntimeValuesTable.KEY_IS_SHADE_LAYOUT_WIDE,
                        if (shadeModeInteractor.isShadeLayoutWide.value) 1 else 0,
                    )
                )
            }
    }

    private suspend fun deleteSelection(uri: Uri, selectionArgs: Array<out String>?): Int {
        if (selectionArgs == null) {
            throw IllegalArgumentException(
@@ -370,5 +397,6 @@ class CustomizationProvider :
        private const val MATCH_CODE_ALL_AFFORDANCES = 2
        private const val MATCH_CODE_ALL_SELECTIONS = 3
        private const val MATCH_CODE_ALL_FLAGS = 4
        private const val MATCH_CODE_ALL_RUNTIME_VALUES = 5
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -273,6 +273,12 @@ class CustomizationProviderTest : SysuiTestCase() {
                    "${Contract.AUTHORITY}." +
                    Contract.FlagsTable.TABLE_NAME
            )
        assertThat(underTest.getType(Contract.RuntimeValuesTable.URI))
            .isEqualTo(
                "vnd.android.cursor.dir/vnd." +
                    "${Contract.AUTHORITY}." +
                    Contract.RuntimeValuesTable.TABLE_NAME
            )
    }

    @Test