summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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, 204 insertions, 275 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/LightInstallSourceInfoLiveData.kt
index 543d8eae2..7a817eb6d 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")
- SafetyLabelInfoLiveData.invalidateSingle(packageName to user)
+ LightInstallSourceInfoLiveData.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 d2ba7031d..e8102c2e0 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt
@@ -18,14 +18,10 @@ 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.permission.safetylabel.DataCategoryConstants
-import com.android.permission.safetylabel.DataLabelConstants
-import com.android.permission.safetylabel.DataTypeConstants
+import com.android.modules.utils.build.SdkLevel
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
@@ -83,6 +79,11 @@ 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
@@ -91,11 +92,16 @@ private constructor(
return
}
+ if (isPlaceholderSafetyLabelDataEnabled()) {
+ postValue(SafetyLabelInfo(SafetyLabel.getPlaceholderSafetyLabel(),
+ installSourcePackageName))
+ return
+ }
+
val safetyLabelInfo: SafetyLabelInfo =
try {
- val metadataBundle: PersistableBundle = getAppMetadata()
- val safetyLabel: SafetyLabel? =
- SafetyLabel.getSafetyLabelFromMetadata(metadataBundle)
+ val safetyLabel: SafetyLabel? = SafetyLabel.getSafetyLabelFromMetadata(
+ app.packageManager.getAppMetadata(packageName))
if (safetyLabel != null) {
SafetyLabelInfo(safetyLabel, installSourcePackageName)
} else {
@@ -109,49 +115,8 @@ 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 e97c6ef4b..8f73f6577 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 = "GrantPermissionsActivit";
+ private static final String LOG_TAG = "GrantPermissionsActivity";
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 007707363..9fad46648 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java
@@ -73,7 +73,6 @@ 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;
@@ -87,12 +86,13 @@ 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,10 +195,9 @@ 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());
- if (KotlinUtils.INSTANCE.isPermissionRationaleEnabled()) {
- mViewModel.getSafetyLabelInfoLiveData().observe(this,
- this::showPermissionRationaleDialog);
- }
+ mViewModel.getShowPermissionRationaleLiveData().observe(this, show -> {
+ showPermissionRationaleDialog(Optional.ofNullable(show).orElse(false));
+ });
mViewModel.getButtonStateLiveData().observe(this, buttonState -> {
if (mIsInitialLoad) {
setRadioButtonsState(buttonState);
@@ -295,11 +294,6 @@ 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,
@@ -307,19 +301,9 @@ public class AppPermissionFragment extends SettingsWithLargeHeader
return root;
}
- 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();
+ private void showPermissionRationaleDialog(boolean showPermissionRationale) {
+ if (!showPermissionRationale) {
+ mAppPermissionRationaleContainer.setVisibility(View.GONE);
} else {
mAppPermissionRationaleContainer.setVisibility(View.VISIBLE);
mAppPermissionRationaleContent.setOnClickListener((v) -> {
@@ -328,10 +312,6 @@ 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 ac20a7748..2e1744f54 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt
@@ -60,7 +60,6 @@ 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
@@ -78,10 +77,8 @@ 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
@@ -114,8 +111,6 @@ class AppPermissionViewModel(
const val PHOTO_PICKER_REQUEST_CODE = 1
}
- val safetyLabelInfoLiveData = SafetyLabelInfoLiveData[packageName, user]
-
interface ConfirmDialogShowingFragment {
fun showConfirmDialog(
changeRequest: ChangeRequest,
@@ -184,6 +179,36 @@ 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>() {
@@ -549,14 +574,6 @@ 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.
*
@@ -564,10 +581,6 @@ 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 b82536dd5..01fd079c6 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
@@ -120,9 +120,7 @@ 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
@@ -147,12 +145,16 @@ class GrantPermissionsViewModel(
private val LOG_TAG = GrantPermissionsViewModel::class.java.simpleName
private val user = Process.myUserHandle()
private val packageInfoLiveData = LightPackageInfoLiveData[packageName, user]
- private val safetyLabelInfoLiveData = SafetyLabelInfoLiveData[packageName, user]
+ private val safetyLabelInfoLiveData =
+ if (requestedPermissions.any { PermissionMapping.isSafetyLabelAwarePermission(it) }) {
+ SafetyLabelInfoLiveData[packageName, user]
+ } else {
+ null
+ }
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 {
@@ -161,7 +163,6 @@ 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.
@@ -198,12 +199,10 @@ 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 (permissionRationaleEnabled) {
+ if (safetyLabelInfoLiveData != null) {
addSource(safetyLabelInfoLiveData) { onPackageLoaded() }
}
@@ -214,17 +213,10 @@ class GrantPermissionsViewModel(
private fun onPackageLoaded() {
if (packageInfoLiveData.isStale ||
packagePermissionsLiveData.isStale ||
- (permissionRationaleEnabled && safetyLabelInfoLiveData.isStale)) {
+ (safetyLabelInfoLiveData != null && 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) {
@@ -568,14 +560,15 @@ class GrantPermissionsViewModel(
}
}
+ val safetyLabel = safetyLabelInfoLiveData?.value?.safetyLabel
+
requestInfos.add(RequestInfo(
groupInfo,
buttonVisibilities,
locationVisibilities,
message,
detailMessage,
- showPermissionRationale = shouldShowPermissionRationale(
- safetyLabel, groupState)))
+ shouldShowPermissionRationale(safetyLabel, groupState)))
}
sortPermissionGroups(requestInfos)
@@ -591,6 +584,19 @@ 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]
@@ -607,14 +613,6 @@ 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 8de8de726..54d94f913 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,23 +29,18 @@ 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.SafetyLabelPermissionMapping
+import com.android.permissioncontroller.permission.utils.PermissionMapping
import com.android.settingslib.HelpUtils
/**
@@ -90,7 +85,7 @@ class PermissionRationaleViewModel(
data class PermissionRationaleInfo(
val groupName: String,
val installSourcePackageName: String?,
- val installSourceLabel: CharSequence?,
+ val installSourceLabel: String?,
val purposeSet: Set<Int>
)
@@ -111,18 +106,15 @@ class PermissionRationaleViewModel(
}
val safetyLabelInfo = safetyLabelInfoLiveData.value
- val safetyLabel = safetyLabelInfo?.safetyLabel
- if (safetyLabelInfo == null ||
- safetyLabelInfo == UNAVAILABLE ||
- safetyLabel == null) {
+ if (safetyLabelInfo?.safetyLabel == null) {
Log.e(LOG_TAG, "Safety label for $packageName not found")
value = null
return
}
val installSourcePackageName = safetyLabelInfo.installSourcePackageName
- val installSourceLabel: CharSequence? =
+ val installSourceLabel: String? =
installSourcePackageName?.let {
KotlinUtils.getPackageLabel(app, it, Process.myUserHandle())
}
@@ -132,36 +124,8 @@ class PermissionRationaleViewModel(
permissionGroupName,
installSourcePackageName,
installSourceLabel,
- 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
+ PermissionMapping.getSafetyLabelSharingPurposesForGroup(
+ safetyLabelInfo.safetyLabel, permissionGroupName))
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
index 3fde87108..45a7fb02e 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
@@ -21,7 +21,13 @@ 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
@@ -31,6 +37,9 @@ 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(
@@ -326,4 +335,64 @@ 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
deleted file mode 100644
index ede87e84f..000000000
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionRationales.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 5fd852bb6..000000000
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/SafetyLabelPermissionMapping.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 564d5479f..676cfa6d7 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/DataLabel.java
@@ -32,7 +32,10 @@ import java.util.Map;
* {@link DataCategory}
*/
public class DataLabel {
- @VisibleForTesting static final String KEY_DATA_LABEL = "data_labels";
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ 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 68770f823..3350a5942 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/DataType.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/DataType.java
@@ -35,7 +35,10 @@ import java.util.Set;
* metadata related to the data usage purpose.
*/
public class DataType {
- @VisibleForTesting static final String KEY_PURPOSES = "purposes";
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ 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 3eb8767b9..0ada11719 100644
--- a/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java
+++ b/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java
@@ -28,6 +28,10 @@ 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;
@@ -69,6 +73,44 @@ 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() {