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

Commit a0317a35 authored by Anton Potapov's avatar Anton Potapov
Browse files

Add disabled by policy state

Test: atest DisabledByPolicyInteractorTest
Bug: 299908705
Change-Id: Id0636fe8fad326572384c9f187c9b5da7e060872
parent d346a1f1
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