Loading packages/SettingsLib/Graph/graph.proto +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +37 −43 Original line number Diff line number Diff line Loading @@ -415,23 +415,20 @@ fun PreferenceMetadata.toProto( for (tag in metadata.tags(context)) addTags(tag) } persistent = metadata.isPersistent(context) if (persistent) { if (metadata is PersistentPreference<*>) { 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() } } 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) && metadata is PersistentPreference<*> && metadata.evalReadPermit(context, callingPid, callingUid) == ReadWritePermit.ALLOW readPermit == ReadWritePermit.ALLOW ) { val storage = metadata.storage(context) value = preferenceValueProto { Loading @@ -455,7 +452,6 @@ fun PreferenceMetadata.toProto( } else -> {} } if (metadata is PersistentPreference<*>) { when (metadata.valueType) { Boolean::class.javaObjectType -> booleanType = true Float::class.javaObjectType -> floatType = true Loading @@ -463,8 +459,6 @@ fun PreferenceMetadata.toProto( } } } } } /** Evaluates the read permit of a persistent preference. */ fun <T> PersistentPreference<T>.evalReadPermit( Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +3 −1 Original line number Diff line number Diff line Loading @@ -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]. */ Loading packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt +32 −18 Original line number Diff line number Diff line Loading @@ -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 } } Loading Loading @@ -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. * Loading @@ -102,16 +121,22 @@ 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]. Loading @@ -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. */ Loading packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
packages/SettingsLib/Graph/graph.proto +2 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +37 −43 Original line number Diff line number Diff line Loading @@ -415,23 +415,20 @@ fun PreferenceMetadata.toProto( for (tag in metadata.tags(context)) addTags(tag) } persistent = metadata.isPersistent(context) if (persistent) { if (metadata is PersistentPreference<*>) { 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() } } 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) && metadata is PersistentPreference<*> && metadata.evalReadPermit(context, callingPid, callingUid) == ReadWritePermit.ALLOW readPermit == ReadWritePermit.ALLOW ) { val storage = metadata.storage(context) value = preferenceValueProto { Loading @@ -455,7 +452,6 @@ fun PreferenceMetadata.toProto( } else -> {} } if (metadata is PersistentPreference<*>) { when (metadata.valueType) { Boolean::class.javaObjectType -> booleanType = true Float::class.javaObjectType -> floatType = true Loading @@ -463,8 +459,6 @@ fun PreferenceMetadata.toProto( } } } } } /** Evaluates the read permit of a persistent preference. */ fun <T> PersistentPreference<T>.evalReadPermit( Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +3 −1 Original line number Diff line number Diff line Loading @@ -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]. */ Loading
packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt +32 −18 Original line number Diff line number Diff line Loading @@ -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 } } Loading Loading @@ -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. * Loading @@ -102,16 +121,22 @@ 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]. Loading @@ -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. */ Loading
packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading