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

Commit dc588bc5 authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Add disabled by policy state" into main

parents 102064b4 a0317a35
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -363,6 +363,8 @@ filegroup {
        "tests/src/com/android/systemui/qs/pipeline/data/**/*Test.kt",
        "tests/src/com/android/systemui/qs/pipeline/domain/**/*Test.kt",
        "tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt",
        "tests/src/com/android/systemui/qs/tiles/base/**/*.kt",
        "tests/src/com/android/systemui/qs/tiles/viewmodel/**/*.kt",
    ],
    path: "tests/src",
}
+7 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractorImpl
import com.android.systemui.qs.pipeline.domain.startable.QSPipelineCoreStartable
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractorImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -60,6 +62,11 @@ abstract class QSPipelineModule {
        impl: InstalledTilesComponentRepositoryImpl
    ): InstalledTilesComponentRepository

    @Binds
    abstract fun provideDisabledByPolicyInteractor(
        impl: DisabledByPolicyInteractorImpl
    ): DisabledByPolicyInteractor

    @Binds
    @IntoMap
    @ClassKey(QSPipelineCoreStartable::class)
+16 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.systemui.qs.tiles.base.actions

import android.content.Intent
+127 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.systemui.qs.tiles.base.interactor

import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor.PolicyResult
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext

/**
 * Provides restrictions data for the tiles. This is used in
 * [com.android.systemui.qs.tiles.base.viewmodel.BaseQSTileViewModel] to determine if the tile is
 * disabled based on the [com.android.systemui.qs.tiles.viewmodel.QSTileConfig.policy].
 */
interface DisabledByPolicyInteractor {

    /**
     * Checks if the tile is restricted by the policy for a specific user. Pass the result to the
     * [handlePolicyResult] to let the user know that the tile is disable by the admin.
     */
    suspend fun isDisabled(userId: Int, userRestriction: String?): PolicyResult

    /**
     * Returns true when [policyResult] is [PolicyResult.TileDisabled] and has been handled by this
     * method. No further handling is required and the input event can be skipped at this point.
     *
     * Returns false when [policyResult] is [PolicyResult.TileEnabled] and this method has done
     * nothing.
     */
    fun handlePolicyResult(policyResult: PolicyResult): Boolean

    sealed interface PolicyResult {
        /** Tile has no policy restrictions. */
        data object TileEnabled : PolicyResult

        /**
         * Tile is disabled by policy. Pass this to [DisabledByPolicyInteractor.handlePolicyResult]
         * to show the user info screen using
         * [RestrictedLockUtils.getShowAdminSupportDetailsIntent].
         */
        data class TileDisabled(val admin: EnforcedAdmin) : PolicyResult
    }
}

@SysUISingleton
class DisabledByPolicyInteractorImpl
@Inject
constructor(
    private val context: Context,
    private val activityStarter: ActivityStarter,
    private val restrictedLockProxy: RestrictedLockProxy,
    @Background private val backgroundDispatcher: CoroutineDispatcher,
) : DisabledByPolicyInteractor {

    override suspend fun isDisabled(userId: Int, userRestriction: String?): PolicyResult =
        withContext(backgroundDispatcher) {
            val admin: EnforcedAdmin =
                restrictedLockProxy.getEnforcedAdmin(userId, userRestriction)
                    ?: return@withContext PolicyResult.TileEnabled

            return@withContext if (
                !restrictedLockProxy.hasBaseUserRestriction(userId, userRestriction)
            ) {
                PolicyResult.TileDisabled(admin)
            } else {
                PolicyResult.TileEnabled
            }
        }

    override fun handlePolicyResult(policyResult: PolicyResult): Boolean =
        when (policyResult) {
            is PolicyResult.TileEnabled -> false
            is PolicyResult.TileDisabled -> {
                val intent =
                    RestrictedLockUtils.getShowAdminSupportDetailsIntent(
                        context,
                        policyResult.admin
                    )
                activityStarter.postStartActivityDismissingKeyguard(intent, 0)
                true
            }
        }
}

/** Mockable proxy for [RestrictedLockUtilsInternal] static methods. */
@VisibleForTesting
class RestrictedLockProxy @Inject constructor(private val context: Context) {

    @WorkerThread
    fun hasBaseUserRestriction(userId: Int, userRestriction: String?): Boolean =
        RestrictedLockUtilsInternal.hasBaseUserRestriction(
            context,
            userRestriction,
            userId,
        )

    @WorkerThread
    fun getEnforcedAdmin(userId: Int, userRestriction: String?): EnforcedAdmin? =
        RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
            context,
            userRestriction,
            userId,
        )
}
+16 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.systemui.qs.tiles.base.interactor

import com.android.systemui.qs.tiles.viewmodel.QSTileState
Loading