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

Commit 1f1e8d72 authored by Evan Severson's avatar Evan Severson
Browse files

Add listeners for individual camera and microphone toggles

Test: Manually add a listener in another serviec and change state with
          `adb shell cmd sensor_privacy enable 0 microphone`.
Bug: 162549680

Change-Id: I4a77bc2bba4405b2ba962e767005ca443a2d732f
parent 2e3ba7cd
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -26,19 +26,19 @@ interface ISensorPrivacyManager {
    // =============== Beginning of transactions used on native side as well ======================
    void addSensorPrivacyListener(in ISensorPrivacyListener listener);

    void addIndividualSensorPrivacyListener(int userId, int sensor,
            in ISensorPrivacyListener listener);

    void removeSensorPrivacyListener(in ISensorPrivacyListener listener);

    boolean isSensorPrivacyEnabled();

    void setSensorPrivacy(boolean enable);
    // =============== End of transactions used on native side as well ============================

    // TODO(evanseverson) add to native interface
    boolean isIndividualSensorPrivacyEnabled(int userId, int sensor);

    // TODO(evanseverson) add to native interface
    void setSensorPrivacy(boolean enable);

    void setIndividualSensorPrivacy(int userId, int sensor, boolean enable);
    void setIndividualSensorPrivacyForProfileGroup(int userId, int sensor, boolean enable);

    // TODO(evanseverson) listeners
    void setIndividualSensorPrivacyForProfileGroup(int userId, int sensor, boolean enable);
    // =============== End of transactions used on native side as well ============================
}
 No newline at end of file
+31 −0
Original line number Diff line number Diff line
@@ -160,6 +160,37 @@ public final class SensorPrivacyManager {
        }
    }

    /**
     * Registers a new listener to receive notification when the state of sensor privacy
     * changes.
     *
     * @param userId the user's id
     * @param sensor the sensor to listen to changes to
     * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor
     *                 privacy changes.
     */
    public void addSensorPrivacyListener(@UserIdInt int userId, @IndividualSensor int sensor,
            final OnSensorPrivacyChangedListener listener) {
        synchronized (mListeners) {
            ISensorPrivacyListener iListener = mListeners.get(listener);
            if (iListener == null) {
                iListener = new ISensorPrivacyListener.Stub() {
                    @Override
                    public void onSensorPrivacyChanged(boolean enabled) {
                        listener.onSensorPrivacyChanged(enabled);
                    }
                };
                mListeners.put(listener, iListener);
            }

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

    /**
     * Unregisters the specified listener from receiving notifications when the state of sensor
     * privacy changes.
+71 −0
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ public final class SensorPrivacyService extends SystemService {
                }
                persistSensorPrivacyState();
            }
            mHandler.onSensorPrivacyChanged(userId, sensor, enable);
        }

        @Override
@@ -557,6 +558,18 @@ public final class SensorPrivacyService extends SystemService {
            mHandler.addListener(listener);
        }

        /**
         * Registers a listener to be notified when the sensor privacy state changes.
         */
        @Override
        public void addIndividualSensorPrivacyListener(int userId, int sensor,
                ISensorPrivacyListener listener) {
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
            }
            mHandler.addListener(userId, sensor, listener);
        }

        /**
         * Unregisters a listener from sensor privacy state change notifications.
         */
@@ -760,6 +773,9 @@ public final class SensorPrivacyService extends SystemService {
        @GuardedBy("mListenerLock")
        private final RemoteCallbackList<ISensorPrivacyListener> mListeners =
                new RemoteCallbackList<>();
        @GuardedBy("mListenerLock")
        private final SparseArray<SparseArray<RemoteCallbackList<ISensorPrivacyListener>>>
                mIndividualSensorListeners = new SparseArray<>();
        private final ArrayMap<ISensorPrivacyListener, DeathRecipient> mDeathRecipients;
        private final Context mContext;

@@ -777,6 +793,14 @@ public final class SensorPrivacyService extends SystemService {
                            mSensorPrivacyServiceImpl));
        }

        public void onSensorPrivacyChanged(int userId, int sensor, boolean enabled) {
            sendMessage(PooledLambda.obtainMessage(SensorPrivacyHandler::handleSensorPrivacyChanged,
                    this, userId, sensor, enabled));
            sendMessage(
                    PooledLambda.obtainMessage(SensorPrivacyServiceImpl::persistSensorPrivacyState,
                            mSensorPrivacyServiceImpl));
        }

        public void addListener(ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = new DeathRecipient(listener);
@@ -785,6 +809,25 @@ public final class SensorPrivacyService extends SystemService {
            }
        }

        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) {
                    listenersForUser = new SparseArray<>();
                    mIndividualSensorListeners.put(userId, listenersForUser);
                }
                RemoteCallbackList<ISensorPrivacyListener> listeners = listenersForUser.get(sensor);
                if (listeners == null) {
                    listeners = new RemoteCallbackList<>();
                    listenersForUser.put(sensor, listeners);
                }
                listeners.register(listener);
            }
        }

        public void removeListener(ISensorPrivacyListener listener) {
            synchronized (mListenerLock) {
                DeathRecipient deathRecipient = mDeathRecipients.remove(listener);
@@ -792,6 +835,12 @@ public final class SensorPrivacyService extends SystemService {
                    deathRecipient.destroy();
                }
                mListeners.unregister(listener);
                for (int i = 0, numUsers = mIndividualSensorListeners.size(); i < numUsers; i++) {
                    for (int j = 0, numListeners = mIndividualSensorListeners.valueAt(i).size();
                            j < numListeners; j++) {
                        mIndividualSensorListeners.valueAt(i).valueAt(j).unregister(listener);
                    }
                }
            }
        }

@@ -807,6 +856,28 @@ public final class SensorPrivacyService extends SystemService {
            }
            mListeners.finishBroadcast();
        }

        public void handleSensorPrivacyChanged(int userId, int sensor, boolean enabled) {
            SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
                    mIndividualSensorListeners.get(userId);
            if (listenersForUser == null) {
                return;
            }
            RemoteCallbackList<ISensorPrivacyListener> listeners = listenersForUser.get(sensor);
            if (listeners == null) {
                return;
            }
            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);
                }
            }
            listeners.finishBroadcast();
        }
    }

    private final class DeathRecipient implements IBinder.DeathRecipient {