Merge changes If8da2ae5,I38445a13 into sc-dev
* changes: Log duration privacy toggle was in previous state Persist the last time a sensor's privacy state changed
This commit is contained in:
committed by
Android (Google) Code Review
commit
f701c8d1d8
@@ -94,6 +94,7 @@ import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.os.ShellCommand;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
@@ -147,6 +148,8 @@ import java.util.Objects;
|
||||
public final class SensorPrivacyService extends SystemService {
|
||||
|
||||
private static final String TAG = SensorPrivacyService.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean DEBUG_LOGGING = false;
|
||||
|
||||
/** Version number indicating compatibility parsing the persisted file */
|
||||
private static final int CURRENT_PERSISTENCE_VERSION = 1;
|
||||
@@ -162,6 +165,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
private static final String XML_ATTRIBUTE_PERSISTENCE_VERSION = "persistence-version";
|
||||
private static final String XML_ATTRIBUTE_VERSION = "version";
|
||||
private static final String XML_ATTRIBUTE_ENABLED = "enabled";
|
||||
private static final String XML_ATTRIBUTE_LAST_CHANGE = "last-change";
|
||||
private static final String XML_ATTRIBUTE_SENSOR = "sensor";
|
||||
|
||||
private static final String SENSOR_PRIVACY_CHANNEL_ID = Context.SENSOR_PRIVACY_SERVICE;
|
||||
@@ -248,7 +252,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
@GuardedBy("mLock")
|
||||
private SparseBooleanArray mEnabled = new SparseBooleanArray();
|
||||
@GuardedBy("mLock")
|
||||
private SparseArray<SparseBooleanArray> mIndividualEnabled = new SparseArray<>();
|
||||
private SparseArray<SparseArray<SensorState>> mIndividualEnabled = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* Packages for which not to show sensor use reminders.
|
||||
@@ -262,6 +266,34 @@ public final class SensorPrivacyService extends SystemService {
|
||||
private final ArrayMap<SensorUseReminderDialogInfo, ArraySet<Integer>>
|
||||
mQueuedSensorUseReminderDialogs = new ArrayMap<>();
|
||||
|
||||
private class SensorState {
|
||||
private boolean mEnabled;
|
||||
private long mLastChange;
|
||||
|
||||
SensorState(boolean enabled) {
|
||||
mEnabled = enabled;
|
||||
mLastChange = getCurrentTimeMillis();
|
||||
}
|
||||
|
||||
SensorState(boolean enabled, long lastChange) {
|
||||
mEnabled = enabled;
|
||||
if (lastChange < 0) {
|
||||
mLastChange = getCurrentTimeMillis();
|
||||
} else {
|
||||
mLastChange = lastChange;
|
||||
}
|
||||
}
|
||||
|
||||
boolean setEnabled(boolean enabled) {
|
||||
if (mEnabled != enabled) {
|
||||
mEnabled = enabled;
|
||||
mLastChange = getCurrentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class SensorUseReminderDialogInfo {
|
||||
private int mTaskId;
|
||||
private UserHandle mUser;
|
||||
@@ -326,11 +358,11 @@ public final class SensorPrivacyService extends SystemService {
|
||||
// Reset sensor privacy when restriction is added
|
||||
if (!prevRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)
|
||||
&& newRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)) {
|
||||
setIndividualSensorPrivacyUnchecked(userId, CAMERA, false);
|
||||
setIndividualSensorPrivacyUnchecked(userId, OTHER, CAMERA, false);
|
||||
}
|
||||
if (!prevRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)
|
||||
&& newRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)) {
|
||||
setIndividualSensorPrivacyUnchecked(userId, MICROPHONE, false);
|
||||
setIndividualSensorPrivacyUnchecked(userId, OTHER, MICROPHONE, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,20 +703,33 @@ public final class SensorPrivacyService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (userId == mUserManagerInternal.getProfileParentId(userId)) {
|
||||
logSensorPrivacyToggle(source, sensor, enable);
|
||||
}
|
||||
|
||||
setIndividualSensorPrivacyUnchecked(userId, sensor, enable);
|
||||
setIndividualSensorPrivacyUnchecked(userId, source, sensor, enable);
|
||||
}
|
||||
|
||||
private void setIndividualSensorPrivacyUnchecked(int userId, int sensor, boolean enable) {
|
||||
private void setIndividualSensorPrivacyUnchecked(int userId, int source, int sensor,
|
||||
boolean enable) {
|
||||
synchronized (mLock) {
|
||||
SparseBooleanArray userIndividualEnabled = mIndividualEnabled.get(userId,
|
||||
new SparseBooleanArray());
|
||||
userIndividualEnabled.put(sensor, enable);
|
||||
SparseArray<SensorState> userIndividualEnabled = mIndividualEnabled.get(userId,
|
||||
new SparseArray<>());
|
||||
SensorState sensorState = userIndividualEnabled.get(sensor);
|
||||
long lastChange;
|
||||
if (sensorState != null) {
|
||||
lastChange = sensorState.mLastChange;
|
||||
if (!sensorState.setEnabled(enable)) {
|
||||
// State not changing
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
sensorState = new SensorState(enable);
|
||||
lastChange = sensorState.mLastChange;
|
||||
userIndividualEnabled.put(sensor, sensorState);
|
||||
}
|
||||
mIndividualEnabled.put(userId, userIndividualEnabled);
|
||||
|
||||
if (userId == mUserManagerInternal.getProfileParentId(userId)) {
|
||||
logSensorPrivacyToggle(source, sensor, sensorState.mEnabled, lastChange);
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -728,12 +773,12 @@ public final class SensorPrivacyService extends SystemService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void logSensorPrivacyToggle(int source, int sensor, boolean enable) {
|
||||
long logMins = 0L;
|
||||
//(TODO:pyuli) : Add timestamp after persistent storage for timestamp is done.
|
||||
private void logSensorPrivacyToggle(int source, int sensor, boolean enabled,
|
||||
long lastChange) {
|
||||
long logMins = Math.max(0, (getCurrentTimeMillis() - lastChange) / (1000 * 60));
|
||||
|
||||
int logAction = -1;
|
||||
if (enable) {
|
||||
if (enabled) {
|
||||
logAction = PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_OFF;
|
||||
} else {
|
||||
logAction = PRIVACY_SENSOR_TOGGLE_INTERACTION__ACTION__TOGGLE_ON;
|
||||
@@ -766,6 +811,11 @@ public final class SensorPrivacyService extends SystemService {
|
||||
logSource = PRIVACY_SENSOR_TOGGLE_INTERACTION__SOURCE__SOURCE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (DEBUG || DEBUG_LOGGING) {
|
||||
Log.d(TAG, "Logging sensor toggle interaction:" + " logSensor=" + logSensor
|
||||
+ " logAction=" + logAction + " logSource=" + logSource + " logMins="
|
||||
+ logMins);
|
||||
}
|
||||
write(PRIVACY_SENSOR_TOGGLE_INTERACTION, logSensor, logAction, logSource, logMins);
|
||||
|
||||
}
|
||||
@@ -828,11 +878,15 @@ public final class SensorPrivacyService extends SystemService {
|
||||
public boolean isIndividualSensorPrivacyEnabled(@UserIdInt int userId, int sensor) {
|
||||
enforceObserveSensorPrivacyPermission();
|
||||
synchronized (mLock) {
|
||||
SparseBooleanArray states = mIndividualEnabled.get(userId);
|
||||
SparseArray<SensorState> states = mIndividualEnabled.get(userId);
|
||||
if (states == null) {
|
||||
return false;
|
||||
}
|
||||
return states.get(sensor, false);
|
||||
SensorState state = states.get(sensor);
|
||||
if (state == null) {
|
||||
return false;
|
||||
}
|
||||
return state.mEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,7 +911,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
// these should never be changed even with refactorings.
|
||||
if (persistenceVersion == 0) {
|
||||
boolean enabled = parser.getAttributeBoolean(null, "enabled", false);
|
||||
SparseBooleanArray individualEnabled = new SparseBooleanArray();
|
||||
SparseArray<SensorState> individualEnabled = new SparseArray<>();
|
||||
version = 0;
|
||||
|
||||
XmlUtils.nextElement(parser);
|
||||
@@ -867,7 +921,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
int sensor = XmlUtils.readIntAttribute(parser, "sensor");
|
||||
boolean indEnabled = XmlUtils.readBooleanAttribute(parser,
|
||||
"enabled");
|
||||
individualEnabled.put(sensor, indEnabled);
|
||||
individualEnabled.put(sensor, new SensorState(indEnabled));
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
} else {
|
||||
XmlUtils.nextElement(parser);
|
||||
@@ -877,7 +931,8 @@ public final class SensorPrivacyService extends SystemService {
|
||||
map.put(VER0_INDIVIDUAL_ENABLED, individualEnabled);
|
||||
} else if (persistenceVersion == CURRENT_PERSISTENCE_VERSION) {
|
||||
SparseBooleanArray enabled = new SparseBooleanArray();
|
||||
SparseArray<SparseBooleanArray> individualEnabled = new SparseArray<>();
|
||||
SparseArray<SparseArray<SensorState>> individualEnabled =
|
||||
new SparseArray<>();
|
||||
version = parser.getAttributeInt(null,
|
||||
XML_ATTRIBUTE_VERSION, 1);
|
||||
|
||||
@@ -913,10 +968,13 @@ public final class SensorPrivacyService extends SystemService {
|
||||
int sensor = parser.getAttributeInt(null, XML_ATTRIBUTE_SENSOR);
|
||||
boolean isEnabled = parser.getAttributeBoolean(null,
|
||||
XML_ATTRIBUTE_ENABLED);
|
||||
SparseBooleanArray userIndividualEnabled = individualEnabled.get(
|
||||
currentUserId, new SparseBooleanArray());
|
||||
long lastChange = parser
|
||||
.getAttributeLong(null, XML_ATTRIBUTE_LAST_CHANGE, -1);
|
||||
SparseArray<SensorState> userIndividualEnabled =
|
||||
individualEnabled.get(currentUserId, new SparseArray<>());
|
||||
|
||||
userIndividualEnabled.put(sensor, isEnabled);
|
||||
userIndividualEnabled
|
||||
.put(sensor, new SensorState(isEnabled, lastChange));
|
||||
individualEnabled.put(currentUserId, userIndividualEnabled);
|
||||
}
|
||||
}
|
||||
@@ -949,7 +1007,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
mEnabled = new SparseBooleanArray();
|
||||
mIndividualEnabled = new SparseArray<>();
|
||||
forAllUsers(userId -> mEnabled.put(userId, false));
|
||||
forAllUsers(userId -> mIndividualEnabled.put(userId, new SparseBooleanArray()));
|
||||
forAllUsers(userId -> mIndividualEnabled.put(userId, new SparseArray<>()));
|
||||
return true;
|
||||
}
|
||||
boolean upgraded = false;
|
||||
@@ -986,7 +1044,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
if (version == CURRENT_VERSION) {
|
||||
mEnabled = (SparseBooleanArray) map.get(VER1_ENABLED);
|
||||
mIndividualEnabled =
|
||||
(SparseArray<SparseBooleanArray>) map.get(VER1_INDIVIDUAL_ENABLED);
|
||||
(SparseArray<SparseArray<SensorState>>) map.get(VER1_INDIVIDUAL_ENABLED);
|
||||
}
|
||||
return upgraded;
|
||||
}
|
||||
@@ -1016,15 +1074,18 @@ public final class SensorPrivacyService extends SystemService {
|
||||
serializer.attributeBoolean(
|
||||
null, XML_ATTRIBUTE_ENABLED, isSensorPrivacyEnabled(userId));
|
||||
|
||||
SparseBooleanArray individualEnabled =
|
||||
mIndividualEnabled.get(userId, new SparseBooleanArray());
|
||||
SparseArray<SensorState> individualEnabled =
|
||||
mIndividualEnabled.get(userId, new SparseArray<>());
|
||||
int numIndividual = individualEnabled.size();
|
||||
for (int i = 0; i < numIndividual; i++) {
|
||||
serializer.startTag(null, XML_TAG_INDIVIDUAL_SENSOR_PRIVACY);
|
||||
int sensor = individualEnabled.keyAt(i);
|
||||
boolean enabled = individualEnabled.valueAt(i);
|
||||
SensorState sensorState = individualEnabled.valueAt(i);
|
||||
boolean enabled = sensorState.mEnabled;
|
||||
long lastChange = sensorState.mLastChange;
|
||||
serializer.attributeInt(null, XML_ATTRIBUTE_SENSOR, sensor);
|
||||
serializer.attributeBoolean(null, XML_ATTRIBUTE_ENABLED, enabled);
|
||||
serializer.attributeLong(null, XML_ATTRIBUTE_LAST_CHANGE, lastChange);
|
||||
serializer.endTag(null, XML_TAG_INDIVIDUAL_SENSOR_PRIVACY);
|
||||
}
|
||||
serializer.endTag(null, XML_TAG_USER);
|
||||
@@ -1229,7 +1290,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
dumpStream.write("is_enabled", SensorPrivacyUserProto.IS_ENABLED,
|
||||
mEnabled.get(userId, false));
|
||||
|
||||
SparseBooleanArray individualEnabled = mIndividualEnabled.get(userId);
|
||||
SparseArray<SensorState> individualEnabled = mIndividualEnabled.get(userId);
|
||||
if (individualEnabled != null) {
|
||||
int numIndividualEnabled = individualEnabled.size();
|
||||
for (int i = 0; i < numIndividualEnabled; i++) {
|
||||
@@ -1241,7 +1302,8 @@ public final class SensorPrivacyService extends SystemService {
|
||||
individualEnabled.keyAt(i));
|
||||
dumpStream.write("is_enabled",
|
||||
SensorPrivacyIndividualEnabledSensorProto.IS_ENABLED,
|
||||
individualEnabled.valueAt(i));
|
||||
individualEnabled.valueAt(i).mEnabled);
|
||||
// TODO dump last change
|
||||
|
||||
dumpStream.end(individualToken);
|
||||
}
|
||||
@@ -1321,7 +1383,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
enforceManageSensorPrivacyPermission();
|
||||
|
||||
synchronized (mLock) {
|
||||
SparseBooleanArray individualEnabled =
|
||||
SparseArray<SensorState> individualEnabled =
|
||||
mIndividualEnabled.get(userId);
|
||||
if (individualEnabled != null) {
|
||||
individualEnabled.delete(sensor);
|
||||
@@ -1682,7 +1744,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
if (mSensorPrivacyServiceImpl
|
||||
.isIndividualSensorPrivacyEnabled(getCurrentUser(), MICROPHONE)) {
|
||||
mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
|
||||
getCurrentUser(), MICROPHONE, false);
|
||||
getCurrentUser(), OTHER, MICROPHONE, false);
|
||||
mMicUnmutedForEmergencyCall = true;
|
||||
} else {
|
||||
mMicUnmutedForEmergencyCall = false;
|
||||
@@ -1697,11 +1759,19 @@ public final class SensorPrivacyService extends SystemService {
|
||||
mIsInEmergencyCall = false;
|
||||
if (mMicUnmutedForEmergencyCall) {
|
||||
mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
|
||||
getCurrentUser(), MICROPHONE, true);
|
||||
getCurrentUser(), OTHER, MICROPHONE, true);
|
||||
mMicUnmutedForEmergencyCall = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static long getCurrentTimeMillis() {
|
||||
try {
|
||||
return SystemClock.currentNetworkTimeMillis();
|
||||
} catch (Exception e) {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user