diff options
3 files changed, 74 insertions, 8 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index cb38cf297cf6..f315772a4eed 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -101,6 +101,7 @@ import android.debug.IAdbManager; import android.devicelock.DeviceLockFrameworkInitializer; import android.graphics.fonts.FontManager; import android.hardware.ConsumerIrManager; +import android.hardware.ISensorPrivacyManager; import android.hardware.ISerialManager; import android.hardware.SensorManager; import android.hardware.SensorPrivacyManager; @@ -704,8 +705,12 @@ public final class SystemServiceRegistry { registerService(Context.SENSOR_PRIVACY_SERVICE, SensorPrivacyManager.class, new CachedServiceFetcher<SensorPrivacyManager>() { @Override - public SensorPrivacyManager createService(ContextImpl ctx) { - return SensorPrivacyManager.getInstance(ctx); + public SensorPrivacyManager createService(ContextImpl ctx) + throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow( + Context.SENSOR_PRIVACY_SERVICE); + return SensorPrivacyManager.getInstance( + ctx, ISensorPrivacyManager.Stub.asInterface(b)); }}); registerService(Context.STATUS_BAR_SERVICE, StatusBarManager.class, diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java index 4cdaaddd05bf..a4c0e87c965b 100644 --- a/core/java/android/hardware/SensorPrivacyManager.java +++ b/core/java/android/hardware/SensorPrivacyManager.java @@ -797,7 +797,7 @@ public final class SensorPrivacyManager { public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable) { setSensorPrivacy(resolveSourceFromCurrentContext(), sensor, enable, - UserHandle.USER_CURRENT); + mContext.getUserId()); } private @Sources.Source int resolveSourceFromCurrentContext() { @@ -837,6 +837,8 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, boolean enable) { + // TODO(b/348510106): Replace USER_CURRENT with Context user and fix any tests that may be + // affected. setSensorPrivacy(source, sensor, enable, UserHandle.USER_CURRENT); } @@ -894,7 +896,7 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacyForProfileGroup(@Sources.Source int source, @Sensors.Sensor int sensor, boolean enable) { - setSensorPrivacyForProfileGroup(source , sensor, enable, UserHandle.USER_CURRENT); + setSensorPrivacyForProfileGroup(source , sensor, enable, mContext.getUserId()); } /** @@ -950,7 +952,7 @@ public final class SensorPrivacyManager { @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) public void suppressSensorPrivacyReminders(int sensor, boolean suppress) { - suppressSensorPrivacyReminders(sensor, suppress, UserHandle.USER_CURRENT); + suppressSensorPrivacyReminders(sensor, suppress, mContext.getUserId()); } /** diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java index 06a2565da75a..81217014bafe 100644 --- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java +++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java @@ -51,6 +51,7 @@ import static android.hardware.SensorPrivacyManager.StateTypes.ENABLED_EXCEPT_AL import static android.hardware.SensorPrivacyManager.TOGGLE_TYPE_HARDWARE; import static android.hardware.SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE; import static android.os.UserHandle.USER_NULL; +import static android.os.UserHandle.getCallingUserId; import static android.service.SensorPrivacyIndividualEnabledSensorProto.UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.PRIVACY_SENSOR_TOGGLE_INTERACTION; @@ -187,6 +188,7 @@ public final class SensorPrivacyService extends SystemService { private final TelephonyManager mTelephonyManager; private final PackageManagerInternal mPackageManagerInternal; private final NotificationManager mNotificationManager; + private final UserManager mUserManager; private CameraPrivacyLightController mCameraPrivacyLightController; @@ -214,6 +216,7 @@ public final class SensorPrivacyService extends SystemService { mTelephonyManager = context.getSystemService(TelephonyManager.class); mPackageManagerInternal = getLocalService(PackageManagerInternal.class); mNotificationManager = mContext.getSystemService(NotificationManager.class); + mUserManager = context.getSystemService(UserManager.class); mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl(); for (String entry : SystemConfig.getInstance().getCameraPrivacyAllowlist()) { mCameraPrivacyAllowlist.add(entry); @@ -379,14 +382,23 @@ public final class SensorPrivacyService extends SystemService { public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions) { // Reset sensor privacy when restriction is added + // Note: isValidCallingUser needs to be called before resetting sensor privacy + // because DISALLOW_CAMERA_TOGGLE and DISALLOW_MICROPHONE_TOGGLE are applied on + // visible background users in Automotive's Multi Display configuration but we don't + // allow sensor privacy to be set on a visible background user. if (!prevRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE) && newRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)) { - setToggleSensorPrivacyUnchecked(TOGGLE_TYPE_SOFTWARE, userId, OTHER, CAMERA, false); + if (isValidCallingUser(userId)) { + setToggleSensorPrivacyUnchecked(TOGGLE_TYPE_SOFTWARE, userId, OTHER, CAMERA, + false); + } } if (!prevRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE) && newRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)) { - setToggleSensorPrivacyUnchecked(TOGGLE_TYPE_SOFTWARE, userId, OTHER, MICROPHONE, - false); + if (isValidCallingUser(userId)) { + setToggleSensorPrivacyUnchecked(TOGGLE_TYPE_SOFTWARE, userId, OTHER, MICROPHONE, + false); + } } } @@ -779,6 +791,10 @@ public final class SensorPrivacyService extends SystemService { @Override public void setSensorPrivacy(boolean enable) { enforceManageSensorPrivacyPermission(); + + // Enforce valid calling user on devices that enable visible background users. + enforceValidCallingUser(getCallingUserId()); + mSensorPrivacyStateController.setAllSensorState(enable); } @@ -795,11 +811,15 @@ public final class SensorPrivacyService extends SystemService { + " enable=" + enable + ")"); } + enforceManageSensorPrivacyPermission(); if (userId == UserHandle.USER_CURRENT) { userId = mCurrentUser; } + // Enforce valid calling user on devices that enable visible background users. + enforceValidCallingUser(userId); + if (!canChangeToggleSensorPrivacy(userId, sensor)) { return; } @@ -831,6 +851,9 @@ public final class SensorPrivacyService extends SystemService { userId = mCurrentUser; } + // Enforce valid calling user on devices that enable visible background users. + enforceValidCallingUser(userId); + if (!canChangeToggleSensorPrivacy(userId, sensor)) { return; } @@ -1151,6 +1174,42 @@ public final class SensorPrivacyService extends SystemService { }); } + // This method enforces valid calling user on devices that enable visible background users. + // Only system user or current user or the user that belongs to the same profile group + // as the current user is permitted to toggle sensor privacy. + // Visible background users are not permitted to toggle sensor privacy. + private void enforceValidCallingUser(@UserIdInt int userId) { + if (!isValidCallingUser(userId)) { + throw new SecurityException("User " + userId + + " is not permitted to toggle sensor privacy"); + } + } + + private boolean isValidCallingUser(@UserIdInt int userId) { + // Check whether visible background users are enabled. + // Visible background users are non current but can have UI access. + // The main use case for visible background users is the passenger in Automotive's + // Multi-Display configuration. + if (!UserManager.isVisibleBackgroundUsersEnabled()) { + return true; + } + + if (userId == UserHandle.USER_SYSTEM || userId == mCurrentUser) { + return true; + } + + final long ident = Binder.clearCallingIdentity(); + try { + if (mUserManager.isSameProfileGroup(userId, mCurrentUser)) { + return true; + } + } finally { + Binder.restoreCallingIdentity(ident); + } + + return false; + } + /** * Enforces the caller contains the necessary permission to change the state of sensor * privacy. |