Loading packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt +6 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ class AppOpsController( context: Context, private val app: ApplicationInfo, private val op: Int, private val setModeByUid: Boolean = false, ) : IAppOpsController { private val appOpsManager = context.appOpsManager Loading @@ -49,7 +50,11 @@ class AppOpsController( override fun setAllowed(allowed: Boolean) { val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED if (setModeByUid) { appOpsManager.setUidMode(op, app.uid, mode) } else { appOpsManager.setMode(op, app.uid, app.packageName, mode) } _mode.postValue(mode) } Loading packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt +16 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,13 @@ abstract class AppOpPermissionListModel( abstract val appOp: Int abstract val permission: String /** * Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed. * * Security related app-ops should be set with setUidMode() instead of setMode(). */ open val setModeByUid = false /** These not changeable packages will also be hidden from app list. */ private val notChangeablePackages = setOf("android", "com.android.systemui", context.packageName) Loading @@ -61,7 +68,7 @@ abstract class AppOpPermissionListModel( AppOpPermissionRecord( app = app, hasRequestPermission = app.packageName in packageNames, appOpsController = AppOpsController(context = context, app = app, op = appOp), appOpsController = createAppOpsController(app), ) } } Loading @@ -69,7 +76,14 @@ abstract class AppOpPermissionListModel( override fun transformItem(app: ApplicationInfo) = AppOpPermissionRecord( app = app, hasRequestPermission = with(packageManagers) { app.hasRequestPermission(permission) }, appOpsController = AppOpsController(context = context, app = app, op = appOp), appOpsController = createAppOpsController(app), ) private fun createAppOpsController(app: ApplicationInfo) = AppOpsController( context = context, app = app, op = appOp, setModeByUid = setModeByUid, ) override fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<AppOpPermissionRecord>>) = Loading packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.settingslib.spaprivileged.model.app import android.app.AppOpsManager import android.app.AppOpsManager.MODE_ALLOWED import android.app.AppOpsManager.MODE_ERRORED import android.content.Context import android.content.pm.ApplicationInfo import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settingslib.spaprivileged.framework.common.appOpsManager import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class AppOpsControllerTest { @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() @Mock private lateinit var appOpsManager: AppOpsManager @Before fun setUp() { whenever(context.appOpsManager).thenReturn(appOpsManager) } @Test fun setAllowed_setToTrue() { val controller = AppOpsController(context = context, app = APP, op = OP) controller.setAllowed(true) verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, MODE_ALLOWED) } @Test fun setAllowed_setToFalse() { val controller = AppOpsController(context = context, app = APP, op = OP) controller.setAllowed(false) verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, MODE_ERRORED) } @Test fun setAllowed_setToTrueByUid() { val controller = AppOpsController(context = context, app = APP, op = OP, setModeByUid = true) controller.setAllowed(true) verify(appOpsManager).setUidMode(OP, APP.uid, MODE_ALLOWED) } @Test fun setAllowed_setToFalseByUid() { val controller = AppOpsController(context = context, app = APP, op = OP, setModeByUid = true) controller.setAllowed(false) verify(appOpsManager).setUidMode(OP, APP.uid, MODE_ERRORED) } @Test fun getMode() { whenever( appOpsManager.checkOpNoThrow(OP, APP.uid, APP.packageName) ).thenReturn(MODE_ALLOWED) val controller = AppOpsController(context = context, app = APP, op = OP) val mode = controller.getMode() assertThat(mode).isEqualTo(MODE_ALLOWED) } private companion object { const val OP = 1 val APP = ApplicationInfo().apply { packageName = "package.name" uid = 123 } } } No newline at end of file packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt +20 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import androidx.lifecycle.MutableLiveData 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.framework.common.appOpsManager import com.android.settingslib.spaprivileged.model.app.IAppOpsController import com.android.settingslib.spaprivileged.model.app.IPackageManagers import com.android.settingslib.spaprivileged.test.R Loading @@ -37,6 +38,8 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule import org.mockito.Mockito.`when` as whenever Loading @@ -50,17 +53,20 @@ class AppOpPermissionAppListTest { @get:Rule val composeTestRule = createComposeRule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() @Mock private lateinit var packageManagers: IPackageManagers @Mock private lateinit var appOpsManager: AppOpsManager private lateinit var listModel: TestAppOpPermissionAppListModel @Before fun setUp() = runTest { whenever(packageManagers.getAppOpPermissionPackages(USER_ID, PERMISSION)) .thenReturn(emptySet()) fun setUp() { whenever(context.appOpsManager).thenReturn(appOpsManager) listModel = TestAppOpPermissionAppListModel() } Loading Loading @@ -221,6 +227,16 @@ class AppOpPermissionAppListTest { assertThat(appOpsController.setAllowedCalledWith).isTrue() } @Test fun setAllowed_setModeByUid() { listModel.setModeByUid = true val record = listModel.transformItem(APP) listModel.setAllowed(record = record, newAllowed = true) verify(appOpsManager).setUidMode(listModel.appOp, APP.uid, AppOpsManager.MODE_ALLOWED) } private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? { lateinit var isAllowedState: State<Boolean?> composeTestRule.setContent { Loading @@ -236,6 +252,7 @@ class AppOpPermissionAppListTest { override val footerResId = R.string.test_app_op_permission_footer override val appOp = AppOpsManager.OP_MANAGE_MEDIA override val permission = PERMISSION override var setModeByUid = false } private companion object { Loading Loading
packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt +6 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ class AppOpsController( context: Context, private val app: ApplicationInfo, private val op: Int, private val setModeByUid: Boolean = false, ) : IAppOpsController { private val appOpsManager = context.appOpsManager Loading @@ -49,7 +50,11 @@ class AppOpsController( override fun setAllowed(allowed: Boolean) { val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED if (setModeByUid) { appOpsManager.setUidMode(op, app.uid, mode) } else { appOpsManager.setMode(op, app.uid, app.packageName, mode) } _mode.postValue(mode) } Loading
packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt +16 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,13 @@ abstract class AppOpPermissionListModel( abstract val appOp: Int abstract val permission: String /** * Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed. * * Security related app-ops should be set with setUidMode() instead of setMode(). */ open val setModeByUid = false /** These not changeable packages will also be hidden from app list. */ private val notChangeablePackages = setOf("android", "com.android.systemui", context.packageName) Loading @@ -61,7 +68,7 @@ abstract class AppOpPermissionListModel( AppOpPermissionRecord( app = app, hasRequestPermission = app.packageName in packageNames, appOpsController = AppOpsController(context = context, app = app, op = appOp), appOpsController = createAppOpsController(app), ) } } Loading @@ -69,7 +76,14 @@ abstract class AppOpPermissionListModel( override fun transformItem(app: ApplicationInfo) = AppOpPermissionRecord( app = app, hasRequestPermission = with(packageManagers) { app.hasRequestPermission(permission) }, appOpsController = AppOpsController(context = context, app = app, op = appOp), appOpsController = createAppOpsController(app), ) private fun createAppOpsController(app: ApplicationInfo) = AppOpsController( context = context, app = app, op = appOp, setModeByUid = setModeByUid, ) override fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<AppOpPermissionRecord>>) = Loading
packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.settingslib.spaprivileged.model.app import android.app.AppOpsManager import android.app.AppOpsManager.MODE_ALLOWED import android.app.AppOpsManager.MODE_ERRORED import android.content.Context import android.content.pm.ApplicationInfo import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settingslib.spaprivileged.framework.common.appOpsManager import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule import org.mockito.Mockito.`when` as whenever @RunWith(AndroidJUnit4::class) class AppOpsControllerTest { @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() @Mock private lateinit var appOpsManager: AppOpsManager @Before fun setUp() { whenever(context.appOpsManager).thenReturn(appOpsManager) } @Test fun setAllowed_setToTrue() { val controller = AppOpsController(context = context, app = APP, op = OP) controller.setAllowed(true) verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, MODE_ALLOWED) } @Test fun setAllowed_setToFalse() { val controller = AppOpsController(context = context, app = APP, op = OP) controller.setAllowed(false) verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, MODE_ERRORED) } @Test fun setAllowed_setToTrueByUid() { val controller = AppOpsController(context = context, app = APP, op = OP, setModeByUid = true) controller.setAllowed(true) verify(appOpsManager).setUidMode(OP, APP.uid, MODE_ALLOWED) } @Test fun setAllowed_setToFalseByUid() { val controller = AppOpsController(context = context, app = APP, op = OP, setModeByUid = true) controller.setAllowed(false) verify(appOpsManager).setUidMode(OP, APP.uid, MODE_ERRORED) } @Test fun getMode() { whenever( appOpsManager.checkOpNoThrow(OP, APP.uid, APP.packageName) ).thenReturn(MODE_ALLOWED) val controller = AppOpsController(context = context, app = APP, op = OP) val mode = controller.getMode() assertThat(mode).isEqualTo(MODE_ALLOWED) } private companion object { const val OP = 1 val APP = ApplicationInfo().apply { packageName = "package.name" uid = 123 } } } No newline at end of file
packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt +20 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import androidx.lifecycle.MutableLiveData 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.framework.common.appOpsManager import com.android.settingslib.spaprivileged.model.app.IAppOpsController import com.android.settingslib.spaprivileged.model.app.IPackageManagers import com.android.settingslib.spaprivileged.test.R Loading @@ -37,6 +38,8 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule import org.mockito.Mockito.`when` as whenever Loading @@ -50,17 +53,20 @@ class AppOpPermissionAppListTest { @get:Rule val composeTestRule = createComposeRule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() @Mock private lateinit var packageManagers: IPackageManagers @Mock private lateinit var appOpsManager: AppOpsManager private lateinit var listModel: TestAppOpPermissionAppListModel @Before fun setUp() = runTest { whenever(packageManagers.getAppOpPermissionPackages(USER_ID, PERMISSION)) .thenReturn(emptySet()) fun setUp() { whenever(context.appOpsManager).thenReturn(appOpsManager) listModel = TestAppOpPermissionAppListModel() } Loading Loading @@ -221,6 +227,16 @@ class AppOpPermissionAppListTest { assertThat(appOpsController.setAllowedCalledWith).isTrue() } @Test fun setAllowed_setModeByUid() { listModel.setModeByUid = true val record = listModel.transformItem(APP) listModel.setAllowed(record = record, newAllowed = true) verify(appOpsManager).setUidMode(listModel.appOp, APP.uid, AppOpsManager.MODE_ALLOWED) } private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? { lateinit var isAllowedState: State<Boolean?> composeTestRule.setContent { Loading @@ -236,6 +252,7 @@ class AppOpPermissionAppListTest { override val footerResId = R.string.test_app_op_permission_footer override val appOp = AppOpsManager.OP_MANAGE_MEDIA override val permission = PERMISSION override var setModeByUid = false } private companion object { Loading