Loading src/com/android/settings/supervision/ipc/PreferenceData.kt 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle data class PreferenceData( val icon: Int? = null, val title: CharSequence? = null, val summary: CharSequence? = null ) { constructor(bundle: Bundle) : this( icon = bundle.getInt(ICON, -1).takeIf { it != -1 }, title = bundle.getCharSequence(TITLE), summary = bundle.getCharSequence(SUMMARY) ) fun toBundle(): Bundle { return Bundle().apply { icon?.let { putInt(ICON, it) } title?.let { putCharSequence(TITLE, it) } summary?.let { putCharSequence(SUMMARY, it) } } } companion object { private const val ICON = "icon" private const val TITLE = "title" private const val SUMMARY = "summary" } } src/com/android/settings/supervision/ipc/PreferenceDataApi.kt 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle import com.android.settingslib.ipc.ApiDescriptor import com.android.settingslib.ipc.MessageCodec /** * Message API between UI(Settings App) and data provider(i.e. System Supervision role holder) * * Request: a list of preference keys to get new preference data of. * Response: a map of preference key to preference data. * * All fields in [PreferenceData] are nullable, null fields will be ignored by UI. */ class PreferenceDataApi : ApiDescriptor<PreferenceDataRequest, Map<String, PreferenceData>> { override val id: Int get() = 1 override val requestCodec: MessageCodec<PreferenceDataRequest> get() = object : MessageCodec<PreferenceDataRequest> { override fun encode(data: PreferenceDataRequest) = data.toBundle() override fun decode(data: Bundle) = PreferenceDataRequest(data) } override val responseCodec: MessageCodec<Map<String, PreferenceData>> get() = object : MessageCodec<Map<String, PreferenceData>> { override fun encode(data: Map<String, PreferenceData>) = Bundle().apply { for ((key, preferenceData) in data) { putBundle(key, preferenceData.toBundle()) } } override fun decode(data: Bundle): Map<String, PreferenceData> { val resultMap = mutableMapOf<String, PreferenceData>() for (key in data.keySet()) { data.getBundle(key)?.let { resultMap[key] = PreferenceData(it) } } return resultMap } } } src/com/android/settings/supervision/ipc/PreferenceDataRequest.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle import java.util.ArrayList /** * Preference data request. * * @param keys a list of preference keys to get new preference data of. */ data class PreferenceDataRequest(val keys: List<CharSequence>) { constructor(bundle: Bundle) : this(keys = bundle.getStringArrayList(KEY) ?: emptyList()) fun toBundle(): Bundle { return Bundle().apply { putCharSequenceArrayList(KEY, ArrayList(keys)) } } companion object { private const val KEY = "key" } } tests/robotests/src/com/android/settings/supervision/ipc/PreferenceDataApiTest.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import org.junit.Assert.assertEquals import org.junit.Test class PreferenceDataApiTest { private val api = PreferenceDataApi() @Test fun testRequestCodec() { val request = PreferenceDataRequest(listOf("key1", "key2")) val encoded = api.requestCodec.encode(request) val decoded = api.requestCodec.decode(encoded) assertEquals(request, decoded) } @Test fun testResponseCodec() { val response = mapOf( "key1" to PreferenceData(icon = 1, title = "Title 1", summary = "Summary 1"), "key2" to PreferenceData(title = "Title 2"), "key3" to PreferenceData(icon = 3, summary = "Summary 3"), "key4" to PreferenceData() ) val encoded = api.responseCodec.encode(response) val decoded = api.responseCodec.decode(encoded) assertEquals(response, decoded) } @Test fun testRequestCodec_emptyList() { val request = PreferenceDataRequest(emptyList()) val encoded = api.requestCodec.encode(request) val decoded = api.requestCodec.decode(encoded) assertEquals(request, decoded) } @Test fun testResponseCodec_emptyMap() { val response = emptyMap<String, PreferenceData>() val encoded = api.responseCodec.encode(response) val decoded = api.responseCodec.decode(encoded) assertEquals(response, decoded) } } Loading
src/com/android/settings/supervision/ipc/PreferenceData.kt 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle data class PreferenceData( val icon: Int? = null, val title: CharSequence? = null, val summary: CharSequence? = null ) { constructor(bundle: Bundle) : this( icon = bundle.getInt(ICON, -1).takeIf { it != -1 }, title = bundle.getCharSequence(TITLE), summary = bundle.getCharSequence(SUMMARY) ) fun toBundle(): Bundle { return Bundle().apply { icon?.let { putInt(ICON, it) } title?.let { putCharSequence(TITLE, it) } summary?.let { putCharSequence(SUMMARY, it) } } } companion object { private const val ICON = "icon" private const val TITLE = "title" private const val SUMMARY = "summary" } }
src/com/android/settings/supervision/ipc/PreferenceDataApi.kt 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle import com.android.settingslib.ipc.ApiDescriptor import com.android.settingslib.ipc.MessageCodec /** * Message API between UI(Settings App) and data provider(i.e. System Supervision role holder) * * Request: a list of preference keys to get new preference data of. * Response: a map of preference key to preference data. * * All fields in [PreferenceData] are nullable, null fields will be ignored by UI. */ class PreferenceDataApi : ApiDescriptor<PreferenceDataRequest, Map<String, PreferenceData>> { override val id: Int get() = 1 override val requestCodec: MessageCodec<PreferenceDataRequest> get() = object : MessageCodec<PreferenceDataRequest> { override fun encode(data: PreferenceDataRequest) = data.toBundle() override fun decode(data: Bundle) = PreferenceDataRequest(data) } override val responseCodec: MessageCodec<Map<String, PreferenceData>> get() = object : MessageCodec<Map<String, PreferenceData>> { override fun encode(data: Map<String, PreferenceData>) = Bundle().apply { for ((key, preferenceData) in data) { putBundle(key, preferenceData.toBundle()) } } override fun decode(data: Bundle): Map<String, PreferenceData> { val resultMap = mutableMapOf<String, PreferenceData>() for (key in data.keySet()) { data.getBundle(key)?.let { resultMap[key] = PreferenceData(it) } } return resultMap } } }
src/com/android/settings/supervision/ipc/PreferenceDataRequest.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import android.os.Bundle import java.util.ArrayList /** * Preference data request. * * @param keys a list of preference keys to get new preference data of. */ data class PreferenceDataRequest(val keys: List<CharSequence>) { constructor(bundle: Bundle) : this(keys = bundle.getStringArrayList(KEY) ?: emptyList()) fun toBundle(): Bundle { return Bundle().apply { putCharSequenceArrayList(KEY, ArrayList(keys)) } } companion object { private const val KEY = "key" } }
tests/robotests/src/com/android/settings/supervision/ipc/PreferenceDataApiTest.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.settings.supervision.ipc import org.junit.Assert.assertEquals import org.junit.Test class PreferenceDataApiTest { private val api = PreferenceDataApi() @Test fun testRequestCodec() { val request = PreferenceDataRequest(listOf("key1", "key2")) val encoded = api.requestCodec.encode(request) val decoded = api.requestCodec.decode(encoded) assertEquals(request, decoded) } @Test fun testResponseCodec() { val response = mapOf( "key1" to PreferenceData(icon = 1, title = "Title 1", summary = "Summary 1"), "key2" to PreferenceData(title = "Title 2"), "key3" to PreferenceData(icon = 3, summary = "Summary 3"), "key4" to PreferenceData() ) val encoded = api.responseCodec.encode(response) val decoded = api.responseCodec.decode(encoded) assertEquals(response, decoded) } @Test fun testRequestCodec_emptyList() { val request = PreferenceDataRequest(emptyList()) val encoded = api.requestCodec.encode(request) val decoded = api.requestCodec.decode(encoded) assertEquals(request, decoded) } @Test fun testResponseCodec_emptyMap() { val response = emptyMap<String, PreferenceData>() val encoded = api.responseCodec.encode(response) val decoded = api.responseCodec.decode(encoded) assertEquals(response, decoded) } }