Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a35c847 authored by Xiang Wang's avatar Xiang Wang Committed by Android (Google) Code Review
Browse files

Merge "Make SensorPrivacyManager and SensorPrivacyService concurrent multi user aware" into main

parents e785842d 7c4da90c
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -104,6 +104,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;
@@ -707,8 +708,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,
+5 −3
Original line number Diff line number Diff line
@@ -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());
    }

    /**
+62 −3
Original line number Diff line number Diff line
@@ -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,16 +382,25 @@ 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)) {
                if (isValidCallingUser(userId)) {
                    setToggleSensorPrivacyUnchecked(TOGGLE_TYPE_SOFTWARE, userId, OTHER, MICROPHONE,
                            false);
                }
            }
        }

        @Override
        public void onOpStarted(int code, int uid, String packageName, String attributionTag,
@@ -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.