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

Commit bf323c18 authored by Xiaomiao Zhang's avatar Xiaomiao Zhang Committed by Android (Google) Code Review
Browse files

Merge "[WebContentFilters] Create an api to pass supported app package names...

Merge "[WebContentFilters] Create an api to pass supported app package names to related web content filters preferences using messenger service." into main
parents 6ffbafca f76d6dbd
Loading
Loading
Loading
Loading
+42 −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

import com.android.settings.supervision.ipc.SupportedApp

/**
 * Interface for providing supported apps.
 *
 * This interface defines a method for retrieving supported apps based on a list of keys.
 * Implementations of this interface are responsible for fetching and returning a map of supported
 * app package names, where the keys in the map correspond to the requested keys.
 */
interface SupportedAppsProvider {

    /** Package of supported apps provider. */
    val packageName: String?

    /**
     * Retrieves supported apps for the specified filter keys.
     *
     * This suspend function fetches supported apps asynchronously.
     *
     * @param keys A list of strings representing the keys for content filters.
     * @return A map where the keys are the requested keys, and the values are the corresponding
     *   list of supported apps.
     */
    suspend fun getSupportedApps(keys: List<String>): Map<String, List<SupportedApp>>
}
+23 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.content.Context
import android.content.Intent
import android.util.Log
import com.android.settings.supervision.PreferenceDataProvider
import com.android.settings.supervision.SupportedAppsProvider
import com.android.settings.supervision.supervisionPackageName
import com.android.settingslib.ipc.MessengerServiceClient
import com.android.settingslib.supervision.SupervisionLog
@@ -33,7 +34,7 @@ import com.android.settingslib.supervision.SupervisionLog
 * @param context The Android Context used for binding to the service.
 */
class SupervisionMessengerClient(context: Context) :
    MessengerServiceClient(context), PreferenceDataProvider {
    MessengerServiceClient(context), PreferenceDataProvider, SupportedAppsProvider {

    override val serviceIntentFactory = { Intent(SUPERVISION_MESSENGER_SERVICE_BIND_ACTION) }

@@ -61,6 +62,27 @@ class SupervisionMessengerClient(context: Context) :
            mapOf()
        }

    /**
     * Retrieves supported apps for the specified filter keys.
     *
     * This suspend function sends a request to the supervision app for the specified content filter
     * keys and returns a map of supported apps. If an error occurs during the communication, an
     * empty map is returned and the error is logged.
     *
     * @param keys A list of strings representing the keys for content filters.
     * @return A map where the keys are the requested keys, and the values are the corresponding
     *   list of supported apps.
     */
    override suspend fun getSupportedApps(keys: List<String>): Map<String, List<SupportedApp>> =
        try {
            val targetPackageName = packageName ?: return mapOf()

            invoke(targetPackageName, SupportedAppsApi(), SupportedAppsRequest(keys = keys)).await()
        } catch (e: Exception) {
            Log.e(SupervisionLog.TAG, "Error fetching supported apps from supervision app", e)
            mapOf()
        }

    companion object {
        const val SUPERVISION_MESSENGER_SERVICE_BIND_ACTION =
            "android.app.supervision.action.SUPERVISION_MESSENGER_SERVICE"
+50 −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 representing the information of a supported app, used by content filters.
 *
 * This class encapsulates data such as title and package name. It provides constructors for
 * creating instances from a Bundle and for converting instances back to a Bundle.
 *
 * @property title Optional title text for the app.
 * @property packageName Optional package name for the app used to retrieve package information.
 */
data class SupportedApp(
    /** Optional title text for the supported app. */
    var title: CharSequence? = null,
    /** Optional package name for the supported app. */
    var packageName: String? = null,
) {
    constructor(
        bundle: Bundle
    ) : this(title = bundle.getCharSequence(TITLE), packageName = bundle.getString(PACKAGE_NAME))

    fun toBundle(): Bundle {
        return Bundle().apply {
            title?.let { putCharSequence(TITLE, it) }
            packageName?.let { putString(PACKAGE_NAME, it) }
        }
    }

    private companion object {
        const val TITLE = "title"
        const val PACKAGE_NAME = "package_name"
    }
}
+58 −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 filter keys to get supported apps for. Response: a map of filter key to a list
 * of supported apps.
 */
class SupportedAppsApi : ApiDescriptor<SupportedAppsRequest, Map<String, List<SupportedApp>>> {
    override val id: Int
        get() = 2

    override val requestCodec: MessageCodec<SupportedAppsRequest> =
        object : MessageCodec<SupportedAppsRequest> {
            override fun encode(data: SupportedAppsRequest) = data.toBundle()

            override fun decode(data: Bundle) = SupportedAppsRequest(data)
        }

    override val responseCodec: MessageCodec<Map<String, List<SupportedApp>>> =
        object : MessageCodec<Map<String, List<SupportedApp>>> {
            override fun encode(data: Map<String, List<SupportedApp>>) =
                Bundle().apply {
                    for ((key, supportedApps) in data) {
                        putParcelableArrayList(key, ArrayList(supportedApps.map { it.toBundle() }))
                    }
                }

            override fun decode(data: Bundle): Map<String, List<SupportedApp>> {
                return buildMap<String, List<SupportedApp>> {
                    for (key in data.keySet()) {
                        data.getParcelableArrayList<Bundle>(key)?.let { supportedApps ->
                            put(key, supportedApps.map { SupportedApp(it) })
                        }
                    }
                }
            }
        }
}
+36 −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

/**
 * Supported apps request.
 *
 * @param keys a list of filter keys to get supported apps for.
 */
data class SupportedAppsRequest(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 = "supported_apps_request"
    }
}
Loading