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. |