summaryrefslogtreecommitdiff
path: root/PermissionController/src
diff options
context:
space:
mode:
Diffstat (limited to 'PermissionController/src')
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/UserPackageInfosLiveData.kt42
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/v34/LightInstallSourceInfoLiveData.kt8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/v34/SafetyLabelInfoLiveData.kt6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/LightInstallSourceInfo.kt45
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/SafetyLabelInfo.kt14
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java5
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/service/v34/SafetyLabelChangesJobService.kt10
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java52
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt13
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/v34/PermissionRationaleViewModel.kt15
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/v34/PermissionRationaleActivity.java28
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/v31/AdminRestrictedPermissionsUtils.java31
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardPreference.java2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt12
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java1
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterScrollWrapperFragment.kt24
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterSubpageFragment.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java28
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SpacerPreference.kt129
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetylabel/SafetyLabelChangedBroadcastReceiver.kt13
22 files changed, 337 insertions, 153 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/UserPackageInfosLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/UserPackageInfosLiveData.kt
index 36586e7cc..02285809c 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/UserPackageInfosLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/UserPackageInfosLiveData.kt
@@ -18,9 +18,13 @@
package com.android.permissioncontroller.permission.data
import android.app.Application
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.GET_ATTRIBUTIONS
+import android.content.pm.PackageManager.GET_ATTRIBUTIONS_LONG
import android.content.pm.PackageManager.GET_PERMISSIONS
import android.content.pm.PackageManager.MATCH_ALL
import android.os.UserHandle
+import com.android.modules.utils.build.SdkLevel
import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo
import kotlinx.coroutines.Job
@@ -31,16 +35,13 @@ import kotlinx.coroutines.Job
* @param app The current application
* @param user The user whose packages are desired
*/
-class UserPackageInfosLiveData private constructor(
- private val app: Application,
- private val user: UserHandle
-) : SmartAsyncMediatorLiveData<@kotlin.jvm.JvmSuppressWildcards List<LightPackageInfo>>(),
+class UserPackageInfosLiveData
+private constructor(private val app: Application, private val user: UserHandle) :
+ SmartAsyncMediatorLiveData<@JvmSuppressWildcards List<LightPackageInfo>>(),
PackageBroadcastReceiver.PackageBroadcastListener,
PermissionListenerMultiplexer.PermissionChangeCallback {
- /**
- * Whether or not the permissions in this liveData are out of date
- */
+ /** Whether or not the permissions in this liveData are out of date */
var permChangeStale = false
override fun onPackageUpdate(packageName: String) {
@@ -68,15 +69,29 @@ class UserPackageInfosLiveData private constructor(
permChangeStale = false
}
- /**
- * Get all of the packages in the system, organized by user.
- */
+ /** Get all of the packages in the system, organized by user. */
override suspend fun loadDataAndPostValue(job: Job) {
if (job.isCancelled) {
return
}
- val packageInfos = app.applicationContext.packageManager
- .getInstalledPackagesAsUser(GET_PERMISSIONS or MATCH_ALL, user.identifier)
+
+ val packageInfos =
+ if (SdkLevel.isAtLeastU()) {
+ app.applicationContext.packageManager.getInstalledPackagesAsUser(
+ PackageManager.PackageInfoFlags.of(
+ GET_PERMISSIONS.toLong() or GET_ATTRIBUTIONS_LONG or MATCH_ALL.toLong()
+ ),
+ user.identifier
+ )
+ } else if (SdkLevel.isAtLeastS()) {
+ app.applicationContext.packageManager.getInstalledPackagesAsUser(
+ GET_PERMISSIONS or GET_ATTRIBUTIONS or MATCH_ALL, user.identifier
+ )
+ } else {
+ app.applicationContext.packageManager.getInstalledPackagesAsUser(
+ GET_PERMISSIONS or MATCH_ALL, user.identifier
+ )
+ }
postValue(packageInfos.map { packageInfo -> LightPackageInfo(packageInfo) })
}
@@ -103,6 +118,7 @@ class UserPackageInfosLiveData private constructor(
/**
* Repository for UserPackageInfosLiveDatas.
+ *
* <p> Key value is a UserHandle, value is its corresponding LiveData.
*/
companion object : DataRepository<UserHandle, UserPackageInfosLiveData>() {
@@ -110,4 +126,4 @@ class UserPackageInfosLiveData private constructor(
return UserPackageInfosLiveData(PermissionControllerApplication.get(), key)
}
}
-} \ No newline at end of file
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/v34/LightInstallSourceInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/v34/LightInstallSourceInfoLiveData.kt
index 8957ea0a9..bbc62dfc9 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/v34/LightInstallSourceInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/v34/LightInstallSourceInfoLiveData.kt
@@ -27,7 +27,7 @@ import com.android.permissioncontroller.permission.data.DataRepositoryForPackage
import com.android.permissioncontroller.permission.data.PackageBroadcastReceiver
import com.android.permissioncontroller.permission.data.SmartAsyncMediatorLiveData
import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo
-import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo.Companion.UNKNOWN_INSTALL_SOURCE
+import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo.Companion.INSTALL_SOURCE_UNAVAILABLE
import kotlinx.coroutines.Job
/**
@@ -73,12 +73,12 @@ private constructor(
val lightInstallSourceInfo: LightInstallSourceInfo =
try {
val installSourceInfo = getInstallSourceInfo(packageName)
- LightInstallSourceInfo(installSourceInfo.initiatingPackageName,
- installSourceInfo.packageSource)
+ LightInstallSourceInfo(
+ installSourceInfo.packageSource, installSourceInfo.initiatingPackageName)
} catch (e: PackageManager.NameNotFoundException) {
Log.w(LOG_TAG, "InstallSourceInfo for $packageName not found")
invalidateSingle(packageName to user)
- UNKNOWN_INSTALL_SOURCE
+ INSTALL_SOURCE_UNAVAILABLE
}
postValue(lightInstallSourceInfo)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/v34/SafetyLabelInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/v34/SafetyLabelInfoLiveData.kt
index 9fd6e3bdd..6229218d4 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/v34/SafetyLabelInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/v34/SafetyLabelInfoLiveData.kt
@@ -82,10 +82,8 @@ private constructor(
return
}
- // TODO(b/261607291): Add support for preinstall apps that provide SafetyLabel. Initiating
- // package is null until updated from an app store
val lightInstallSourceInfo = lightInstallSourceInfoLiveData.value
- if (lightInstallSourceInfo?.isStoreInstalled() != true) {
+ if (lightInstallSourceInfo?.supportsSafetyLabel != true) {
postValue(SafetyLabelInfo.UNAVAILABLE)
return
}
@@ -94,7 +92,7 @@ private constructor(
try {
val safetyLabel: SafetyLabel? = getSafetyLabel(packageName, user)
if (safetyLabel != null) {
- SafetyLabelInfo(safetyLabel, lightInstallSourceInfo.initiatingPackageName)
+ SafetyLabelInfo(safetyLabel, lightInstallSourceInfo)
} else {
SafetyLabelInfo.UNAVAILABLE
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/LightInstallSourceInfo.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/LightInstallSourceInfo.kt
index 8be6054e5..e75c1eadf 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/LightInstallSourceInfo.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/LightInstallSourceInfo.kt
@@ -16,37 +16,46 @@
package com.android.permissioncontroller.permission.model.livedatatypes.v34
-import android.content.pm.PackageInstaller
import android.content.pm.PackageInstaller.PACKAGE_SOURCE_STORE
import android.content.pm.PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED
/**
* A lighter version of the system's InstallSourceInfo class, containing select information about
* the install source.
- *
- * @param initiatingPackageName The package name of the install source (usually the app store)
- * @param packageSource Indicates the package source of the app [PackageInstaller.PackageSourceType]
*/
-data class LightInstallSourceInfo(
- val initiatingPackageName: String?,
- private val packageSource: Int
-) {
- /** Return {@code true} if package considered to be installed by a store */
- fun isStoreInstalled(): Boolean {
+class LightInstallSourceInfo {
+ private constructor() {
+ initiatingPackageName = null
+ isPreloadedApp = false
+ supportsSafetyLabel = false
+ }
+
+ constructor(packageSource: Int, initiatingPackage: String?) {
+ initiatingPackageName = initiatingPackage
// Stores should be setting PACKAGE_SOURCE_STORE, but it's not enforced. So include the
// default source of unspecified. All other sources should be explicitly set to another
// PACKAGE_SOURCE_ value
- return initiatingPackageName != null &&
- (packageSource == PACKAGE_SOURCE_STORE ||
- packageSource == PACKAGE_SOURCE_UNSPECIFIED)
- }
+ val isStoreInstalled =
+ initiatingPackageName != null &&
+ (packageSource == PACKAGE_SOURCE_STORE ||
+ packageSource == PACKAGE_SOURCE_UNSPECIFIED)
- /** Return {@code true} if package considered to be provided as a preloaded app */
- fun isPreloadedApp(): Boolean {
- return initiatingPackageName == null && packageSource == PACKAGE_SOURCE_UNSPECIFIED
+ isPreloadedApp = initiatingPackageName == null &&
+ packageSource == PACKAGE_SOURCE_UNSPECIFIED
+ supportsSafetyLabel = isStoreInstalled || isPreloadedApp
}
+ /** The package name of the install source (usually the app store) */
+ val initiatingPackageName: String?
+
+ /** Whether packages from this install source support safety labels. */
+ val supportsSafetyLabel: Boolean
+
+ /** Whether this install source indicates that the package was preloaded onto the device. */
+ val isPreloadedApp: Boolean
+
companion object {
- val UNKNOWN_INSTALL_SOURCE = LightInstallSourceInfo(null, PACKAGE_SOURCE_UNSPECIFIED)
+ /** Indicates an unavailable install source. */
+ val INSTALL_SOURCE_UNAVAILABLE = LightInstallSourceInfo()
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/SafetyLabelInfo.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/SafetyLabelInfo.kt
index d1a2e3f25..7128e3069 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/SafetyLabelInfo.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v34/SafetyLabelInfo.kt
@@ -17,18 +17,20 @@
package com.android.permissioncontroller.permission.model.livedatatypes.v34
import com.android.permission.safetylabel.SafetyLabel
+import com.android.permissioncontroller.permission.model.livedatatypes.v34.LightInstallSourceInfo.Companion.INSTALL_SOURCE_UNAVAILABLE
/**
* A wrapping class for [SafetyLabel] class that includes the install source package name
*
- * @param safetyLabel The resulting [SafetyLabel], or null if none found
- * @param installSourcePackageName The package name of the install source for the APK and safety
- * label(usually the app store)
+ * @param safetyLabel the resulting [SafetyLabel], or null if none found
+ * @param installSourceInfo the install source information for the package
*/
-class SafetyLabelInfo(val safetyLabel: SafetyLabel?, val installSourcePackageName: String?) {
-
+class SafetyLabelInfo(
+ val safetyLabel: SafetyLabel?,
+ val installSourceInfo: LightInstallSourceInfo
+ ) {
companion object {
/** Default definition of unavailable or no safety label found */
- val UNAVAILABLE = SafetyLabelInfo(null, null)
+ val UNAVAILABLE = SafetyLabelInfo(null, INSTALL_SOURCE_UNAVAILABLE)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java b/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java
index 001520c1b..d5c43335c 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java
@@ -547,8 +547,6 @@ public final class PermissionControllerServiceImpl extends PermissionControllerL
final boolean isManagedProfile = getSystemService(UserManager.class).isManagedProfile();
DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
- final boolean isOrganizationOwnedDevice = dpm.isOrganizationOwnedDeviceWithManagedProfile();
-
int numPerms = expandedPermissions.size();
for (int i = 0; i < numPerms; i++) {
String permName = expandedPermissions.get(i);
@@ -565,8 +563,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerL
switch (grantState) {
case PERMISSION_GRANT_STATE_GRANTED:
if (AdminRestrictedPermissionsUtils.mayAdminGrantPermission(perm.getName(),
- canAdminGrantSensorsPermissions, isManagedProfile,
- isOrganizationOwnedDevice)) {
+ canAdminGrantSensorsPermissions, isManagedProfile, dpm)) {
perm.setPolicyFixed(true);
group.grantRuntimePermissions(false, false, new String[]{permName});
autoGrantPermissionsNotifier.onPermissionAutoGranted(permName);
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/v34/SafetyLabelChangesJobService.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/v34/SafetyLabelChangesJobService.kt
index 98c5fc975..9231dc17b 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/service/v34/SafetyLabelChangesJobService.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/service/v34/SafetyLabelChangesJobService.kt
@@ -420,7 +420,7 @@ class SafetyLabelChangesJobService : JobService() {
private suspend fun getAllStoreInstalledPackagesRequestingLocation():
Set<Pair<String, UserHandle>> =
getAllPackagesRequestingLocation()
- .filter { isStoreInstalledPackage(it) }
+ .filter { isSafetyLabelSupported(it) }
.toSet()
private suspend fun getAllPackagesRequestingLocation(): Set<Pair<String, UserHandle>> =
@@ -437,12 +437,10 @@ class SafetyLabelChangesJobService : JobService() {
private fun AppPermGroupUiInfo.isPermissionGranted() =
permGrantState in setOf(PERMS_ALLOWED_ALWAYS, PERMS_ALLOWED_FOREGROUND_ONLY)
- private suspend fun isStoreInstalledPackage(
- pkg: Pair<String, UserHandle>
- ): Boolean {
+ private suspend fun isSafetyLabelSupported(packageUser: Pair<String, UserHandle>): Boolean {
val lightInstallSourceInfo =
- LightInstallSourceInfoLiveData[pkg].getInitializedValue()
- return lightInstallSourceInfo.isStoreInstalled()
+ LightInstallSourceInfoLiveData[packageUser].getInitializedValue()
+ return lightInstallSourceInfo.supportsSafetyLabel
}
private suspend fun postSafetyLabelChangedNotification() {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java
index 1f1bf1056..cb6d21aec 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java
@@ -32,8 +32,10 @@ import static com.android.permissioncontroller.PermissionControllerStatsLog.PERM
import android.Manifest;
import android.app.ActionBar;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.Bundle;
@@ -81,6 +83,7 @@ import com.android.permissioncontroller.permission.utils.KotlinUtils;
import com.android.permissioncontroller.permission.utils.PermissionMapping;
import com.android.permissioncontroller.permission.utils.Utils;
+import java.util.Objects;
import java.util.Random;
/**
@@ -123,12 +126,24 @@ public final class ManagePermissionsActivity extends SettingsActivity {
+ ".permissioncontroller.extra.SHOW_7_DAYS";
/**
+ * Name of the aliased activity.
+ */
+ public static final String ALIAS_ACTIVITY_NAME =
+ "com.android.permissioncontroller.permission.ui.ManagePermissionsActivityAlias";
+
+ /**
* The requestCode used when we decide not to use this activity, but instead launch
* another activity in our place. When that activity finishes, we set it's result
* as our result and then finish.
*/
private static final int PROXY_ACTIVITY_REQUEST_CODE = 5;
+ private static final String LAUNCH_PERMISSION_SETTINGS =
+ "android.permission.LAUNCH_PERMISSION_SETTINGS";
+
+ private static final String APP_PERMISSIONS_SETTINGS =
+ "android.settings.APP_PERMISSIONS_SETTINGS";
+
@Override
public void onCreate(Bundle savedInstanceState) {
if (DeviceUtils.isAuto(this)) {
@@ -170,6 +185,16 @@ public final class ManagePermissionsActivity extends SettingsActivity {
int openFromIntentAction =
APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__OPENED_FROM_INTENT;
+ ComponentName component = getIntent().getComponent();
+ if (component != null
+ && Objects.equals(component.getClassName(), ALIAS_ACTIVITY_NAME)
+ && !Objects.equals(action, APP_PERMISSIONS_SETTINGS)) {
+ Log.w(LOG_TAG, ALIAS_ACTIVITY_NAME + " can only be launched with "
+ + APP_PERMISSIONS_SETTINGS);
+ finishAfterTransition();
+ return;
+ }
+
String permissionName;
switch (action) {
case Intent.ACTION_MANAGE_PERMISSIONS:
@@ -276,7 +301,25 @@ public final class ManagePermissionsActivity extends SettingsActivity {
return;
}
- case Intent.ACTION_MANAGE_APP_PERMISSIONS: {
+ case Intent.ACTION_MANAGE_APP_PERMISSIONS:
+ case APP_PERMISSIONS_SETTINGS: {
+ if (Objects.equals(action, APP_PERMISSIONS_SETTINGS)) {
+ PermissionInfo permissionInfo;
+ try {
+ permissionInfo = getPackageManager()
+ .getPermissionInfo(LAUNCH_PERMISSION_SETTINGS, 0);
+ } catch (NameNotFoundException e) {
+ permissionInfo = null;
+ }
+ if (permissionInfo == null
+ || !Objects.equals(permissionInfo.packageName, Utils.OS_PKG)) {
+ Log.w(LOG_TAG, LAUNCH_PERMISSION_SETTINGS
+ + " must be defined by platform.");
+ finishAfterTransition();
+ return;
+ }
+ }
+
String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
if (packageName == null) {
Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME");
@@ -340,7 +383,8 @@ public final class ManagePermissionsActivity extends SettingsActivity {
setNavGraph(args, R.id.app_permission_groups);
return;
}
- } break;
+ break;
+ }
case Intent.ACTION_MANAGE_PERMISSION_APPS: {
permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
@@ -433,7 +477,9 @@ public final class ManagePermissionsActivity extends SettingsActivity {
setNavGraph(UnusedAppsFragment.createArgs(sessionId), R.id.auto_revoke);
return;
}
- } break;
+
+ break;
+ }
case PermissionManager.ACTION_REVIEW_PERMISSION_DECISIONS: {
UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
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 4e88d4c9b..24dc51bdf 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
@@ -39,6 +39,7 @@ import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP
import android.os.Build
import android.os.Bundle
import android.os.Process
+import android.os.UserManager
import android.permission.PermissionManager
import android.provider.MediaStore
import android.util.Log
@@ -1346,10 +1347,18 @@ class GrantPermissionsViewModel(
}
requestInfosLiveData.update()
}
- activity.startActivityForResult(Intent(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP)
+ // A clone profile doesn't have a MediaProvider. If this user is a clone profile, open
+ // the photo picker in the parent profile
+ val userManager = activity.getSystemService(UserManager::class.java)!!
+ val user = if (userManager.isCloneProfile) {
+ userManager.getProfileParent(Process.myUserHandle()) ?: Process.myUserHandle()
+ } else {
+ Process.myUserHandle()
+ }
+ activity.startActivityForResultAsUser(Intent(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP)
.putExtra(Intent.EXTRA_UID, packageInfo.uid)
.setType(KotlinUtils.getMimeTypeForPermissions(unfilteredAffectedPermissions)),
- PHOTO_PICKER_REQUEST_CODE)
+ PHOTO_PICKER_REQUEST_CODE, user)
}
/**
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 3fe96017a..304dc3db4 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
@@ -88,11 +88,12 @@ class PermissionRationaleViewModel(
* should be shown with it.
*/
data class PermissionRationaleInfo(
- val groupName: String,
- val installSourcePackageName: String?,
- val installSourceLabel: String?,
- val purposeSet: Set<Int>
- )
+ val groupName: String,
+ val isPreloadedApp: Boolean,
+ val installSourcePackageName: String?,
+ val installSourceLabel: String?,
+ val purposeSet: Set<Int>
+ )
/** A [LiveData] which holds the currently pending PermissionRationaleInfo */
val permissionRationaleInfoLiveData =
@@ -118,7 +119,8 @@ class PermissionRationaleViewModel(
return
}
- val installSourcePackageName = safetyLabelInfo.installSourcePackageName
+ val installSourcePackageName =
+ safetyLabelInfo.installSourceInfo.initiatingPackageName
val installSourceLabel: String? =
installSourcePackageName?.let {
KotlinUtils.getPackageLabel(app, it, Process.myUserHandle())
@@ -132,6 +134,7 @@ class PermissionRationaleViewModel(
value =
PermissionRationaleInfo(
permissionGroupName,
+ safetyLabelInfo.installSourceInfo.isPreloadedApp,
installSourcePackageName,
installSourceLabel,
purposes)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/v34/PermissionRationaleActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/v34/PermissionRationaleActivity.java
index d58dfa341..606ce8157 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/v34/PermissionRationaleActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/v34/PermissionRationaleActivity.java
@@ -353,17 +353,7 @@ public class PermissionRationaleActivity extends SettingsActivity implements
@StringRes int titleResId = getTitleResIdForPermissionGroup(mPermissionGroupName);
setTitle(titleResId);
CharSequence title = getString(titleResId);
-
- String installSourcePackageName = mPermissionRationaleInfo.getInstallSourcePackageName();
- CharSequence installSourceLabel = mPermissionRationaleInfo.getInstallSourceLabel();
- checkStringNotEmpty(installSourcePackageName,
- "installSourcePackageName cannot be null or empty");
- checkStringNotEmpty(installSourceLabel,
- "installSourceLabel cannot be null or empty");
- CharSequence dataSharingSourceMessage = createDataSharingSourceMessageWithSpans(
- getText(R.string.permission_rationale_data_sharing_source_message),
- installSourceLabel,
- getLinkToAppStore(installSourcePackageName));
+ CharSequence dataSharingSourceMessage = getDataSharingSourceMessage();
CharSequence purposeTitle =
getString(getPurposeTitleResIdForPermissionGroup(mPermissionGroupName));
@@ -418,6 +408,22 @@ public class PermissionRationaleActivity extends SettingsActivity implements
}
}
+ private CharSequence getDataSharingSourceMessage() {
+ if (mPermissionRationaleInfo.isPreloadedApp()) {
+ return getText(R.string.permission_rationale_data_sharing_device_manufacturer_message);
+ }
+
+ String installSourcePackageName = mPermissionRationaleInfo.getInstallSourcePackageName();
+ CharSequence installSourceLabel = mPermissionRationaleInfo.getInstallSourceLabel();
+ checkStringNotEmpty(installSourcePackageName,
+ "installSourcePackageName cannot be null or empty");
+ checkStringNotEmpty(installSourceLabel, "installSourceLabel cannot be null or empty");
+ return createDataSharingSourceMessageWithSpans(
+ getText(R.string.permission_rationale_data_sharing_source_message),
+ installSourceLabel,
+ getLinkToAppStore(installSourcePackageName));
+ }
+
@StringRes
private int getTitleResIdForPermissionGroup(String permissionGroupName) {
if (LOCATION.equals(permissionGroupName)) {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/v31/AdminRestrictedPermissionsUtils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/v31/AdminRestrictedPermissionsUtils.java
index 9b7927c1d..770ee6c95 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/v31/AdminRestrictedPermissionsUtils.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/v31/AdminRestrictedPermissionsUtils.java
@@ -18,13 +18,13 @@ package com.android.permissioncontroller.permission.utils.v31;
import android.Manifest;
import android.app.admin.DevicePolicyManager;
+import android.app.admin.ManagedSubscriptionsPolicy;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArraySet;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permissioncontroller.permission.utils.Utils;
/**
* A class for dealing with permissions that the admin may not grant in certain configurations.
@@ -56,16 +56,6 @@ public final class AdminRestrictedPermissionsUtils {
}
/**
- * A set of permissions that the non-organization owned managed Profile Owner cannot grant.
- */
- private static final ArraySet<String> MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS =
- new ArraySet<>();
-
- static {
- MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS.add(Manifest.permission.READ_SMS);
- }
-
- /**
* Returns true if the admin may grant this permission, false otherwise.
*/
public static boolean mayAdminGrantPermission(Context context, String permission, int userId) {
@@ -75,10 +65,8 @@ public final class AdminRestrictedPermissionsUtils {
Context userContext = context.createContextAsUser(UserHandle.of(userId), /* flags= */0);
DevicePolicyManager dpm = userContext.getSystemService(DevicePolicyManager.class);
UserManager um = userContext.getSystemService(UserManager.class);
- if (um.isManagedProfile(userId)
- && MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS.contains(permission)
- && !(SdkLevel.isAtLeastU() && dpm.isOrganizationOwnedDeviceWithManagedProfile())) {
- return false;
+ if (um.isManagedProfile(userId) && Manifest.permission.READ_SMS.equals(permission)) {
+ return mayManagedProfileAdminGrantReadSms(dpm);
}
if (!ADMIN_RESTRICTED_SENSORS_PERMISSIONS.contains(permission)) {
return true;
@@ -92,13 +80,12 @@ public final class AdminRestrictedPermissionsUtils {
*/
public static boolean mayAdminGrantPermission(String permission,
boolean canAdminGrantSensorsPermissions, boolean isManagedProfile,
- boolean isOrganizationOwnedDevice) {
+ DevicePolicyManager dpm) {
if (!SdkLevel.isAtLeastS()) {
return true;
}
- if (isManagedProfile && MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS.contains(permission)
- && !(SdkLevel.isAtLeastU() && isOrganizationOwnedDevice)) {
- return false;
+ if (isManagedProfile && Manifest.permission.READ_SMS.equals(permission)) {
+ return mayManagedProfileAdminGrantReadSms(dpm);
}
if (!ADMIN_RESTRICTED_SENSORS_PERMISSIONS.contains(permission)) {
return true;
@@ -106,4 +93,10 @@ public final class AdminRestrictedPermissionsUtils {
return canAdminGrantSensorsPermissions;
}
+
+ private static boolean mayManagedProfileAdminGrantReadSms(DevicePolicyManager dpm) {
+ return SdkLevel.isAtLeastU() && dpm.isOrganizationOwnedDeviceWithManagedProfile()
+ && dpm.getManagedSubscriptionsPolicy().getPolicyType()
+ == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS;
+ }
}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardPreference.java
index f6eaa319d..c56cce0a5 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/IssueCardPreference.java
@@ -462,7 +462,7 @@ public class IssueCardPreference extends Preference implements ComparablePrefere
public void buildAndAddToView(LinearLayout buttonList) {
MaterialButton button = new MaterialButton(mContextThemeWrapper, null, getStyle());
- if (SdkLevel.isAtLeastU()) {
+ if (SdkLevel.isAtLeastU() && !mIsLargeScreen) {
configureGroupStyleCorners(button);
}
setButtonColors(button);
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
index 68c12c767..2acd6b5a3 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/PreferenceHighlightManager.kt
@@ -74,21 +74,21 @@ internal class PreferenceHighlightManager(private val fragment: PreferenceFragme
/** Restore previously saved instance state from [Bundle] */
fun restoreState(savedInstanceState: Bundle?) {
- if (savedInstanceState == null) {
+ if (!SafetyCenterUiFlags.getShowSubpages() || savedInstanceState == null) {
return
}
- if (!SafetyCenterUiFlags.getShowSubpages()) {
- preferenceHighlighted = savedInstanceState.getBoolean(SAVE_HIGHLIGHTED_KEY, false)
- }
+ preferenceHighlighted = savedInstanceState.getBoolean(SAVE_HIGHLIGHTED_KEY, false)
}
/** Save current instance state to provided [Bundle] */
fun saveState(outState: Bundle) {
if (!SafetyCenterUiFlags.getShowSubpages()) {
- val highlightRequested = preferenceGroupAdapter?.isHighlightRequested
- highlightRequested?.let { outState.putBoolean(SAVE_HIGHLIGHTED_KEY, it) }
+ return
}
+
+ val highlightRequested = preferenceGroupAdapter?.isHighlightRequested
+ highlightRequested?.let { outState.putBoolean(SAVE_HIGHLIGHTED_KEY, it) }
}
/** Scrolls to a particular preference in the recycler view and highlights it */
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
index dd90fd559..940cb2f69 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterDashboardFragment.java
@@ -41,6 +41,7 @@ import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
+import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
@@ -65,6 +66,7 @@ public final class SafetyCenterDashboardFragment extends SafetyCenterFragment {
private static final String ISSUES_GROUP_KEY = "issues_group";
private static final String ENTRIES_GROUP_KEY = "entries_group";
private static final String STATIC_ENTRIES_GROUP_KEY = "static_entries_group";
+ private static final String SPACER_KEY = "spacer";
private SafetyStatusPreference mSafetyStatusPreference;
private final CollapsableGroupCardHelper mCollapsableGroupCardHelper =
@@ -116,6 +118,8 @@ public final class SafetyCenterDashboardFragment extends SafetyCenterFragment {
mEntriesGroup = null;
getPreferenceScreen().removePreference(mStaticEntriesGroup);
mStaticEntriesGroup = null;
+ Preference spacerPreference = getPreferenceScreen().findPreference(SPACER_KEY);
+ getPreferenceScreen().removePreference(spacerPreference);
}
getSafetyCenterViewModel().getStatusUiLiveData().observe(this, this::updateStatus);
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
index 93407b023..f69746e39 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
@@ -150,7 +150,6 @@ public class SafetyCenterQsFragment extends Fragment {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.safety_center_qs, container, false);
root.setVisibility(View.GONE);
- root.setBackgroundColor(getResources().getColor(R.color.sc_qs_background_color));
View closeButton = root.findViewById(R.id.close_button);
closeButton.setOnClickListener((v) -> requireActivity().finish());
SafetyCenterTouchTarget.configureSize(
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterScrollWrapperFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterScrollWrapperFragment.kt
index beda65ee3..c064b94f0 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterScrollWrapperFragment.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterScrollWrapperFragment.kt
@@ -24,18 +24,26 @@ import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.utils.Utils
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
-internal class SafetyCenterScrollWrapperFragment : Fragment(R.layout.safety_center_scroll_wrapper) {
+internal class SafetyCenterScrollWrapperFragment :
+ Fragment(
+ if (SafetyCenterUiFlags.getShowSubpages()) R.layout.safety_center_non_scroll_wrapper
+ else R.layout.safety_center_scroll_wrapper
+ ) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
- childFragmentManager.beginTransaction()
- .add(R.id.fragment_container,
- SafetyCenterDashboardFragment.newInstance(
- Utils.getOrGenerateSessionId(requireActivity().getIntent()),
- /* isQuickSettingsFragment= */ false))
- .commitNow()
+ childFragmentManager
+ .beginTransaction()
+ .add(
+ R.id.fragment_container,
+ SafetyCenterDashboardFragment.newInstance(
+ Utils.getOrGenerateSessionId(requireActivity().getIntent()),
+ /* isQuickSettingsFragment= */ false
+ )
+ )
+ .commitNow()
}
}
-} \ No newline at end of file
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterSubpageFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterSubpageFragment.kt
index 8625e1959..5e45d2b3c 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterSubpageFragment.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterSubpageFragment.kt
@@ -105,7 +105,9 @@ class SafetyCenterSubpageFragment : SafetyCenterFragment() {
Log.w(TAG, "$sourceGroupId doesn't have any matching footer")
subpageFooter.setVisible(false)
}
-
+ // footer is ordered last by default
+ // in order to keep a spacer after the footer, footer needs to be the second from last
+ subpageFooter.setOrder(Int.MAX_VALUE - 2)
subpageFooter.setSummary(footerText)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
index 61b36fc60..0b8706a38 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyStatusPreference.java
@@ -27,7 +27,6 @@ import android.os.Looper;
import android.safetycenter.SafetyCenterStatus;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -37,7 +36,6 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import com.android.permissioncontroller.R;
-import com.android.permissioncontroller.permission.utils.KotlinUtils;
import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterViewModel;
import com.android.permissioncontroller.safetycenter.ui.model.StatusUiData;
import com.android.permissioncontroller.safetycenter.ui.view.StatusCardView;
@@ -90,7 +88,6 @@ public class SafetyStatusPreference extends Preference implements ComparablePref
updateStatusText(statusCardView.getTitleView(), statusCardView.getSummaryView());
- configureSafetyProtectionView(statusCardView, context);
mFirstBind = false;
}
@@ -121,31 +118,6 @@ public class SafetyStatusPreference extends Preference implements ComparablePref
statusCardView.showButtons(mStatus);
}
- private void configureSafetyProtectionView(StatusCardView statusCardView, Context context) {
- View safetyProtectionSectionView =
- statusCardView.findViewById(R.id.safety_protection_section_view);
- if (KotlinUtils.INSTANCE.shouldShowSafetyProtectionResources(context)) {
- // Hide the Safety Protection branding if there are any issue cards
- safetyProtectionSectionView.setVisibility(
- mStatus.hasIssues() ? View.GONE : View.VISIBLE);
- }
- if (safetyProtectionSectionView.getVisibility() == View.GONE) {
- statusCardView.setPaddingRelative(
- statusCardView.getPaddingStart(),
- statusCardView.getPaddingTop(),
- statusCardView.getPaddingEnd(),
- /* bottom= */ getContext()
- .getResources()
- .getDimensionPixelSize(R.dimen.sc_card_margin_bottom));
- } else {
- statusCardView.setPaddingRelative(
- statusCardView.getPaddingStart(),
- statusCardView.getPaddingTop(),
- statusCardView.getPaddingEnd(),
- /* bottom= */ 0);
- }
- }
-
private void updateStatusText(TextView title, TextView summary) {
if (mFirstBind) {
title.setText(mStatus.getTitle());
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SpacerPreference.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SpacerPreference.kt
new file mode 100644
index 000000000..bb09783be
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SpacerPreference.kt
@@ -0,0 +1,129 @@
+/*
+ * 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.safetycenter.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import androidx.preference.PreferenceViewHolder
+import com.android.permissioncontroller.R
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
+import com.android.settingslib.widget.FooterPreference
+import kotlin.math.max
+
+/**
+ * A preference that adds an empty space to the bottom of a Safety Center subpage.
+ *
+ * Due to the logic of [CollapsingToolbarBaseActivity], its content won't be scrollable if it fits
+ * the single page. This logic conflicts with the UX of collapsible and expandable items of Safety
+ * Center, and with some other use cases (i.e. opening the page from Search might scroll to bottom
+ * while the scroll is disabled). In such cases user won't be able to expand the collapsed toolbar
+ * by scrolling the screen content.
+ *
+ * [SpacerPreference] makes the page to be slightly bigger than the screen size to unlock the scroll
+ * regardless of the content length and to mitigate this UX problem.
+ *
+ * If a [FooterPreference] is added to the same [PreferenceScreen], its order should be decreased to
+ * keep it with the last visible content above the [SpacerPreference].
+ */
+internal class SpacerPreference(context: Context, attrs: AttributeSet) :
+ Preference(context, attrs) {
+
+ init {
+ setLayoutResource(R.layout.preference_spacer)
+ isVisible = SafetyCenterUiFlags.getShowSubpages()
+ // spacer should be the last item on screen
+ setOrder(Int.MAX_VALUE - 1)
+ }
+
+ private var maxKnownToolbarHeight = 0
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
+ super.onBindViewHolder(holder)
+ val spacer = holder.itemView
+
+ // we should ensure we won't add multiple listeners to the same view,
+ // and Preferences API does not allow to do cleanups when onViewRecycled,
+ // so we are keeping a track of the added listener attaching it as a tag to the View
+ val listener: View.OnLayoutChangeListener = spacer.tag as? View.OnLayoutChangeListener
+ ?: object : View.OnLayoutChangeListener {
+ override fun onLayoutChange(
+ v: View?,
+ left: Int,
+ top: Int,
+ right: Int,
+ bottom: Int,
+ oldLeft: Int,
+ oldTop: Int,
+ oldRight: Int,
+ oldBottom: Int
+ ) {
+ adjustHeight(spacer)
+ }}.also { spacer.tag = it }
+
+ spacer.removeOnLayoutChangeListener(listener)
+ spacer.addOnLayoutChangeListener(listener)
+ }
+
+ private fun adjustHeight(spacer: View) {
+ val root = spacer.rootView as? ViewGroup
+ if (root == null) {
+ return
+ }
+
+ val contentParent = root.findViewById<ViewGroup>(R.id.content_parent)
+ if (contentParent == null) {
+ return
+ }
+ // when opening the Subpage from Search the layout pass may be triggered
+ // differently due to the auto-scroll to highlight a specific item,
+ // and in this case we need to wait the content parent to be measured
+ if (contentParent.height == 0) {
+ val globalLayoutObserver = object : ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ contentParent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+ adjustHeight(spacer)
+ }
+ }
+ contentParent.viewTreeObserver.addOnGlobalLayoutListener(globalLayoutObserver)
+ return
+ }
+
+ val collapsingToolbar = root.findViewById<View>(R.id.collapsing_toolbar)
+ maxKnownToolbarHeight = max(maxKnownToolbarHeight, collapsingToolbar.height)
+
+ val contentHeight = spacer.top + maxKnownToolbarHeight
+ val desiredSpacerHeight = if (contentHeight > contentParent.height) {
+ // making it 0 height will remove if from recyclerview
+ 1
+ } else {
+ // to unlock the scrolling we need spacer to go slightly beyond the screen
+ contentParent.height - contentHeight + 1
+ }
+
+ val layoutParams = spacer.layoutParams
+ if (layoutParams.height != desiredSpacerHeight) {
+ layoutParams.height = desiredSpacerHeight
+ spacer.layoutParams = layoutParams
+ // need to let RecyclerView to update scroll position
+ spacer.post(::notifyChanged)
+ }
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
index 000f773ee..013f32c85 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/StatusCardView.kt
@@ -25,7 +25,6 @@ import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
import com.android.permissioncontroller.R
-import com.android.permissioncontroller.permission.ui.v33.widget.SafetyProtectionSectionView
import com.android.permissioncontroller.safetycenter.ui.model.StatusUiData
import com.google.android.material.button.MaterialButton
@@ -51,9 +50,6 @@ constructor(
val summaryView: TextView by lazy { findViewById(R.id.status_summary) }
val reviewSettingsButton: MaterialButton by lazy { findViewById(R.id.review_settings_button) }
val rescanButton: MaterialButton by lazy { findViewById(R.id.rescan_button) }
- val safetyProtectionSectionView: SafetyProtectionSectionView by lazy {
- findViewById(R.id.safety_protection_section_view)
- }
fun showButtons(statusUiData: StatusUiData) {
rescanButton.isEnabled = !statusUiData.isRefreshInProgress
diff --git a/PermissionController/src/com/android/permissioncontroller/safetylabel/SafetyLabelChangedBroadcastReceiver.kt b/PermissionController/src/com/android/permissioncontroller/safetylabel/SafetyLabelChangedBroadcastReceiver.kt
index cc9487210..99f4adb02 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetylabel/SafetyLabelChangedBroadcastReceiver.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetylabel/SafetyLabelChangedBroadcastReceiver.kt
@@ -30,8 +30,8 @@ import android.util.Log
import androidx.annotation.MainThread
import androidx.annotation.RequiresApi
import com.android.permission.safetylabel.SafetyLabel as AppMetadataSafetyLabel
-import com.android.permissioncontroller.permission.data.v34.LightInstallSourceInfoLiveData
import com.android.permissioncontroller.permission.data.LightPackageInfoLiveData
+import com.android.permissioncontroller.permission.data.v34.LightInstallSourceInfoLiveData
import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.PermissionMapping
@@ -104,9 +104,8 @@ class SafetyLabelChangedBroadcastReceiver : BroadcastReceiver() {
if (!isAppRequestingLocationPermission(lightPackageInfo)) {
return
}
- // TODO(b/261607291): Enable safety label change notifications feature for
- // preinstalled apps.
- if (!isStoreInstalledPackage(Pair(packageName, user))) {
+
+ if (!isSafetyLabelSupported(Pair(packageName, user))) {
return
}
writeSafetyLabel(context, lightPackageInfo, user)
@@ -188,12 +187,10 @@ class SafetyLabelChangedBroadcastReceiver : BroadcastReceiver() {
return lightPackageInfo.requestedPermissions.any { LOCATION_PERMISSIONS.contains(it) }
}
- private suspend fun isStoreInstalledPackage(
- packageUser: Pair<String, UserHandle>
- ): Boolean {
+ private suspend fun isSafetyLabelSupported(packageUser: Pair<String, UserHandle>): Boolean {
val lightInstallSourceInfo =
LightInstallSourceInfoLiveData[packageUser].getInitializedValue()
- return lightInstallSourceInfo.isStoreInstalled()
+ return lightInstallSourceInfo.supportsSafetyLabel
}
private fun isPackageAddedBroadcast(intentAction: String?) =