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

Commit 0f9d5aea authored by Evan Severson's avatar Evan Severson
Browse files

Expose SensorPrivacy as SystemApi

Rename the apis to be more consistent.
Also expose to test api.
Have the aosp mark that it supports the toggle features by default.

Test: atest CtsSensorPrivacyTestCases
Bug: 162549680

Change-Id: Ib38c16adfc5cec931347e1a1891618983d78248b
parent 9924535b
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ package android {
    field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
    field public static final String OBSERVE_NETWORK_POLICY = "android.permission.OBSERVE_NETWORK_POLICY";
    field public static final String OBSERVE_ROLE_HOLDERS = "android.permission.OBSERVE_ROLE_HOLDERS";
    field public static final String OBSERVE_SENSOR_PRIVACY = "android.permission.OBSERVE_SENSOR_PRIVACY";
    field public static final String OPEN_ACCESSIBILITY_DETAILS_SETTINGS = "android.permission.OPEN_ACCESSIBILITY_DETAILS_SETTINGS";
    field public static final String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
    field public static final String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
@@ -2545,10 +2546,12 @@ package android.content.pm {
    field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
    field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
    field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
    field public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";
    field public static final String FEATURE_CONTEXT_HUB = "android.hardware.context_hub";
    field public static final String FEATURE_CROSS_LAYER_BLUR = "android.software.cross_layer_blur";
    field @Deprecated public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery";
    field public static final String FEATURE_INCREMENTAL_DELIVERY_VERSION = "android.software.incremental_delivery_version";
    field public static final String FEATURE_MICROPHONE_TOGGLE = "android.hardware.microphone.toggle";
    field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow";
    field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock";
    field public static final String FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION = "android.hardware.telephony.ims.singlereg";
@@ -2903,6 +2906,22 @@ package android.hardware {
    method public boolean injectSensorData(android.hardware.Sensor, float[], int, long);
  }
  public final class SensorPrivacyManager {
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void addSensorPrivacyListener(int, @NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void addSensorPrivacyListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public boolean isSensorPrivacyEnabled(int);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void removeSensorPrivacyListener(@NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
  }
  public static interface SensorPrivacyManager.OnSensorPrivacyChangedListener {
    method public void onSensorPrivacyChanged(boolean);
  }
  public static class SensorPrivacyManager.Sensors {
    field public static final int CAMERA = 2; // 0x2
    field public static final int MICROPHONE = 1; // 0x1
  }
}
package android.hardware.biometrics {
+17 −5
Original line number Diff line number Diff line
@@ -696,8 +696,10 @@ package android.content.pm {
    method public void holdLock(android.os.IBinder, int);
    method @RequiresPermission(android.Manifest.permission.KEEP_UNINSTALLED_PACKAGES) public void setKeepUninstalledPackages(@NonNull java.util.List<java.lang.String>);
    field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
    field public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";
    field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
    field public static final String FEATURE_HDMI_CEC = "android.hardware.hdmi.cec";
    field public static final String FEATURE_MICROPHONE_TOGGLE = "android.hardware.microphone.toggle";
    field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80
    field public static final int MATCH_KNOWN_PACKAGES = 4202496; // 0x402000
    field public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
@@ -858,11 +860,21 @@ package android.graphics.fonts {
package android.hardware {

  public final class SensorPrivacyManager {
    method public boolean isIndividualSensorPrivacyEnabled(int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setIndividualSensorPrivacy(int, boolean);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setIndividualSensorPrivacyForProfileGroup(int, boolean);
    field public static final int INDIVIDUAL_SENSOR_CAMERA = 2; // 0x2
    field public static final int INDIVIDUAL_SENSOR_MICROPHONE = 1; // 0x1
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void addSensorPrivacyListener(int, @NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void addSensorPrivacyListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public boolean isSensorPrivacyEnabled(int);
    method @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY) public void removeSensorPrivacyListener(@NonNull android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacy(int, boolean);
    method @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public void setSensorPrivacyForProfileGroup(int, boolean);
  }

  public static interface SensorPrivacyManager.OnSensorPrivacyChangedListener {
    method public void onSensorPrivacyChanged(boolean);
  }

  public static class SensorPrivacyManager.Sensors {
    field public static final int CAMERA = 2; // 0x2
    field public static final int MICROPHONE = 1; // 0x1
  }

}
+16 −1
Original line number Diff line number Diff line
@@ -3623,11 +3623,26 @@ public abstract class PackageManager {
    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports a enabling/disabling sensor privacy for
     * camera. When sensory privacy for the camera is enabled no camera data is send to clients,
     * microphone. When sensory privacy for the microphone is enabled no microphone data is sent to
     * clients, e.g. all audio data is silent.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_MICROPHONE_TOGGLE = "android.hardware.microphone.toggle";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports a enabling/disabling sensor privacy for
     * camera. When sensory privacy for the camera is enabled no camera data is sent to clients,
     * e.g. the view finder in a camera app would appear blank.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";

+85 −29
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.hardware;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
@@ -33,6 +34,7 @@ import com.android.internal.annotations.GuardedBy;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;

/**
 * This class provides access to the sensor privacy services; sensor privacy allows the
@@ -42,9 +44,21 @@ import java.lang.annotation.RetentionPolicy;
 *
 * @hide
 */
@SystemApi
@TestApi
@SystemService(Context.SENSOR_PRIVACY_SERVICE)
public final class SensorPrivacyManager {

    /**
     * @hide
     */
    public static final boolean USE_MICROPHONE_TOGGLE = true;

    /**
     * @hide
     */
    public static final boolean USE_CAMERA_TOGGLE = true;

    /**
     * Unique Id of this manager to identify to the service
     * @hide
@@ -58,28 +72,39 @@ public final class SensorPrivacyManager {
    public static final String EXTRA_SENSOR = SensorPrivacyManager.class.getName()
            + ".extra.sensor";

    /**
     * Individual sensors not listed in {@link Sensors}
     * @hide
     */
    @SystemApi
    @TestApi
    public static class Sensors {

        private Sensors() {}

        /** Microphone
         * @hide */
        @SystemApi
        @TestApi
    public static final int INDIVIDUAL_SENSOR_MICROPHONE =
            SensorPrivacyIndividualEnabledSensorProto.MICROPHONE;

        public static final int MICROPHONE = SensorPrivacyIndividualEnabledSensorProto.MICROPHONE;
        /** Camera
         * @hide */
        @SystemApi
        @TestApi
    public static final int INDIVIDUAL_SENSOR_CAMERA =
            SensorPrivacyIndividualEnabledSensorProto.CAMERA;
        public static final int CAMERA = SensorPrivacyIndividualEnabledSensorProto.CAMERA;

        /**
     * Individual sensors not listed in {@link Sensor}
         * Individual sensors not listed in {@link Sensors}
         *
         * @hide
         */
    @IntDef(prefix = "INDIVIDUAL_SENSOR_", value = {
            INDIVIDUAL_SENSOR_MICROPHONE,
            INDIVIDUAL_SENSOR_CAMERA
        @IntDef(value = {
                MICROPHONE,
                CAMERA
        })
        @Retention(RetentionPolicy.SOURCE)
    public @interface IndividualSensor {}
        public @interface Sensor {}
    }

    /**
     * A class implementing this interface can register with the {@link
@@ -88,6 +113,8 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public interface OnSensorPrivacyChangedListener {
        /**
         * Callback invoked when the sensor privacy state changes.
@@ -165,7 +192,8 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    public void addSensorPrivacyListener(final OnSensorPrivacyChangedListener listener) {
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void addSensorPrivacyListener(@NonNull final OnSensorPrivacyChangedListener listener) {
        synchronized (mListeners) {
            ISensorPrivacyListener iListener = mListeners.get(listener);
            if (iListener == null) {
@@ -196,15 +224,37 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    public void addSensorPrivacyListener(@IndividualSensor int sensor,
            final OnSensorPrivacyChangedListener listener) {
    @SystemApi
    @TestApi
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void addSensorPrivacyListener(@Sensors.Sensor int sensor,
            @NonNull OnSensorPrivacyChangedListener listener) {
        addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener);
    }

    /**
     * Registers a new listener to receive notification when the state of sensor privacy
     * changes.
     *
     * @param sensor the sensor to listen to changes to
     * @param executor the executor to dispatch the callback on
     * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor
     *                 privacy changes.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor,
            @NonNull OnSensorPrivacyChangedListener listener) {
        synchronized (mListeners) {
            ISensorPrivacyListener iListener = mListeners.get(listener);
            if (iListener == null) {
                iListener = new ISensorPrivacyListener.Stub() {
                    @Override
                    public void onSensorPrivacyChanged(boolean enabled) {
                        listener.onSensorPrivacyChanged(enabled);
                        executor.execute(() -> listener.onSensorPrivacyChanged(enabled));
                    }
                };
                mListeners.put(listener, iListener);
@@ -228,7 +278,10 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    public void removeSensorPrivacyListener(OnSensorPrivacyChangedListener listener) {
    @SystemApi
    @TestApi
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public void removeSensorPrivacyListener(@NonNull OnSensorPrivacyChangedListener listener) {
        synchronized (mListeners) {
            ISensorPrivacyListener iListener = mListeners.get(listener);
            if (iListener != null) {
@@ -249,6 +302,7 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public boolean isSensorPrivacyEnabled() {
        try {
            return mService.isSensorPrivacyEnabled();
@@ -264,8 +318,10 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public boolean isIndividualSensorPrivacyEnabled(@IndividualSensor int sensor) {
    @RequiresPermission(android.Manifest.permission.OBSERVE_SENSOR_PRIVACY)
    public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) {
        try {
            return mService.isIndividualSensorPrivacyEnabled(mContext.getUserId(), sensor);
        } catch (RemoteException e) {
@@ -283,8 +339,7 @@ public final class SensorPrivacyManager {
     */
    @TestApi
    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
    public void setIndividualSensorPrivacy(@IndividualSensor int sensor,
            boolean enable) {
    public void setSensorPrivacy(@Sensors.Sensor int sensor, boolean enable) {
        try {
            mService.setIndividualSensorPrivacy(mContext.getUserId(), sensor, enable);
        } catch (RemoteException e) {
@@ -303,7 +358,7 @@ public final class SensorPrivacyManager {
     */
    @TestApi
    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
    public void setIndividualSensorPrivacyForProfileGroup(@IndividualSensor int sensor,
    public void setSensorPrivacyForProfileGroup(@Sensors.Sensor int sensor,
            boolean enable) {
        try {
            mService.setIndividualSensorPrivacyForProfileGroup(mContext.getUserId(), sensor,
@@ -321,7 +376,8 @@ public final class SensorPrivacyManager {
     *
     * @hide
     */
    public void suppressIndividualSensorPrivacyReminders(@NonNull String packageName,
    @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY)
    public void suppressSensorPrivacyReminders(@NonNull String packageName,
            boolean suppress) {
        try {
            mService.suppressIndividualSensorPrivacyReminders(mContext.getUserId(), packageName,
+9 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.hardware.SensorPrivacyManager;
import android.os.Build;
import android.os.CarrierAssociatedAppEntry;
import android.os.Environment;
@@ -1252,6 +1253,14 @@ public class SystemConfig {
            addFeature(PackageManager.FEATURE_CROSS_LAYER_BLUR, 0);
        }

        if (SensorPrivacyManager.USE_MICROPHONE_TOGGLE) {
            addFeature(PackageManager.FEATURE_MICROPHONE_TOGGLE, 0);
        }

        if (SensorPrivacyManager.USE_CAMERA_TOGGLE) {
            addFeature(PackageManager.FEATURE_CAMERA_TOGGLE, 0);
        }

        for (String featureName : mUnavailableFeatures) {
            removeFeature(featureName);
        }
Loading