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
This commit is contained in:
Evan Severson
2020-12-22 16:12:55 -08:00
parent 2e3ba7cd30
commit 1f1e8d72ab
3 changed files with 110 additions and 8 deletions

View File

@@ -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 setIndividualSensorPrivacy(int userId, int sensor, boolean enable);
void setIndividualSensorPrivacyForProfileGroup(int userId, int sensor, boolean enable);
void setSensorPrivacy(boolean enable);
// TODO(evanseverson) listeners
void setIndividualSensorPrivacy(int userId, int sensor, boolean enable);
void setIndividualSensorPrivacyForProfileGroup(int userId, int sensor, boolean enable);
// =============== End of transactions used on native side as well ============================
}

View File

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

View File

@@ -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 {