Loading packages/SettingsLib/Graph/graph.proto +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,14 @@ message PreferenceScreenProto { optional PreferenceGroupProto root = 2; // If the preference screen provides complete hierarchy by source code. optional bool complete_hierarchy = 3; // Parameterized screens (not recursive, provided on the top level only) repeated ParameterizedPreferenceScreenProto parameterized_screens = 4; } // Proto of parameterized preference screen message ParameterizedPreferenceScreenProto { optional BundleProto args = 1; optional PreferenceScreenProto screen = 2; } // Proto of PreferenceGroup. Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt +23 −16 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package com.android.settingslib.graph import android.app.Application import android.os.Bundle import android.os.Parcelable import android.os.SystemClock import com.android.settingslib.graph.proto.PreferenceGraphProto import com.android.settingslib.ipc.ApiHandler import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.ipc.MessageCodec import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenRegistry import com.android.settingslib.preference.PreferenceScreenProvider import java.util.Locale Loading Loading @@ -59,10 +61,9 @@ class GetPreferenceGraphApiHandler( var success = false try { val builder = PreferenceGraphBuilder.of(application, callingPid, callingUid, request) if (request.screenKeys.isEmpty()) { PreferenceScreenRegistry.preferenceScreenMetadataFactories.forEachKeyAsync { builder.addPreferenceScreenFromRegistry(it) } if (request.screens.isEmpty()) { val factories = PreferenceScreenRegistry.preferenceScreenMetadataFactories factories.forEachAsync { _, factory -> builder.addPreferenceScreen(factory) } for (provider in preferenceScreenProviders) { builder.addPreferenceScreenProvider(provider) } Loading @@ -84,15 +85,15 @@ class GetPreferenceGraphApiHandler( /** * Request of [GetPreferenceGraphApiHandler]. * * @param screenKeys screen keys of the preference graph * @param visitedScreens keys of the visited preference screen * @param screens screens of the preference graph * @param visitedScreens visited preference screens * @param locale locale of the preference graph */ data class GetPreferenceGraphRequest @JvmOverloads constructor( val screenKeys: Set<String> = setOf(), val visitedScreens: Set<String> = setOf(), val screens: Set<PreferenceScreenCoordinate> = setOf(), val visitedScreens: Set<PreferenceScreenCoordinate> = setOf(), val locale: Locale? = null, val flags: Int = PreferenceGetterFlags.ALL, val includeValueDescriptor: Boolean = true, Loading @@ -101,26 +102,32 @@ constructor( object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> { override fun encode(data: GetPreferenceGraphRequest): Bundle = Bundle(4).apply { putStringArray(KEY_SCREEN_KEYS, data.screenKeys.toTypedArray()) putStringArray(KEY_VISITED_KEYS, data.visitedScreens.toTypedArray()) putParcelableArray(KEY_SCREENS, data.screens.toTypedArray()) putParcelableArray(KEY_VISITED_SCREENS, data.visitedScreens.toTypedArray()) putString(KEY_LOCALE, data.locale?.toLanguageTag()) putInt(KEY_FLAGS, data.flags) } @Suppress("DEPRECATION") override fun decode(data: Bundle): GetPreferenceGraphRequest { val screenKeys = data.getStringArray(KEY_SCREEN_KEYS) ?: arrayOf() val visitedScreens = data.getStringArray(KEY_VISITED_KEYS) ?: arrayOf() data.classLoader = PreferenceScreenCoordinate::class.java.classLoader val screens = data.getParcelableArray(KEY_SCREENS) ?: arrayOf() val visitedScreens = data.getParcelableArray(KEY_VISITED_SCREENS) ?: arrayOf() fun String?.toLocale() = if (this != null) Locale.forLanguageTag(this) else null fun Array<Parcelable>.toScreenCoordinates() = buildSet(size) { for (element in this@toScreenCoordinates) add(element as PreferenceScreenCoordinate) } return GetPreferenceGraphRequest( screenKeys.toSet(), visitedScreens.toSet(), screens.toScreenCoordinates(), visitedScreens.toScreenCoordinates(), data.getString(KEY_LOCALE).toLocale(), data.getInt(KEY_FLAGS), ) } private const val KEY_SCREEN_KEYS = "k" private const val KEY_VISITED_KEYS = "v" private const val KEY_SCREENS = "s" private const val KEY_VISITED_SCREENS = "v" private const val KEY_LOCALE = "l" private const val KEY_FLAGS = "f" } Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt +5 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.metadata.PreferenceCoordinate import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenRegistry /** Loading Loading @@ -105,8 +106,10 @@ class PreferenceGetterApiHandler( val errors = mutableMapOf<PreferenceCoordinate, Int>() val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>() val flags = request.flags for ((screenKey, coordinates) in request.preferences.groupBy { it.screenKey }) { val screenMetadata = PreferenceScreenRegistry.create(application, screenKey) val groups = request.preferences.groupBy { PreferenceScreenCoordinate(it.screenKey, it.args) } for ((screen, coordinates) in groups) { val screenMetadata = PreferenceScreenRegistry.create(application, screen) if (screenMetadata == null) { val latencyMs = SystemClock.elapsedRealtime() - elapsedRealtime for (coordinate in coordinates) { Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +58 −31 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.graph.proto.PreferenceProto.ActionTarget import com.android.settingslib.graph.proto.PreferenceScreenProto import com.android.settingslib.graph.proto.TextProto import com.android.settingslib.metadata.EXTRA_BINDING_SCREEN_ARGS import com.android.settingslib.metadata.IntRangeValuePreference import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider Loading @@ -47,7 +48,10 @@ import com.android.settingslib.metadata.PreferenceHierarchy import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceRestrictionProvider import com.android.settingslib.metadata.PreferenceScreenBindingKeyProvider import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenMetadata import com.android.settingslib.metadata.PreferenceScreenMetadataFactory import com.android.settingslib.metadata.PreferenceScreenMetadataParameterizedFactory import com.android.settingslib.metadata.PreferenceScreenRegistry import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.PreferenceTitleProvider Loading @@ -72,15 +76,19 @@ private constructor( PreferenceScreenFactory(context.ofLocale(request.locale)) } private val builder by lazy { PreferenceGraphProto.newBuilder() } private val visitedScreens = mutableSetOf<String>().apply { addAll(request.visitedScreens) } private val visitedScreens = request.visitedScreens.toMutableSet() private val screens = mutableMapOf<String, PreferenceScreenProto.Builder>() private suspend fun init() { for (key in request.screenKeys) { addPreferenceScreenFromRegistry(key) for (screen in request.screens) { PreferenceScreenRegistry.create(context, screen)?.let { addPreferenceScreen(it) } } } fun build(): PreferenceGraphProto = builder.build() fun build(): PreferenceGraphProto { for ((key, screenBuilder) in screens) builder.putScreens(key, screenBuilder.build()) return builder.build() } /** * Adds an activity to the graph. Loading Loading @@ -138,17 +146,10 @@ private constructor( null } suspend fun addPreferenceScreenFromRegistry(key: String): Boolean { val metadata = PreferenceScreenRegistry.create(context, key) ?: return false return addPreferenceScreenMetadata(metadata) } private suspend fun addPreferenceScreenMetadata(metadata: PreferenceScreenMetadata): Boolean = addPreferenceScreen(metadata.key) { preferenceScreenProto { completeHierarchy = metadata.hasCompleteHierarchy() root = metadata.getPreferenceHierarchy(context).toProto(metadata, true) } private suspend fun addPreferenceScreenFromRegistry(key: String): Boolean { val factory = PreferenceScreenRegistry.preferenceScreenMetadataFactories[key] ?: return false return addPreferenceScreen(factory) } suspend fun addPreferenceScreenProvider(activityClass: Class<*>) { Loading Loading @@ -188,25 +189,51 @@ private constructor( Log.e(TAG, "\"$preferenceScreen\" has no key") return } @Suppress("CheckReturnValue") addPreferenceScreen(key) { preferenceScreen.toProto(intent) } val args = preferenceScreen.peekExtras()?.getBundle(EXTRA_BINDING_SCREEN_ARGS) @Suppress("CheckReturnValue") addPreferenceScreen(key, args) { this.intent = intent.toProto() root = preferenceScreen.toProto() } } suspend fun addPreferenceScreen(factory: PreferenceScreenMetadataFactory): Boolean { if (factory is PreferenceScreenMetadataParameterizedFactory) { factory.parameters(context).collect { addPreferenceScreen(factory.create(context, it)) } return true } return addPreferenceScreen(factory.create(context)) } private suspend fun addPreferenceScreen(metadata: PreferenceScreenMetadata): Boolean = addPreferenceScreen(metadata.key, metadata.arguments) { completeHierarchy = metadata.hasCompleteHierarchy() root = metadata.getPreferenceHierarchy(context).toProto(metadata, true) } private suspend fun addPreferenceScreen( key: String, preferenceScreenProvider: suspend () -> PreferenceScreenProto, ): Boolean = if (visitedScreens.add(key)) { builder.putScreens(key, preferenceScreenProvider()) true } else { Log.w(TAG, "$key visited") false args: Bundle?, init: suspend PreferenceScreenProto.Builder.() -> Unit, ): Boolean { if (!visitedScreens.add(PreferenceScreenCoordinate(key, args))) { Log.w(TAG, "$key $args visited") return false } private suspend fun PreferenceScreen.toProto(intent: Intent?): PreferenceScreenProto = preferenceScreenProto { intent?.let { this.intent = it.toProto() } root = (this@toProto as PreferenceGroup).toProto() if (args == null) { // normal screen screens[key] = PreferenceScreenProto.newBuilder().also { init(it) } } else if (args.isEmpty) { // parameterized screen with backward compatibility val builder = screens.getOrPut(key) { PreferenceScreenProto.newBuilder() } init(builder) } else { // parameterized screen with non-empty arguments val builder = screens.getOrPut(key) { PreferenceScreenProto.newBuilder() } val parameterizedScreen = parameterizedPreferenceScreenProto { setArgs(args.toProto()) setScreen(PreferenceScreenProto.newBuilder().also { init(it) }) } builder.addParameterizedScreens(parameterizedScreen) } return true } private suspend fun PreferenceGroup.toProto(): PreferenceGroupProto = preferenceGroupProto { Loading Loading @@ -271,7 +298,7 @@ private constructor( .toProto(context, callingPid, callingUid, screenMetadata, isRoot, request.flags) .also { if (metadata is PreferenceScreenMetadata) { @Suppress("CheckReturnValue") addPreferenceScreenMetadata(metadata) @Suppress("CheckReturnValue") addPreferenceScreen(metadata) } metadata.intent(context)?.resolveActivity(context.packageManager)?.let { if (it.packageName == context.packageName) { Loading Loading @@ -322,7 +349,7 @@ private constructor( val screenKey = screen?.key if (!screenKey.isNullOrEmpty()) { @Suppress("CheckReturnValue") addPreferenceScreen(screenKey) { screen.toProto(null) } addPreferenceScreen(screenKey, null) { root = screen.toProto() } return actionTargetProto { key = screenKey } } } catch (e: Exception) { Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +11 −7 Original line number Diff line number Diff line Loading @@ -40,11 +40,12 @@ import com.android.settingslib.metadata.SensitivityLevel.Companion.HIGH_SENSITIV import com.android.settingslib.metadata.SensitivityLevel.Companion.UNKNOWN_SENSITIVITY /** Request to set preference value. */ data class PreferenceSetterRequest( val screenKey: String, val key: String, class PreferenceSetterRequest( screenKey: String, args: Bundle?, key: String, val value: PreferenceValueProto, ) ) : PreferenceCoordinate(screenKey, args, key) /** Result of preference setter request. */ @IntDef( Loading Loading @@ -121,7 +122,7 @@ class PreferenceSetterApiHandler( metricsLogger?.logSetterApi( application, callingUid, PreferenceCoordinate(request.screenKey, request.key), request, null, null, PreferenceSetterResult.UNSUPPORTED, Loading @@ -130,7 +131,7 @@ class PreferenceSetterApiHandler( return PreferenceSetterResult.UNSUPPORTED } val screenMetadata = PreferenceScreenRegistry.create(application, request.screenKey) ?: return notFound() PreferenceScreenRegistry.create(application, request) ?: return notFound() val key = request.key val metadata = screenMetadata.getPreferenceHierarchy(application).find(key) ?: return notFound() Loading Loading @@ -199,7 +200,7 @@ class PreferenceSetterApiHandler( metricsLogger?.logSetterApi( application, callingUid, PreferenceCoordinate(request.screenKey, request.key), request, screenMetadata, metadata, result, Loading Loading @@ -235,6 +236,7 @@ object PreferenceSetterRequestCodec : MessageCodec<PreferenceSetterRequest> { override fun encode(data: PreferenceSetterRequest) = Bundle(3).apply { putString(SCREEN_KEY, data.screenKey) putBundle(ARGS, data.args) putString(KEY, data.key) putByteArray(null, data.value.toByteArray()) } Loading @@ -242,10 +244,12 @@ object PreferenceSetterRequestCodec : MessageCodec<PreferenceSetterRequest> { override fun decode(data: Bundle) = PreferenceSetterRequest( data.getString(SCREEN_KEY)!!, data.getBundle(ARGS), data.getString(KEY)!!, PreferenceValueProto.parseFrom(data.getByteArray(null)!!), ) private const val SCREEN_KEY = "s" private const val KEY = "k" private const val ARGS = "a" } Loading
packages/SettingsLib/Graph/graph.proto +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,14 @@ message PreferenceScreenProto { optional PreferenceGroupProto root = 2; // If the preference screen provides complete hierarchy by source code. optional bool complete_hierarchy = 3; // Parameterized screens (not recursive, provided on the top level only) repeated ParameterizedPreferenceScreenProto parameterized_screens = 4; } // Proto of parameterized preference screen message ParameterizedPreferenceScreenProto { optional BundleProto args = 1; optional PreferenceScreenProto screen = 2; } // Proto of PreferenceGroup. Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt +23 −16 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package com.android.settingslib.graph import android.app.Application import android.os.Bundle import android.os.Parcelable import android.os.SystemClock import com.android.settingslib.graph.proto.PreferenceGraphProto import com.android.settingslib.ipc.ApiHandler import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.ipc.MessageCodec import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenRegistry import com.android.settingslib.preference.PreferenceScreenProvider import java.util.Locale Loading Loading @@ -59,10 +61,9 @@ class GetPreferenceGraphApiHandler( var success = false try { val builder = PreferenceGraphBuilder.of(application, callingPid, callingUid, request) if (request.screenKeys.isEmpty()) { PreferenceScreenRegistry.preferenceScreenMetadataFactories.forEachKeyAsync { builder.addPreferenceScreenFromRegistry(it) } if (request.screens.isEmpty()) { val factories = PreferenceScreenRegistry.preferenceScreenMetadataFactories factories.forEachAsync { _, factory -> builder.addPreferenceScreen(factory) } for (provider in preferenceScreenProviders) { builder.addPreferenceScreenProvider(provider) } Loading @@ -84,15 +85,15 @@ class GetPreferenceGraphApiHandler( /** * Request of [GetPreferenceGraphApiHandler]. * * @param screenKeys screen keys of the preference graph * @param visitedScreens keys of the visited preference screen * @param screens screens of the preference graph * @param visitedScreens visited preference screens * @param locale locale of the preference graph */ data class GetPreferenceGraphRequest @JvmOverloads constructor( val screenKeys: Set<String> = setOf(), val visitedScreens: Set<String> = setOf(), val screens: Set<PreferenceScreenCoordinate> = setOf(), val visitedScreens: Set<PreferenceScreenCoordinate> = setOf(), val locale: Locale? = null, val flags: Int = PreferenceGetterFlags.ALL, val includeValueDescriptor: Boolean = true, Loading @@ -101,26 +102,32 @@ constructor( object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> { override fun encode(data: GetPreferenceGraphRequest): Bundle = Bundle(4).apply { putStringArray(KEY_SCREEN_KEYS, data.screenKeys.toTypedArray()) putStringArray(KEY_VISITED_KEYS, data.visitedScreens.toTypedArray()) putParcelableArray(KEY_SCREENS, data.screens.toTypedArray()) putParcelableArray(KEY_VISITED_SCREENS, data.visitedScreens.toTypedArray()) putString(KEY_LOCALE, data.locale?.toLanguageTag()) putInt(KEY_FLAGS, data.flags) } @Suppress("DEPRECATION") override fun decode(data: Bundle): GetPreferenceGraphRequest { val screenKeys = data.getStringArray(KEY_SCREEN_KEYS) ?: arrayOf() val visitedScreens = data.getStringArray(KEY_VISITED_KEYS) ?: arrayOf() data.classLoader = PreferenceScreenCoordinate::class.java.classLoader val screens = data.getParcelableArray(KEY_SCREENS) ?: arrayOf() val visitedScreens = data.getParcelableArray(KEY_VISITED_SCREENS) ?: arrayOf() fun String?.toLocale() = if (this != null) Locale.forLanguageTag(this) else null fun Array<Parcelable>.toScreenCoordinates() = buildSet(size) { for (element in this@toScreenCoordinates) add(element as PreferenceScreenCoordinate) } return GetPreferenceGraphRequest( screenKeys.toSet(), visitedScreens.toSet(), screens.toScreenCoordinates(), visitedScreens.toScreenCoordinates(), data.getString(KEY_LOCALE).toLocale(), data.getInt(KEY_FLAGS), ) } private const val KEY_SCREEN_KEYS = "k" private const val KEY_VISITED_KEYS = "v" private const val KEY_SCREENS = "s" private const val KEY_VISITED_SCREENS = "v" private const val KEY_LOCALE = "l" private const val KEY_FLAGS = "f" } Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt +5 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.metadata.PreferenceCoordinate import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenRegistry /** Loading Loading @@ -105,8 +106,10 @@ class PreferenceGetterApiHandler( val errors = mutableMapOf<PreferenceCoordinate, Int>() val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>() val flags = request.flags for ((screenKey, coordinates) in request.preferences.groupBy { it.screenKey }) { val screenMetadata = PreferenceScreenRegistry.create(application, screenKey) val groups = request.preferences.groupBy { PreferenceScreenCoordinate(it.screenKey, it.args) } for ((screen, coordinates) in groups) { val screenMetadata = PreferenceScreenRegistry.create(application, screen) if (screenMetadata == null) { val latencyMs = SystemClock.elapsedRealtime() - elapsedRealtime for (coordinate in coordinates) { Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +58 −31 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.graph.proto.PreferenceProto.ActionTarget import com.android.settingslib.graph.proto.PreferenceScreenProto import com.android.settingslib.graph.proto.TextProto import com.android.settingslib.metadata.EXTRA_BINDING_SCREEN_ARGS import com.android.settingslib.metadata.IntRangeValuePreference import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider Loading @@ -47,7 +48,10 @@ import com.android.settingslib.metadata.PreferenceHierarchy import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceRestrictionProvider import com.android.settingslib.metadata.PreferenceScreenBindingKeyProvider import com.android.settingslib.metadata.PreferenceScreenCoordinate import com.android.settingslib.metadata.PreferenceScreenMetadata import com.android.settingslib.metadata.PreferenceScreenMetadataFactory import com.android.settingslib.metadata.PreferenceScreenMetadataParameterizedFactory import com.android.settingslib.metadata.PreferenceScreenRegistry import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.PreferenceTitleProvider Loading @@ -72,15 +76,19 @@ private constructor( PreferenceScreenFactory(context.ofLocale(request.locale)) } private val builder by lazy { PreferenceGraphProto.newBuilder() } private val visitedScreens = mutableSetOf<String>().apply { addAll(request.visitedScreens) } private val visitedScreens = request.visitedScreens.toMutableSet() private val screens = mutableMapOf<String, PreferenceScreenProto.Builder>() private suspend fun init() { for (key in request.screenKeys) { addPreferenceScreenFromRegistry(key) for (screen in request.screens) { PreferenceScreenRegistry.create(context, screen)?.let { addPreferenceScreen(it) } } } fun build(): PreferenceGraphProto = builder.build() fun build(): PreferenceGraphProto { for ((key, screenBuilder) in screens) builder.putScreens(key, screenBuilder.build()) return builder.build() } /** * Adds an activity to the graph. Loading Loading @@ -138,17 +146,10 @@ private constructor( null } suspend fun addPreferenceScreenFromRegistry(key: String): Boolean { val metadata = PreferenceScreenRegistry.create(context, key) ?: return false return addPreferenceScreenMetadata(metadata) } private suspend fun addPreferenceScreenMetadata(metadata: PreferenceScreenMetadata): Boolean = addPreferenceScreen(metadata.key) { preferenceScreenProto { completeHierarchy = metadata.hasCompleteHierarchy() root = metadata.getPreferenceHierarchy(context).toProto(metadata, true) } private suspend fun addPreferenceScreenFromRegistry(key: String): Boolean { val factory = PreferenceScreenRegistry.preferenceScreenMetadataFactories[key] ?: return false return addPreferenceScreen(factory) } suspend fun addPreferenceScreenProvider(activityClass: Class<*>) { Loading Loading @@ -188,25 +189,51 @@ private constructor( Log.e(TAG, "\"$preferenceScreen\" has no key") return } @Suppress("CheckReturnValue") addPreferenceScreen(key) { preferenceScreen.toProto(intent) } val args = preferenceScreen.peekExtras()?.getBundle(EXTRA_BINDING_SCREEN_ARGS) @Suppress("CheckReturnValue") addPreferenceScreen(key, args) { this.intent = intent.toProto() root = preferenceScreen.toProto() } } suspend fun addPreferenceScreen(factory: PreferenceScreenMetadataFactory): Boolean { if (factory is PreferenceScreenMetadataParameterizedFactory) { factory.parameters(context).collect { addPreferenceScreen(factory.create(context, it)) } return true } return addPreferenceScreen(factory.create(context)) } private suspend fun addPreferenceScreen(metadata: PreferenceScreenMetadata): Boolean = addPreferenceScreen(metadata.key, metadata.arguments) { completeHierarchy = metadata.hasCompleteHierarchy() root = metadata.getPreferenceHierarchy(context).toProto(metadata, true) } private suspend fun addPreferenceScreen( key: String, preferenceScreenProvider: suspend () -> PreferenceScreenProto, ): Boolean = if (visitedScreens.add(key)) { builder.putScreens(key, preferenceScreenProvider()) true } else { Log.w(TAG, "$key visited") false args: Bundle?, init: suspend PreferenceScreenProto.Builder.() -> Unit, ): Boolean { if (!visitedScreens.add(PreferenceScreenCoordinate(key, args))) { Log.w(TAG, "$key $args visited") return false } private suspend fun PreferenceScreen.toProto(intent: Intent?): PreferenceScreenProto = preferenceScreenProto { intent?.let { this.intent = it.toProto() } root = (this@toProto as PreferenceGroup).toProto() if (args == null) { // normal screen screens[key] = PreferenceScreenProto.newBuilder().also { init(it) } } else if (args.isEmpty) { // parameterized screen with backward compatibility val builder = screens.getOrPut(key) { PreferenceScreenProto.newBuilder() } init(builder) } else { // parameterized screen with non-empty arguments val builder = screens.getOrPut(key) { PreferenceScreenProto.newBuilder() } val parameterizedScreen = parameterizedPreferenceScreenProto { setArgs(args.toProto()) setScreen(PreferenceScreenProto.newBuilder().also { init(it) }) } builder.addParameterizedScreens(parameterizedScreen) } return true } private suspend fun PreferenceGroup.toProto(): PreferenceGroupProto = preferenceGroupProto { Loading Loading @@ -271,7 +298,7 @@ private constructor( .toProto(context, callingPid, callingUid, screenMetadata, isRoot, request.flags) .also { if (metadata is PreferenceScreenMetadata) { @Suppress("CheckReturnValue") addPreferenceScreenMetadata(metadata) @Suppress("CheckReturnValue") addPreferenceScreen(metadata) } metadata.intent(context)?.resolveActivity(context.packageManager)?.let { if (it.packageName == context.packageName) { Loading Loading @@ -322,7 +349,7 @@ private constructor( val screenKey = screen?.key if (!screenKey.isNullOrEmpty()) { @Suppress("CheckReturnValue") addPreferenceScreen(screenKey) { screen.toProto(null) } addPreferenceScreen(screenKey, null) { root = screen.toProto() } return actionTargetProto { key = screenKey } } } catch (e: Exception) { Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +11 −7 Original line number Diff line number Diff line Loading @@ -40,11 +40,12 @@ import com.android.settingslib.metadata.SensitivityLevel.Companion.HIGH_SENSITIV import com.android.settingslib.metadata.SensitivityLevel.Companion.UNKNOWN_SENSITIVITY /** Request to set preference value. */ data class PreferenceSetterRequest( val screenKey: String, val key: String, class PreferenceSetterRequest( screenKey: String, args: Bundle?, key: String, val value: PreferenceValueProto, ) ) : PreferenceCoordinate(screenKey, args, key) /** Result of preference setter request. */ @IntDef( Loading Loading @@ -121,7 +122,7 @@ class PreferenceSetterApiHandler( metricsLogger?.logSetterApi( application, callingUid, PreferenceCoordinate(request.screenKey, request.key), request, null, null, PreferenceSetterResult.UNSUPPORTED, Loading @@ -130,7 +131,7 @@ class PreferenceSetterApiHandler( return PreferenceSetterResult.UNSUPPORTED } val screenMetadata = PreferenceScreenRegistry.create(application, request.screenKey) ?: return notFound() PreferenceScreenRegistry.create(application, request) ?: return notFound() val key = request.key val metadata = screenMetadata.getPreferenceHierarchy(application).find(key) ?: return notFound() Loading Loading @@ -199,7 +200,7 @@ class PreferenceSetterApiHandler( metricsLogger?.logSetterApi( application, callingUid, PreferenceCoordinate(request.screenKey, request.key), request, screenMetadata, metadata, result, Loading Loading @@ -235,6 +236,7 @@ object PreferenceSetterRequestCodec : MessageCodec<PreferenceSetterRequest> { override fun encode(data: PreferenceSetterRequest) = Bundle(3).apply { putString(SCREEN_KEY, data.screenKey) putBundle(ARGS, data.args) putString(KEY, data.key) putByteArray(null, data.value.toByteArray()) } Loading @@ -242,10 +244,12 @@ object PreferenceSetterRequestCodec : MessageCodec<PreferenceSetterRequest> { override fun decode(data: Bundle) = PreferenceSetterRequest( data.getString(SCREEN_KEY)!!, data.getBundle(ARGS), data.getString(KEY)!!, PreferenceValueProto.parseFrom(data.getByteArray(null)!!), ) private const val SCREEN_KEY = "s" private const val KEY = "k" private const val ARGS = "a" }