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

Commit 3f23752b authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support async hierarchy in DeviceState" into main

parents 3f71c824 b0bf708e
Loading
Loading
Loading
Loading
+82 −29
Original line number Diff line number Diff line
@@ -35,8 +35,14 @@ import com.android.extensions.appfunctions.ExecuteAppFunctionRequest
import com.android.extensions.appfunctions.ExecuteAppFunctionResponse
import com.android.settings.utils.getLocale
import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceHierarchy
import com.android.settingslib.metadata.PreferenceScreenCoordinate
import com.android.settingslib.metadata.PreferenceHierarchyGenerator
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceScreenMetadata
import com.android.settingslib.metadata.PreferenceScreenRegistry
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.PreferenceTitleProvider
import com.google.android.appfunctions.schema.common.v1.devicestate.DeviceStateItem
import com.google.android.appfunctions.schema.common.v1.devicestate.DeviceStateResponse
import com.google.android.appfunctions.schema.common.v1.devicestate.LocalizedString
@@ -119,7 +125,7 @@ class DeviceStateAppFunctionService : AppFunctionService() {
        )
    }

    private fun buildPerScreenDeviceStates(
    private suspend fun buildPerScreenDeviceStates(
        screenKey: String,
        requestCategory: DeviceStateCategory,
    ): PerScreenDeviceStates? {
@@ -136,55 +142,102 @@ class DeviceStateAppFunctionService : AppFunctionService() {
            return null
        }
        val deviceStateItemList: MutableList<DeviceStateItem> = ArrayList()
        // TODO(b/405344827): support PreferenceHierarchyGenerator
        val hierarchy = screenMetaData.getPreferenceHierarchy(applicationContext)
        hierarchy.forEach {
            val metadata = it.metadata as? PersistentPreference<*> ?: return@forEach
        val hierarchy = (screenMetaData as? PreferenceHierarchyGenerator<*>)
            ?.asyncHierarchy(perScreenConfig)
            ?: screenMetaData.getPreferenceHierarchy(applicationContext)
        hierarchy.forEachRecursively {
            val metadata = it.metadata
            val config = settingConfigMap[metadata.key]
            if (config == null || !config.enabled) {
                return@forEach
            // skip over explicitly disabled preferences
            if (!(config?.enabled ?: true)) {
                return@forEachRecursively
            }
            val valueType = metadata.valueType
            var jasonValue: String? = when (valueType) {
            val jsonValue = (metadata as? PersistentPreference<*>)?.let {
                when (metadata.valueType) {
                    Int::class.javaObjectType -> metadata.storage(applicationContext)
                    ?.getInt("")
                        .getInt("")
                        .toString()

                    Boolean::class.javaObjectType -> metadata.storage(applicationContext)
                    ?.getBoolean("").toString()
                        .getBoolean("").toString()

                    Long::class.javaObjectType -> metadata.storage(applicationContext)
                    ?.getLong("")
                        .getLong("")
                        .toString()

                    Float::class.javaObjectType -> metadata.storage(applicationContext)
                    ?.getLong("")
                        .getLong("")
                        .toString()

                String::class.javaObjectType -> metadata.storage(applicationContext)?.getString("")
                else -> null
            }
            if (jasonValue == null) {
                jasonValue = tryGetStringRes(metadata.summary)
                    String::class.javaObjectType -> metadata.storage(applicationContext)
                        .getString("")
                    else -> getSummary(applicationContext, metadata)
                }
            } ?: getSummary(applicationContext, metadata)
            deviceStateItemList.add(
                DeviceStateItem(
                    key = metadata.key,
                    // TODO check dynamic title
                    name = getLocalizedString(metadata.title),
                    jsonValue = jasonValue,
                    hintText = config.hintText
                    jsonValue = jsonValue,
                    hintText = config?.hintText ?: ""
                )
            )
        }

        val launchingIntent = screenMetaData.getLaunchIntent(applicationContext, null)
        return PerScreenDeviceStates(
            description = tryGetStringRes(screenMetaData.title),
            description = getScreenTitle(screenMetaData) ?: "",
            deviceStateItems = deviceStateItemList,
            intentUri = launchingIntent?.toUri(Intent.URI_INTENT_SCHEME)
        )
    }

    private suspend fun PreferenceHierarchyGenerator<*>.asyncHierarchy(
        config: PerScreenConfig
    ): PreferenceHierarchy {
        return when (config.defaultType) {
            Boolean::class.java -> (this as PreferenceHierarchyGenerator<Boolean>)
                .generatePreferenceHierarchy(
                    applicationContext,
                    config.defaultTypeValue as Boolean
                )
            Int::class.java -> (this as PreferenceHierarchyGenerator<Int>)
                .generatePreferenceHierarchy(
                    applicationContext,
                    config.defaultTypeValue as Int
                )
            else -> generatePreferenceHierarchy(applicationContext)
        }
    }

    private fun getScreenTitle(metadata: PreferenceScreenMetadata): String? {
        val screenTitleRes = metadata.screenTitle
        if (screenTitleRes != 0) {
            return tryGetStringRes(screenTitleRes)
        }
        metadata.getScreenTitle(applicationContext)?.let {
            return it.toString()
        }
        val dynamicTitle = (metadata as? PreferenceTitleProvider)?.getTitle(applicationContext)
        if (dynamicTitle != null) {
            return dynamicTitle.toString()
        }
        val titleRes = metadata.title
        if (titleRes != 0) {
            return tryGetStringRes(titleRes)
        }
        return null
    }

    private fun getSummary(context: Context, metadata: PreferenceMetadata): String? {
        return if (metadata.summary != 0) {
            tryGetStringRes(metadata.summary)
        } else {
            (metadata as? PreferenceSummaryProvider)?.getSummary(context).toString()
        }
    }

    private fun tryGetStringRes(resId: Int): String {
        return try {
            applicationContext.getString(resId)
+27 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoScreen
import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionScreen
import com.android.settings.deviceinfo.legal.LegalSettingsScreen
import com.android.settings.deviceinfo.legal.ModuleLicensesScreen
import com.android.settings.deviceinfo.storage.StoragePreferenceScreen
import com.android.settings.display.AutoBrightnessScreen
import com.android.settings.display.DisplayScreen
import com.android.settings.display.ScreenTimeoutScreen
@@ -40,8 +41,11 @@ import com.android.settings.network.NetworkProviderScreen
import com.android.settings.network.tether.TetherScreen
import com.android.settings.notification.SoundScreen
import com.android.settings.security.LockScreenPreferenceScreen
import com.android.settings.spa.app.catalyst.AllAppsScreen
import com.android.settings.spa.app.catalyst.AppStorageAppListScreen
import com.android.settings.supervision.SupervisionDashboardScreen
import com.android.settings.supervision.SupervisionPinManagementScreen
import com.android.settingslib.metadata.PreferenceHierarchyGenerator

enum class DeviceStateCategory(val functionId: String) {
    UNCATEGORIZED("getUncategorizedDeviceState"),
@@ -67,7 +71,7 @@ enum class DeviceStateCategory(val functionId: String) {
 * @param hintText additional context about the device state
 */
data class DeviceStateItemConfig(
    val enabled: Boolean,
    val enabled: Boolean = true,
    val settingKey: String,
    val settingScreenKey: String,
    val hintText: String = "",
@@ -79,12 +83,16 @@ data class DeviceStateItemConfig(
 * @param enabled whether expose device states on this screen to App Functions.
 * @param screenKey the unique ID for the screen.
 * @param category the device state category of the screen. The default is UNCATEGORIZED.
 * @param defaultType class type associated with [PreferenceHierarchyGenerator] for PreferenceScreen
 * @param defaultTypeValue value to pass in to [PreferenceHierarchyGenerator.generatePreferenceHierarchy]
 */
data class PerScreenConfig(
    val enabled: Boolean,
    val screenKey: String,
    // TODO(b/405344827): map categories to PreferenceMetadata#tags
    val category: Set<DeviceStateCategory> = setOf(DeviceStateCategory.UNCATEGORIZED)
    val category: Set<DeviceStateCategory> = setOf(DeviceStateCategory.UNCATEGORIZED),
    val defaultType: Class<*>? = null,
    val defaultTypeValue: Any? = null
)

fun getScreenConfigs() = listOf(
@@ -210,6 +218,23 @@ fun getScreenConfigs() = listOf(
    PerScreenConfig(
        enabled = true,
        screenKey = VibrationScreen.KEY,
    ),
    PerScreenConfig(
        enabled = true,
        screenKey = AppStorageAppListScreen.KEY,
        category = setOf(DeviceStateCategory.STORAGE),
        defaultType = Boolean::class.java,
        defaultTypeValue = false, // do not include system apps
    ),
    PerScreenConfig(
        enabled = true,
        screenKey = AllAppsScreen.KEY,
        category = setOf(DeviceStateCategory.STORAGE)
    ),
    PerScreenConfig(
        enabled = true,
        screenKey = StoragePreferenceScreen.KEY,
        category = setOf(DeviceStateCategory.STORAGE)
    )
)

+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class AppStorageAppListScreen : PreferenceScreenCreator, PreferenceHierarchyGene

    override fun tags(context: Context) = arrayOf(TAG_DEVICE_STATE_SCREEN)

    override fun isFlagEnabled(context: Context) = Flags.catalystAppList()
    override fun isFlagEnabled(context: Context) = Flags.catalystAppList() || Flags.deviceState()

    override fun hasCompleteHierarchy() = false