diff --git a/core/api/current.txt b/core/api/current.txt index a9df1a4ab1b37..5d9460fe95e07 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -31982,6 +31982,7 @@ package android.os { field public static final String DISALLOW_AUTOFILL = "no_autofill"; field public static final String DISALLOW_BLUETOOTH = "no_bluetooth"; field public static final String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing"; + field public static final String DISALLOW_CAMERA_TOGGLE = "disallow_camera_toggle"; field public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth"; field public static final String DISALLOW_CONFIG_BRIGHTNESS = "no_config_brightness"; field public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts"; @@ -32006,6 +32007,7 @@ package android.os { field public static final String DISALLOW_INSTALL_APPS = "no_install_apps"; field public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources"; field public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY = "no_install_unknown_sources_globally"; + field public static final String DISALLOW_MICROPHONE_TOGGLE = "disallow_microphone_toggle"; field public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts"; field public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media"; field public static final String DISALLOW_NETWORK_RESET = "no_network_reset"; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 326012d7142a1..224cd84bc777a 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1285,6 +1285,40 @@ public class UserManager { public static final String DISALLOW_CONFIG_PRIVATE_DNS = "disallow_config_private_dns"; + /** + * Specifies whether the microphone toggle is available to the user. If this restriction is set, + * the user will not be able to block microphone access via the system toggle. If microphone + * access is blocked when the restriction is added, it will be automatically re-enabled. + * + * This restriction can only be set by a device owner. + * + *

The default value is false. + * + * @see android.hardware.SensorPrivacyManager + * @see DevicePolicyManager#addUserRestriction(ComponentName, String) + * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) + * @see #getUserRestrictions() + */ + public static final String DISALLOW_MICROPHONE_TOGGLE = + "disallow_microphone_toggle"; + + /** + * Specifies whether the camera toggle is available to the user. If this restriction is set, + * the user will not be able to block camera access via the system toggle. If camera + * access is blocked when the restriction is added, it will be automatically re-enabled. + * + * This restriction can only be set by a device owner. + * + *

The default value is false. + * + * @see android.hardware.SensorPrivacyManager + * @see DevicePolicyManager#addUserRestriction(ComponentName, String) + * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) + * @see #getUserRestrictions() + */ + public static final String DISALLOW_CAMERA_TOGGLE = + "disallow_camera_toggle"; + /** * Application restriction key that is used to indicate the pending arrival * of real restrictions for the app. @@ -1376,6 +1410,8 @@ public class UserManager { DISALLOW_SHARE_INTO_MANAGED_PROFILE, DISALLOW_PRINTING, DISALLOW_CONFIG_PRIVATE_DNS, + DISALLOW_MICROPHONE_TOGGLE, + DISALLOW_CAMERA_TOGGLE, KEY_RESTRICTIONS_PENDING, }) @Retention(RetentionPolicy.SOURCE) diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index ca59ce3acac78..74840c86c7e95 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -61,6 +61,7 @@ import android.hardware.ISensorPrivacyManager; import android.hardware.SensorPrivacyManager; import android.hardware.SensorPrivacyManagerInternal; import android.os.Binder; +import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.IBinder; @@ -72,6 +73,7 @@ import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; import android.service.SensorPrivacyIndividualEnabledSensorProto; import android.service.SensorPrivacyServiceDumpProto; @@ -193,7 +195,7 @@ public final class SensorPrivacyService extends SystemService { class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements AppOpsManager.OnOpNotedListener, AppOpsManager.OnOpStartedListener, - IBinder.DeathRecipient { + IBinder.DeathRecipient, UserManagerInternal.UserRestrictionsListener { private final SensorPrivacyHandler mHandler; private final Object mLock = new Object(); @@ -280,6 +282,21 @@ public final class SensorPrivacyService extends SystemService { } }, new IntentFilter(ACTION_DISABLE_INDIVIDUAL_SENSOR_PRIVACY), MANAGE_SENSOR_PRIVACY, null); + mUserManagerInternal.addUserRestrictionsListener(this); + } + + @Override + public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, + Bundle prevRestrictions) { + // Reset sensor privacy when restriction is added + if (!prevRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE) + && newRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)) { + setIndividualSensorPrivacyUnchecked(userId, CAMERA, false); + } + if (!prevRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE) + && newRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)) { + setIndividualSensorPrivacyUnchecked(userId, MICROPHONE, false); + } } @Override @@ -608,6 +625,17 @@ public final class SensorPrivacyService extends SystemService { return false; } + if (sensor == MICROPHONE && mUserManagerInternal.getUserRestriction(userId, + UserManager.DISALLOW_MICROPHONE_TOGGLE)) { + Log.i(TAG, "Can't change mic toggle due to admin restriction"); + return false; + } + + if (sensor == CAMERA && mUserManagerInternal.getUserRestriction(userId, + UserManager.DISALLOW_CAMERA_TOGGLE)) { + Log.i(TAG, "Can't change camera toggle due to admin restriction"); + return false; + } return true; } diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index ff90043bec942..3a1ffe16066e5 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -138,7 +138,9 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_AMBIENT_DISPLAY, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT, UserManager.DISALLOW_PRINTING, - UserManager.DISALLOW_CONFIG_PRIVATE_DNS + UserManager.DISALLOW_CONFIG_PRIVATE_DNS, + UserManager.DISALLOW_MICROPHONE_TOGGLE, + UserManager.DISALLOW_CAMERA_TOGGLE }); public static final Set DEPRECATED_USER_RESTRICTIONS = Sets.newArraySet( @@ -180,7 +182,9 @@ public class UserRestrictionsUtils { */ private static final Set DEVICE_OWNER_ONLY_RESTRICTIONS = Sets.newArraySet( UserManager.DISALLOW_USER_SWITCH, - UserManager.DISALLOW_CONFIG_PRIVATE_DNS + UserManager.DISALLOW_CONFIG_PRIVATE_DNS, + UserManager.DISALLOW_MICROPHONE_TOGGLE, + UserManager.DISALLOW_CAMERA_TOGGLE ); /**