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

Commit 4e092349 authored by Evan Severson's avatar Evan Severson Committed by Android (Google) Code Review
Browse files

Merge "Update mic/cam quicksetting toggles when user changes" into sc-dev

parents f4b27a4b 8f7f7ab9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -48,4 +48,8 @@ interface ISensorPrivacyManager {

    void suppressIndividualSensorPrivacyReminders(int userId, int sensor, IBinder token,
            boolean suppress);

    void addUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener);

    void removeUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener);
}
 No newline at end of file
+34 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -247,8 +248,7 @@ public final class SensorPrivacyManager {
    @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void addSensorPrivacyListener(@Sensors.Sensor int sensor,
            @NonNull OnSensorPrivacyChangedListener listener) {
        addSensorPrivacyListener(sensor, mContext.getUserId(), mContext.getMainExecutor(),
                listener);
        addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener);
    }

    /**
@@ -283,7 +283,25 @@ public final class SensorPrivacyManager {
    @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor,
            @NonNull OnSensorPrivacyChangedListener listener) {
        addSensorPrivacyListener(sensor, mContext.getUserId(), executor, listener);
        Pair<OnSensorPrivacyChangedListener, Integer> key = new Pair<>(listener, sensor);
        synchronized (mIndividualListeners) {
            ISensorPrivacyListener iListener = mIndividualListeners.get(key);
            if (iListener == null) {
                iListener = new ISensorPrivacyListener.Stub() {
                    @Override
                    public void onSensorPrivacyChanged(boolean enabled) {
                        executor.execute(() -> listener.onSensorPrivacyChanged(sensor, enabled));
                    }
                };
                mIndividualListeners.put(key, iListener);
            }

            try {
                mService.addUserGlobalIndividualSensorPrivacyListener(sensor, iListener);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -361,7 +379,7 @@ public final class SensorPrivacyManager {
    @SystemApi
    @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) {
        return isSensorPrivacyEnabled(sensor, mContext.getUserId());
        return isSensorPrivacyEnabled(sensor, getCurrentUserId());
    }

    /**
@@ -392,7 +410,7 @@ public final class SensorPrivacyManager {
    @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
    public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor,
            boolean enable) {
        setSensorPrivacy(source, sensor, enable, mContext.getUserId());
        setSensorPrivacy(source, sensor, enable, getCurrentUserId());
    }

    /**
@@ -428,7 +446,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, mContext.getUserId());
        setSensorPrivacyForProfileGroup(source , sensor, enable, getCurrentUserId());
    }

    /**
@@ -463,7 +481,7 @@ public final class SensorPrivacyManager {
    @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
    public void suppressSensorPrivacyReminders(int sensor,
            boolean suppress) {
        suppressSensorPrivacyReminders(sensor, suppress, mContext.getUserId());
        suppressSensorPrivacyReminders(sensor, suppress, getCurrentUserId());
    }

    /**
@@ -590,4 +608,13 @@ public final class SensorPrivacyManager {
            throw e.rethrowFromSystemServer();
        }
    }

    private int getCurrentUserId() {
        try {
            return ActivityManager.getService().getCurrentUserId();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return 0;
    }
}
+191 −53
Original line number Diff line number Diff line
@@ -232,14 +232,14 @@ public final class SensorPrivacyService extends SystemService {
    public void onUserStarting(TargetUser user) {
        if (mCurrentUser == -1) {
            mCurrentUser = user.getUserIdentifier();
            setGlobalRestriction();
            mSensorPrivacyServiceImpl.userSwitching(-1, user.getUserIdentifier());
        }
    }

    @Override
    public void onUserSwitching(TargetUser from, TargetUser to) {
        mCurrentUser = to.getUserIdentifier();
        setGlobalRestriction();
        mSensorPrivacyServiceImpl.userSwitching(from.getUserIdentifier(), to.getUserIdentifier());
    }

    class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements
@@ -897,6 +897,11 @@ public final class SensorPrivacyService extends SystemService {
        public boolean isIndividualSensorPrivacyEnabled(@UserIdInt int userId, int sensor) {
            enforceObserveSensorPrivacyPermission();
            synchronized (mLock) {
                return isIndividualSensorPrivacyEnabledLocked(userId, sensor);
            }
        }

        private boolean isIndividualSensorPrivacyEnabledLocked(int userId, int sensor) {
            SparseArray<SensorState> states = mIndividualEnabled.get(userId);
            if (states == null) {
                return false;
@@ -907,7 +912,6 @@ public final class SensorPrivacyService extends SystemService {
            }
            return state.mEnabled;
        }
        }

        /**
         * Returns the state of sensor privacy from persistent storage.
@@ -1149,11 +1153,27 @@ public final class SensorPrivacyService extends SystemService {
                ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
                throw new IllegalArgumentException("listener cannot be null");
            }
            mHandler.addListener(userId, sensor, listener);
        }


        /**
         * Registers a listener to be notified when the sensor privacy state changes. The callback
         * can be called if the user changes and the setting is different between the transitioning
         * users.
         */
        @Override
        public void addUserGlobalIndividualSensorPrivacyListener(int sensor,
                ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new IllegalArgumentException("listener cannot be null");
            }
            mHandler.addUserGlobalListener(sensor, listener);
        }

        /**
         * Unregisters a listener from sensor privacy state change notifications.
         */
@@ -1174,11 +1194,21 @@ public final class SensorPrivacyService extends SystemService {
                ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
                throw new IllegalArgumentException("listener cannot be null");
            }
            mHandler.removeListener(sensor, listener);
        }

        @Override
        public void removeUserGlobalIndividualSensorPrivacyListener(int sensor,
                ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new IllegalArgumentException("listener cannot be null");
            }
            mHandler.removeUserGlobalListener(sensor, listener);
        }

        @Override
        public void suppressIndividualSensorPrivacyReminders(int userId, int sensor,
                IBinder token, boolean suppress) {
@@ -1209,6 +1239,40 @@ public final class SensorPrivacyService extends SystemService {
            }
        }

        private void userSwitching(int from, int to) {
            boolean micState;
            boolean camState;
            boolean prevMicState;
            boolean prevCamState;
            synchronized (mLock) {
                prevMicState = isIndividualSensorPrivacyEnabledLocked(from, MICROPHONE);
                prevCamState = isIndividualSensorPrivacyEnabledLocked(from, CAMERA);
                micState = isIndividualSensorPrivacyEnabledLocked(to, MICROPHONE);
                camState = isIndividualSensorPrivacyEnabledLocked(to, CAMERA);
            }
            if (prevMicState != micState) {
                mHandler.onUserGlobalSensorPrivacyChanged(MICROPHONE, micState);
                setGlobalRestriction(MICROPHONE, micState);
            }
            if (prevCamState != camState) {
                mHandler.onUserGlobalSensorPrivacyChanged(CAMERA, camState);
                setGlobalRestriction(CAMERA, micState);
            }
        }

        private void setGlobalRestriction(int sensor, boolean enabled) {
            switch(sensor) {
                case MICROPHONE:
                    mAppOpsManagerInternal.setGlobalRestriction(OP_RECORD_AUDIO, enabled,
                            mAppOpsRestrictionToken);
                    break;
                case CAMERA:
                    mAppOpsManagerInternal.setGlobalRestriction(OP_CAMERA, enabled,
                            mAppOpsRestrictionToken);
                    break;
            }
        }

        /**
         * Remove a sensor use reminder suppression token.
         *
@@ -1454,7 +1518,12 @@ public final class SensorPrivacyService extends SystemService {
        @GuardedBy("mListenerLock")
        private final SparseArray<SparseArray<RemoteCallbackList<ISensorPrivacyListener>>>
                mIndividualSensorListeners = new SparseArray<>();
        private final ArrayMap<ISensorPrivacyListener, DeathRecipient> mDeathRecipients;
        @GuardedBy("mListenerLock")
        private final SparseArray<RemoteCallbackList<ISensorPrivacyListener>>
                mUserGlobalIndividualSensorListeners = new SparseArray<>();
        @GuardedBy("mListenerLock")
        private final ArrayMap<ISensorPrivacyListener, Pair<DeathRecipient, Integer>>
                mDeathRecipients;
        private final Context mContext;

        SensorPrivacyHandler(Looper looper, Context context) {
@@ -1479,18 +1548,22 @@ public final class SensorPrivacyService extends SystemService {
                            mSensorPrivacyServiceImpl));
        }

        public void onUserGlobalSensorPrivacyChanged(int sensor, boolean enabled) {
            sendMessage(PooledLambda.obtainMessage(
                    SensorPrivacyHandler::handleUserGlobalSensorPrivacyChanged,
                    this, sensor, enabled));
        }

        public void addListener(ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = new DeathRecipient(listener);
                mDeathRecipients.put(listener, deathRecipient);
                mListeners.register(listener);
                if (mListeners.register(listener)) {
                    addDeathRecipient(listener);
                }
            }
        }

        public void addListener(int userId, int sensor, ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = new DeathRecipient(listener);
                mDeathRecipients.put(listener, deathRecipient);
                SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
                        mIndividualSensorListeners.get(userId);
                if (listenersForUser == null) {
@@ -1502,32 +1575,55 @@ public final class SensorPrivacyService extends SystemService {
                    listeners = new RemoteCallbackList<>();
                    listenersForUser.put(sensor, listeners);
                }
                listeners.register(listener);
                if (listeners.register(listener)) {
                    addDeathRecipient(listener);
                }
            }
        }

        public void removeListener(ISensorPrivacyListener listener) {
        public void addUserGlobalListener(int sensor, ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = mDeathRecipients.remove(listener);
                if (deathRecipient != null) {
                    deathRecipient.destroy();
                RemoteCallbackList<ISensorPrivacyListener> listeners =
                        mUserGlobalIndividualSensorListeners.get(sensor);
                if (listeners == null) {
                    listeners = new RemoteCallbackList<>();
                    mUserGlobalIndividualSensorListeners.put(sensor, listeners);
                }
                if (listeners.register(listener)) {
                    addDeathRecipient(listener);
                }
                mListeners.unregister(listener);
            }
        }

        public void removeListener(int sensor, ISensorPrivacyListener listener) {
        public void removeListener(ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = mDeathRecipients.remove(listener);
                if (deathRecipient != null) {
                    deathRecipient.destroy();
                if (mListeners.unregister(listener)) {
                    removeDeathRecipient(listener);
                }
            }
        }

        public void removeListener(int sensor, ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                for (int i = 0, numUsers = mIndividualSensorListeners.size(); i < numUsers; i++) {
                    RemoteCallbackList callbacks =
                            mIndividualSensorListeners.valueAt(i).get(sensor);
                    if (callbacks != null) {
                        callbacks.unregister(listener);
                        if (callbacks.unregister(listener)) {
                            removeDeathRecipient(listener);
                        }
                    }
                }
            }
        }

        public void removeUserGlobalListener(int sensor, ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                RemoteCallbackList callbacks =
                        mUserGlobalIndividualSensorListeners.get(sensor);
                if (callbacks != null) {
                    if (callbacks.unregister(listener)) {
                        removeDeathRecipient(listener);
                    }
                }
            }
@@ -1551,9 +1647,12 @@ public final class SensorPrivacyService extends SystemService {
            SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
                    mIndividualSensorListeners.get(userId);

            setGlobalRestriction();
            if (userId == mCurrentUser) {
                setGlobalRestriction();
                mSensorPrivacyServiceImpl.setGlobalRestriction(sensor, enabled);
            }

            if (userId == mCurrentUser) {
                onUserGlobalSensorPrivacyChanged(sensor, enabled);
            }

            if (listenersForUser == null) {
@@ -1563,6 +1662,7 @@ public final class SensorPrivacyService extends SystemService {
            if (listeners == null) {
                return;
            }
            try {
                final int count = listeners.beginBroadcast();
                for (int i = 0; i < count; i++) {
                    ISensorPrivacyListener listener = listeners.getBroadcastItem(i);
@@ -1572,8 +1672,33 @@ public final class SensorPrivacyService extends SystemService {
                        Log.e(TAG, "Caught an exception notifying listener " + listener + ": ", e);
                    }
                }
            } finally {
                listeners.finishBroadcast();
            }
        }

        public void handleUserGlobalSensorPrivacyChanged(int sensor, boolean enabled) {
            RemoteCallbackList<ISensorPrivacyListener> listeners =
                    mUserGlobalIndividualSensorListeners.get(sensor);

            if (listeners == null) {
                return;
            }

            try {
                final int count = listeners.beginBroadcast();
                for (int i = 0; i < count; i++) {
                    ISensorPrivacyListener listener = listeners.getBroadcastItem(i);
                    try {
                        listener.onSensorPrivacyChanged(enabled);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Caught an exception notifying listener " + listener + ": ", e);
                    }
                }
            } finally {
                listeners.finishBroadcast();
            }
        }

        public void removeSuppressPackageReminderToken(Pair<Integer, UserHandle> key,
                IBinder token) {
@@ -1581,20 +1706,33 @@ public final class SensorPrivacyService extends SystemService {
                    SensorPrivacyServiceImpl::removeSuppressPackageReminderToken,
                    mSensorPrivacyServiceImpl, key, token));
        }
    }

    private void setGlobalRestriction() {
        boolean camState =
                mSensorPrivacyServiceImpl
                        .isIndividualSensorPrivacyEnabled(mCurrentUser, CAMERA);
        boolean micState =
                mSensorPrivacyServiceImpl
                        .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE);
        private void addDeathRecipient(ISensorPrivacyListener listener) {
            Pair<DeathRecipient, Integer> deathRecipient = mDeathRecipients.get(listener);
            if (deathRecipient == null) {
                deathRecipient = new Pair<>(new DeathRecipient(listener), 1);
            } else {
                int newRefCount = deathRecipient.second + 1;
                deathRecipient = new Pair<>(deathRecipient.first, newRefCount);
            }
            mDeathRecipients.put(listener, deathRecipient);
        }

        mAppOpsManagerInternal
                .setGlobalRestriction(OP_CAMERA, camState, mAppOpsRestrictionToken);
        mAppOpsManagerInternal
                .setGlobalRestriction(OP_RECORD_AUDIO, micState, mAppOpsRestrictionToken);
        private void removeDeathRecipient(ISensorPrivacyListener listener) {
            Pair<DeathRecipient, Integer> deathRecipient = mDeathRecipients.get(listener);
            if (deathRecipient == null) {
                return;
            } else {
                int newRefCount = deathRecipient.second - 1;
                if (newRefCount == 0) {
                    mDeathRecipients.remove(listener);
                    deathRecipient.first.destroy();
                    return;
                }
                deathRecipient = new Pair<>(deathRecipient.first, newRefCount);
            }
            mDeathRecipients.put(listener, deathRecipient);
        }
    }

    private final class DeathRecipient implements IBinder.DeathRecipient {