summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiulio Fiscella <fiscella@google.com>2023-01-24 18:08:06 +0000
committerGiulio Fiscella <fiscella@google.com>2023-01-25 14:08:45 +0000
commita89cb6b277c35e203677475c334f1a514936d4c3 (patch)
tree64e494efb5abfe8c198db14c116c9594b0d73868
parentccb3bf318c4747e35519ce7f9a547bfb0346b7cc (diff)
downloadPermission-a89cb6b277c35e203677475c334f1a514936d4c3.tar.gz
Fix toggles when disallowed by admin
Copy the same behaviour used by top level tiles: - Still display the toggle but with a different style so that the user knows the current state of the sensor. - Show a dialog to explain that the toggle is disabled by the device owner when tapping on the toggle. Relnote: Fix Safety Center quick setting toggles when disallowed by admin Bug: 263364047 Test: manual Change-Id: Ib2f66f8c77cb6898a2c733d26fa6aac5fb5444d1
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java73
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterQsViewModel.kt39
2 files changed, 86 insertions, 26 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
index 4c48fbb59..e5dc3d59b 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterQsFragment.java
@@ -26,6 +26,7 @@ import static com.android.permissioncontroller.Constants.INVALID_SESSION_ID;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
@@ -64,8 +65,11 @@ import com.android.permissioncontroller.safetycenter.ui.SafetyCenterTouchTarget;
import com.android.permissioncontroller.safetycenter.ui.Sensor;
import com.android.permissioncontroller.safetycenter.ui.model.LiveSafetyCenterViewModelFactory;
import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterQsViewModel;
+import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterQsViewModel.SensorState;
import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterQsViewModelFactory;
import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterViewModel;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.google.android.material.button.MaterialButton;
@@ -562,7 +566,7 @@ public class SafetyCenterQsFragment extends Fragment {
return layered;
}
- private void setSensorToggleState(Map<String, Boolean> sensorState, View rootView) {
+ private void setSensorToggleState(Map<String, SensorState> sensorStates, View rootView) {
if (rootView == null) {
if (getView() == null) {
return;
@@ -573,23 +577,36 @@ public class SafetyCenterQsFragment extends Fragment {
}
}
- if (sensorState == null) {
- sensorState = new ArrayMap<>();
+ if (sensorStates == null) {
+ sensorStates = new ArrayMap<>();
}
for (int i = 0; i < sToggleButtons.size(); i++) {
View toggle = rootView.findViewById(sToggleButtons.valueAt(i));
String groupName = sToggleButtons.keyAt(i);
+ EnforcedAdmin admin =
+ sensorStates.containsKey(groupName)
+ ? sensorStates.get(groupName).getAdmin()
+ : null;
+ boolean sensorBlockedByAdmin = admin != null;
if (!toggle.hasOnClickListeners()) {
- toggle.setOnClickListener(
- (v) -> {
- mViewModel.toggleSensor(groupName);
- mSafetyCenterViewModel
- .getInteractionLogger()
- .recordForSensor(
- Action.PRIVACY_CONTROL_TOGGLE_CLICKED,
- Sensor.fromPermissionGroupName(groupName));
- });
+ if (sensorBlockedByAdmin) {
+ toggle.setOnClickListener(
+ (v) ->
+ startActivity(
+ RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+ mContext, admin)));
+ } else {
+ toggle.setOnClickListener(
+ (v) -> {
+ mViewModel.toggleSensor(groupName);
+ mSafetyCenterViewModel
+ .getInteractionLogger()
+ .recordForSensor(
+ Action.PRIVACY_CONTROL_TOGGLE_CLICKED,
+ Sensor.fromPermissionGroupName(groupName));
+ });
+ }
}
TextView groupLabel = toggle.findViewById(R.id.toggle_sensor_name);
@@ -601,16 +618,21 @@ public class SafetyCenterQsFragment extends Fragment {
blockedStatus.setSelected(true);
ImageView iconView = toggle.findViewById(R.id.toggle_sensor_icon);
boolean sensorEnabled =
- !sensorState.containsKey(groupName) || sensorState.get(groupName);
+ !sensorStates.containsKey(groupName)
+ || sensorStates.get(groupName).getEnabled();
Drawable icon;
- int colorPrimary = getTextColor(true, sensorEnabled);
- int colorSecondary = getTextColor(false, sensorEnabled);
- if (sensorEnabled) {
+ boolean useEnabledBackground = sensorEnabled && !sensorBlockedByAdmin;
+ int colorPrimary = getTextColor(true, useEnabledBackground, sensorBlockedByAdmin);
+ int colorSecondary = getTextColor(false, useEnabledBackground, sensorBlockedByAdmin);
+ if (useEnabledBackground) {
toggle.setBackgroundResource(R.drawable.safety_center_sensor_toggle_enabled);
- icon = KotlinUtils.INSTANCE.getPermGroupIcon(mContext, groupName, colorPrimary);
} else {
toggle.setBackgroundResource(R.drawable.safety_center_sensor_toggle_disabled);
+ }
+ if (sensorEnabled) {
+ icon = KotlinUtils.INSTANCE.getPermGroupIcon(mContext, groupName, colorPrimary);
+ } else {
icon = mContext.getDrawable(getBlockedIconResId(groupName));
icon.setTint(colorPrimary);
}
@@ -634,7 +656,7 @@ public class SafetyCenterQsFragment extends Fragment {
}
@ColorInt
- private Integer getTextColor(boolean primary, boolean inverse) {
+ private int getTextColor(boolean primary, boolean inverse, boolean useLowerOpacity) {
int primaryAttribute =
inverse ? android.R.attr.textColorPrimaryInverse : android.R.attr.textColorPrimary;
int secondaryAttribute =
@@ -645,7 +667,20 @@ public class SafetyCenterQsFragment extends Fragment {
TypedValue value = new TypedValue();
mContext.getTheme().resolveAttribute(attribute, value, true);
int colorRes = value.resourceId != 0 ? value.resourceId : value.data;
- return mContext.getColor(colorRes);
+ int color = mContext.getColor(colorRes);
+ if (useLowerOpacity) {
+ color = colorWithAdjustedAlpha(color, 0.5f);
+ }
+ return color;
+ }
+
+ @ColorInt
+ private int colorWithAdjustedAlpha(@ColorInt int color, float factor) {
+ return Color.argb(
+ Math.round(Color.alpha(color) * factor),
+ Color.red(color),
+ Color.green(color),
+ Color.blue(color));
}
private CharSequence getPermGroupLabel(String permissionGroup) {
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterQsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterQsViewModel.kt
index c7d838919..c19af8c8a 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterQsViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterQsViewModel.kt
@@ -27,10 +27,12 @@ import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.hardware.SensorPrivacyManager
import android.hardware.SensorPrivacyManager.Sensors
+import android.hardware.SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE
import android.location.LocationManager
import android.os.Build
import android.os.Process
import android.os.UserHandle
+import android.os.UserManager
import android.permission.PermissionGroupUsage
import android.provider.Settings
import androidx.annotation.RequiresApi
@@ -43,6 +45,8 @@ import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveD
import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup
import com.android.permissioncontroller.permission.utils.KotlinUtils
import com.android.permissioncontroller.permission.utils.LocationUtils
+import com.android.settingslib.RestrictedLockUtils
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
import kotlin.collections.set
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@@ -56,6 +60,7 @@ class SafetyCenterQsViewModel(
app.getSystemService(SensorPrivacyManager::class.java)!!
private val locationManager: LocationManager =
app.getSystemService(LocationManager::class.java)!!
+ private val userManager: UserManager = app.getSystemService(UserManager::class.java)!!
val lightAppPermMap = mutableMapOf<LightAppPermissionGroupUsageKey, LightAppPermGroup?>()
val revokedUsages = mutableSetOf<PermissionGroupUsage>()
@@ -149,21 +154,27 @@ class SafetyCenterQsViewModel(
fragment.startActivity(Intent(Settings.ACTION_SECURITY_SETTINGS))
}
- val sensorPrivacyLiveData: SmartUpdateMediatorLiveData<Map<String, Boolean>> =
+ data class SensorState(val enabled: Boolean, val admin: EnforcedAdmin?)
+
+ val sensorPrivacyLiveData: SmartUpdateMediatorLiveData<Map<String, SensorState>> =
object :
- SmartUpdateMediatorLiveData<Map<String, Boolean>>(),
+ SmartUpdateMediatorLiveData<Map<String, SensorState>>(),
SensorPrivacyManager.OnSensorPrivacyChangedListener,
LocationUtils.LocationListener {
override fun onUpdate() {
- val cameraEnabled = !sensorPrivacyManager.isSensorPrivacyEnabled(Sensors.CAMERA)
- val micEnabled = !sensorPrivacyManager.isSensorPrivacyEnabled(Sensors.MICROPHONE)
val locationEnabled =
locationManager.isLocationEnabledForUser(Process.myUserHandle())
+ val locationEnforcedAdmin =
+ getEnforcedAdmin(UserManager.DISALLOW_SHARE_LOCATION)
+ ?: getEnforcedAdmin(UserManager.DISALLOW_CONFIG_LOCATION)
value =
mapOf(
- CAMERA to cameraEnabled,
- MICROPHONE to micEnabled,
- LOCATION to locationEnabled)
+ CAMERA to
+ getSensorState(Sensors.CAMERA, UserManager.DISALLOW_CAMERA_TOGGLE),
+ MICROPHONE to
+ getSensorState(
+ Sensors.MICROPHONE, UserManager.DISALLOW_MICROPHONE_TOGGLE),
+ LOCATION to SensorState(locationEnabled, locationEnforcedAdmin))
}
override fun onSensorPrivacyChanged(sensor: Int, enabled: Boolean) {
@@ -190,6 +201,20 @@ class SafetyCenterQsViewModel(
}
}
+ private fun getSensorState(sensor: Int, restriction: String) =
+ SensorState(
+ !sensorPrivacyManager.isSensorPrivacyEnabled(TOGGLE_TYPE_SOFTWARE, sensor),
+ getEnforcedAdmin(restriction))
+
+ private fun getEnforcedAdmin(restriction: String) =
+ if (userManager
+ .getUserRestrictionSources(restriction, Process.myUserHandle())
+ .isNotEmpty()) {
+ RestrictedLockUtils.getProfileOrDeviceOwner(app, Process.myUserHandle())
+ } else {
+ null
+ }
+
fun navigateToManageService(fragment: Fragment, navigationIntent: Intent) {
fragment.startActivity(navigationIntent)
}