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

Commit 8a0379eb authored by Evan Severson's avatar Evan Severson Committed by Automerger Merge Worker
Browse files

Merge changes If8da2ae5,I38445a13 into sc-dev am: f701c8d1 am: 269c960b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15224092

Change-Id: I77051f519c9d35d51b85560c4e0785a470acefe8
parents 9faa470a 269c960b
Loading
Loading
Loading
Loading
+104 −34
Original line number Diff line number Diff line
@@ -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) {
                    final 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();
        }
    }
}