summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adam Wright <adamdwright@google.com> 2023-02-22 14:31:05 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-02-22 14:31:05 +0000
commitdcc53073c5b079a8e3f9b975169418df832feedd (patch)
tree9ac37f7facb5a216e9dfa9203eae407a30dcff4e
parentdba921871424ac9913344419c7307593522e62b3 (diff)
Revert "Don't unnecessarily query package metadata for SafetyLabels"
This reverts commit dba921871424ac9913344419c7307593522e62b3. Reason for revert: DM P0 breakage (b/270255253) Change-Id: Ibf50d32e2d0cb4cc8e25ff604ecd8d92c97a56dc
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt63
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java38
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt47
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt50
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt48
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt69
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionRationales.kt64
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/SafetyLabelPermissionMapping.kt44
-rw-r--r--SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java5
-rw-r--r--SafetyLabel/java/com/android/permission/safetylabel/DataType.java5
-rw-r--r--SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java42
13 files changed, 275 insertions, 204 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt
index 7a817eb6d..543d8eae2 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt
@@ -74,7 +74,7 @@ private constructor(
getInstallSourceInfo(userContext, packageName).installingPackageName)
} catch (e: PackageManager.NameNotFoundException) {
Log.w(LOG_TAG, "InstallSourceInfo for $packageName not found")
- LightInstallSourceInfoLiveData.invalidateSingle(packageName to user)
+ SafetyLabelInfoLiveData.invalidateSingle(packageName to user)
UNKNOWN_INSTALL_SOURCE
}
postValue(lightInstallSourceInfo)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt
index e8102c2e0..d2ba7031d 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt
@@ -18,10 +18,14 @@ package com.android.permissioncontroller.permission.data
import android.app.Application
import android.content.pm.PackageManager
+import android.os.PersistableBundle
import android.os.UserHandle
import android.util.Log
-import com.android.modules.utils.build.SdkLevel
+import com.android.permission.safetylabel.DataCategoryConstants
+import com.android.permission.safetylabel.DataLabelConstants
+import com.android.permission.safetylabel.DataTypeConstants
import com.android.permission.safetylabel.SafetyLabel
+import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION
import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.model.livedatatypes.SafetyLabelInfo
import com.android.permissioncontroller.permission.utils.KotlinUtils.isPlaceholderSafetyLabelDataEnabled
@@ -79,11 +83,6 @@ private constructor(
return
}
- if (!SdkLevel.isAtLeastU()) {
- postValue(SafetyLabelInfo.UNAVAILABLE)
- return
- }
-
// TODO(b/261607291): Add support preinstall apps that provide SafetyLabel. Installing
// package is null until updated from an app store
val installSourcePackageName = lightInstallSourceInfoLiveData.value?.installingPackageName
@@ -92,16 +91,11 @@ private constructor(
return
}
- if (isPlaceholderSafetyLabelDataEnabled()) {
- postValue(SafetyLabelInfo(SafetyLabel.getPlaceholderSafetyLabel(),
- installSourcePackageName))
- return
- }
-
val safetyLabelInfo: SafetyLabelInfo =
try {
- val safetyLabel: SafetyLabel? = SafetyLabel.getSafetyLabelFromMetadata(
- app.packageManager.getAppMetadata(packageName))
+ val metadataBundle: PersistableBundle = getAppMetadata()
+ val safetyLabel: SafetyLabel? =
+ SafetyLabel.getSafetyLabelFromMetadata(metadataBundle)
if (safetyLabel != null) {
SafetyLabelInfo(safetyLabel, installSourcePackageName)
} else {
@@ -115,8 +109,49 @@ private constructor(
postValue(safetyLabelInfo)
}
+ private fun getAppMetadata(): PersistableBundle {
+ return if (isPlaceholderSafetyLabelDataEnabled()) {
+ placeholderMetadataBundle()
+ } else {
+ app.packageManager.getAppMetadata(packageName)
+ }
+ }
+
+ private fun placeholderMetadataBundle(): PersistableBundle {
+ val approximateLocationBundle =
+ PersistableBundle().apply { putIntArray("purposes", (1..7).toList().toIntArray()) }
+
+ val locationBundle =
+ PersistableBundle().apply {
+ putPersistableBundle(
+ DataTypeConstants.LOCATION_APPROX_LOCATION, approximateLocationBundle)
+ }
+
+ val dataSharedBundle =
+ PersistableBundle().apply {
+ putPersistableBundle(DataCategoryConstants.CATEGORY_LOCATION, locationBundle)
+ }
+
+ val dataLabelBundle =
+ PersistableBundle().apply {
+ putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED, dataSharedBundle)
+ }
+
+ val safetyLabelBundle = PersistableBundle().apply {
+ putLong(KEY_VERSION, INITIAL_SAFETY_LABELS_VERSION)
+ putPersistableBundle("data_labels", dataLabelBundle)
+ }
+
+ return PersistableBundle().apply {
+ putLong(KEY_VERSION, INITIAL_METADATA_VERSION)
+ putPersistableBundle("safety_labels", safetyLabelBundle)
+ }
+ }
+
companion object : DataRepositoryForPackage<Pair<String, UserHandle>, SafetyLabelInfoLiveData>(
) {
+ private const val INITIAL_METADATA_VERSION = 1L
+ private const val INITIAL_SAFETY_LABELS_VERSION = 1L
private val LOG_TAG = SafetyLabelInfoLiveData::class.java.simpleName
override fun newValue(key: Pair<String, UserHandle>): SafetyLabelInfoLiveData {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
index 8f73f6577..e97c6ef4b 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
@@ -89,7 +89,7 @@ import java.util.Random;
public class GrantPermissionsActivity extends SettingsActivity
implements GrantPermissionsViewHandler.ResultListener {
- private static final String LOG_TAG = "GrantPermissionsActivity";
+ private static final String LOG_TAG = "GrantPermissionsActivit";
private static final String KEY_SESSION_ID = GrantPermissionsActivity.class.getName()
+ "_REQUEST_ID";
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java
index 9fad46648..007707363 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java
@@ -73,6 +73,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.data.FullStoragePermissionAppsLiveData.FullStoragePackageState;
+import com.android.permissioncontroller.permission.model.livedatatypes.SafetyLabelInfo;
import com.android.permissioncontroller.permission.ui.AdvancedConfirmDialogArgs;
import com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler;
import com.android.permissioncontroller.permission.ui.model.AppPermissionViewModel;
@@ -86,13 +87,12 @@ import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.widget.ActionBarShadowController;
-import kotlin.Pair;
-
import java.util.Map;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
+import kotlin.Pair;
+
/**
* Show and manage a single permission group for an app.
*
@@ -195,9 +195,10 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
getActivity().getApplication(), mPackageName, mPermGroupName, mUser, mSessionId);
mViewModel = new ViewModelProvider(this, factory).get(AppPermissionViewModel.class);
Handler delayHandler = new Handler(Looper.getMainLooper());
- mViewModel.getShowPermissionRationaleLiveData().observe(this, show -> {
- showPermissionRationaleDialog(Optional.ofNullable(show).orElse(false));
- });
+ if (KotlinUtils.INSTANCE.isPermissionRationaleEnabled()) {
+ mViewModel.getSafetyLabelInfoLiveData().observe(this,
+ this::showPermissionRationaleDialog);
+ }
mViewModel.getButtonStateLiveData().observe(this, buttonState -> {
if (mIsInitialLoad) {
setRadioButtonsState(buttonState);
@@ -294,6 +295,11 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
root.requireViewById(R.id.app_permission_rationale_container);
mAppPermissionRationaleContent =
root.requireViewById(R.id.app_permission_rationale_content);
+ if (!KotlinUtils.INSTANCE.isPermissionRationaleEnabled()) {
+ hidePermissionRationaleContainer();
+ } else {
+ setPermissionRationaleContainer(root, context);
+ }
getActivity().setTitle(
getPreferenceManager().getContext().getString(R.string.app_permission_title,
@@ -301,9 +307,19 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
return root;
}
- private void showPermissionRationaleDialog(boolean showPermissionRationale) {
- if (!showPermissionRationale) {
- mAppPermissionRationaleContainer.setVisibility(View.GONE);
+ private void setPermissionRationaleContainer(View root, Context context) {
+ ((TextView) root.requireViewById(R.id.app_permission_rationale_message)).setText(
+ context.getString(R.string.app_permission_rationale_message));
+ ((TextView) root.requireViewById(R.id.app_permission_rationale_title)).setText(
+ context.getString(R.string.app_location_permission_rationale_title));
+ ((TextView) root.requireViewById(R.id.app_permission_rationale_subtitle)).setText(
+ context.getString(R.string.app_location_permission_rationale_subtitle));
+ }
+
+ private void showPermissionRationaleDialog(@Nullable SafetyLabelInfo safetyLabelInfo) {
+ if (safetyLabelInfo == null
+ || !mViewModel.shouldShowPermissionRationale(safetyLabelInfo, mPermGroupName)) {
+ hidePermissionRationaleContainer();
} else {
mAppPermissionRationaleContainer.setVisibility(View.VISIBLE);
mAppPermissionRationaleContent.setOnClickListener((v) -> {
@@ -312,6 +328,10 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
}
}
+ private void hidePermissionRationaleContainer() {
+ mAppPermissionRationaleContainer.setVisibility(View.GONE);
+ }
+
private void setBottomLinkState(TextView view, String caller, String action) {
if ((Objects.equals(caller, AppPermissionGroupsFragment.class.getName())
&& action.equals(Intent.ACTION_MANAGE_APP_PERMISSIONS))
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt
index 2e1744f54..ac20a7748 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt
@@ -60,6 +60,7 @@ import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveD
import com.android.permissioncontroller.permission.data.get
import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup
import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission
+import com.android.permissioncontroller.permission.model.livedatatypes.SafetyLabelInfo
import com.android.permissioncontroller.permission.service.PermissionChangeStorageImpl
import com.android.permissioncontroller.permission.service.v33.PermissionDecisionStorageImpl
import com.android.permissioncontroller.permission.ui.AdvancedConfirmDialogArgs
@@ -77,8 +78,10 @@ import com.android.permissioncontroller.permission.ui.v34.PermissionRationaleAct
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.KotlinUtils.getDefaultPrecision
import com.android.permissioncontroller.permission.utils.KotlinUtils.isLocationAccuracyEnabled
+import com.android.permissioncontroller.permission.utils.KotlinUtils.isPermissionRationaleEnabled
import com.android.permissioncontroller.permission.utils.LocationUtils
import com.android.permissioncontroller.permission.utils.PermissionMapping
+import com.android.permissioncontroller.permission.utils.PermissionRationales
import com.android.permissioncontroller.permission.utils.SafetyNetLogger
import com.android.permissioncontroller.permission.utils.Utils
import com.android.permissioncontroller.permission.utils.navigateSafe
@@ -111,6 +114,8 @@ class AppPermissionViewModel(
const val PHOTO_PICKER_REQUEST_CODE = 1
}
+ val safetyLabelInfoLiveData = SafetyLabelInfoLiveData[packageName, user]
+
interface ConfirmDialogShowingFragment {
fun showConfirmDialog(
changeRequest: ChangeRequest,
@@ -179,36 +184,6 @@ class AppPermissionViewModel(
val showAdminSupportLiveData = MutableLiveData<RestrictedLockUtils.EnforcedAdmin>()
/**
- * A livedata for determining the display state of safety label information
- */
- val showPermissionRationaleLiveData = object : SmartUpdateMediatorLiveData<Boolean>() {
- private val safetyLabelInfoLiveData = SafetyLabelInfoLiveData[packageName, user]
-
- init {
- if (PermissionMapping.isSafetyLabelAwarePermission(permGroupName)) {
- addSource(safetyLabelInfoLiveData) { update() }
- } else {
- value = false
- }
- }
-
- override fun onUpdate() {
- if (safetyLabelInfoLiveData.isStale) {
- return
- }
-
- val safetyLabel = safetyLabelInfoLiveData.value?.safetyLabel
- if (safetyLabel == null) {
- value = false
- return
- }
-
- value = PermissionMapping.getSafetyLabelSharingPurposesForGroup(
- safetyLabel, permGroupName).any()
- }
- }
-
- /**
* A livedata which determines which detail string, if any, should be shown
*/
val fullStorageStateLiveData = object : SmartUpdateMediatorLiveData<FullStoragePackageState>() {
@@ -574,6 +549,14 @@ class AppPermissionViewModel(
return true
}
+ fun shouldShowPermissionRationale(
+ safetyLabelInfo: SafetyLabelInfo,
+ groupName: String
+ ): Boolean {
+ return PermissionRationales.shouldShowPermissionRationale(
+ safetyLabelInfo.safetyLabel, groupName)
+ }
+
/**
* Shows the Permission Rationale Dialog. For use with U+ only, otherwise no-op.
*
@@ -581,6 +564,10 @@ class AppPermissionViewModel(
* @param groupName The name of the permission group whose fragment should be opened
*/
fun showPermissionRationaleActivity(activity: Activity, groupName: String) {
+ if (!isPermissionRationaleEnabled()) {
+ return
+ }
+
val intent = Intent(activity, PermissionRationaleActivity::class.java).apply {
putExtra(Intent.EXTRA_PACKAGE_NAME, packageName)
putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
index 01fd079c6..b82536dd5 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
@@ -120,7 +120,9 @@ import com.android.permissioncontroller.permission.utils.KotlinUtils.getDefaultP
import com.android.permissioncontroller.permission.utils.KotlinUtils.grantBackgroundRuntimePermissions
import com.android.permissioncontroller.permission.utils.KotlinUtils.grantForegroundRuntimePermissions
import com.android.permissioncontroller.permission.utils.KotlinUtils.isLocationAccuracyEnabled
+import com.android.permissioncontroller.permission.utils.KotlinUtils.isPermissionRationaleEnabled
import com.android.permissioncontroller.permission.utils.PermissionMapping
+import com.android.permissioncontroller.permission.utils.PermissionRationales
import com.android.permissioncontroller.permission.utils.SafetyNetLogger
import com.android.permissioncontroller.permission.utils.Utils
@@ -145,16 +147,12 @@ class GrantPermissionsViewModel(
private val LOG_TAG = GrantPermissionsViewModel::class.java.simpleName
private val user = Process.myUserHandle()
private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user]
- private val safetyLabelInfoLiveData =
- if (requestedPermissions.any { PermissionMapping.isSafetyLabelAwarePermission(it) }) {
- SafetyLabelInfoLiveData[packageName, user]
- } else {
- null
- }
+ private val safetyLabelInfoLiveData = SafetyLabelInfoLiveData[packageName, user]
private val dpm = app.getSystemService(DevicePolicyManager::class.java)!!
private val permissionPolicy = dpm.getPermissionPolicy(null)
private val permGroupsToSkip = mutableListOf<String>()
private var groupStates = mutableMapOf<Pair<String, Boolean>, GroupState>()
+ private val permissionRationaleEnabled: Boolean by lazy { isPermissionRationaleEnabled() }
private var autoGrantNotifier: AutoGrantPermissionsNotifier? = null
private fun getAutoGrantNotifier(): AutoGrantPermissionsNotifier {
@@ -163,6 +161,7 @@ class GrantPermissionsViewModel(
}
private lateinit var packageInfo: LightPackageInfo
+ private var safetyLabel: SafetyLabel? = null
// All permissions that could possibly be affected by the provided requested permissions, before
// filtering system fixed, auto grant, etc.
@@ -199,10 +198,12 @@ class GrantPermissionsViewModel(
private val LOG_TAG = GrantPermissionsViewModel::class.java.simpleName
private val packagePermissionsLiveData = PackagePermissionsLiveData[packageName, user]
+ // TODO(b/260873483): only query safety label for supported permission groups. should only
+ // query location, but currently queries for all groups
init {
addSource(packagePermissionsLiveData) { onPackageLoaded() }
addSource(packageInfoLiveData) { onPackageLoaded() }
- if (safetyLabelInfoLiveData != null) {
+ if (permissionRationaleEnabled) {
addSource(safetyLabelInfoLiveData) { onPackageLoaded() }
}
@@ -213,10 +214,17 @@ class GrantPermissionsViewModel(
private fun onPackageLoaded() {
if (packageInfoLiveData.isStale ||
packagePermissionsLiveData.isStale ||
- (safetyLabelInfoLiveData != null && safetyLabelInfoLiveData.isStale)) {
+ (permissionRationaleEnabled && safetyLabelInfoLiveData.isStale)) {
return
}
+ safetyLabel =
+ if (permissionRationaleEnabled) {
+ safetyLabelInfoLiveData.value?.safetyLabel
+ } else {
+ null
+ }
+
val groups = packagePermissionsLiveData.value
val pI = packageInfoLiveData.value
if (groups == null || groups.isEmpty() || pI == null) {
@@ -560,15 +568,14 @@ class GrantPermissionsViewModel(
}
}
- val safetyLabel = safetyLabelInfoLiveData?.value?.safetyLabel
-
requestInfos.add(RequestInfo(
groupInfo,
buttonVisibilities,
locationVisibilities,
message,
detailMessage,
- shouldShowPermissionRationale(safetyLabel, groupState)))
+ showPermissionRationale = shouldShowPermissionRationale(
+ safetyLabel, groupState)))
}
sortPermissionGroups(requestInfos)
@@ -584,19 +591,6 @@ class GrantPermissionsViewModel(
}
}
- private fun shouldShowPermissionRationale(
- safetyLabel: SafetyLabel?,
- groupState: GroupState
- ): Boolean {
- if (safetyLabel == null) {
- return false
- }
-
- val purposes = PermissionMapping.getSafetyLabelSharingPurposesForGroup(safetyLabel,
- groupState.group.permGroupName)
- return purposes.isNotEmpty()
- }
-
fun sortPermissionGroups(requestInfos: MutableList<RequestInfo>) {
requestInfos.sortWith { rhs, lhs ->
val rhsHasOneTime = rhs.buttonVisibilities[ALLOW_ONE_TIME_BUTTON]
@@ -613,6 +607,14 @@ class GrantPermissionsViewModel(
}
}
+ private fun shouldShowPermissionRationale(
+ safetyLabel: SafetyLabel?,
+ groupState: GroupState
+ ): Boolean {
+ return PermissionRationales.shouldShowPermissionRationale(
+ safetyLabel, groupState.group.permGroupName)
+ }
+
/**
* Converts a list of LightAppPermGroups into a list of GroupStates
*/
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt
index 54d94f913..8de8de726 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt
@@ -29,18 +29,23 @@ import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import com.android.permission.safetylabel.DataCategory
+import com.android.permission.safetylabel.DataType
+import com.android.permission.safetylabel.DataTypeConstants
+import com.android.permission.safetylabel.SafetyLabel
import com.android.permissioncontroller.Constants
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.data.SafetyLabelInfoLiveData
import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData
import com.android.permissioncontroller.permission.data.get
+import com.android.permissioncontroller.permission.model.livedatatypes.SafetyLabelInfo.Companion.UNAVAILABLE
import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity
import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity.EXTRA_RESULT_PERMISSION_INTERACTED
import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity.EXTRA_RESULT_PERMISSION_RESULT
import com.android.permissioncontroller.permission.ui.v34.PermissionRationaleActivity
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.KotlinUtils.getAppStoreIntent
-import com.android.permissioncontroller.permission.utils.PermissionMapping
+import com.android.permissioncontroller.permission.utils.SafetyLabelPermissionMapping
import com.android.settingslib.HelpUtils
/**
@@ -85,7 +90,7 @@ class PermissionRationaleViewModel(
data class PermissionRationaleInfo(
val groupName: String,
val installSourcePackageName: String?,
- val installSourceLabel: String?,
+ val installSourceLabel: CharSequence?,
val purposeSet: Set<Int>
)
@@ -106,15 +111,18 @@ class PermissionRationaleViewModel(
}
val safetyLabelInfo = safetyLabelInfoLiveData.value
+ val safetyLabel = safetyLabelInfo?.safetyLabel
- if (safetyLabelInfo?.safetyLabel == null) {
+ if (safetyLabelInfo == null ||
+ safetyLabelInfo == UNAVAILABLE ||
+ safetyLabel == null) {
Log.e(LOG_TAG, "Safety label for $packageName not found")
value = null
return
}
val installSourcePackageName = safetyLabelInfo.installSourcePackageName
- val installSourceLabel: String? =
+ val installSourceLabel: CharSequence? =
installSourcePackageName?.let {
KotlinUtils.getPackageLabel(app, it, Process.myUserHandle())
}
@@ -124,8 +132,36 @@ class PermissionRationaleViewModel(
permissionGroupName,
installSourcePackageName,
installSourceLabel,
- PermissionMapping.getSafetyLabelSharingPurposesForGroup(
- safetyLabelInfo.safetyLabel, permissionGroupName))
+ getSafetyLabelSharingPurposesForGroup(safetyLabel, permissionGroupName))
+ }
+
+ private fun getSafetyLabelSharingPurposesForGroup(
+ safetyLabel: SafetyLabel,
+ groupName: String
+ ): Set<Int> {
+ val purposeSet = mutableSetOf<Int>()
+ val categoriesForPermission: List<String> =
+ SafetyLabelPermissionMapping.getCategoriesForPermissionGroup(groupName)
+ categoriesForPermission.forEach categoryLoop@{ category ->
+ val dataCategory: DataCategory? = safetyLabel.dataLabel.dataShared[category]
+ if (dataCategory == null) {
+ // Continue to next
+ return@categoryLoop
+ }
+ val typesForCategory = DataTypeConstants.getValidDataTypesForCategory(category)
+ typesForCategory.forEach typeLoop@{ type ->
+ val dataType: DataType? = dataCategory.dataTypes[type]
+ if (dataType == null) {
+ // Continue to next
+ return@typeLoop
+ }
+ if (dataType.purposeSet.isNotEmpty()) {
+ purposeSet.addAll(dataType.purposeSet)
+ }
+ }
+ }
+
+ return purposeSet
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
index 45a7fb02e..3fde87108 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
@@ -21,13 +21,7 @@ import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP
import android.util.Log
-
import com.android.modules.utils.build.SdkLevel
-import com.android.permission.safetylabel.DataCategory
-import com.android.permission.safetylabel.DataCategoryConstants
-import com.android.permission.safetylabel.DataType
-import com.android.permission.safetylabel.DataTypeConstants
-import com.android.permission.safetylabel.SafetyLabel
/**
* This file contains the canonical mapping of permission to permission group, used in the
@@ -37,9 +31,6 @@ object PermissionMapping {
private val LOG_TAG = "PermissionMapping"
- private val PERMISSION_GROUPS_TO_DATA_CATEGORIES: Map<String, List<String>> = mapOf(
- Manifest.permission_group.LOCATION to listOf(DataCategoryConstants.CATEGORY_LOCATION))
-
@JvmField
val SENSOR_DATA_PERMISSIONS: List<String> =
listOf(
@@ -335,64 +326,4 @@ object PermissionMapping {
fun isHealthPermission(permissionName: String): Boolean {
return HEALTH_PERMISSIONS_SET.contains(permissionName)
}
-
- /**
- * Get the sharing purposes for a SafetyLabel related to a specific permission group.
- */
- @JvmStatic
- fun getSafetyLabelSharingPurposesForGroup(
- safetyLabel: SafetyLabel,
- groupName: String
- ): Set<Int> {
- val purposeSet = mutableSetOf<Int>()
- val categoriesForPermission = getDataCategoriesForPermissionGroup(groupName)
- categoriesForPermission.forEach categoryLoop@{ category ->
- val dataCategory: DataCategory? = safetyLabel.dataLabel.dataShared[category]
- if (dataCategory == null) {
- // Continue to next
- return@categoryLoop
- }
- val typesForCategory = DataTypeConstants.getValidDataTypesForCategory(category)
- typesForCategory.forEach typeLoop@{ type ->
- val dataType: DataType? = dataCategory.dataTypes[type]
- if (dataType == null) {
- // Continue to next
- return@typeLoop
- }
- if (dataType.purposeSet.isNotEmpty()) {
- purposeSet.addAll(dataType.purposeSet)
- }
- }
- }
-
- return purposeSet
- }
-
- /**
- * Get the SafetyLabel categories pertaining to a specified permission group.
- *
- * @return The categories, or an empty list if the group does not have a supported mapping
- * to safety label category
- */
- fun getDataCategoriesForPermissionGroup(permissionGroupName: String): List<String> {
- return if (isSafetyLabelAwarePermission(permissionGroupName)) {
- PERMISSION_GROUPS_TO_DATA_CATEGORIES[permissionGroupName] ?: emptyList()
- } else {
- emptyList()
- }
- }
-
- /**
- * Whether this permission group maps to a SafetyLabel data category.
- *
- * @param permissionGroupName the permission group name
- */
- @JvmStatic
- fun isSafetyLabelAwarePermission(permissionGroupName: String): Boolean {
- if (!KotlinUtils.isPermissionRationaleEnabled()) {
- return false
- }
-
- return PERMISSION_GROUPS_TO_DATA_CATEGORIES.containsKey(permissionGroupName)
- }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionRationales.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionRationales.kt
new file mode 100644
index 000000000..ede87e84f
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionRationales.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.utils
+
+import com.android.permission.safetylabel.DataCategory
+import com.android.permission.safetylabel.DataType
+import com.android.permission.safetylabel.DataTypeConstants
+import com.android.permission.safetylabel.SafetyLabel
+
+/**
+ * A set of util functions used for permission rationale dialog.
+ */
+object PermissionRationales {
+
+ /**
+ * Returns if the permission rationale dialog should be shown.
+ * @param safetyLabel the [SafetyLabel] bundle provided
+ * @param groupName the permission group name
+ * @return true if the permission dialog should be shown, otherwise false.
+ */
+ fun shouldShowPermissionRationale(
+ safetyLabel: SafetyLabel?,
+ groupName: String
+ ): Boolean {
+ if (safetyLabel == null || safetyLabel.dataLabel.dataShared.isEmpty()) {
+ return false
+ }
+ val categoriesForPermission: List<String> =
+ SafetyLabelPermissionMapping.getCategoriesForPermissionGroup(groupName)
+ categoriesForPermission.forEach categoryLoop@{ category ->
+ val dataCategory: DataCategory? = safetyLabel.dataLabel.dataShared[category]
+ if (dataCategory == null) {
+ // Continue to next
+ return@categoryLoop
+ }
+ val typesForCategory = DataTypeConstants.getValidDataTypesForCategory(category)
+ typesForCategory.forEach typeLoop@{ type ->
+ val dataType: DataType? = dataCategory.dataTypes[type]
+ if (dataType == null) {
+ // Continue to next
+ return@typeLoop
+ }
+ if (dataType.purposeSet.isNotEmpty()) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+} \ No newline at end of file
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/SafetyLabelPermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/SafetyLabelPermissionMapping.kt
new file mode 100644
index 000000000..5fd852bb6
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/SafetyLabelPermissionMapping.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.utils
+
+import android.Manifest
+import com.android.permission.safetylabel.DataCategoryConstants
+
+/**
+ * This file contains the canonical mapping of permission and permission group to Safety Label
+ * categories and types used in the Permission settings screens and grant dialog. It also includes
+ * methods related to that mapping.
+ */
+object SafetyLabelPermissionMapping {
+
+ /**
+ * Get the Safety Label categories pertaining to a specified permission group.
+ *
+ * @param groupName the permission group name
+ *
+ * @return The categories or an empty list if the group does not have supported and mapped group
+ * to safety label category
+ */
+ fun getCategoriesForPermissionGroup(groupName: String): List<String> {
+ return if (groupName == Manifest.permission_group.LOCATION) {
+ listOf(DataCategoryConstants.CATEGORY_LOCATION)
+ } else {
+ emptyList()
+ }
+ }
+}
diff --git a/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java b/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java
index 676cfa6d7..564d5479f 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java
@@ -32,10 +32,7 @@ import java.util.Map;
* {@link DataCategory}
*/
public class DataLabel {
-
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- static final String KEY_DATA_LABEL = "data_labels";
-
+ @VisibleForTesting static final String KEY_DATA_LABEL = "data_labels";
private final Map<String, DataCategory> mDataCollected;
private final Map<String, DataCategory> mDataShared;
diff --git a/SafetyLabel/java/com/android/permission/safetylabel/DataType.java b/SafetyLabel/java/com/android/permission/safetylabel/DataType.java
index 3350a5942..68770f823 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/DataType.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/DataType.java
@@ -35,10 +35,7 @@ import java.util.Set;
* metadata related to the data usage purpose.
*/
public class DataType {
-
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- static final String KEY_PURPOSES = "purposes";
-
+ @VisibleForTesting static final String KEY_PURPOSES = "purposes";
@VisibleForTesting static final String KEY_IS_COLLECTION_OPTIONAL = "is_collection_optional";
@VisibleForTesting static final String KEY_EPHEMERAL = "ephemeral";
diff --git a/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java b/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java
index 0ada11719..3eb8767b9 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java
@@ -28,10 +28,6 @@ import java.util.Locale;
/** Safety Label representation containing zero or more {@link DataCategory} for data shared */
public class SafetyLabel {
private static final String TAG = "SafetyLabel";
-
- private static final long INITIAL_METADATA_VERSION = 1L;
- private static final long INITIAL_SAFETY_LABELS_VERSION = 1L;
-
@VisibleForTesting static final String KEY_SAFETY_LABEL = "safety_labels";
public static final String KEY_VERSION = "version";
private final DataLabel mDataLabel;
@@ -73,44 +69,6 @@ public class SafetyLabel {
return new SafetyLabel(dataLabel);
}
- /**
- * Create a placeholder SafetyLabel for use for testing.
- * This is accessible through device configs.
- */
- @NonNull
- public static SafetyLabel getPlaceholderSafetyLabel() {
- return getSafetyLabelFromMetadata(getPlaceholderMetadataBundle());
- }
-
- @NonNull
- private static PersistableBundle getPlaceholderMetadataBundle() {
- PersistableBundle approximateLocationBundle = new PersistableBundle();
- approximateLocationBundle.putIntArray(DataType.KEY_PURPOSES,
- new int[] { 1, 2, 3, 4, 5, 6, 7 });
-
- PersistableBundle locationBundle = new PersistableBundle();
- locationBundle.putPersistableBundle(DataTypeConstants.LOCATION_APPROX_LOCATION,
- approximateLocationBundle);
-
- PersistableBundle dataSharedBundle = new PersistableBundle();
- dataSharedBundle.putPersistableBundle(DataCategoryConstants.CATEGORY_LOCATION,
- locationBundle);
-
- PersistableBundle dataLabelBundle = new PersistableBundle();
- dataLabelBundle.putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED,
- dataSharedBundle);
-
- PersistableBundle safetyLabelBundle = new PersistableBundle();
- safetyLabelBundle.putLong(KEY_VERSION, INITIAL_SAFETY_LABELS_VERSION);
- safetyLabelBundle.putPersistableBundle(DataLabel.KEY_DATA_LABEL, dataLabelBundle);
-
- PersistableBundle metadataBundle = new PersistableBundle();
- metadataBundle.putLong(KEY_VERSION, INITIAL_METADATA_VERSION);
- metadataBundle.putPersistableBundle(KEY_SAFETY_LABEL, safetyLabelBundle);
-
- return metadataBundle;
- }
-
/** Returns the data label for the safety label */
@NonNull
public DataLabel getDataLabel() {