Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt +7 −3 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ abstract class GetPreferenceGraphApiHandler( callingUid: Int, request: GetPreferenceGraphRequest, ): PreferenceGraphProto { val builder = PreferenceGraphBuilder.of(application, request) val builder = PreferenceGraphBuilder.of(application, myUid, callingUid, request) if (request.screenKeys.isEmpty()) { for (key in PreferenceScreenRegistry.preferenceScreens.keys) { builder.addPreferenceScreenFromRegistry(key) Loading @@ -68,16 +68,18 @@ constructor( val screenKeys: Set<String> = setOf(), val visitedScreens: Set<String> = setOf(), val locale: Locale? = null, val includeValue: Boolean = true, val flags: Int = PreferenceGetterFlags.ALL, val includeValue: Boolean = true, // TODO: clean up val includeValueDescriptor: Boolean = true, ) object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> { override fun encode(data: GetPreferenceGraphRequest): Bundle = Bundle(3).apply { Bundle(4).apply { putStringArray(KEY_SCREEN_KEYS, data.screenKeys.toTypedArray()) putStringArray(KEY_VISITED_KEYS, data.visitedScreens.toTypedArray()) putString(KEY_LOCALE, data.locale?.toLanguageTag()) putInt(KEY_FLAGS, data.flags) } override fun decode(data: Bundle): GetPreferenceGraphRequest { Loading @@ -88,12 +90,14 @@ object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> screenKeys.toSet(), visitedScreens.toSet(), 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_LOCALE = "l" private const val KEY_FLAGS = "f" } object PreferenceGraphProtoCodec : MessageCodec<PreferenceGraphProto> { Loading packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceCoordinate.kt 0 → 100644 +45 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.os.Parcel import android.os.Parcelable /** * Coordinate to locate a preference. * * Within an app, the preference screen key (unique among screens) plus preference key (unique on * the screen) is used to locate a preference. */ data class PreferenceCoordinate(val screenKey: String, val key: String) : Parcelable { constructor(parcel: Parcel) : this(parcel.readString()!!, parcel.readString()!!) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(screenKey) parcel.writeString(key) } override fun describeContents() = 0 companion object CREATOR : Parcelable.Creator<PreferenceCoordinate> { override fun createFromParcel(parcel: Parcel) = PreferenceCoordinate(parcel) override fun newArray(size: Int) = arrayOfNulls<PreferenceCoordinate>(size) } } packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.app.Application import androidx.annotation.IntDef import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.ipc.ApiDescriptor import com.android.settingslib.ipc.ApiHandler import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.metadata.PreferenceScreenRegistry /** * Request to get preference information. * * @param preferences coordinate of preferences * @param flags a combination of constants in [PreferenceGetterFlags] */ class PreferenceGetterRequest(val preferences: Array<PreferenceCoordinate>, val flags: Int) /** Error code of preference getter request. */ @Target(AnnotationTarget.TYPE) @IntDef( PreferenceGetterErrorCode.NOT_FOUND, PreferenceGetterErrorCode.DISALLOW, PreferenceGetterErrorCode.INTERNAL_ERROR, ) @Retention(AnnotationRetention.SOURCE) annotation class PreferenceGetterErrorCode { companion object { /** Preference is not found. */ const val NOT_FOUND = 1 /** Disallow to get preference value (e.g. uid not allowed). */ const val DISALLOW = 2 /** Internal error happened when get preference information. */ const val INTERNAL_ERROR = 3 fun getMessage(code: Int) = when (code) { NOT_FOUND -> "Preference not found" DISALLOW -> "Disallow to get preference value" INTERNAL_ERROR -> "Internal error" else -> "Unknown error" } } } /** Response of the getter API. */ class PreferenceGetterResponse( val errors: Map<PreferenceCoordinate, @PreferenceGetterErrorCode Int>, val preferences: Map<PreferenceCoordinate, PreferenceProto>, ) /** Preference getter API descriptor. */ class PreferenceGetterApiDescriptor(override val id: Int) : ApiDescriptor<PreferenceGetterRequest, PreferenceGetterResponse> { override val requestCodec = PreferenceGetterRequestCodec() override val responseCodec = PreferenceGetterResponseCodec() } /** Preference getter API implementation. */ class PreferenceGetterApiHandler( override val id: Int, private val permissionChecker: ApiPermissionChecker<PreferenceGetterRequest>, ) : ApiHandler<PreferenceGetterRequest, PreferenceGetterResponse> { override fun hasPermission( application: Application, myUid: Int, callingUid: Int, request: PreferenceGetterRequest, ) = permissionChecker.hasPermission(application, myUid, callingUid, request) override suspend fun invoke( application: Application, myUid: Int, callingUid: Int, request: PreferenceGetterRequest, ): PreferenceGetterResponse { 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[screenKey] if (screenMetadata == null) { for (coordinate in coordinates) { errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND } continue } val nodes = mutableMapOf<String, PreferenceHierarchyNode?>() for (coordinate in coordinates) nodes[coordinate.key] = null screenMetadata.getPreferenceHierarchy(application).forEachRecursively { val metadata = it.metadata val key = metadata.key if (nodes.containsKey(key)) nodes[key] = it } for (coordinate in coordinates) { val node = nodes[coordinate.key] if (node == null) { errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND continue } val metadata = node.metadata try { val preferenceProto = metadata.toProto( application, myUid, callingUid, screenMetadata, metadata.key == screenMetadata.key, flags, ) if (flags == PreferenceGetterFlags.VALUE && !preferenceProto.hasValue()) { errors[coordinate] = PreferenceGetterErrorCode.DISALLOW } else { preferences[coordinate] = preferenceProto } } catch (e: Exception) { errors[coordinate] = PreferenceGetterErrorCode.INTERNAL_ERROR } } } return PreferenceGetterResponse(errors, preferences) } override val requestCodec = PreferenceGetterRequestCodec() override val responseCodec = PreferenceGetterResponseCodec() } packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterCodecs.kt 0 → 100644 +126 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.os.Bundle import android.os.Parcel import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.ipc.MessageCodec import java.util.Arrays /** Message codec for [PreferenceGetterRequest]. */ class PreferenceGetterRequestCodec : MessageCodec<PreferenceGetterRequest> { override fun encode(data: PreferenceGetterRequest) = Bundle(2).apply { putParcelableArray(null, data.preferences) putInt(FLAGS, data.flags) } @Suppress("DEPRECATION") override fun decode(data: Bundle): PreferenceGetterRequest { data.classLoader = PreferenceCoordinate::class.java.classLoader val array = data.getParcelableArray(null)!! return PreferenceGetterRequest( Arrays.copyOf(array, array.size, Array<PreferenceCoordinate>::class.java), data.getInt(FLAGS), ) } companion object { private const val FLAGS = "f" } } /** Message codec for [PreferenceGetterResponse]. */ class PreferenceGetterResponseCodec : MessageCodec<PreferenceGetterResponse> { override fun encode(data: PreferenceGetterResponse) = Bundle(2).apply { data.errors.toErrorsByteArray()?.let { putByteArray(ERRORS, it) } data.preferences.toPreferencesByteArray()?.let { putByteArray(null, it) } } private fun Map<PreferenceCoordinate, Int>.toErrorsByteArray(): ByteArray? { if (isEmpty()) return null val parcel = Parcel.obtain() parcel.writeInt(size) for ((coordinate, code) in this) { coordinate.writeToParcel(parcel, 0) parcel.writeInt(code) } val bytes = parcel.marshall() parcel.recycle() return bytes } private fun Map<PreferenceCoordinate, PreferenceProto>.toPreferencesByteArray(): ByteArray? { if (isEmpty()) return null val parcel = Parcel.obtain() parcel.writeInt(size) for ((coordinate, preferenceProto) in this) { coordinate.writeToParcel(parcel, 0) val data = preferenceProto.toByteArray() parcel.writeInt(data.size) parcel.writeByteArray(data) } val bytes = parcel.marshall() parcel.recycle() return bytes } override fun decode(data: Bundle) = PreferenceGetterResponse( data.getByteArray(ERRORS).toErrors(), data.getByteArray(null).toPreferences(), ) private fun ByteArray?.toErrors(): Map<PreferenceCoordinate, Int> { if (this == null) return emptyMap() val parcel = Parcel.obtain() parcel.unmarshall(this, 0, size) parcel.setDataPosition(0) val count = parcel.readInt() val errors = mutableMapOf<PreferenceCoordinate, Int>() repeat(count) { val coordinate = PreferenceCoordinate(parcel) errors[coordinate] = parcel.readInt() } parcel.recycle() return errors } private fun ByteArray?.toPreferences(): Map<PreferenceCoordinate, PreferenceProto> { if (this == null) return emptyMap() val parcel = Parcel.obtain() parcel.unmarshall(this, 0, size) parcel.setDataPosition(0) val count = parcel.readInt() val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>() repeat(count) { val coordinate = PreferenceCoordinate(parcel) val bytes = parcel.readInt() val array = ByteArray(bytes).also { parcel.readByteArray(it) } preferences[coordinate] = PreferenceProto.parseFrom(array) } parcel.recycle() return preferences } companion object { private const val ERRORS = "e" } } packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterFlags.kt 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph /** Flags for preference getter operation. */ object PreferenceGetterFlags { const val VALUE = 1 shl 0 const val VALUE_DESCRIPTOR = 1 shl 1 const val METADATA = 1 shl 2 const val ALL = (1 shl 3) - 1 fun Int.includeValue() = (this and VALUE) != 0 fun Int.includeValueDescriptor() = (this and VALUE_DESCRIPTOR) != 0 fun Int.includeMetadata() = (this and METADATA) != 0 } Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt +7 −3 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ abstract class GetPreferenceGraphApiHandler( callingUid: Int, request: GetPreferenceGraphRequest, ): PreferenceGraphProto { val builder = PreferenceGraphBuilder.of(application, request) val builder = PreferenceGraphBuilder.of(application, myUid, callingUid, request) if (request.screenKeys.isEmpty()) { for (key in PreferenceScreenRegistry.preferenceScreens.keys) { builder.addPreferenceScreenFromRegistry(key) Loading @@ -68,16 +68,18 @@ constructor( val screenKeys: Set<String> = setOf(), val visitedScreens: Set<String> = setOf(), val locale: Locale? = null, val includeValue: Boolean = true, val flags: Int = PreferenceGetterFlags.ALL, val includeValue: Boolean = true, // TODO: clean up val includeValueDescriptor: Boolean = true, ) object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> { override fun encode(data: GetPreferenceGraphRequest): Bundle = Bundle(3).apply { Bundle(4).apply { putStringArray(KEY_SCREEN_KEYS, data.screenKeys.toTypedArray()) putStringArray(KEY_VISITED_KEYS, data.visitedScreens.toTypedArray()) putString(KEY_LOCALE, data.locale?.toLanguageTag()) putInt(KEY_FLAGS, data.flags) } override fun decode(data: Bundle): GetPreferenceGraphRequest { Loading @@ -88,12 +90,14 @@ object GetPreferenceGraphRequestCodec : MessageCodec<GetPreferenceGraphRequest> screenKeys.toSet(), visitedScreens.toSet(), 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_LOCALE = "l" private const val KEY_FLAGS = "f" } object PreferenceGraphProtoCodec : MessageCodec<PreferenceGraphProto> { Loading
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceCoordinate.kt 0 → 100644 +45 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.os.Parcel import android.os.Parcelable /** * Coordinate to locate a preference. * * Within an app, the preference screen key (unique among screens) plus preference key (unique on * the screen) is used to locate a preference. */ data class PreferenceCoordinate(val screenKey: String, val key: String) : Parcelable { constructor(parcel: Parcel) : this(parcel.readString()!!, parcel.readString()!!) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(screenKey) parcel.writeString(key) } override fun describeContents() = 0 companion object CREATOR : Parcelable.Creator<PreferenceCoordinate> { override fun createFromParcel(parcel: Parcel) = PreferenceCoordinate(parcel) override fun newArray(size: Int) = arrayOfNulls<PreferenceCoordinate>(size) } }
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.app.Application import androidx.annotation.IntDef import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.ipc.ApiDescriptor import com.android.settingslib.ipc.ApiHandler import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.metadata.PreferenceScreenRegistry /** * Request to get preference information. * * @param preferences coordinate of preferences * @param flags a combination of constants in [PreferenceGetterFlags] */ class PreferenceGetterRequest(val preferences: Array<PreferenceCoordinate>, val flags: Int) /** Error code of preference getter request. */ @Target(AnnotationTarget.TYPE) @IntDef( PreferenceGetterErrorCode.NOT_FOUND, PreferenceGetterErrorCode.DISALLOW, PreferenceGetterErrorCode.INTERNAL_ERROR, ) @Retention(AnnotationRetention.SOURCE) annotation class PreferenceGetterErrorCode { companion object { /** Preference is not found. */ const val NOT_FOUND = 1 /** Disallow to get preference value (e.g. uid not allowed). */ const val DISALLOW = 2 /** Internal error happened when get preference information. */ const val INTERNAL_ERROR = 3 fun getMessage(code: Int) = when (code) { NOT_FOUND -> "Preference not found" DISALLOW -> "Disallow to get preference value" INTERNAL_ERROR -> "Internal error" else -> "Unknown error" } } } /** Response of the getter API. */ class PreferenceGetterResponse( val errors: Map<PreferenceCoordinate, @PreferenceGetterErrorCode Int>, val preferences: Map<PreferenceCoordinate, PreferenceProto>, ) /** Preference getter API descriptor. */ class PreferenceGetterApiDescriptor(override val id: Int) : ApiDescriptor<PreferenceGetterRequest, PreferenceGetterResponse> { override val requestCodec = PreferenceGetterRequestCodec() override val responseCodec = PreferenceGetterResponseCodec() } /** Preference getter API implementation. */ class PreferenceGetterApiHandler( override val id: Int, private val permissionChecker: ApiPermissionChecker<PreferenceGetterRequest>, ) : ApiHandler<PreferenceGetterRequest, PreferenceGetterResponse> { override fun hasPermission( application: Application, myUid: Int, callingUid: Int, request: PreferenceGetterRequest, ) = permissionChecker.hasPermission(application, myUid, callingUid, request) override suspend fun invoke( application: Application, myUid: Int, callingUid: Int, request: PreferenceGetterRequest, ): PreferenceGetterResponse { 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[screenKey] if (screenMetadata == null) { for (coordinate in coordinates) { errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND } continue } val nodes = mutableMapOf<String, PreferenceHierarchyNode?>() for (coordinate in coordinates) nodes[coordinate.key] = null screenMetadata.getPreferenceHierarchy(application).forEachRecursively { val metadata = it.metadata val key = metadata.key if (nodes.containsKey(key)) nodes[key] = it } for (coordinate in coordinates) { val node = nodes[coordinate.key] if (node == null) { errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND continue } val metadata = node.metadata try { val preferenceProto = metadata.toProto( application, myUid, callingUid, screenMetadata, metadata.key == screenMetadata.key, flags, ) if (flags == PreferenceGetterFlags.VALUE && !preferenceProto.hasValue()) { errors[coordinate] = PreferenceGetterErrorCode.DISALLOW } else { preferences[coordinate] = preferenceProto } } catch (e: Exception) { errors[coordinate] = PreferenceGetterErrorCode.INTERNAL_ERROR } } } return PreferenceGetterResponse(errors, preferences) } override val requestCodec = PreferenceGetterRequestCodec() override val responseCodec = PreferenceGetterResponseCodec() }
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterCodecs.kt 0 → 100644 +126 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph import android.os.Bundle import android.os.Parcel import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.ipc.MessageCodec import java.util.Arrays /** Message codec for [PreferenceGetterRequest]. */ class PreferenceGetterRequestCodec : MessageCodec<PreferenceGetterRequest> { override fun encode(data: PreferenceGetterRequest) = Bundle(2).apply { putParcelableArray(null, data.preferences) putInt(FLAGS, data.flags) } @Suppress("DEPRECATION") override fun decode(data: Bundle): PreferenceGetterRequest { data.classLoader = PreferenceCoordinate::class.java.classLoader val array = data.getParcelableArray(null)!! return PreferenceGetterRequest( Arrays.copyOf(array, array.size, Array<PreferenceCoordinate>::class.java), data.getInt(FLAGS), ) } companion object { private const val FLAGS = "f" } } /** Message codec for [PreferenceGetterResponse]. */ class PreferenceGetterResponseCodec : MessageCodec<PreferenceGetterResponse> { override fun encode(data: PreferenceGetterResponse) = Bundle(2).apply { data.errors.toErrorsByteArray()?.let { putByteArray(ERRORS, it) } data.preferences.toPreferencesByteArray()?.let { putByteArray(null, it) } } private fun Map<PreferenceCoordinate, Int>.toErrorsByteArray(): ByteArray? { if (isEmpty()) return null val parcel = Parcel.obtain() parcel.writeInt(size) for ((coordinate, code) in this) { coordinate.writeToParcel(parcel, 0) parcel.writeInt(code) } val bytes = parcel.marshall() parcel.recycle() return bytes } private fun Map<PreferenceCoordinate, PreferenceProto>.toPreferencesByteArray(): ByteArray? { if (isEmpty()) return null val parcel = Parcel.obtain() parcel.writeInt(size) for ((coordinate, preferenceProto) in this) { coordinate.writeToParcel(parcel, 0) val data = preferenceProto.toByteArray() parcel.writeInt(data.size) parcel.writeByteArray(data) } val bytes = parcel.marshall() parcel.recycle() return bytes } override fun decode(data: Bundle) = PreferenceGetterResponse( data.getByteArray(ERRORS).toErrors(), data.getByteArray(null).toPreferences(), ) private fun ByteArray?.toErrors(): Map<PreferenceCoordinate, Int> { if (this == null) return emptyMap() val parcel = Parcel.obtain() parcel.unmarshall(this, 0, size) parcel.setDataPosition(0) val count = parcel.readInt() val errors = mutableMapOf<PreferenceCoordinate, Int>() repeat(count) { val coordinate = PreferenceCoordinate(parcel) errors[coordinate] = parcel.readInt() } parcel.recycle() return errors } private fun ByteArray?.toPreferences(): Map<PreferenceCoordinate, PreferenceProto> { if (this == null) return emptyMap() val parcel = Parcel.obtain() parcel.unmarshall(this, 0, size) parcel.setDataPosition(0) val count = parcel.readInt() val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>() repeat(count) { val coordinate = PreferenceCoordinate(parcel) val bytes = parcel.readInt() val array = ByteArray(bytes).also { parcel.readByteArray(it) } preferences[coordinate] = PreferenceProto.parseFrom(array) } parcel.recycle() return preferences } companion object { private const val ERRORS = "e" } }
packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterFlags.kt 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settingslib.graph /** Flags for preference getter operation. */ object PreferenceGetterFlags { const val VALUE = 1 shl 0 const val VALUE_DESCRIPTOR = 1 shl 1 const val METADATA = 1 shl 2 const val ALL = (1 shl 3) - 1 fun Int.includeValue() = (this and VALUE) != 0 fun Int.includeValueDescriptor() = (this and VALUE_DESCRIPTOR) != 0 fun Int.includeMetadata() = (this and METADATA) != 0 }