summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yilin Cai <cyl@google.com> 2022-12-15 15:46:37 +0800
committer Yilin Cai <cyl@google.com> 2023-01-04 14:03:55 +0800
commit288b38a3270c2246516198e449436161e4cd805e (patch)
treeb6792a16ed4d1a7fea16fae4169e4c18fb3764b5
parent613dc2608856a1115009a562b1d1a174c01cca88 (diff)
Adjust "AppOpPermissionListModel" and "AppOpsController" for SPA migration.
The adjustments are for the WiFi control permission page migration. Extensions including: - A broader permission NETWORK_SETTINGS should trump CHANGE_WIFI_STATE. - CHANGE_WIFI_STATE is not at protection level "appop", thus the method "getAppOpPermissionPackages" returns an empty list for permission "CHANGE_WIFI_STATE" in "AppOpPermissionListModel.transform". We need to check requested permissions instead. - WiFi control sets mode to "MODE_IGNORED" instead of "MODE_ERRORED" when disallows. Test: atest SpaPrivilegedLibTests:AppOpsControllerTest Test: atest SpaPrivilegedLibTests:AppOpPermissionAppListTest Bug: 262206181 Change-Id: Ib566ff3a28458e18014ea9456cd3870cf68ff973
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt19
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt102
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt67
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt214
4 files changed, 270 insertions, 132 deletions
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
index e8788048776e..6cd6e951ef02 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
@@ -17,7 +17,6 @@
package com.android.settingslib.spaprivileged.model.app
import android.app.AppOpsManager.MODE_ALLOWED
-import android.app.AppOpsManager.MODE_ERRORED
import android.app.AppOpsManager.Mode
import android.content.Context
import android.content.pm.ApplicationInfo
@@ -33,14 +32,14 @@ interface IAppOpsController {
fun setAllowed(allowed: Boolean)
- @Mode
- fun getMode(): Int
+ @Mode fun getMode(): Int
}
class AppOpsController(
context: Context,
private val app: ApplicationInfo,
private val op: Int,
+ private val modeForNotAllowed: Int,
private val setModeByUid: Boolean = false,
) : IAppOpsController {
private val appOpsManager = context.appOpsManager
@@ -49,7 +48,7 @@ class AppOpsController(
get() = _mode
override fun setAllowed(allowed: Boolean) {
- val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED
+ val mode = if (allowed) MODE_ALLOWED else modeForNotAllowed
if (setModeByUid) {
appOpsManager.setUidMode(op, app.uid, mode)
} else {
@@ -58,12 +57,12 @@ class AppOpsController(
_mode.postValue(mode)
}
- @Mode
- override fun getMode(): Int = appOpsManager.checkOpNoThrow(op, app.uid, app.packageName)
+ @Mode override fun getMode(): Int = appOpsManager.checkOpNoThrow(op, app.uid, app.packageName)
- private val _mode = object : MutableLiveData<Int>() {
- override fun onActive() {
- postValue(getMode())
+ private val _mode =
+ object : MutableLiveData<Int>() {
+ override fun onActive() {
+ postValue(getMode())
+ }
}
- }
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
index ee21b81fe92a..53af25b81580 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
@@ -18,6 +18,7 @@ package com.android.settingslib.spaprivileged.template.app
import android.app.AppOpsManager.MODE_ALLOWED
import android.app.AppOpsManager.MODE_DEFAULT
+import android.app.AppOpsManager.MODE_ERRORED
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable
@@ -25,6 +26,8 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
+import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.framework.util.asyncMapItem
import com.android.settingslib.spa.framework.util.filterItem
import com.android.settingslib.spaprivileged.model.app.AppOpsController
import com.android.settingslib.spaprivileged.model.app.AppRecord
@@ -37,6 +40,7 @@ import kotlinx.coroutines.flow.map
data class AppOpPermissionRecord(
override val app: ApplicationInfo,
+ val hasRequestBroaderPermission: Boolean,
val hasRequestPermission: Boolean,
var appOpsController: IAppOpsController,
) : AppRecord
@@ -50,9 +54,26 @@ abstract class AppOpPermissionListModel(
abstract val permission: String
/**
+ * When set, specifies the broader permission who trumps the [permission].
+ *
+ * When trumped, the [permission] is not changeable and model shows the [permission] as allowed.
+ */
+ open val broaderPermission: String? = null
+
+ /**
+ * Indicates whether [permission] has protection level appop flag.
+ *
+ * If true, it uses getAppOpPermissionPackages() to fetch bits to decide whether the permission
+ * is requested.
+ */
+ open val permissionHasAppopFlag: Boolean = true
+
+ open val modeForNotAllowed: Int = MODE_ERRORED
+
+ /**
* Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed.
*
- * Security related app-ops should be set with setUidMode() instead of setMode().
+ * Security or privacy related app-ops should be set with setUidMode() instead of setMode().
*/
open val setModeByUid = false
@@ -60,31 +81,54 @@ abstract class AppOpPermissionListModel(
private val notChangeablePackages =
setOf("android", "com.android.systemui", context.packageName)
+ private fun createAppOpsController(app: ApplicationInfo) =
+ AppOpsController(
+ context = context,
+ app = app,
+ op = appOp,
+ setModeByUid = setModeByUid,
+ modeForNotAllowed = modeForNotAllowed,
+ )
+
+ private fun createRecord(
+ app: ApplicationInfo,
+ hasRequestPermission: Boolean
+ ): AppOpPermissionRecord =
+ with(packageManagers) {
+ AppOpPermissionRecord(
+ app = app,
+ hasRequestBroaderPermission =
+ broaderPermission?.let { app.hasRequestPermission(it) } ?: false,
+ hasRequestPermission = hasRequestPermission,
+ appOpsController = createAppOpsController(app),
+ )
+ }
+
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
- userIdFlow.map { userId ->
- packageManagers.getAppOpPermissionPackages(userId, permission)
- }.combine(appListFlow) { packageNames, appList ->
- appList.map { app ->
- AppOpPermissionRecord(
- app = app,
- hasRequestPermission = app.packageName in packageNames,
- appOpsController = createAppOpsController(app),
- )
+ if (permissionHasAppopFlag) {
+ userIdFlow
+ .map { userId -> packageManagers.getAppOpPermissionPackages(userId, permission) }
+ .combine(appListFlow) { packageNames, appList ->
+ appList.map { app ->
+ createRecord(
+ app = app,
+ hasRequestPermission = app.packageName in packageNames,
+ )
+ }
+ }
+ } else {
+ appListFlow.asyncMapItem { app ->
+ with(packageManagers) { createRecord(app, app.hasRequestPermission(permission)) }
}
}
- override fun transformItem(app: ApplicationInfo) = AppOpPermissionRecord(
- app = app,
- hasRequestPermission = with(packageManagers) { app.hasRequestPermission(permission) },
- appOpsController = createAppOpsController(app),
- )
-
- private fun createAppOpsController(app: ApplicationInfo) = AppOpsController(
- context = context,
- app = app,
- op = appOp,
- setModeByUid = setModeByUid,
- )
+ override fun transformItem(app: ApplicationInfo) =
+ with(packageManagers) {
+ createRecord(
+ app = app,
+ hasRequestPermission = app.hasRequestPermission(permission),
+ )
+ }
override fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<AppOpPermissionRecord>>) =
recordListFlow.filterItem(::isChangeable)
@@ -95,15 +139,19 @@ abstract class AppOpPermissionListModel(
*/
@Composable
override fun isAllowed(record: AppOpPermissionRecord): State<Boolean?> {
+ if (record.hasRequestBroaderPermission) {
+ // Broader permission trumps the specific permission.
+ return stateOf(true)
+ }
+
val mode = record.appOpsController.mode.observeAsState()
return remember {
derivedStateOf {
when (mode.value) {
null -> null
MODE_ALLOWED -> true
- MODE_DEFAULT -> with(packageManagers) {
- record.app.hasGrantPermission(permission)
- }
+ MODE_DEFAULT ->
+ with(packageManagers) { record.app.hasGrantPermission(permission) }
else -> false
}
}
@@ -111,7 +159,9 @@ abstract class AppOpPermissionListModel(
}
override fun isChangeable(record: AppOpPermissionRecord) =
- record.hasRequestPermission && record.app.packageName !in notChangeablePackages
+ record.hasRequestPermission &&
+ !record.hasRequestBroaderPermission &&
+ record.app.packageName !in notChangeablePackages
override fun setAllowed(record: AppOpPermissionRecord, newAllowed: Boolean) {
record.appOpsController.setAllowed(newAllowed)
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
index 668bfdfd7e32..53e52d0e02e8 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
@@ -31,21 +31,18 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
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()
+ @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
- @Spy
- private val context: Context = ApplicationProvider.getApplicationContext()
+ @Spy private val context: Context = ApplicationProvider.getApplicationContext()
- @Mock
- private lateinit var appOpsManager: AppOpsManager
+ @Mock private lateinit var appOpsManager: AppOpsManager
@Before
fun setUp() {
@@ -54,7 +51,13 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToTrue() {
- val controller = AppOpsController(context = context, app = APP, op = OP)
+ val controller =
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_ERRORED
+ )
controller.setAllowed(true)
@@ -63,7 +66,13 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToFalse() {
- val controller = AppOpsController(context = context, app = APP, op = OP)
+ val controller =
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_ERRORED
+ )
controller.setAllowed(false)
@@ -73,7 +82,13 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToTrueByUid() {
val controller =
- AppOpsController(context = context, app = APP, op = OP, setModeByUid = true)
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_ERRORED,
+ setModeByUid = true
+ )
controller.setAllowed(true)
@@ -83,7 +98,13 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToFalseByUid() {
val controller =
- AppOpsController(context = context, app = APP, op = OP, setModeByUid = true)
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_ERRORED,
+ setModeByUid = true
+ )
controller.setAllowed(false)
@@ -92,10 +113,15 @@ class AppOpsControllerTest {
@Test
fun getMode() {
- whenever(
- appOpsManager.checkOpNoThrow(OP, APP.uid, APP.packageName)
- ).thenReturn(MODE_ALLOWED)
- val controller = AppOpsController(context = context, app = APP, op = OP)
+ whenever(appOpsManager.checkOpNoThrow(OP, APP.uid, APP.packageName))
+ .thenReturn(MODE_ALLOWED)
+ val controller =
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_ERRORED
+ )
val mode = controller.getMode()
@@ -104,9 +130,10 @@ class AppOpsControllerTest {
private companion object {
const val OP = 1
- val APP = ApplicationInfo().apply {
- packageName = "package.name"
- uid = 123
- }
+ val APP =
+ ApplicationInfo().apply {
+ packageName = "package.name"
+ uid = 123
+ }
}
-} \ No newline at end of file
+}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
index 966b86927e55..da765ba87e46 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
@@ -39,28 +39,23 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
-import org.mockito.Mockito.`when` as whenever
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class AppOpPermissionAppListTest {
- @get:Rule
- val mockito: MockitoRule = MockitoJUnit.rule()
+ @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
- @get:Rule
- val composeTestRule = createComposeRule()
+ @get:Rule val composeTestRule = createComposeRule()
- @Spy
- private val context: Context = ApplicationProvider.getApplicationContext()
+ @Spy private val context: Context = ApplicationProvider.getApplicationContext()
- @Mock
- private lateinit var packageManagers: IPackageManagers
+ @Mock private lateinit var packageManagers: IPackageManagers
- @Mock
- private lateinit var appOpsManager: AppOpsManager
+ @Mock private lateinit var appOpsManager: AppOpsManager
private lateinit var listModel: TestAppOpPermissionAppListModel
@@ -79,9 +74,7 @@ class AppOpPermissionAppListTest {
@Test
fun transformItem_hasRequestPermission() = runTest {
- with(packageManagers) {
- whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(true)
- }
+ with(packageManagers) { whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(true) }
val record = listModel.transformItem(APP)
@@ -90,25 +83,47 @@ class AppOpPermissionAppListTest {
@Test
fun transformItem_notRequestPermission() = runTest {
+ with(packageManagers) { whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(false) }
+
+ val record = listModel.transformItem(APP)
+
+ assertThat(record.hasRequestPermission).isFalse()
+ }
+
+ @Test
+ fun transformItem_hasRequestBroaderPermission() = runTest {
+ listModel.broaderPermission = BROADER_PERMISSION
with(packageManagers) {
- whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(false)
+ whenever(APP.hasRequestPermission(BROADER_PERMISSION)).thenReturn(true)
}
val record = listModel.transformItem(APP)
- assertThat(record.hasRequestPermission).isFalse()
+ assertThat(record.hasRequestBroaderPermission).isTrue()
}
@Test
- fun filter() = runTest {
+ fun transformItem_notRequestBroaderPermission() = runTest {
+ listModel.broaderPermission = BROADER_PERMISSION
with(packageManagers) {
- whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(false)
+ whenever(APP.hasRequestPermission(BROADER_PERMISSION)).thenReturn(false)
}
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = false,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+
+ val record = listModel.transformItem(APP)
+
+ assertThat(record.hasRequestPermission).isFalse()
+ }
+
+ @Test
+ fun filter() = runTest {
+ with(packageManagers) { whenever(APP.hasRequestPermission(PERMISSION)).thenReturn(false) }
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = false,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
val recordListFlow = listModel.filter(flowOf(USER_ID), flowOf(listOf(record)))
@@ -118,11 +133,13 @@ class AppOpPermissionAppListTest {
@Test
fun isAllowed_allowed() {
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ALLOWED),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ALLOWED),
+ )
val isAllowed = getIsAllowed(record)
@@ -131,14 +148,14 @@ class AppOpPermissionAppListTest {
@Test
fun isAllowed_defaultAndHasGrantPermission() {
- with(packageManagers) {
- whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(true)
- }
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+ with(packageManagers) { whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(true) }
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
val isAllowed = getIsAllowed(record)
@@ -147,27 +164,49 @@ class AppOpPermissionAppListTest {
@Test
fun isAllowed_defaultAndNotGrantPermission() {
+ with(packageManagers) { whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(false) }
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
+
+ val isAllowed = getIsAllowed(record)
+
+ assertThat(isAllowed).isFalse()
+ }
+
+ @Test
+ fun isAllowed_broaderPermissionTrumps() {
+ listModel.broaderPermission = BROADER_PERMISSION
with(packageManagers) {
whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(false)
+ whenever(APP.hasGrantPermission(BROADER_PERMISSION)).thenReturn(true)
}
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = true,
+ hasRequestPermission = false,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ERRORED),
+ )
val isAllowed = getIsAllowed(record)
- assertThat(isAllowed).isFalse()
+ assertThat(isAllowed).isTrue()
}
@Test
fun isAllowed_notAllowed() {
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ERRORED),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ERRORED),
+ )
val isAllowed = getIsAllowed(record)
@@ -176,11 +215,13 @@ class AppOpPermissionAppListTest {
@Test
fun isChangeable_notRequestPermission() {
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = false,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = false,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
val isChangeable = listModel.isChangeable(record)
@@ -189,11 +230,13 @@ class AppOpPermissionAppListTest {
@Test
fun isChangeable_notChangeablePackages() {
- val record = AppOpPermissionRecord(
- app = NOT_CHANGEABLE_APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = NOT_CHANGEABLE_APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
val isChangeable = listModel.isChangeable(record)
@@ -202,11 +245,13 @@ class AppOpPermissionAppListTest {
@Test
fun isChangeable_hasRequestPermissionAndChangeable() {
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
val isChangeable = listModel.isChangeable(record)
@@ -214,13 +259,31 @@ class AppOpPermissionAppListTest {
}
@Test
+ fun isChangeable_broaderPermissionTrumps() {
+ listModel.broaderPermission = BROADER_PERMISSION
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = true,
+ hasRequestPermission = true,
+ appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ )
+
+ val isChangeable = listModel.isChangeable(record)
+
+ assertThat(isChangeable).isFalse()
+ }
+
+ @Test
fun setAllowed() {
val appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
- val record = AppOpPermissionRecord(
- app = APP,
- hasRequestPermission = true,
- appOpsController = appOpsController,
- )
+ val record =
+ AppOpPermissionRecord(
+ app = APP,
+ hasRequestBroaderPermission = false,
+ hasRequestPermission = true,
+ appOpsController = appOpsController,
+ )
listModel.setAllowed(record = record, newAllowed = true)
@@ -239,9 +302,7 @@ class AppOpPermissionAppListTest {
private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? {
lateinit var isAllowedState: State<Boolean?>
- composeTestRule.setContent {
- isAllowedState = listModel.isAllowed(record)
- }
+ composeTestRule.setContent { isAllowedState = listModel.isAllowed(record) }
return isAllowedState.value
}
@@ -250,8 +311,12 @@ class AppOpPermissionAppListTest {
override val pageTitleResId = R.string.test_app_op_permission_title
override val switchTitleResId = R.string.test_app_op_permission_switch_title
override val footerResId = R.string.test_app_op_permission_footer
+
override val appOp = AppOpsManager.OP_MANAGE_MEDIA
override val permission = PERMISSION
+ override val permissionHasAppopFlag = true
+ override var broaderPermission: String? = null
+
override var setModeByUid = false
}
@@ -259,12 +324,9 @@ class AppOpPermissionAppListTest {
const val USER_ID = 0
const val PACKAGE_NAME = "package.name"
const val PERMISSION = "PERMISSION"
- val APP = ApplicationInfo().apply {
- packageName = PACKAGE_NAME
- }
- val NOT_CHANGEABLE_APP = ApplicationInfo().apply {
- packageName = "android"
- }
+ const val BROADER_PERMISSION = "BROADER_PERMISSION"
+ val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME }
+ val NOT_CHANGEABLE_APP = ApplicationInfo().apply { packageName = "android" }
}
}