diff options
| author | 2025-02-07 20:29:05 -0800 | |
|---|---|---|
| committer | 2025-02-07 20:29:05 -0800 | |
| commit | 7d2f2aed39c8fdbf904f0ee3976ff248c2af392f (patch) | |
| tree | b16e3f32b8574e2cd69c50a58a6bfd89cfbd66dc | |
| parent | b4966e18cd4da193f7166c1a281e4b0b9a7be5ee (diff) | |
| parent | 0f6c24108c02773e83049a8b8ecf65144b1d4b60 (diff) | |
Merge "[Catalyst] Include read/write permit into proto" into main
6 files changed, 82 insertions, 111 deletions
diff --git a/packages/SettingsLib/Graph/graph.proto b/packages/SettingsLib/Graph/graph.proto index ec287c1b65b7..52a2160cdd74 100644 --- a/packages/SettingsLib/Graph/graph.proto +++ b/packages/SettingsLib/Graph/graph.proto @@ -95,6 +95,8 @@ message PreferenceProto { optional PermissionsProto write_permissions = 18; // Tag constants associated with the preference. repeated string tags = 19; + // Permit to read and write preference value (the lower 15 bits is reserved for read permit). + optional int32 read_write_permit = 20; // Target of an Intent message ActionTarget { diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt index e511bf1c175d..4964bbfefe07 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt @@ -415,52 +415,46 @@ fun PreferenceMetadata.toProto( for (tag in metadata.tags(context)) addTags(tag) } persistent = metadata.isPersistent(context) - if (persistent) { - if (metadata is PersistentPreference<*>) { - sensitivityLevel = metadata.sensitivityLevel - metadata.getReadPermissions(context)?.let { - if (it.size > 0) readPermissions = it.toProto() - } - metadata.getWritePermissions(context)?.let { - if (it.size > 0) writePermissions = it.toProto() - } - } - if ( - flags.includeValue() && - enabled && - (!hasAvailable() || available) && - (!hasRestricted() || !restricted) && - metadata is PersistentPreference<*> && - metadata.evalReadPermit(context, callingPid, callingUid) == ReadWritePermit.ALLOW - ) { - val storage = metadata.storage(context) - value = preferenceValueProto { - when (metadata.valueType) { - Int::class.javaObjectType -> storage.getInt(metadata.key)?.let { intValue = it } - Boolean::class.javaObjectType -> - storage.getBoolean(metadata.key)?.let { booleanValue = it } - Float::class.javaObjectType -> - storage.getFloat(metadata.key)?.let { floatValue = it } - else -> {} - } + if (metadata !is PersistentPreference<*>) return@preferenceProto + sensitivityLevel = metadata.sensitivityLevel + metadata.getReadPermissions(context)?.let { if (it.size > 0) readPermissions = it.toProto() } + metadata.getWritePermissions(context)?.let { if (it.size > 0) writePermissions = it.toProto() } + val readPermit = metadata.evalReadPermit(context, callingPid, callingUid) + val writePermit = + metadata.getWritePermit(context, callingPid, callingUid) ?: ReadWritePermit.ALLOW + readWritePermit = ReadWritePermit.make(readPermit, writePermit) + if ( + flags.includeValue() && + enabled && + (!hasAvailable() || available) && + (!hasRestricted() || !restricted) && + readPermit == ReadWritePermit.ALLOW + ) { + val storage = metadata.storage(context) + value = preferenceValueProto { + when (metadata.valueType) { + Int::class.javaObjectType -> storage.getInt(metadata.key)?.let { intValue = it } + Boolean::class.javaObjectType -> + storage.getBoolean(metadata.key)?.let { booleanValue = it } + Float::class.javaObjectType -> + storage.getFloat(metadata.key)?.let { floatValue = it } + else -> {} } } - if (flags.includeValueDescriptor()) { - valueDescriptor = preferenceValueDescriptorProto { - when (metadata) { - is IntRangeValuePreference -> rangeValue = rangeValueProto { - min = metadata.getMinValue(context) - max = metadata.getMaxValue(context) - step = metadata.getIncrementStep(context) - } - else -> {} - } - if (metadata is PersistentPreference<*>) { - when (metadata.valueType) { - Boolean::class.javaObjectType -> booleanType = true - Float::class.javaObjectType -> floatType = true + } + if (flags.includeValueDescriptor()) { + valueDescriptor = preferenceValueDescriptorProto { + when (metadata) { + is IntRangeValuePreference -> rangeValue = rangeValueProto { + min = metadata.getMinValue(context) + max = metadata.getMaxValue(context) + step = metadata.getIncrementStep(context) } - } + else -> {} + } + when (metadata.valueType) { + Boolean::class.javaObjectType -> booleanType = true + Float::class.javaObjectType -> floatType = true } } } diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt index 60f9c6bb92a3..35c4fce1c909 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt @@ -228,7 +228,9 @@ fun <T> PersistentPreference<T>.evalWritePermit( ReadWritePermit.DISALLOW getWritePermissions(context)?.check(context, callingPid, callingUid) == false -> ReadWritePermit.REQUIRE_APP_PERMISSION - else -> getWritePermit(context, value, callingPid, callingUid) + else -> + getWritePermit(context, callingPid, callingUid) + ?: getWritePermit(context, value, callingPid, callingUid) } /** Message codec for [PreferenceSetterRequest]. */ diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt index e456a7f1aa1c..520425607e1f 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt @@ -41,6 +41,19 @@ annotation class ReadWritePermit { const val REQUIRE_APP_PERMISSION = 2 /** Require explicit user agreement (e.g. terms of service). */ const val REQUIRE_USER_AGREEMENT = 3 + + private const val READ_PERMIT_BITS = 15 + private const val READ_PERMIT_MASK = (1 shl 16) - 1 + + /** Wraps given read and write permit into an integer. */ + fun make(readPermit: @ReadWritePermit Int, writePermit: @ReadWritePermit Int): Int = + (writePermit shl READ_PERMIT_BITS) or readPermit + + /** Extracts the read permit from given integer generated by [make]. */ + fun getReadPermit(readWritePermit: Int): Int = readWritePermit and READ_PERMIT_MASK + + /** Extracts the write permit from given integer generated by [make]. */ + fun getWritePermit(readWritePermit: Int): Int = readWritePermit shr READ_PERMIT_BITS } } @@ -81,6 +94,12 @@ interface PersistentPreference<T> : PreferenceMetadata { /** The value type the preference is associated with. */ val valueType: Class<T> + /** The sensitivity level of the preference. */ + val sensitivityLevel: @SensitivityLevel Int + get() = SensitivityLevel.UNKNOWN_SENSITIVITY + + override fun isPersistent(context: Context) = true + /** * Returns the key-value storage of the preference. * @@ -102,18 +121,24 @@ interface PersistentPreference<T> : PreferenceMetadata { * behind the scene. */ fun getReadPermit(context: Context, callingPid: Int, callingUid: Int): @ReadWritePermit Int = - PreferenceScreenRegistry.getReadPermit( - context, - callingPid, - callingUid, - this, - ) + PreferenceScreenRegistry.defaultReadPermit /** Returns the required permissions to write preference value. */ fun getWritePermissions(context: Context): Permissions? = null /** * Returns if the external application (identified by [callingPid] and [callingUid]) is + * permitted to write preference value. + * + * The underlying implementation does NOT need to check common states like isEnabled, + * isRestricted, isAvailable or permissions in [getWritePermissions]. The framework will do it + * behind the scene. + */ + fun getWritePermit(context: Context, callingPid: Int, callingUid: Int): @ReadWritePermit Int? = + null + + /** + * Returns if the external application (identified by [callingPid] and [callingUid]) is * permitted to write preference with given [value]. * * The underlying implementation does NOT need to check common states like isEnabled, @@ -125,18 +150,7 @@ interface PersistentPreference<T> : PreferenceMetadata { value: T?, callingPid: Int, callingUid: Int, - ): @ReadWritePermit Int = - PreferenceScreenRegistry.getWritePermit( - context, - value, - callingPid, - callingUid, - this, - ) - - /** The sensitivity level of the preference. */ - val sensitivityLevel: @SensitivityLevel Int - get() = SensitivityLevel.UNKNOWN_SENSITIVITY + ): @ReadWritePermit Int = PreferenceScreenRegistry.defaultWritePermit } /** Descriptor of values. */ diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt index a8939ab0d902..7f2a61081fbb 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt @@ -127,7 +127,7 @@ interface PreferenceMetadata { fun dependencies(context: Context): Array<String> = arrayOf() /** Returns if the preference is persistent in datastore. */ - fun isPersistent(context: Context): Boolean = this is PersistentPreference<*> + fun isPersistent(context: Context): Boolean = false /** * Returns if preference value backup is allowed (by default returns `true` if preference is diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt index 246310984db9..8d4bfffb1fdb 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt @@ -22,12 +22,18 @@ import android.util.Log import com.android.settingslib.datastore.KeyValueStore /** Registry of all available preference screens in the app. */ -object PreferenceScreenRegistry : ReadWritePermitProvider { +object PreferenceScreenRegistry { private const val TAG = "ScreenRegistry" /** Provider of key-value store. */ private lateinit var keyValueStoreProvider: KeyValueStoreProvider + /** The default permit for external application to read preference values. */ + var defaultReadPermit: @ReadWritePermit Int = ReadWritePermit.DISALLOW + + /** The default permit for external application to write preference values. */ + var defaultWritePermit: @ReadWritePermit Int = ReadWritePermit.DISALLOW + /** * Factories of all available [PreferenceScreenMetadata]s. * @@ -38,9 +44,6 @@ object PreferenceScreenRegistry : ReadWritePermitProvider { /** Metrics logger for preference actions triggered by user interaction. */ var preferenceUiActionMetricsLogger: PreferenceUiActionMetricsLogger? = null - private var readWritePermitProvider: ReadWritePermitProvider = - object : ReadWritePermitProvider {} - /** Sets the [KeyValueStoreProvider]. */ fun setKeyValueStoreProvider(keyValueStoreProvider: KeyValueStoreProvider) { this.keyValueStoreProvider = keyValueStoreProvider @@ -77,28 +80,6 @@ object PreferenceScreenRegistry : ReadWritePermitProvider { return null } } - - /** - * Sets the provider to check read write permit. Read and write requests are denied by default. - */ - fun setReadWritePermitProvider(readWritePermitProvider: ReadWritePermitProvider) { - this.readWritePermitProvider = readWritePermitProvider - } - - override fun getReadPermit( - context: Context, - callingPid: Int, - callingUid: Int, - preference: PreferenceMetadata, - ) = readWritePermitProvider.getReadPermit(context, callingPid, callingUid, preference) - - override fun getWritePermit( - context: Context, - value: Any?, - callingPid: Int, - callingUid: Int, - preference: PreferenceMetadata, - ) = readWritePermitProvider.getWritePermit(context, value, callingPid, callingUid, preference) } /** Provider of [KeyValueStore]. */ @@ -113,25 +94,3 @@ fun interface KeyValueStoreProvider { */ fun getKeyValueStore(context: Context, preference: PreferenceMetadata): KeyValueStore? } - -/** Provider of read and write permit. */ -interface ReadWritePermitProvider { - - val defaultReadWritePermit: @ReadWritePermit Int - get() = ReadWritePermit.DISALLOW - - fun getReadPermit( - context: Context, - callingPid: Int, - callingUid: Int, - preference: PreferenceMetadata, - ): @ReadWritePermit Int = defaultReadWritePermit - - fun getWritePermit( - context: Context, - value: Any?, - callingPid: Int, - callingUid: Int, - preference: PreferenceMetadata, - ): @ReadWritePermit Int = defaultReadWritePermit -} |