summaryrefslogtreecommitdiff
path: root/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33
diff options
context:
space:
mode:
authorKevin Han <kevhan@google.com>2022-04-19 16:49:16 -0700
committerKevin Han <kevhan@google.com>2022-04-21 17:26:57 -0700
commit5d1b5b5f03eb4fddbf824edc5c4b8954b3168d3b (patch)
tree50563477e7d4ebde0010206a5e61c97461198c40 /PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33
parent357f206601a97d07a3b6231b111e79f328670345 (diff)
downloadPermission-5d1b5b5f03eb4fddbf824edc5c4b8954b3168d3b.tar.gz
Move all permission event classes to v33
Move all permission event classes to v33 as they are not running on R/S currently. This should help mitigate the coverage issues. Eventually, once go/tracking-permission-changes is fully implemented, a lot of this will be running on R, and we will refactor the code back then. Bug: 229664579 Test: atest PermissionControllerMockingTests Test: make -j64 RUN_ERROR_PRONE=true Change-Id: I59caa8d14b918220d67c11089687c0bb1001d313
Diffstat (limited to 'PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33')
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/ReviewPermissionDecisionsViewModel.kt160
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/package-info.java18
2 files changed, 178 insertions, 0 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/ReviewPermissionDecisionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/ReviewPermissionDecisionsViewModel.kt
new file mode 100644
index 000000000..8e523be90
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/ReviewPermissionDecisionsViewModel.kt
@@ -0,0 +1,160 @@
+/*
+ * 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.permissioncontroller.permission.ui.model.v33
+
+import android.app.Application
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import android.icu.lang.UCharacter
+import android.os.Build
+import android.os.UserHandle
+import android.text.BidiFormatter
+import androidx.annotation.RequiresApi
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.android.permissioncontroller.DumpableLog
+import com.android.permissioncontroller.R
+import com.android.permissioncontroller.permission.data.SmartAsyncMediatorLiveData
+import com.android.permissioncontroller.permission.data.UserPackageInfosLiveData
+import com.android.permissioncontroller.permission.data.v33.PermissionDecision
+import com.android.permissioncontroller.permission.data.v33.RecentPermissionDecisionsLiveData
+import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo
+import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity
+import com.android.permissioncontroller.permission.ui.auto.AutoReviewPermissionDecisionsFragment
+import com.android.permissioncontroller.permission.utils.KotlinUtils
+import com.android.permissioncontroller.permission.utils.StringUtils
+import com.android.permissioncontroller.permission.utils.Utils
+import kotlinx.coroutines.Job
+import java.util.concurrent.TimeUnit
+
+/** Viewmodel for [ReviewPermissionDecisionsFragment] */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+class ReviewPermissionDecisionsViewModel(val app: Application, val user: UserHandle) : ViewModel() {
+
+ val LOG_TAG = "ReviewPermissionDecisionsViewModel"
+
+ private val recentPermissionsLiveData = RecentPermissionDecisionsLiveData()
+ private val userPackageInfosLiveData = UserPackageInfosLiveData[user]
+
+ val recentPermissionDecisionsLiveData = object
+ : SmartAsyncMediatorLiveData<List<PermissionDecision>>(
+ alwaysUpdateOnActive = false
+ ) {
+
+ init {
+ addSource(recentPermissionsLiveData) {
+ onUpdate()
+ }
+
+ addSource(userPackageInfosLiveData) {
+ onUpdate()
+ }
+ }
+
+ override suspend fun loadDataAndPostValue(job: Job) {
+ if (!recentPermissionsLiveData.isInitialized ||
+ !userPackageInfosLiveData.isInitialized) {
+ return
+ }
+
+ // create package info lookup map for performance
+ val packageToLightPackageInfo: MutableMap<String, LightPackageInfo> = mutableMapOf()
+ for (lightPackageInfo in userPackageInfosLiveData.value!!) {
+ packageToLightPackageInfo[lightPackageInfo.packageName] = lightPackageInfo
+ }
+
+ // verify that permission state is still correct. Will also filter out any apps that
+ // were uninstalled
+ val decisionsToReview: MutableList<PermissionDecision> = mutableListOf()
+ for (recentDecision in recentPermissionsLiveData.value!!) {
+ val lightPackageInfo = packageToLightPackageInfo[recentDecision.packageName]
+ if (lightPackageInfo == null) {
+ DumpableLog.e(LOG_TAG, "Package $recentDecision.packageName " +
+ "is no longer installed")
+ continue
+ }
+ val grantedGroups: List<String?> = lightPackageInfo.grantedPermissions.map {
+ Utils.getGroupOfPermission(
+ app.packageManager.getPermissionInfo(it, /* flags= */ 0))
+ }
+ val currentlyGranted = grantedGroups.contains(recentDecision.permissionGroupName)
+ if (currentlyGranted && recentDecision.isGranted) {
+ decisionsToReview.add(recentDecision)
+ } else if (!currentlyGranted && !recentDecision.isGranted) {
+ decisionsToReview.add(recentDecision)
+ } else {
+ // It's okay for this to happen - the state could change due to role changes,
+ // app hibernation, or other non-user-driven actions.
+ DumpableLog.d(LOG_TAG,
+ "Permission decision grant state (${recentDecision.isGranted}) " +
+ "for ${recentDecision.packageName} access to " +
+ "${recentDecision.permissionGroupName} does not match current " +
+ "grant state $currentlyGranted")
+ }
+ }
+
+ postValue(decisionsToReview)
+ }
+ }
+
+ fun getAppIcon(packageName: String): Drawable? {
+ return KotlinUtils.getBadgedPackageIcon(app, packageName, user)
+ }
+
+ fun createPreferenceTitle(permissionDecision: PermissionDecision): String {
+ val packageLabel = BidiFormatter.getInstance().unicodeWrap(
+ KotlinUtils.getPackageLabel(app, permissionDecision.packageName, user))
+ val permissionGroupLabel = KotlinUtils.getPermGroupLabel(app,
+ permissionDecision.permissionGroupName).toString()
+ return if (permissionDecision.isGranted) {
+ app.getString(R.string.granted_permission_decision, packageLabel,
+ UCharacter.toLowerCase(permissionGroupLabel))
+ } else {
+ app.getString(R.string.denied_permission_decision, packageLabel,
+ UCharacter.toLowerCase(permissionGroupLabel))
+ }
+ }
+
+ fun createManageAppPermissionIntent(permissionDecision: PermissionDecision): Intent {
+ return Intent(Intent.ACTION_MANAGE_APP_PERMISSION).apply {
+ putExtra(Intent.EXTRA_PACKAGE_NAME, permissionDecision.packageName)
+ putExtra(Intent.EXTRA_PERMISSION_NAME, permissionDecision.permissionGroupName)
+ putExtra(Intent.EXTRA_USER, user)
+ putExtra(ManagePermissionsActivity.EXTRA_CALLER_NAME,
+ AutoReviewPermissionDecisionsFragment::class.java.name)
+ }
+ }
+
+ fun createSummaryText(permissionDecision: PermissionDecision): String {
+ val diff = System.currentTimeMillis() - permissionDecision.eventTime
+ val daysAgo = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS).toInt()
+ return StringUtils.getIcuPluralsString(app, R.string.days_ago, daysAgo)
+ }
+}
+
+/**
+ * Factory for a [ReviewPermissionDecisionsViewModel]
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+class ReviewPermissionDecisionsViewModelFactory(val app: Application, val user: UserHandle) :
+ ViewModelProvider.Factory {
+
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ @Suppress("UNCHECKED_CAST")
+ return ReviewPermissionDecisionsViewModel(app, user) as T
+ }
+} \ No newline at end of file
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/package-info.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/package-info.java
new file mode 100644
index 000000000..9c074c8ac
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v33/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+@androidx.annotation.RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU)
+package com.android.permissioncontroller.permission.ui.model.v33;