Merge "Add setModeByUid for AppOpPermissionListModel"

This commit is contained in:
Chaohui Wang
2022-12-22 14:14:16 +00:00
committed by Android (Google) Code Review
4 changed files with 154 additions and 6 deletions

View File

@@ -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
@@ -49,7 +50,11 @@ class AppOpsController(
override fun setAllowed(allowed: Boolean) {
val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED
appOpsManager.setMode(op, app.uid, app.packageName, mode)
if (setModeByUid) {
appOpsManager.setUidMode(op, app.uid, mode)
} else {
appOpsManager.setMode(op, app.uid, app.packageName, mode)
}
_mode.postValue(mode)
}

View File

@@ -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)
@@ -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),
)
}
}
@@ -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>>) =

View File

@@ -0,0 +1,112 @@
/*
* 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
}
}
}

View File

@@ -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
@@ -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
@@ -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()
}
@@ -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 {
@@ -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 {