Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7f0734c authored by Jacky Wang's avatar Jacky Wang
Browse files

[Catalyst] Add ApiPermissionChecker and refactor code for preference service

Bug: 373895596
Flag: EXEMPT library
Test: manual
Change-Id: I30788cc7c247a3a1662abe24d7bc07611d6004bb
parent b5bc3cbe
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import androidx.annotation.IntDef
import com.android.settingslib.graph.proto.PreferenceValueProto
import com.android.settingslib.ipc.ApiDescriptor
import com.android.settingslib.ipc.ApiHandler
import com.android.settingslib.ipc.ApiPermissionChecker
import com.android.settingslib.ipc.IntMessageCodec
import com.android.settingslib.ipc.MessageCodec
import com.android.settingslib.metadata.BooleanValue
@@ -45,7 +46,11 @@ data class PreferenceSetterRequest(
    PreferenceSetterResult.OK,
    PreferenceSetterResult.UNSUPPORTED,
    PreferenceSetterResult.DISABLED,
    PreferenceSetterResult.RESTRICTED,
    PreferenceSetterResult.UNAVAILABLE,
    PreferenceSetterResult.REQUIRE_APP_PERMISSION,
    PreferenceSetterResult.REQUIRE_USER_AGREEMENT,
    PreferenceSetterResult.DISALLOW,
    PreferenceSetterResult.INVALID_REQUEST,
    PreferenceSetterResult.INTERNAL_ERROR,
)
@@ -87,14 +92,17 @@ class PreferenceSetterApiDescriptor(override val id: Int) :
}

/** Preference setter API implementation. */
class PreferenceSetterApiHandler(override val id: Int) : ApiHandler<PreferenceSetterRequest, Int> {
class PreferenceSetterApiHandler(
    override val id: Int,
    private val permissionChecker: ApiPermissionChecker<PreferenceSetterRequest>,
) : ApiHandler<PreferenceSetterRequest, Int> {

    override fun hasPermission(
        application: Application,
        myUid: Int,
        callingUid: Int,
        request: PreferenceSetterRequest,
    ): Boolean = true
    ) = permissionChecker.hasPermission(application, myUid, callingUid, request)

    override suspend fun invoke(
        application: Application,
+23 −12
Original line number Diff line number Diff line
@@ -56,6 +56,27 @@ interface ApiDescriptor<Request, Response> {
    val responseCodec: MessageCodec<Response>
}

/** Permission checker for api. */
fun interface ApiPermissionChecker<R> {
    /**
     * Returns if the request is permitted.
     *
     * @param application application context
     * @param myUid uid of current process
     * @param callingUid uid of peer process
     * @param request API request
     * @return `false` if permission is denied, otherwise `true`
     */
    fun hasPermission(application: Application, myUid: Int, callingUid: Int, request: R): Boolean

    companion object {
        private val ALWAYS_ALLOW = ApiPermissionChecker<Any> { _, _, _, _ -> true }

        @Suppress("UNCHECKED_CAST")
        fun <T> alwaysAllow(): ApiPermissionChecker<T> = ALWAYS_ALLOW as ApiPermissionChecker<T>
    }
}

/**
 * Handler of API.
 *
@@ -64,18 +85,8 @@ interface ApiDescriptor<Request, Response> {
 *
 * The implementation must be threadsafe.
 */
interface ApiHandler<Request, Response> : ApiDescriptor<Request, Response> {
    /**
     * Returns if the request is permitted.
     *
     * @return `false` if permission is denied, otherwise `true`
     */
    fun hasPermission(
        application: Application,
        myUid: Int,
        callingUid: Int,
        request: Request,
    ): Boolean
interface ApiHandler<Request, Response> :
    ApiDescriptor<Request, Response>, ApiPermissionChecker<Request> {

    /**
     * Invokes the API.
+4 −2
Original line number Diff line number Diff line
@@ -19,11 +19,13 @@ package com.android.settingslib.service
import android.app.Application
import com.android.settingslib.graph.GetPreferenceGraphApiHandler
import com.android.settingslib.graph.GetPreferenceGraphRequest
import com.android.settingslib.ipc.ApiPermissionChecker
import com.android.settingslib.preference.PreferenceScreenProvider

/** Api to get preference graph. */
internal class PreferenceGraphApi(
    preferenceScreenProviders: Set<Class<out PreferenceScreenProvider>>
    preferenceScreenProviders: Set<Class<out PreferenceScreenProvider>>,
    private val permissionChecker: ApiPermissionChecker<GetPreferenceGraphRequest>,
) : GetPreferenceGraphApiHandler(preferenceScreenProviders) {

    override val id: Int
@@ -34,5 +36,5 @@ internal class PreferenceGraphApi(
        myUid: Int,
        callingUid: Int,
        request: GetPreferenceGraphRequest,
    ) = true
    ) = permissionChecker.hasPermission(application, myUid, callingUid, request)
}
+12 −4
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package com.android.settingslib.service

import com.android.settingslib.graph.GetPreferenceGraphRequest
import com.android.settingslib.graph.PreferenceSetterApiHandler
import com.android.settingslib.graph.PreferenceSetterRequest
import com.android.settingslib.ipc.ApiHandler
import com.android.settingslib.ipc.ApiPermissionChecker
import com.android.settingslib.ipc.MessengerService
import com.android.settingslib.ipc.PermissionChecker
import com.android.settingslib.preference.PreferenceScreenProvider
@@ -29,15 +32,20 @@ import com.android.settingslib.preference.PreferenceScreenProvider
 * [PREFERENCE_SERVICE_ACTION].
 */
open class PreferenceService(
    name: String = "PreferenceService",
    permissionChecker: PermissionChecker = PermissionChecker { _, _, _ -> true },
    preferenceScreenProviders: Set<Class<out PreferenceScreenProvider>> = setOf(),
    enablePreferenceSetterApi: Boolean = false,
    name: String = "PreferenceService",
    graphPermissionChecker: ApiPermissionChecker<GetPreferenceGraphRequest>? = null,
    setterPermissionChecker: ApiPermissionChecker<PreferenceSetterRequest>? = null,
    vararg apiHandlers: ApiHandler<*, *>,
) :
    MessengerService(
        mutableListOf<ApiHandler<*, *>>().apply {
            add(PreferenceGraphApi(preferenceScreenProviders))
            if (enablePreferenceSetterApi) add(PreferenceSetterApiHandler(API_PREFERENCE_SETTER))
            graphPermissionChecker?.let { add(PreferenceGraphApi(preferenceScreenProviders, it)) }
            setterPermissionChecker?.let {
                add(PreferenceSetterApiHandler(API_PREFERENCE_SETTER, it))
            }
            addAll(apiHandlers)
        },
        permissionChecker,
        name,
+9 −0
Original line number Diff line number Diff line
@@ -18,5 +18,14 @@ package com.android.settingslib.service

const val PREFERENCE_SERVICE_ACTION = "com.android.settingslib.PREFERENCE_SERVICE"

/** API id for retrieving preference graph. */
internal const val API_GET_PREFERENCE_GRAPH = 1

/** API id for preference value setter. */
internal const val API_PREFERENCE_SETTER = 2

/**
 * The max API id reserved for internal preference service usages. Custom API id should start with
 * **1000** to avoid conflict.
 */
internal const val API_MAX_RESERVED = 999