/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server;

import static android.Manifest.permission.MANAGE_SENSOR_PRIVACY;
import static android.app.ActivityManager.RunningServiceInfo;
import static android.app.ActivityManager.RunningTaskInfo;
import static android.app.ActivityManager.getCurrentUser;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS;
import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR;
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.SensorPrivacyIndividualEnabledSensorProto.UNKNOWN;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppOpsManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.hardware.ISensorPrivacyListener;
import android.hardware.ISensorPrivacyManager;
import android.hardware.SensorPrivacyManager;
import android.hardware.SensorPrivacyManagerInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.SensorPrivacyIndividualEnabledSensorProto;
import android.service.SensorPrivacyServiceDumpProto;
import android.service.SensorPrivacyUserProto;
import android.service.voice.VoiceInteractionManagerInternal;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.text.Html;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FunctionalUtils;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.pm.UserManagerInternal;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;

/** @hide */
public final class SensorPrivacyService extends SystemService {

    private static final String TAG = SensorPrivacyService.class.getSimpleName();

    /** Version number indicating compatibility parsing the persisted file */
    private static final int CURRENT_PERSISTENCE_VERSION = 1;
    /** Version number indicating the persisted data needs upgraded to match new internal data
     *  structures and features */
    private static final int CURRENT_VERSION = 1;

    private static final String SENSOR_PRIVACY_XML_FILE = "sensor_privacy.xml";
    private static final String XML_TAG_SENSOR_PRIVACY = "sensor-privacy";
    private static final String XML_TAG_USER = "user";
    private static final String XML_TAG_INDIVIDUAL_SENSOR_PRIVACY = "individual-sensor-privacy";
    private static final String XML_ATTRIBUTE_ID = "id";
    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_SENSOR = "sensor";

    private static final String SENSOR_PRIVACY_CHANNEL_ID = Context.SENSOR_PRIVACY_SERVICE;
    private static final String ACTION_DISABLE_INDIVIDUAL_SENSOR_PRIVACY =
            SensorPrivacyService.class.getName() + ".action.disable_sensor_privacy";

    // These are associated with fields that existed for older persisted versions of files
    private static final int VER0_ENABLED = 0;
    private static final int VER0_INDIVIDUAL_ENABLED = 1;
    private static final int VER1_ENABLED = 0;
    private static final int VER1_INDIVIDUAL_ENABLED = 1;
    public static final int REMINDER_DIALOG_DELAY_MILLIS = 500;

    private final Context mContext;
    private final SensorPrivacyServiceImpl mSensorPrivacyServiceImpl;
    private final UserManagerInternal mUserManagerInternal;
    private final ActivityManager mActivityManager;
    private final ActivityTaskManager mActivityTaskManager;
    private final AppOpsManager mAppOpsManager;
    private final TelephonyManager mTelephonyManager;

    private final IBinder mAppOpsRestrictionToken = new Binder();

    private SensorPrivacyManagerInternalImpl mSensorPrivacyManagerInternal;

    private EmergencyCallHelper mEmergencyCallHelper;
    private KeyguardManager mKeyguardManager;

    public SensorPrivacyService(Context context) {
        super(context);
        mContext = context;
        mAppOpsManager = context.getSystemService(AppOpsManager.class);
        mUserManagerInternal = getLocalService(UserManagerInternal.class);
        mActivityManager = context.getSystemService(ActivityManager.class);
        mActivityTaskManager = context.getSystemService(ActivityTaskManager.class);
        mTelephonyManager = context.getSystemService(TelephonyManager.class);

        mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl();
    }

    @Override
    public void onStart() {
        publishBinderService(Context.SENSOR_PRIVACY_SERVICE, mSensorPrivacyServiceImpl);
        mSensorPrivacyManagerInternal = new SensorPrivacyManagerInternalImpl();
        publishLocalService(SensorPrivacyManagerInternal.class,
                mSensorPrivacyManagerInternal);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_SYSTEM_SERVICES_READY) {
            mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
            mEmergencyCallHelper = new EmergencyCallHelper();
        }
    }

    class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements
            AppOpsManager.OnOpNotedListener, AppOpsManager.OnOpStartedListener,
            IBinder.DeathRecipient, UserManagerInternal.UserRestrictionsListener {

        private final SensorPrivacyHandler mHandler;
        private final Object mLock = new Object();
        @GuardedBy("mLock")
        private final AtomicFile mAtomicFile;
        @GuardedBy("mLock")
        private SparseBooleanArray mEnabled = new SparseBooleanArray();
        @GuardedBy("mLock")
        private SparseArray<SparseBooleanArray> mIndividualEnabled = new SparseArray<>();

        /**
         * Packages for which not to show sensor use reminders.
         *
         * <Package, User> -> list of suppressor tokens
         */
        @GuardedBy("mLock")
        private ArrayMap<Pair<String, UserHandle>, ArrayList<IBinder>> mSuppressReminders =
                new ArrayMap<>();

        private final ArrayMap<SensorUseReminderDialogInfo, ArraySet<Integer>>
                mQueuedSensorUseReminderDialogs = new ArrayMap<>();

        private class SensorUseReminderDialogInfo {
            private int mTaskId;
            private UserHandle mUser;
            private String mPackageName;

            SensorUseReminderDialogInfo(int taskId, UserHandle user, String packageName) {
                mTaskId = taskId;
                mUser = user;
                mPackageName = packageName;
            }

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || !(o instanceof SensorUseReminderDialogInfo)) return false;
                SensorUseReminderDialogInfo that = (SensorUseReminderDialogInfo) o;
                return mTaskId == that.mTaskId
                        && Objects.equals(mUser, that.mUser)
                        && Objects.equals(mPackageName, that.mPackageName);
            }

            @Override
            public int hashCode() {
                return Objects.hash(mTaskId, mUser, mPackageName);
            }
        }

        SensorPrivacyServiceImpl() {
            mHandler = new SensorPrivacyHandler(FgThread.get().getLooper(), mContext);
            File sensorPrivacyFile = new File(Environment.getDataSystemDirectory(),
                    SENSOR_PRIVACY_XML_FILE);
            mAtomicFile = new AtomicFile(sensorPrivacyFile);
            synchronized (mLock) {
                if (readPersistedSensorPrivacyStateLocked()) {
                    persistSensorPrivacyStateLocked();
                }

                for (int i = 0; i < mIndividualEnabled.size(); i++) {
                    int userId = mIndividualEnabled.keyAt(i);
                    SparseBooleanArray userIndividualEnabled =
                            mIndividualEnabled.valueAt(i);
                    for (int j = 0; j < userIndividualEnabled.size(); j++) {
                        int sensor = userIndividualEnabled.keyAt(j);
                        boolean enabled = userIndividualEnabled.valueAt(j);
                        setUserRestriction(userId, sensor, enabled);
                    }
                }
            }

            int[] micAndCameraOps = new int[]{OP_RECORD_AUDIO, OP_PHONE_CALL_MICROPHONE,
                    OP_CAMERA, OP_PHONE_CALL_CAMERA};
            mAppOpsManager.startWatchingNoted(micAndCameraOps, this);
            mAppOpsManager.startWatchingStarted(micAndCameraOps, this);

            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    setIndividualSensorPrivacy(
                            ((UserHandle) intent.getParcelableExtra(
                                    Intent.EXTRA_USER)).getIdentifier(),
                            intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false);
                }
            }, new IntentFilter(ACTION_DISABLE_INDIVIDUAL_SENSOR_PRIVACY),
                    MANAGE_SENSOR_PRIVACY, null);
            mUserManagerInternal.addUserRestrictionsListener(this);
        }

        @Override
        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
                Bundle prevRestrictions) {
            // Reset sensor privacy when restriction is added
            if (!prevRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)
                    && newRestrictions.getBoolean(UserManager.DISALLOW_CAMERA_TOGGLE)) {
                setIndividualSensorPrivacyUnchecked(userId, CAMERA, false);
            }
            if (!prevRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)
                    && newRestrictions.getBoolean(UserManager.DISALLOW_MICROPHONE_TOGGLE)) {
                setIndividualSensorPrivacyUnchecked(userId, MICROPHONE, false);
            }
        }

        @Override
        public void onOpStarted(int code, int uid, String packageName, String attributionTag,
                @AppOpsManager.OpFlags int flags, @AppOpsManager.Mode int result) {
            onOpNoted(code, uid, packageName, attributionTag, flags, result);
        }

        @Override
        public void onOpNoted(int code, int uid, String packageName,
                String attributionTag, @AppOpsManager.OpFlags int flags,
                @AppOpsManager.Mode int result) {
            if ((flags & AppOpsManager.OP_FLAGS_ALL_TRUSTED) == 0) {
                return;
            }

            int sensor;
            if (result == MODE_IGNORED) {
                if (code == OP_RECORD_AUDIO) {
                    sensor = MICROPHONE;
                } else if (code == OP_CAMERA) {
                    sensor = CAMERA;
                } else {
                    return;
                }
            } else if (result == MODE_ALLOWED) {
                if (code == OP_PHONE_CALL_MICROPHONE) {
                    sensor = MICROPHONE;
                } else if (code == OP_PHONE_CALL_CAMERA) {
                    sensor = CAMERA;
                } else {
                    return;
                }
            } else {
                return;
            }

            long token = Binder.clearCallingIdentity();
            try {
                onSensorUseStarted(uid, packageName, sensor);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        /**
         * Called when a sensor protected by individual sensor privacy is attempting to get used.
         *
         * @param uid The uid of the app using the sensor
         * @param packageName The package name of the app using the sensor
         * @param sensor The sensor that is attempting to be used
         */
        private void onSensorUseStarted(int uid, String packageName, int sensor) {
            UserHandle user = UserHandle.getUserHandleForUid(uid);
            if (!isIndividualSensorPrivacyEnabled(user.getIdentifier(), sensor)) {
                return;
            }

            synchronized (mLock) {
                if (mSuppressReminders.containsKey(new Pair<>(packageName, user))) {
                    Log.d(TAG,
                            "Suppressed sensor privacy reminder for " + packageName + "/" + user);
                    return;
                }
            }

            if (uid == Process.SYSTEM_UID) {
                enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor);
                return;
            }

            // TODO: Handle reminders with multiple sensors

            // - If we have a likely activity that triggered the sensor use overlay a dialog over
            //   it. This should be the most common case.
            // - If there is no use visible entity that triggered the sensor don't show anything as
            //   this is - from the point of the user - a background usage
            // - Otherwise show a notification as we are not quite sure where to display the dialog.

            List<RunningTaskInfo> tasksOfPackageUsingSensor = new ArrayList<>();

            List<RunningTaskInfo> tasks = mActivityTaskManager.getTasks(Integer.MAX_VALUE);
            int numTasks = tasks.size();
            for (int taskNum = 0; taskNum < numTasks; taskNum++) {
                RunningTaskInfo task = tasks.get(taskNum);

                if (task.isVisible && task.topActivity.getPackageName().equals(packageName)) {
                    if (task.isFocused) {
                        // There is the one focused activity
                        enqueueSensorUseReminderDialogAsync(task.taskId, user, packageName, sensor);
                        return;
                    }

                    tasksOfPackageUsingSensor.add(task);
                }
            }

            // TODO: Test this case
            // There is one or more non-focused activity
            if (tasksOfPackageUsingSensor.size() == 1) {
                enqueueSensorUseReminderDialogAsync(tasksOfPackageUsingSensor.get(0).taskId, user,
                        packageName, sensor);
                return;
            } else if (tasksOfPackageUsingSensor.size() > 1) {
                showSensorUseReminderNotification(user, packageName, sensor);
                return;
            }

            // TODO: Test this case
            // Check if there is a foreground service for this package
            List<RunningServiceInfo> services = mActivityManager.getRunningServices(
                    Integer.MAX_VALUE);
            int numServices = services.size();
            for (int serviceNum = 0; serviceNum < numServices; serviceNum++) {
                RunningServiceInfo service = services.get(serviceNum);

                if (service.foreground && service.service.getPackageName().equals(packageName)) {
                    showSensorUseReminderNotification(user, packageName, sensor);
                    return;
                }
            }

            VoiceInteractionManagerInternal voiceInteractionManagerInternal =
                    LocalServices.getService(VoiceInteractionManagerInternal.class);

            if (sensor == MICROPHONE && voiceInteractionManagerInternal != null
                    && voiceInteractionManagerInternal.hasActiveSession(packageName)) {
                enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor);
                return;
            }

            Log.i(TAG, packageName + "/" + uid + " started using sensor " + sensor
                    + " but no activity or foreground service was running. The user will not be"
                    + " informed. System components should check if sensor privacy is enabled for"
                    + " the sensor before accessing it.");
        }

        /**
         * Show a dialog that informs the user that a sensor use or a blocked sensor started.
         * The user can then react to this event.
         *
         * @param taskId The task this dialog should be overlaid on.
         * @param user The user of the package using the sensor.
         * @param packageName The name of the package using the sensor.
         * @param sensor The sensor that is being used.
         */
        private void enqueueSensorUseReminderDialogAsync(int taskId, @NonNull UserHandle user,
                @NonNull String packageName, int sensor) {
            mHandler.sendMessage(PooledLambda.obtainMessage(
                    this:: enqueueSensorUseReminderDialog, taskId, user, packageName, sensor));
        }

        private void enqueueSensorUseReminderDialog(int taskId, @NonNull UserHandle user,
                @NonNull String packageName, int sensor) {
            SensorUseReminderDialogInfo info =
                    new SensorUseReminderDialogInfo(taskId, user, packageName);
            if (!mQueuedSensorUseReminderDialogs.containsKey(info)) {
                ArraySet<Integer> sensors = new ArraySet<Integer>();
                sensors.add(sensor);
                mQueuedSensorUseReminderDialogs.put(info, sensors);
                mHandler.sendMessageDelayed(
                        PooledLambda.obtainMessage(this::showSensorUserReminderDialog, info),
                        REMINDER_DIALOG_DELAY_MILLIS);
                return;
            }
            ArraySet<Integer> sensors = mQueuedSensorUseReminderDialogs.get(info);
            sensors.add(sensor);
        }

        private void showSensorUserReminderDialog(@NonNull SensorUseReminderDialogInfo info) {
            ArraySet<Integer> sensors = mQueuedSensorUseReminderDialogs.get(info);
            mQueuedSensorUseReminderDialogs.remove(info);
            if (sensors == null) {
                Log.e(TAG, "Unable to show sensor use dialog because sensor set is null."
                        + " Was the dialog queue modified from outside the handler thread?");
                return;
            }
            Intent dialogIntent = new Intent();
            dialogIntent.setComponent(ComponentName.unflattenFromString(
                    mContext.getResources().getString(
                            R.string.config_sensorUseStartedActivity)));

            ActivityOptions options = ActivityOptions.makeBasic();
            options.setLaunchTaskId(info.mTaskId);
            options.setTaskOverlay(true, true);

            dialogIntent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

            dialogIntent.putExtra(EXTRA_PACKAGE_NAME, info.mPackageName);
            if (sensors.size() == 1) {
                dialogIntent.putExtra(EXTRA_SENSOR, sensors.valueAt(0));
            } else if (sensors.size() == 2) {
                dialogIntent.putExtra(EXTRA_ALL_SENSORS, true);
            } else {
                // Currently the only cases can be 1 or two
                Log.e(TAG, "Attempted to show sensor use dialog for " + sensors.size()
                        + " sensors");
                return;
            }
            mContext.startActivityAsUser(dialogIntent, options.toBundle(), info.mUser);
        }

        /**
         * Show a notification that informs the user that a sensor use or a blocked sensor started.
         * The user can then react to this event.
         *
         * @param user The user of the package using the sensor.
         * @param packageName The name of the package using the sensor.
         * @param sensor The sensor that is being used.
         */
        private void showSensorUseReminderNotification(@NonNull UserHandle user,
                @NonNull String packageName, int sensor) {
            int iconRes;
            int messageRes;

            CharSequence packageLabel;
            try {
                packageLabel = getUiContext().getPackageManager()
                        .getApplicationInfoAsUser(packageName, 0, user)
                        .loadLabel(mContext.getPackageManager());
            } catch (PackageManager.NameNotFoundException e) {
                Log.e(TAG, "Cannot show sensor use notification for " + packageName);
                return;
            }

            if (sensor == MICROPHONE) {
                iconRes = R.drawable.ic_mic_blocked;
                messageRes = R.string.sensor_privacy_start_use_mic_notification_content_title;
            } else {
                iconRes = R.drawable.ic_camera_blocked;
                messageRes = R.string.sensor_privacy_start_use_camera_notification_content_title;
            }

            NotificationManager notificationManager =
                    mContext.getSystemService(NotificationManager.class);
            NotificationChannel channel = new NotificationChannel(
                    SENSOR_PRIVACY_CHANNEL_ID,
                    getUiContext().getString(R.string.sensor_privacy_notification_channel_label),
                    NotificationManager.IMPORTANCE_HIGH);
            channel.setSound(null, null);
            channel.setBypassDnd(true);
            channel.enableVibration(false);
            channel.setBlockable(false);

            notificationManager.createNotificationChannel(channel);

            Icon icon = Icon.createWithResource(getUiContext().getResources(), iconRes);
            notificationManager.notify(sensor,
                    new Notification.Builder(mContext, SENSOR_PRIVACY_CHANNEL_ID)
                            .setContentTitle(getUiContext().getString(messageRes))
                            .setContentText(Html.fromHtml(getUiContext().getString(
                                    R.string.sensor_privacy_start_use_notification_content_text,
                                    packageLabel),0))
                            .setSmallIcon(icon)
                            .addAction(new Notification.Action.Builder(icon,
                                    getUiContext().getString(
                                            R.string.sensor_privacy_start_use_dialog_turn_on_button),
                                    PendingIntent.getBroadcast(mContext, sensor,
                                            new Intent(ACTION_DISABLE_INDIVIDUAL_SENSOR_PRIVACY)
                                                    .setPackage(mContext.getPackageName())
                                                    .putExtra(EXTRA_SENSOR, sensor)
                                                    .putExtra(Intent.EXTRA_USER, user),
                                            PendingIntent.FLAG_IMMUTABLE
                                                    | PendingIntent.FLAG_UPDATE_CURRENT))
                                    .build())
                            .setContentIntent(PendingIntent.getActivity(mContext, sensor,
                                    new Intent(Settings.ACTION_PRIVACY_SETTINGS),
                                    PendingIntent.FLAG_IMMUTABLE
                                            | PendingIntent.FLAG_UPDATE_CURRENT))
                            .build());
        }

        /**
         * Sets the sensor privacy to the provided state and notifies all listeners of the new
         * state.
         */
        @Override
        public void setSensorPrivacy(boolean enable) {
            enforceManageSensorPrivacyPermission();
            // Keep the state consistent between all users to make it a single global state
            forAllUsers(userId -> setSensorPrivacy(userId, enable));
        }

        private void setSensorPrivacy(@UserIdInt int userId, boolean enable) {
            synchronized (mLock) {
                mEnabled.put(userId, enable);
                persistSensorPrivacyStateLocked();
            }
            mHandler.onSensorPrivacyChanged(enable);
        }

        @Override
        public void setIndividualSensorPrivacy(@UserIdInt int userId, int sensor, boolean enable) {
            enforceManageSensorPrivacyPermission();
            if (!canChangeIndividualSensorPrivacy(userId, sensor)) {
                return;
            }

            setIndividualSensorPrivacyUnchecked(userId, sensor, enable);
        }

        private void setIndividualSensorPrivacyUnchecked(int userId, int sensor, boolean enable) {
            synchronized (mLock) {
                SparseBooleanArray userIndividualEnabled = mIndividualEnabled.get(userId,
                        new SparseBooleanArray());
                userIndividualEnabled.put(sensor, enable);
                mIndividualEnabled.put(userId, userIndividualEnabled);

                if (!enable) {
                    long token = Binder.clearCallingIdentity();
                    try {
                        // Remove any notifications prompting the user to disable sensory privacy
                        NotificationManager notificationManager =
                                mContext.getSystemService(NotificationManager.class);

                        notificationManager.cancel(sensor);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
                }
                persistSensorPrivacyState();
            }
            mHandler.onSensorPrivacyChanged(userId, sensor, enable);
        }

        private boolean canChangeIndividualSensorPrivacy(@UserIdInt int userId, int sensor) {
            if (sensor == MICROPHONE && mEmergencyCallHelper.isInEmergencyCall()) {
                // During emergency call the microphone toggle managed automatically
                Log.i(TAG, "Can't change mic toggle during an emergency call");
                return false;
            }

            if (mKeyguardManager != null && mKeyguardManager.isDeviceLocked(userId)) {
                Log.i(TAG, "Can't change mic/cam toggle while device is locked");
                return false;
            }

            if (sensor == MICROPHONE && mUserManagerInternal.getUserRestriction(userId,
                    UserManager.DISALLOW_MICROPHONE_TOGGLE)) {
                Log.i(TAG, "Can't change mic toggle due to admin restriction");
                return false;
            }

            if (sensor == CAMERA && mUserManagerInternal.getUserRestriction(userId,
                    UserManager.DISALLOW_CAMERA_TOGGLE)) {
                Log.i(TAG, "Can't change camera toggle due to admin restriction");
                return false;
            }
            return true;
        }

        @Override
        public void setIndividualSensorPrivacyForProfileGroup(@UserIdInt int userId, int sensor,
                boolean enable) {
            enforceManageSensorPrivacyPermission();
            int parentId = mUserManagerInternal.getProfileParentId(userId);
            forAllUsers(userId2 -> {
                if (parentId == mUserManagerInternal.getProfileParentId(userId2)) {
                    setIndividualSensorPrivacy(userId2, sensor, enable);
                }
            });
        }

        /**
         * Enforces the caller contains the necessary permission to change the state of sensor
         * privacy.
         */
        private void enforceManageSensorPrivacyPermission() {
            enforcePermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY,
                    "Changing sensor privacy requires the following permission: "
                            + MANAGE_SENSOR_PRIVACY);
        }

        /**
         * Enforces the caller contains the necessary permission to observe changes to the sate of
         * sensor privacy.
         */
        private void enforceObserveSensorPrivacyPermission() {
            enforcePermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY,
                    "Observing sensor privacy changes requires the following permission: "
                            + android.Manifest.permission.OBSERVE_SENSOR_PRIVACY);
        }

        private void enforcePermission(String permission, String message) {
            if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
                return;
            }
            throw new SecurityException(message);
        }

        /**
         * Returns whether sensor privacy is enabled.
         */
        @Override
        public boolean isSensorPrivacyEnabled() {
            enforceObserveSensorPrivacyPermission();
            return isSensorPrivacyEnabled(USER_SYSTEM);
        }

        private boolean isSensorPrivacyEnabled(@UserIdInt int userId) {
            synchronized (mLock) {
                return mEnabled.get(userId, false);
            }
        }

        @Override
        public boolean isIndividualSensorPrivacyEnabled(@UserIdInt int userId, int sensor) {
            enforceObserveSensorPrivacyPermission();
            synchronized (mLock) {
                SparseBooleanArray states = mIndividualEnabled.get(userId);
                if (states == null) {
                    return false;
                }
                return states.get(sensor, false);
            }
        }

        /**
         * Returns the state of sensor privacy from persistent storage.
         */
        private boolean readPersistedSensorPrivacyStateLocked() {
            // if the file does not exist then sensor privacy has not yet been enabled on
            // the device.

            SparseArray<Object> map = new SparseArray<>();
            int version = -1;

            if (mAtomicFile.exists()) {
                try (FileInputStream inputStream = mAtomicFile.openRead()) {
                    TypedXmlPullParser parser = Xml.resolvePullParser(inputStream);
                    XmlUtils.beginDocument(parser, XML_TAG_SENSOR_PRIVACY);
                    final int persistenceVersion = parser.getAttributeInt(null,
                            XML_ATTRIBUTE_PERSISTENCE_VERSION, 0);

                    // Use inline string literals for xml tags/attrs when parsing old versions since
                    // these should never be changed even with refactorings.
                    if (persistenceVersion == 0) {
                        boolean enabled = parser.getAttributeBoolean(null, "enabled", false);
                        SparseBooleanArray individualEnabled = new SparseBooleanArray();
                        version = 0;

                        XmlUtils.nextElement(parser);
                        while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                            String tagName = parser.getName();
                            if ("individual-sensor-privacy".equals(tagName)) {
                                int sensor = XmlUtils.readIntAttribute(parser, "sensor");
                                boolean indEnabled = XmlUtils.readBooleanAttribute(parser,
                                        "enabled");
                                individualEnabled.put(sensor, indEnabled);
                                XmlUtils.skipCurrentTag(parser);
                            } else {
                                XmlUtils.nextElement(parser);
                            }
                        }
                        map.put(VER0_ENABLED, enabled);
                        map.put(VER0_INDIVIDUAL_ENABLED, individualEnabled);
                    } else if (persistenceVersion == CURRENT_PERSISTENCE_VERSION) {
                        SparseBooleanArray enabled = new SparseBooleanArray();
                        SparseArray<SparseBooleanArray> individualEnabled = new SparseArray<>();
                        version = parser.getAttributeInt(null,
                                XML_ATTRIBUTE_VERSION, 1);

                        int currentUserId = -1;
                        while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                            XmlUtils.nextElement(parser);
                            String tagName = parser.getName();
                            if (XML_TAG_USER.equals(tagName)) {
                                currentUserId = parser.getAttributeInt(null, XML_ATTRIBUTE_ID);
                                boolean isEnabled = parser.getAttributeBoolean(null,
                                        XML_ATTRIBUTE_ENABLED);
                                if (enabled.indexOfKey(currentUserId) >= 0) {
                                    Log.e(TAG, "User listed multiple times in file.",
                                            new RuntimeException());
                                    mAtomicFile.delete();
                                    version = -1;
                                    break;
                                }

                                if (mUserManagerInternal.getUserInfo(currentUserId) == null) {
                                    // User may no longer exist, skip this user
                                    currentUserId = -1;
                                    continue;
                                }

                                enabled.put(currentUserId, isEnabled);
                            }
                            if (XML_TAG_INDIVIDUAL_SENSOR_PRIVACY.equals(tagName)) {
                                if (mUserManagerInternal.getUserInfo(currentUserId) == null) {
                                    // User may no longer exist or isn't set
                                    continue;
                                }
                                int sensor = parser.getAttributeInt(null, XML_ATTRIBUTE_SENSOR);
                                boolean isEnabled = parser.getAttributeBoolean(null,
                                        XML_ATTRIBUTE_ENABLED);
                                SparseBooleanArray userIndividualEnabled = individualEnabled.get(
                                        currentUserId, new SparseBooleanArray());

                                userIndividualEnabled.put(sensor, isEnabled);
                                individualEnabled.put(currentUserId, userIndividualEnabled);
                            }
                        }

                        map.put(VER1_ENABLED, enabled);
                        map.put(VER1_INDIVIDUAL_ENABLED, individualEnabled);
                    } else {
                        Log.e(TAG, "Unknown persistence version: " + persistenceVersion
                                        + ". Deleting.",
                                new RuntimeException());
                        mAtomicFile.delete();
                        version = -1;
                    }

                } catch (IOException | XmlPullParserException e) {
                    Log.e(TAG, "Caught an exception reading the state from storage: ", e);
                    // Delete the file to prevent the same error on subsequent calls and assume
                    // sensor privacy is not enabled.
                    mAtomicFile.delete();
                    version = -1;
                }
            }

            return upgradeAndInit(version, map);
        }

        private boolean upgradeAndInit(int version, SparseArray map) {
            if (version == -1) {
                // New file, default state for current version goes here.
                mEnabled = new SparseBooleanArray();
                mIndividualEnabled = new SparseArray<>();
                forAllUsers(userId -> mEnabled.put(userId, false));
                forAllUsers(userId -> mIndividualEnabled.put(userId, new SparseBooleanArray()));
                return true;
            }
            boolean upgraded = false;
            final int[] users = getLocalService(UserManagerInternal.class).getUserIds();
            if (version == 0) {
                final boolean enabled = (boolean) map.get(VER0_ENABLED);
                final SparseBooleanArray individualEnabled =
                        (SparseBooleanArray) map.get(VER0_INDIVIDUAL_ENABLED);

                final SparseBooleanArray perUserEnabled = new SparseBooleanArray();
                final SparseArray<SparseBooleanArray> perUserIndividualEnabled =
                        new SparseArray<>();

                // Copy global state to each user
                for (int i = 0; i < users.length; i++) {
                    int user = users[i];
                    perUserEnabled.put(user, enabled);
                    SparseBooleanArray userIndividualSensorEnabled = new SparseBooleanArray();
                    perUserIndividualEnabled.put(user, userIndividualSensorEnabled);
                    for (int j = 0; j < individualEnabled.size(); j++) {
                        final int sensor = individualEnabled.keyAt(j);
                        final boolean isSensorEnabled = individualEnabled.valueAt(j);
                        userIndividualSensorEnabled.put(sensor, isSensorEnabled);
                    }
                }

                map.clear();
                map.put(VER1_ENABLED, perUserEnabled);
                map.put(VER1_INDIVIDUAL_ENABLED, perUserIndividualEnabled);

                version = 1;
                upgraded = true;
            }
            if (version == CURRENT_VERSION) {
                mEnabled = (SparseBooleanArray) map.get(VER1_ENABLED);
                mIndividualEnabled =
                        (SparseArray<SparseBooleanArray>) map.get(VER1_INDIVIDUAL_ENABLED);
            }
            return upgraded;
        }

        /**
         * Persists the state of sensor privacy.
         */
        private void persistSensorPrivacyState() {
            synchronized (mLock) {
                persistSensorPrivacyStateLocked();
            }
        }

        private void persistSensorPrivacyStateLocked() {
            FileOutputStream outputStream = null;
            try {
                outputStream = mAtomicFile.startWrite();
                TypedXmlSerializer serializer = Xml.resolveSerializer(outputStream);
                serializer.startDocument(null, true);
                serializer.startTag(null, XML_TAG_SENSOR_PRIVACY);
                serializer.attributeInt(
                        null, XML_ATTRIBUTE_PERSISTENCE_VERSION, CURRENT_PERSISTENCE_VERSION);
                serializer.attributeInt(null, XML_ATTRIBUTE_VERSION, CURRENT_VERSION);
                forAllUsers(userId -> {
                    serializer.startTag(null, XML_TAG_USER);
                    serializer.attributeInt(null, XML_ATTRIBUTE_ID, userId);
                    serializer.attributeBoolean(
                            null, XML_ATTRIBUTE_ENABLED, isSensorPrivacyEnabled(userId));

                    SparseBooleanArray individualEnabled =
                            mIndividualEnabled.get(userId, new SparseBooleanArray());
                    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);
                        serializer.attributeInt(null, XML_ATTRIBUTE_SENSOR, sensor);
                        serializer.attributeBoolean(null, XML_ATTRIBUTE_ENABLED, enabled);
                        serializer.endTag(null, XML_TAG_INDIVIDUAL_SENSOR_PRIVACY);
                    }
                    serializer.endTag(null, XML_TAG_USER);

                });
                serializer.endTag(null, XML_TAG_SENSOR_PRIVACY);
                serializer.endDocument();
                mAtomicFile.finishWrite(outputStream);
            } catch (IOException e) {
                Log.e(TAG, "Caught an exception persisting the sensor privacy state: ", e);
                mAtomicFile.failWrite(outputStream);
            }
        }

        @Override
        public boolean supportsSensorToggle(int sensor) {
            if (sensor == MICROPHONE) {
                return mContext.getResources().getBoolean(R.bool.config_supportsMicToggle);
            } else if (sensor == CAMERA) {
                return mContext.getResources().getBoolean(R.bool.config_supportsCamToggle);
            }
            throw new IllegalArgumentException("Unable to find value " + sensor);
        }

        /**
         * Registers a listener to be notified when the sensor privacy state changes.
         */
        @Override
        public void addSensorPrivacyListener(ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
            }
            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) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
            }
            mHandler.addListener(userId, sensor, listener);
        }

        /**
         * Unregisters a listener from sensor privacy state change notifications.
         */
        @Override
        public void removeSensorPrivacyListener(ISensorPrivacyListener listener) {
            enforceObserveSensorPrivacyPermission();
            if (listener == null) {
                throw new NullPointerException("listener cannot be null");
            }
            mHandler.removeListener(listener);
        }

        @Override
        public void suppressIndividualSensorPrivacyReminders(int userId, String packageName,
                IBinder token, boolean suppress) {
            enforceManageSensorPrivacyPermission();
            Objects.requireNonNull(packageName);
            Objects.requireNonNull(token);

            Pair<String, UserHandle> key = new Pair<>(packageName, UserHandle.of(userId));

            synchronized (mLock) {
                if (suppress) {
                    try {
                        token.linkToDeath(this, 0);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Could not suppress sensor use reminder", e);
                        return;
                    }

                    ArrayList<IBinder> suppressPackageReminderTokens = mSuppressReminders.get(key);
                    if (suppressPackageReminderTokens == null) {
                        suppressPackageReminderTokens = new ArrayList<>(1);
                        mSuppressReminders.put(key, suppressPackageReminderTokens);
                    }

                    suppressPackageReminderTokens.add(token);
                } else {
                    mHandler.removeSuppressPackageReminderToken(key, token);
                }
            }
        }

        /**
         * Remove a sensor use reminder suppression token.
         *
         * @param key Key the token is in
         * @param token The token to remove
         */
        private void removeSuppressPackageReminderToken(@NonNull Pair<String, UserHandle> key,
                @NonNull IBinder token) {
            synchronized (mLock) {
                ArrayList<IBinder> suppressPackageReminderTokens =
                        mSuppressReminders.get(key);
                if (suppressPackageReminderTokens == null) {
                    Log.e(TAG, "No tokens for " + key);
                    return;
                }

                boolean wasRemoved = suppressPackageReminderTokens.remove(token);
                if (wasRemoved) {
                    token.unlinkToDeath(this, 0);

                    if (suppressPackageReminderTokens.isEmpty()) {
                        mSuppressReminders.remove(key);
                    }
                } else {
                    Log.w(TAG, "Could not remove sensor use reminder suppression token " + token
                            + " from " + key);
                }
            }
        }

        /**
         * A owner of a suppressor token died. Clean up.
         *
         * @param token The token that is invalid now.
         */
        @Override
        public void binderDied(@NonNull IBinder token) {
            synchronized (mLock) {
                for (Pair<String, UserHandle> key : mSuppressReminders.keySet()) {
                    removeSuppressPackageReminderToken(key, token);
                }
            }
        }

        @Override
        public void binderDied() {
            // Handled in binderDied(IBinder)
        }

        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            Objects.requireNonNull(fd);

            if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

            int opti = 0;
            boolean dumpAsProto = false;
            while (opti < args.length) {
                String opt = args[opti];
                if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
                    break;
                }
                opti++;
                if ("--proto".equals(opt)) {
                    dumpAsProto = true;
                } else {
                    pw.println("Unknown argument: " + opt + "; use -h for help");
                }
            }

            final long identity = Binder.clearCallingIdentity();
            try {
                if (dumpAsProto) {
                    dump(new DualDumpOutputStream(new ProtoOutputStream(fd)));
                } else {
                    pw.println("SENSOR PRIVACY MANAGER STATE (dumpsys "
                            + Context.SENSOR_PRIVACY_SERVICE + ")");

                    dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, "  ")));
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }

        /**
         * Dump state to {@link DualDumpOutputStream}.
         *
         * @param dumpStream The destination to dump to
         */
        private void dump(@NonNull DualDumpOutputStream dumpStream) {
            synchronized (mLock) {

                forAllUsers(userId -> {
                    long userToken = dumpStream.start("users", SensorPrivacyServiceDumpProto.USER);
                    dumpStream.write("user_id", SensorPrivacyUserProto.USER_ID, userId);
                    dumpStream.write("is_enabled", SensorPrivacyUserProto.IS_ENABLED,
                            mEnabled.get(userId, false));

                    SparseBooleanArray individualEnabled = mIndividualEnabled.get(userId);
                    if (individualEnabled != null) {
                        int numIndividualEnabled = individualEnabled.size();
                        for (int i = 0; i < numIndividualEnabled; i++) {
                            long individualToken = dumpStream.start("individual_enabled_sensor",
                                    SensorPrivacyUserProto.INDIVIDUAL_ENABLED_SENSOR);

                            dumpStream.write("sensor",
                                    SensorPrivacyIndividualEnabledSensorProto.SENSOR,
                                    individualEnabled.keyAt(i));
                            dumpStream.write("is_enabled",
                                    SensorPrivacyIndividualEnabledSensorProto.IS_ENABLED,
                                    individualEnabled.valueAt(i));

                            dumpStream.end(individualToken);
                        }
                    }
                    dumpStream.end(userToken);
                });
            }

            dumpStream.flush();
        }

        /**
         * Convert a string into a {@link SensorPrivacyManager.Sensors.Sensor id}.
         *
         * @param sensor The name to convert
         *
         * @return The id corresponding to the name
         */
        private @SensorPrivacyManager.Sensors.Sensor int sensorStrToId(@Nullable String sensor) {
            if (sensor == null) {
                return UNKNOWN;
            }

            switch (sensor) {
                case "microphone":
                    return MICROPHONE;
                case "camera":
                    return CAMERA;
                default: {
                    return UNKNOWN;
                }
            }
        }

        @Override
        public void onShellCommand(FileDescriptor in, FileDescriptor out,
                FileDescriptor err, String[] args, ShellCallback callback,
                ResultReceiver resultReceiver) {
            (new ShellCommand() {
                @Override
                public int onCommand(String cmd) {
                    if (cmd == null) {
                        return handleDefaultCommands(cmd);
                    }

                    int userId = Integer.parseInt(getNextArgRequired());

                    final PrintWriter pw = getOutPrintWriter();
                    switch (cmd) {
                        case "enable" : {
                            int sensor = sensorStrToId(getNextArgRequired());
                            if (sensor == UNKNOWN) {
                                pw.println("Invalid sensor");
                                return -1;
                            }

                            setIndividualSensorPrivacy(userId, sensor, true);
                        }
                        break;
                        case "disable" : {
                            int sensor = sensorStrToId(getNextArgRequired());
                            if (sensor == UNKNOWN) {
                                pw.println("Invalid sensor");
                                return -1;
                            }

                            setIndividualSensorPrivacy(userId, sensor, false);
                        }
                        break;
                        case "reset": {
                            int sensor = sensorStrToId(getNextArgRequired());
                            if (sensor == UNKNOWN) {
                                pw.println("Invalid sensor");
                                return -1;
                            }

                            enforceManageSensorPrivacyPermission();

                            synchronized (mLock) {
                                SparseBooleanArray individualEnabled =
                                        mIndividualEnabled.get(userId);
                                if (individualEnabled != null) {
                                    individualEnabled.delete(sensor);
                                }
                                persistSensorPrivacyState();
                            }
                        }
                        break;
                        default:
                            return handleDefaultCommands(cmd);
                    }

                    return 0;
                }

                @Override
                public void onHelp() {
                    final PrintWriter pw = getOutPrintWriter();

                    pw.println("Sensor privacy manager (" + Context.SENSOR_PRIVACY_SERVICE
                            + ") commands:");
                    pw.println("  help");
                    pw.println("    Print this help text.");
                    pw.println("");
                    pw.println("  enable USER_ID SENSOR");
                    pw.println("    Enable privacy for a certain sensor.");
                    pw.println("");
                    pw.println("  disable USER_ID SENSOR");
                    pw.println("    Disable privacy for a certain sensor.");
                    pw.println("");
                    pw.println("  reset USER_ID SENSOR");
                    pw.println("    Reset privacy state for a certain sensor.");
                    pw.println("");
                }
            }).exec(this, in, out, err, args, callback, resultReceiver);
        }
    }

    /**
     * Handles sensor privacy state changes and notifying listeners of the change.
     */
    private final class SensorPrivacyHandler extends Handler {
        private static final int MESSAGE_SENSOR_PRIVACY_CHANGED = 1;

        private final Object mListenerLock = new Object();

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

        SensorPrivacyHandler(Looper looper, Context context) {
            super(looper);
            mDeathRecipients = new ArrayMap<>();
            mContext = context;
        }

        public void onSensorPrivacyChanged(boolean enabled) {
            sendMessage(PooledLambda.obtainMessage(SensorPrivacyHandler::handleSensorPrivacyChanged,
                    this, enabled));
            sendMessage(
                    PooledLambda.obtainMessage(SensorPrivacyServiceImpl::persistSensorPrivacyState,
                            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);
                mDeathRecipients.put(listener, deathRecipient);
                mListeners.register(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) {
                    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);
                if (deathRecipient != null) {
                    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);
                    }
                }
            }
        }

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

        public void handleSensorPrivacyChanged(int userId, int sensor, boolean enabled) {
            mSensorPrivacyManagerInternal.dispatch(userId, sensor, enabled);
            SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
                    mIndividualSensorListeners.get(userId);

            setUserRestriction(userId, sensor, enabled);

            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();
        }

        public void removeSuppressPackageReminderToken(Pair<String, UserHandle> key,
                IBinder token) {
            sendMessage(PooledLambda.obtainMessage(
                    SensorPrivacyServiceImpl::removeSuppressPackageReminderToken,
                    mSensorPrivacyServiceImpl, key, token));
        }
    }

    private void setUserRestriction(int userId, int sensor, boolean enabled) {
        if (sensor == CAMERA) {
            mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled,
                    mAppOpsRestrictionToken, null, userId);
        } else if (sensor == MICROPHONE) {
            mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled,
                    mAppOpsRestrictionToken, null, userId);
            mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled,
                    mAppOpsRestrictionToken, null, userId);
        }
    }

    private final class DeathRecipient implements IBinder.DeathRecipient {

        private ISensorPrivacyListener mListener;

        DeathRecipient(ISensorPrivacyListener listener) {
            mListener = listener;
            try {
                mListener.asBinder().linkToDeath(this, 0);
            } catch (RemoteException e) {
            }
        }

        @Override
        public void binderDied() {
            mSensorPrivacyServiceImpl.removeSensorPrivacyListener(mListener);
        }

        public void destroy() {
            try {
                mListener.asBinder().unlinkToDeath(this, 0);
            } catch (NoSuchElementException e) {
            }
        }
    }

    private void forAllUsers(FunctionalUtils.ThrowingConsumer<Integer> c) {
        int[] userIds = mUserManagerInternal.getUserIds();
        for (int i = 0; i < userIds.length; i++) {
            c.accept(userIds[i]);
        }
    }

    private class SensorPrivacyManagerInternalImpl extends SensorPrivacyManagerInternal {

        private ArrayMap<Integer, ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>>>
                mListeners = new ArrayMap<>();
        private ArrayMap<Integer, ArraySet<OnUserSensorPrivacyChangedListener>> mAllUserListeners =
                new ArrayMap<>();

        private final Object mLock = new Object();

        private void dispatch(int userId, int sensor, boolean enabled) {
            synchronized (mLock) {
                ArraySet<OnUserSensorPrivacyChangedListener> allUserSensorListeners =
                        mAllUserListeners.get(sensor);
                if (allUserSensorListeners != null) {
                    for (int i = 0; i < allUserSensorListeners.size(); i++) {
                        OnUserSensorPrivacyChangedListener listener =
                                allUserSensorListeners.valueAt(i);
                        BackgroundThread.getHandler().post(() ->
                                listener.onSensorPrivacyChanged(userId, enabled));
                    }
                }

                ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>> userSensorListeners =
                        mListeners.get(userId);
                if (userSensorListeners != null) {
                    ArraySet<OnSensorPrivacyChangedListener> sensorListeners =
                            userSensorListeners.get(sensor);
                    if (sensorListeners != null) {
                        for (int i = 0; i < sensorListeners.size(); i++) {
                            OnSensorPrivacyChangedListener listener = sensorListeners.valueAt(i);
                            BackgroundThread.getHandler().post(() ->
                                    listener.onSensorPrivacyChanged(enabled));
                        }
                    }
                }
            }
        }

        @Override
        public boolean isSensorPrivacyEnabled(int userId, int sensor) {
            return SensorPrivacyService.this
                    .mSensorPrivacyServiceImpl.isIndividualSensorPrivacyEnabled(userId, sensor);
        }

        @Override
        public void addSensorPrivacyListener(int userId, int sensor,
                OnSensorPrivacyChangedListener listener) {
            synchronized (mLock) {
                ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>> userSensorListeners =
                        mListeners.get(userId);
                if (userSensorListeners == null) {
                    userSensorListeners = new ArrayMap<>();
                    mListeners.put(userId, userSensorListeners);
                }

                ArraySet<OnSensorPrivacyChangedListener> sensorListeners =
                        userSensorListeners.get(sensor);
                if (sensorListeners == null) {
                    sensorListeners = new ArraySet<>();
                    userSensorListeners.put(sensor, sensorListeners);
                }

                sensorListeners.add(listener);
            }
        }

        @Override
        public void addSensorPrivacyListenerForAllUsers(int sensor,
                OnUserSensorPrivacyChangedListener listener) {
            synchronized (mLock) {
                ArraySet<OnUserSensorPrivacyChangedListener> sensorListeners =
                        mAllUserListeners.get(sensor);
                if (sensorListeners == null) {
                    sensorListeners = new ArraySet<>();
                    mAllUserListeners.put(sensor, sensorListeners);
                }

                sensorListeners.add(listener);
            }
        }
    }

    private class EmergencyCallHelper {
        private OutogingEmergencyStateCallback mEmergencyStateCallback;
        private CallStateCallback mCallStateCallback;

        private boolean mIsInEmergencyCall;
        private boolean mMicUnmutedForEmergencyCall;

        private Object mEmergencyStateLock = new Object();

        EmergencyCallHelper() {
            mEmergencyStateCallback = new OutogingEmergencyStateCallback();
            mCallStateCallback = new CallStateCallback();

            mTelephonyManager.registerTelephonyCallback(FgThread.getExecutor(),
                    mEmergencyStateCallback);
            mTelephonyManager.registerTelephonyCallback(FgThread.getExecutor(),
                    mCallStateCallback);
        }

        boolean isInEmergencyCall() {
            synchronized (mEmergencyStateLock) {
                return mIsInEmergencyCall;
            }
        }

        private class OutogingEmergencyStateCallback extends TelephonyCallback implements
                TelephonyCallback.OutgoingEmergencyCallListener {
            @Override
            public void onOutgoingEmergencyCall(EmergencyNumber placedEmergencyNumber,
                    int subscriptionId) {
                onEmergencyCall();
            }
        }

        private class CallStateCallback extends TelephonyCallback implements
                TelephonyCallback.CallStateListener {
            @Override
            public void onCallStateChanged(int state) {
                if (state == TelephonyManager.CALL_STATE_IDLE) {
                    onCallOver();
                }
            }
        }

        private void onEmergencyCall() {
            synchronized (mEmergencyStateLock) {
                if (!mIsInEmergencyCall) {
                    mIsInEmergencyCall = true;
                    if (mSensorPrivacyServiceImpl
                            .isIndividualSensorPrivacyEnabled(getCurrentUser(), MICROPHONE)) {
                        mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
                                getCurrentUser(), MICROPHONE, false);
                        mMicUnmutedForEmergencyCall = true;
                    } else {
                        mMicUnmutedForEmergencyCall = false;
                    }
                }
            }
        }

        private void onCallOver() {
            synchronized (mEmergencyStateLock) {
                if (mIsInEmergencyCall) {
                    mIsInEmergencyCall = false;
                    if (mMicUnmutedForEmergencyCall) {
                        mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
                                getCurrentUser(), MICROPHONE, true);
                        mMicUnmutedForEmergencyCall = false;
                    }
                }
            }
        }
    }
}
