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

Commit 83aeb45f authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Fix default mode for AlarmsAndRemindersAppList

When app ops permission's app ops mode is default, should check if
permission is grant.

Fix: 339846642
Test: manual - on AlarmsAndRemindersAppList
Test: unit test
Change-Id: Ia0f05211f5774637304502ead79dd98a1cf89886
parent 7a8d8fd0
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settingslib.R
import com.android.settingslib.spa.lifecycle.collectAsCallbackWithLifecycle
import com.android.settingslib.spaprivileged.model.app.AppOps
import com.android.settingslib.spaprivileged.model.app.AppOpsController
import com.android.settingslib.spaprivileged.model.app.AppOpsPermissionController
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
import com.android.settingslib.spaprivileged.model.app.PackageManagers
@@ -49,7 +49,7 @@ data class AlarmsAndRemindersAppRecord(
    override val app: ApplicationInfo,
    val isTrumped: Boolean,
    val isChangeable: Boolean,
    var controller: AppOpsController,
    val controller: AppOpsPermissionController,
) : AppRecord

class AlarmsAndRemindersAppListModel(
@@ -84,7 +84,7 @@ class AlarmsAndRemindersAppListModel(
    @Composable
    override fun isAllowed(record: AlarmsAndRemindersAppRecord): () -> Boolean? = when {
        record.isTrumped -> ({ true })
        else -> record.controller.isAllowed.collectAsCallbackWithLifecycle()
        else -> record.controller.isAllowedFlow.collectAsCallbackWithLifecycle()
    }

    override fun isChangeable(record: AlarmsAndRemindersAppRecord) = record.isChangeable
@@ -114,10 +114,11 @@ class AlarmsAndRemindersAppListModel(
            app = app,
            isTrumped = isTrumped,
            isChangeable = hasRequestPermission && !isTrumped,
            controller = AppOpsController(
            controller = AppOpsPermissionController(
                context = context,
                app = app,
                appOps = APP_OPS,
                permission = PERMISSION,
            ),
        )
    }
+16 −19
Original line number Diff line number Diff line
@@ -17,14 +17,13 @@
package com.android.settings.spa.app.specialaccess

import android.Manifest
import android.app.AppOpsManager
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spaprivileged.model.app.IAppOpsController
import com.android.settingslib.spaprivileged.model.app.IAppOpsPermissionController
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
import com.android.settingslib.spaprivileged.template.app.AppOpPermissionRecord
import com.google.common.truth.Truth.assertThat
@@ -117,14 +116,14 @@ class WifiControlAppListModelTest {
                app = APP_NOT_REQUEST_PERMISSION,
                hasRequestPermission = false,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )
        val appRequestedNetworkSettingsRecord =
            AppOpPermissionRecord(
                app = APP_REQUESTED_NETWORK_SETTINGS,
                hasRequestPermission = true,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val recordListFlow =
@@ -144,7 +143,7 @@ class WifiControlAppListModelTest {
                app = APP,
                hasRequestPermission = false,
                hasRequestBroaderPermission = true,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val isAllowed = getIsAllowed(record)
@@ -159,7 +158,7 @@ class WifiControlAppListModelTest {
                app = APP,
                hasRequestPermission = true,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ALLOWED),
                appOpsPermissionController = FakeAppOpsPermissionController(true),
            )

        val isAllowed = getIsAllowed(record)
@@ -174,7 +173,7 @@ class WifiControlAppListModelTest {
                app = APP,
                hasRequestPermission = true,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_IGNORED),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val isAllowed = getIsAllowed(record)
@@ -189,7 +188,7 @@ class WifiControlAppListModelTest {
                app = APP,
                hasRequestPermission = false,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val isChangeable = listModel.isChangeable(record)
@@ -198,13 +197,13 @@ class WifiControlAppListModelTest {
    }

    @Test
    fun isChangeable_notChangableWhenRequestedNetworkSettingPermissions() {
    fun isChangeable_notChangeableWhenRequestedNetworkSettingPermissions() {
        val record =
            AppOpPermissionRecord(
                app = APP,
                hasRequestPermission = false,
                hasRequestBroaderPermission = true,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val isChangeable = listModel.isChangeable(record)
@@ -213,13 +212,13 @@ class WifiControlAppListModelTest {
    }

    @Test
    fun isChangeable_changableWhenRequestedChangeWifiStatePermission() {
    fun isChangeable_changeableWhenRequestedChangeWifiStatePermission() {
        val record =
            AppOpPermissionRecord(
                app = APP,
                hasRequestPermission = true,
                hasRequestBroaderPermission = false,
                appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                appOpsPermissionController = FakeAppOpsPermissionController(false),
            )

        val isChangeable = listModel.isChangeable(record)
@@ -229,18 +228,18 @@ class WifiControlAppListModelTest {

    @Test
    fun setAllowed_shouldCallController() {
        val appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
        val appOpsPermissionController = FakeAppOpsPermissionController(false)
        val record =
            AppOpPermissionRecord(
                app = APP,
                hasRequestPermission = true,
                hasRequestBroaderPermission = false,
                appOpsController = appOpsController,
                appOpsPermissionController = appOpsPermissionController,
            )

        listModel.setAllowed(record = record, newAllowed = true)

        assertThat(appOpsController.setAllowedCalledWith).isTrue()
        assertThat(appOpsPermissionController.setAllowedCalledWith).isTrue()
    }

    private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? {
@@ -266,14 +265,12 @@ class WifiControlAppListModelTest {
    }
}

private class FakeAppOpsController(private val fakeMode: Int) : IAppOpsController {
private class FakeAppOpsPermissionController(allowed: Boolean) : IAppOpsPermissionController {
    var setAllowedCalledWith: Boolean? = null

    override val modeFlow = flowOf(fakeMode)
    override val isAllowedFlow = flowOf(allowed)

    override fun setAllowed(allowed: Boolean) {
        setAllowedCalledWith = allowed
    }

    override fun getMode() = fakeMode
}
+21 −26
Original line number Diff line number Diff line
@@ -30,10 +30,10 @@ import com.android.media.flags.Flags
import com.android.settings.R
import com.android.settings.testutils.FakeFeatureFactory
import com.android.settingslib.spaprivileged.model.app.AppOps
import com.android.settingslib.spaprivileged.model.app.IAppOpsController
import com.android.settingslib.spaprivileged.model.app.IAppOpsPermissionController
import com.android.settingslib.spaprivileged.template.app.AppOpPermissionRecord
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -50,7 +50,7 @@ class MediaRoutingControlTest {
    @get:Rule
    val mockito: MockitoRule = MockitoJUnit.rule()

    @get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule();
    @get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule()

    @Spy
    private val context: Context = ApplicationProvider.getApplicationContext()
@@ -86,29 +86,29 @@ class MediaRoutingControlTest {

    @Test
    fun setAllowed_callWithNewStatusAsTrue_shouldChangeAppControllerModeToAllowed() {
        val fakeAppOpController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
        val fakeAppOpsPermissionController = FakeAppOpsPermissionController(false)
        val permissionRequestedRecord =
                AppOpPermissionRecord(
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController = fakeAppOpController,
                        appOpsPermissionController = fakeAppOpsPermissionController,
                )

        listModel.setAllowed(permissionRequestedRecord, true)

        assertThat(fakeAppOpController.getMode()).isEqualTo(AppOpsManager.MODE_ALLOWED)
        assertThat(fakeAppOpsPermissionController.setAllowedCalledWith).isTrue()
    }

    @Test
    fun setAllowed_callWithNewStatusAsTrue_shouldLogPermissionToggleActionAsAllowed() {
        val fakeAppOpController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
        val fakeAppOpsPermissionController = FakeAppOpsPermissionController(false)
        val permissionRequestedRecord =
                AppOpPermissionRecord(
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController = fakeAppOpController,
                        appOpsPermissionController = fakeAppOpsPermissionController,
                )

        listModel.setAllowed(permissionRequestedRecord, true)
@@ -119,29 +119,29 @@ class MediaRoutingControlTest {

    @Test
    fun setAllowed_callWithNewStatusAsFalse_shouldChangeAppControllerModeToErrored() {
        val fakeAppOpController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
        val fakeAppOpsPermissionController = FakeAppOpsPermissionController(false)
        val permissionRequestedRecord =
                AppOpPermissionRecord(
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController = fakeAppOpController,
                        appOpsPermissionController = fakeAppOpsPermissionController,
                )

        listModel.setAllowed(permissionRequestedRecord, false)

        assertThat(fakeAppOpController.getMode()).isEqualTo(AppOpsManager.MODE_ERRORED)
        assertThat(fakeAppOpsPermissionController.setAllowedCalledWith).isFalse()
    }

    @Test
    fun setAllowed_callWithNewStatusAsFalse_shouldLogPermissionToggleActionAsDenied() {
        val fakeAppOpController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
        val fakeAppOpsPermissionController = FakeAppOpsPermissionController(false)
        val permissionRequestedRecord =
                AppOpPermissionRecord(
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController = fakeAppOpController,
                        appOpsPermissionController = fakeAppOpsPermissionController,
                )

        listModel.setAllowed(permissionRequestedRecord, false)
@@ -158,8 +158,7 @@ class MediaRoutingControlTest {
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController =
                            FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                        appOpsPermissionController = FakeAppOpsPermissionController(false),
                )
        whenever(mockRoleManager.getRoleHolders(AssociationRequest.DEVICE_PROFILE_WATCH))
                .thenReturn(listOf(PACKAGE_NAME))
@@ -177,8 +176,7 @@ class MediaRoutingControlTest {
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = false,
                        hasRequestBroaderPermission = false,
                        appOpsController =
                            FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                        appOpsPermissionController = FakeAppOpsPermissionController(false),
                )
        whenever(mockRoleManager.getRoleHolders(AssociationRequest.DEVICE_PROFILE_WATCH))
                .thenReturn(listOf(PACKAGE_NAME))
@@ -196,8 +194,7 @@ class MediaRoutingControlTest {
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController =
                            FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                        appOpsPermissionController = FakeAppOpsPermissionController(false),
                )
        whenever(mockRoleManager.getRoleHolders(AssociationRequest.DEVICE_PROFILE_WATCH))
                .thenReturn(listOf("other.package.name"))
@@ -215,8 +212,7 @@ class MediaRoutingControlTest {
                        app = ApplicationInfo().apply { packageName = PACKAGE_NAME },
                        hasRequestPermission = true,
                        hasRequestBroaderPermission = false,
                        appOpsController =
                        FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
                        appOpsPermissionController = FakeAppOpsPermissionController(false),
                )
        whenever(mockRoleManager.getRoleHolders(AssociationRequest.DEVICE_PROFILE_WATCH))
                .thenReturn(listOf(PACKAGE_NAME))
@@ -226,15 +222,14 @@ class MediaRoutingControlTest {
        assertThat(isSpecialAccessChangeable).isFalse()
    }

    private class FakeAppOpsController(fakeMode: Int) : IAppOpsController {
    private class FakeAppOpsPermissionController(allowed: Boolean) : IAppOpsPermissionController {
        var setAllowedCalledWith: Boolean? = null

        override val modeFlow = MutableStateFlow(fakeMode)
        override val isAllowedFlow = flowOf(allowed)

        override fun setAllowed(allowed: Boolean) {
            modeFlow.value = if (allowed) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED
            setAllowedCalledWith = allowed
        }

        override fun getMode(): Int = modeFlow.value
    }

    companion object {