Loading src/com/android/settings/appfunctions/DeviceStateAppFunctionService.kt +82 −29 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -119,7 +125,7 @@ class DeviceStateAppFunctionService : AppFunctionService() { ) } private fun buildPerScreenDeviceStates( private suspend fun buildPerScreenDeviceStates( screenKey: String, requestCategory: DeviceStateCategory, ): PerScreenDeviceStates? { Loading @@ -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) Loading src/com/android/settings/appfunctions/DeviceStateConfig.kt +27 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"), Loading @@ -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 = "", Loading @@ -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( Loading Loading @@ -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) ) ) Loading src/com/android/settings/spa/app/catalyst/AppsStorageScreen.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
src/com/android/settings/appfunctions/DeviceStateAppFunctionService.kt +82 −29 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -119,7 +125,7 @@ class DeviceStateAppFunctionService : AppFunctionService() { ) } private fun buildPerScreenDeviceStates( private suspend fun buildPerScreenDeviceStates( screenKey: String, requestCategory: DeviceStateCategory, ): PerScreenDeviceStates? { Loading @@ -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) Loading
src/com/android/settings/appfunctions/DeviceStateConfig.kt +27 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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"), Loading @@ -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 = "", Loading @@ -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( Loading Loading @@ -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) ) ) Loading
src/com/android/settings/spa/app/catalyst/AppsStorageScreen.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading