1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware; 18 19 import android.Manifest; 20 import android.annotation.FlaggedApi; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.annotation.SystemService; 26 import android.annotation.TestApi; 27 import android.annotation.UserIdInt; 28 import android.content.Context; 29 import android.os.Binder; 30 import android.os.IBinder; 31 import android.os.RemoteException; 32 import android.os.ServiceManager; 33 import android.os.UserHandle; 34 import android.service.SensorPrivacyIndividualEnabledSensorProto; 35 import android.service.SensorPrivacySensorProto; 36 import android.service.SensorPrivacyToggleSourceProto; 37 import android.util.ArrayMap; 38 import android.util.Log; 39 import android.util.Pair; 40 41 import com.android.internal.annotations.GuardedBy; 42 import com.android.internal.camera.flags.Flags; 43 44 import java.lang.annotation.Retention; 45 import java.lang.annotation.RetentionPolicy; 46 import java.util.List; 47 import java.util.Objects; 48 import java.util.concurrent.Executor; 49 50 /** 51 * This class provides information about the microphone and camera toggles. 52 */ 53 @SystemService(Context.SENSOR_PRIVACY_SERVICE) 54 public final class SensorPrivacyManager { 55 56 private static final String LOG_TAG = SensorPrivacyManager.class.getSimpleName(); 57 58 /** 59 * Unique Id of this manager to identify to the service 60 * @hide 61 */ 62 private IBinder token = new Binder(); 63 64 /** 65 * An extra containing a sensor 66 * @hide 67 */ 68 public static final String EXTRA_SENSOR = SensorPrivacyManager.class.getName() 69 + ".extra.sensor"; 70 71 /** 72 * An extra containing the notification id that triggered the intent 73 * @hide 74 */ 75 public static final String EXTRA_NOTIFICATION_ID = SensorPrivacyManager.class.getName() 76 + ".extra.notification_id"; 77 78 /** 79 * An extra indicating if all sensors are affected 80 * @hide 81 */ 82 public static final String EXTRA_ALL_SENSORS = SensorPrivacyManager.class.getName() 83 + ".extra.all_sensors"; 84 85 /** 86 * An extra containing the sensor type 87 * @hide 88 */ 89 public static final String EXTRA_TOGGLE_TYPE = SensorPrivacyManager.class.getName() 90 + ".extra.toggle_type"; 91 92 /** 93 * Sensor constants which are used in {@link SensorPrivacyManager} 94 */ 95 public static class Sensors { 96 Sensors()97 private Sensors() {} 98 99 /** 100 * Constant for the microphone 101 */ 102 public static final int MICROPHONE = SensorPrivacySensorProto.MICROPHONE; 103 104 /** 105 * Constant for the camera 106 */ 107 public static final int CAMERA = SensorPrivacySensorProto.CAMERA; 108 109 /** 110 * Individual sensors not listed in {@link Sensors} 111 * 112 * @hide 113 */ 114 @IntDef(value = { 115 MICROPHONE, 116 CAMERA 117 }) 118 @Retention(RetentionPolicy.SOURCE) 119 public @interface Sensor {} 120 } 121 122 /** 123 * Source through which Privacy Sensor was toggled. 124 * @hide 125 */ 126 @TestApi 127 public static class Sources { Sources()128 private Sources() {} 129 130 /** 131 * Constant for the Quick Setting Tile. 132 */ 133 public static final int QS_TILE = SensorPrivacyToggleSourceProto.QS_TILE; 134 135 /** 136 * Constant for the Settings. 137 */ 138 public static final int SETTINGS = SensorPrivacyToggleSourceProto.SETTINGS; 139 140 /** 141 * Constant for Dialog. 142 */ 143 public static final int DIALOG = SensorPrivacyToggleSourceProto.DIALOG; 144 145 /** 146 * Constant for SHELL. 147 */ 148 public static final int SHELL = SensorPrivacyToggleSourceProto.SHELL; 149 150 /** 151 * Constant for OTHER. 152 */ 153 public static final int OTHER = SensorPrivacyToggleSourceProto.OTHER; 154 155 /** 156 * Constant for SAFETY_CENTER. 157 */ 158 public static final int SAFETY_CENTER = SensorPrivacyToggleSourceProto.SAFETY_CENTER; 159 160 /** 161 * Source for toggling sensors 162 * 163 * @hide 164 */ 165 @IntDef(value = { 166 QS_TILE, 167 SETTINGS, 168 DIALOG, 169 SHELL, 170 OTHER, 171 SAFETY_CENTER 172 }) 173 @Retention(RetentionPolicy.SOURCE) 174 public @interface Source {} 175 176 } 177 178 179 /** 180 * Constant for software toggle. 181 */ 182 public static final int TOGGLE_TYPE_SOFTWARE = 183 SensorPrivacyIndividualEnabledSensorProto.SOFTWARE; 184 185 /** 186 * Constant for hardware toggle. 187 */ 188 public static final int TOGGLE_TYPE_HARDWARE = 189 SensorPrivacyIndividualEnabledSensorProto.HARDWARE; 190 191 /** 192 * Types of toggles which can exist for sensor privacy 193 * 194 * @hide 195 */ 196 @IntDef(value = { 197 TOGGLE_TYPE_SOFTWARE, 198 TOGGLE_TYPE_HARDWARE 199 }) 200 @Retention(RetentionPolicy.SOURCE) 201 public @interface ToggleType {} 202 203 /** 204 * Types of state which can exist for the sensor privacy toggle 205 * @hide 206 */ 207 @SystemApi 208 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) 209 public static class StateTypes { StateTypes()210 private StateTypes() {} 211 212 /** 213 * Constant indicating privacy is enabled. 214 */ 215 public static final int ENABLED = SensorPrivacyIndividualEnabledSensorProto.ENABLED; 216 217 /** 218 * Constant indicating privacy is disabled. 219 */ 220 public static final int DISABLED = SensorPrivacyIndividualEnabledSensorProto.DISABLED; 221 222 /** 223 * Constant indicating privacy is enabled except for the automotive driver assistance apps 224 * which are required by car manufacturer for driving. 225 */ 226 public static final int ENABLED_EXCEPT_ALLOWLISTED_APPS = 227 SensorPrivacyIndividualEnabledSensorProto.ENABLED_EXCEPT_ALLOWLISTED_APPS; 228 229 /** 230 * Types of state which can exist for a sensor privacy toggle 231 * 232 * @hide 233 */ 234 @IntDef(value = { 235 ENABLED, 236 DISABLED, 237 ENABLED_EXCEPT_ALLOWLISTED_APPS 238 }) 239 @Retention(RetentionPolicy.SOURCE) 240 public @interface StateType {} 241 242 } 243 244 /** 245 * A class implementing this interface can register with the {@link 246 * android.hardware.SensorPrivacyManager} to receive notification when the sensor privacy 247 * state changes. 248 * 249 * @hide 250 */ 251 @SystemApi 252 public interface OnSensorPrivacyChangedListener { 253 /** 254 * Callback invoked when the sensor privacy state changes. 255 * 256 * @param params Parameters describing the new state 257 */ onSensorPrivacyChanged(@onNull SensorPrivacyChangedParams params)258 default void onSensorPrivacyChanged(@NonNull SensorPrivacyChangedParams params) { 259 onSensorPrivacyChanged(params.mSensor, params.mEnabled); 260 } 261 262 /** 263 * Callback invoked when the sensor privacy state changes. 264 * 265 * @param sensor the sensor whose state is changing 266 * @param enabled true if sensor privacy is enabled, false otherwise. 267 * 268 * @deprecated Please use 269 * {@link #onSensorPrivacyChanged(SensorPrivacyChangedParams)} 270 */ 271 @Deprecated onSensorPrivacyChanged(int sensor, boolean enabled)272 void onSensorPrivacyChanged(int sensor, boolean enabled); 273 274 /** 275 * A class containing information about what the sensor privacy state has changed to. 276 */ 277 class SensorPrivacyChangedParams { 278 279 private int mToggleType; 280 private int mSensor; 281 private boolean mEnabled; 282 private int mState; 283 284 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) SensorPrivacyChangedParams(int toggleType, int sensor, int state)285 private SensorPrivacyChangedParams(int toggleType, int sensor, int state) { 286 mToggleType = toggleType; 287 mSensor = sensor; 288 mState = state; 289 if (state == StateTypes.ENABLED) { 290 mEnabled = true; 291 } else { 292 mEnabled = false; 293 } 294 } 295 SensorPrivacyChangedParams(int toggleType, int sensor, boolean enabled)296 private SensorPrivacyChangedParams(int toggleType, int sensor, boolean enabled) { 297 mToggleType = toggleType; 298 mSensor = sensor; 299 mEnabled = enabled; 300 } 301 getToggleType()302 public @ToggleType int getToggleType() { 303 return mToggleType; 304 } 305 getSensor()306 public @Sensors.Sensor int getSensor() { 307 return mSensor; 308 } 309 isEnabled()310 public boolean isEnabled() { 311 return mEnabled; 312 } 313 314 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) getState()315 public @StateTypes.StateType int getState() { 316 return mState; 317 } 318 319 } 320 } 321 322 private static final Object sInstanceLock = new Object(); 323 324 private final Object mLock = new Object(); 325 326 @GuardedBy("sInstanceLock") 327 private static SensorPrivacyManager sInstance; 328 329 @NonNull 330 private final Context mContext; 331 332 @NonNull 333 private final ISensorPrivacyManager mService; 334 335 @GuardedBy("mLock") 336 private final ArrayMap<Pair<Integer, Integer>, Boolean> mToggleSupportCache = new ArrayMap<>(); 337 338 @NonNull 339 private final ArrayMap<OnAllSensorPrivacyChangedListener, ISensorPrivacyListener> mListeners; 340 341 /** Registered listeners */ 342 @GuardedBy("mLock") 343 @NonNull 344 private final ArrayMap<OnSensorPrivacyChangedListener, Executor> mToggleListeners = 345 new ArrayMap<>(); 346 347 /** Listeners registered using the deprecated APIs and which 348 * OnSensorPrivacyChangedListener they're using. */ 349 @GuardedBy("mLock") 350 @NonNull 351 private final ArrayMap<Pair<Integer, OnSensorPrivacyChangedListener>, 352 OnSensorPrivacyChangedListener> mLegacyToggleListeners = new ArrayMap<>(); 353 354 /** The singleton ISensorPrivacyListener for IPC which will be used to dispatch to local 355 * listeners */ 356 @NonNull 357 private final ISensorPrivacyListener mIToggleListener = new ISensorPrivacyListener.Stub() { 358 @Override 359 public void onSensorPrivacyChanged(int toggleType, int sensor, boolean enabled) { 360 synchronized (mLock) { 361 for (int i = 0; i < mToggleListeners.size(); i++) { 362 OnSensorPrivacyChangedListener listener = mToggleListeners.keyAt(i); 363 if (Flags.cameraPrivacyAllowlist()) { 364 int state = enabled ? StateTypes.ENABLED : StateTypes.DISABLED; 365 mToggleListeners.valueAt(i).execute(() -> listener 366 .onSensorPrivacyChanged(new OnSensorPrivacyChangedListener 367 .SensorPrivacyChangedParams(toggleType, sensor, state))); 368 } else { 369 mToggleListeners.valueAt(i).execute(() -> listener 370 .onSensorPrivacyChanged(new OnSensorPrivacyChangedListener 371 .SensorPrivacyChangedParams(toggleType, sensor, enabled))); 372 } 373 } 374 } 375 } 376 377 @Override 378 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) 379 public void onSensorPrivacyStateChanged(@ToggleType int toggleType, 380 @Sensors.Sensor int sensor, @StateTypes.StateType int state) { 381 synchronized (mLock) { 382 for (int i = 0; i < mToggleListeners.size(); i++) { 383 OnSensorPrivacyChangedListener listener = mToggleListeners.keyAt(i); 384 mToggleListeners.valueAt(i).execute(() -> listener 385 .onSensorPrivacyChanged(new OnSensorPrivacyChangedListener 386 .SensorPrivacyChangedParams(toggleType, sensor, state))); 387 } 388 } 389 } 390 391 }; 392 393 /** Whether the singleton ISensorPrivacyListener has been registered */ 394 @GuardedBy("mLock") 395 @NonNull 396 private boolean mToggleListenerRegistered = false; 397 398 private Boolean mRequiresAuthentication = null; 399 400 /** 401 * Private constructor to ensure only a single instance is created. 402 */ SensorPrivacyManager(Context context, ISensorPrivacyManager service)403 private SensorPrivacyManager(Context context, ISensorPrivacyManager service) { 404 mContext = context; 405 mService = service; 406 mListeners = new ArrayMap<>(); 407 } 408 409 /** 410 * Returns the single instance of the SensorPrivacyManager. 411 * 412 * @hide 413 */ getInstance(Context context)414 public static SensorPrivacyManager getInstance(Context context) { 415 synchronized (sInstanceLock) { 416 if (sInstance == null) { 417 try { 418 IBinder b = ServiceManager.getServiceOrThrow(Context.SENSOR_PRIVACY_SERVICE); 419 ISensorPrivacyManager service = ISensorPrivacyManager.Stub.asInterface(b); 420 sInstance = new SensorPrivacyManager(context, service); 421 } catch (ServiceManager.ServiceNotFoundException e) { 422 throw new IllegalStateException(e); 423 } 424 } 425 return sInstance; 426 } 427 } 428 429 /** 430 * Returns the single instance of the SensorPrivacyManager. 431 * 432 * @hide 433 */ getInstance(Context context, ISensorPrivacyManager service)434 public static SensorPrivacyManager getInstance(Context context, ISensorPrivacyManager service) { 435 synchronized (sInstanceLock) { 436 sInstance = new SensorPrivacyManager(context, service); 437 return sInstance; 438 } 439 } 440 441 /** 442 * Checks if the given toggle is supported on this device 443 * @param sensor The sensor to check 444 * @return whether the toggle for the sensor is supported on this device. 445 */ supportsSensorToggle(@ensors.Sensor int sensor)446 public boolean supportsSensorToggle(@Sensors.Sensor int sensor) { 447 return supportsSensorToggle(TOGGLE_TYPE_SOFTWARE, sensor); 448 } 449 450 /** 451 * Checks if the given toggle is supported on this device 452 * @param sensor The sensor to check 453 * @return whether the toggle for the sensor is supported on this device. 454 * 455 */ supportsSensorToggle(@oggleType int toggleType, @Sensors.Sensor int sensor)456 public boolean supportsSensorToggle(@ToggleType int toggleType, @Sensors.Sensor int sensor) { 457 try { 458 Pair key = new Pair(toggleType, sensor); 459 synchronized (mLock) { 460 Boolean val = mToggleSupportCache.get(key); 461 if (val == null) { 462 val = mService.supportsSensorToggle(toggleType, sensor); 463 mToggleSupportCache.put(key, val); 464 } 465 return val; 466 } 467 } catch (RemoteException e) { 468 throw e.rethrowFromSystemServer(); 469 } 470 } 471 472 /** 473 * 474 * Registers a new listener to receive notification when the state of sensor privacy 475 * changes. 476 * 477 * @param sensor the sensor to listen to changes to 478 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 479 * privacy changes. 480 * 481 * @hide 482 */ 483 @SystemApi 484 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull OnSensorPrivacyChangedListener listener)485 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, 486 @NonNull OnSensorPrivacyChangedListener listener) { 487 addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener); 488 } 489 490 /** 491 * 492 * Registers a new listener to receive notification when the state of sensor privacy 493 * changes. 494 * 495 * @param sensor the sensor to listen to changes to 496 * @param userId the user's id 497 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 498 * privacy changes. 499 * 500 * @hide 501 */ 502 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, int userId, @NonNull OnSensorPrivacyChangedListener listener)503 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, int userId, 504 @NonNull OnSensorPrivacyChangedListener listener) { 505 addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener); 506 } 507 508 /** 509 * 510 * Registers a new listener to receive notification when the state of sensor privacy 511 * changes. 512 * 513 * @param sensor the sensor to listen to changes to 514 * @param executor the executor to dispatch the callback on 515 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 516 * privacy changes. 517 * 518 * @hide 519 */ 520 @SystemApi 521 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)522 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor, 523 @NonNull OnSensorPrivacyChangedListener listener) { 524 Pair<Integer, OnSensorPrivacyChangedListener> pair = new Pair(sensor, listener); 525 OnSensorPrivacyChangedListener toggleListener = new OnSensorPrivacyChangedListener() { 526 @Override 527 public void onSensorPrivacyChanged(SensorPrivacyChangedParams params) { 528 if (params.getSensor() == sensor) { 529 listener.onSensorPrivacyChanged(params); 530 } 531 } 532 @Override 533 public void onSensorPrivacyChanged(int sensor, boolean enabled) { 534 } 535 }; 536 537 synchronized (mLock) { 538 mLegacyToggleListeners.put(pair, toggleListener); 539 addSensorPrivacyListenerLocked(executor, toggleListener); 540 } 541 } 542 543 /** 544 * 545 * Registers a new listener to receive notification when the state of sensor privacy 546 * changes. 547 * 548 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 549 * sensor privacy changes. 550 * 551 * @hide 552 */ 553 @SystemApi 554 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@onNull OnSensorPrivacyChangedListener listener)555 public void addSensorPrivacyListener(@NonNull OnSensorPrivacyChangedListener listener) { 556 addSensorPrivacyListener(mContext.getMainExecutor(), listener); 557 } 558 559 /** 560 * 561 * Registers a new listener to receive notification when the state of sensor privacy 562 * changes. 563 * 564 * @param executor the executor to dispatch the callback on 565 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 566 * sensor privacy changes. 567 * 568 * @hide 569 */ 570 @SystemApi 571 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@onNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)572 public void addSensorPrivacyListener(@NonNull Executor executor, 573 @NonNull OnSensorPrivacyChangedListener listener) { 574 synchronized (mLock) { 575 addSensorPrivacyListenerLocked(executor, listener); 576 } 577 } 578 579 @GuardedBy("mLock") addSensorPrivacyListenerLocked(@onNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)580 private void addSensorPrivacyListenerLocked(@NonNull Executor executor, 581 @NonNull OnSensorPrivacyChangedListener listener) { 582 if (!mToggleListenerRegistered) { 583 try { 584 mService.addToggleSensorPrivacyListener(mIToggleListener); 585 mToggleListenerRegistered = true; 586 } catch (RemoteException e) { 587 e.rethrowFromSystemServer(); 588 } 589 } 590 if (mToggleListeners.containsKey(listener)) { 591 throw new IllegalArgumentException("listener is already registered"); 592 } 593 mToggleListeners.put(listener, executor); 594 } 595 596 /** 597 * Unregisters the specified listener from receiving notifications when the state of any sensor 598 * privacy changes. 599 * 600 * @param listener the OnSensorPrivacyChangedListener to be unregistered from notifications when 601 * sensor privacy changes. 602 * 603 * @hide 604 */ 605 @SystemApi 606 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull OnSensorPrivacyChangedListener listener)607 public void removeSensorPrivacyListener(@Sensors.Sensor int sensor, 608 @NonNull OnSensorPrivacyChangedListener listener) { 609 Pair<Integer, OnSensorPrivacyChangedListener> pair = new Pair(sensor, listener); 610 synchronized (mLock) { 611 OnSensorPrivacyChangedListener onToggleSensorPrivacyChangedListener = 612 mLegacyToggleListeners.remove(pair); 613 if (onToggleSensorPrivacyChangedListener != null) { 614 removeSensorPrivacyListenerLocked(onToggleSensorPrivacyChangedListener); 615 } 616 } 617 } 618 619 /** 620 * Unregisters the specified listener from receiving notifications when the state of any sensor 621 * privacy changes. 622 * 623 * @param listener the {@link OnSensorPrivacyChangedListener} to be unregistered from 624 * notifications when sensor privacy changes. 625 * 626 * @hide 627 */ 628 @SystemApi 629 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeSensorPrivacyListener( @onNull OnSensorPrivacyChangedListener listener)630 public void removeSensorPrivacyListener( 631 @NonNull OnSensorPrivacyChangedListener listener) { 632 synchronized (mLock) { 633 removeSensorPrivacyListenerLocked(listener); 634 } 635 } 636 637 @GuardedBy("mLock") removeSensorPrivacyListenerLocked( @onNull OnSensorPrivacyChangedListener listener)638 private void removeSensorPrivacyListenerLocked( 639 @NonNull OnSensorPrivacyChangedListener listener) { 640 mToggleListeners.remove(listener); 641 if (mToggleListeners.size() == 0) { 642 try { 643 mService.removeToggleSensorPrivacyListener(mIToggleListener); 644 mToggleListenerRegistered = false; 645 } catch (RemoteException e) { 646 e.rethrowFromSystemServer(); 647 } 648 } 649 } 650 651 /** 652 * Returns whether sensor privacy is currently enabled by software control for a specific 653 * sensor. 654 * 655 * @return true if sensor privacy is currently enabled, false otherwise. 656 * 657 * @deprecated Prefer to use {@link #isSensorPrivacyEnabled(int, int)} 658 * 659 * @hide 660 */ 661 @Deprecated 662 @SystemApi 663 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isSensorPrivacyEnabled(@ensors.Sensor int sensor)664 public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) { 665 return isSensorPrivacyEnabled(TOGGLE_TYPE_SOFTWARE, sensor); 666 } 667 668 /** 669 * Returns whether sensor privacy is currently enabled for a specific sensor. 670 * 671 * @return true if sensor privacy is currently enabled, false otherwise. 672 * 673 * @hide 674 */ 675 @SystemApi 676 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isSensorPrivacyEnabled(@oggleType int toggleType, @Sensors.Sensor int sensor)677 public boolean isSensorPrivacyEnabled(@ToggleType int toggleType, 678 @Sensors.Sensor int sensor) { 679 try { 680 return mService.isToggleSensorPrivacyEnabled(toggleType, sensor); 681 } catch (RemoteException e) { 682 throw e.rethrowFromSystemServer(); 683 } 684 } 685 686 /** 687 * Returns whether sensor privacy is currently enabled for a specific sensor. 688 * Combines the state of the SW + HW toggles and returns true if either the 689 * SOFTWARE or the HARDWARE toggles are enabled. 690 * 691 * @return true if sensor privacy is currently enabled, false otherwise. 692 * 693 * @hide 694 */ 695 @SystemApi 696 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) areAnySensorPrivacyTogglesEnabled(@ensors.Sensor int sensor)697 public boolean areAnySensorPrivacyTogglesEnabled(@Sensors.Sensor int sensor) { 698 try { 699 return mService.isCombinedToggleSensorPrivacyEnabled(sensor); 700 } catch (RemoteException e) { 701 throw e.rethrowFromSystemServer(); 702 } 703 } 704 705 /** 706 * Returns sensor privacy state for a specific sensor. 707 * 708 * @param toggleType The type of toggle to use 709 * @param sensor The sensor to check 710 * @return int sensor privacy state. 711 * 712 * @hide 713 */ 714 @SystemApi 715 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) 716 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) getSensorPrivacyState(@oggleType int toggleType, @Sensors.Sensor int sensor)717 public @StateTypes.StateType int getSensorPrivacyState(@ToggleType int toggleType, 718 @Sensors.Sensor int sensor) { 719 try { 720 return mService.getToggleSensorPrivacyState(toggleType, sensor); 721 } catch (RemoteException e) { 722 throw e.rethrowFromSystemServer(); 723 } 724 } 725 726 /** 727 * Returns if camera privacy is enabled for a specific package. 728 * 729 * @param packageName The package to check 730 * @return boolean camera privacy state. 731 * 732 * @hide 733 */ 734 @SystemApi 735 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) 736 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) isCameraPrivacyEnabled(@onNull String packageName)737 public boolean isCameraPrivacyEnabled(@NonNull String packageName) { 738 try { 739 return mService.isCameraPrivacyEnabled(packageName); 740 } catch (RemoteException e) { 741 throw e.rethrowFromSystemServer(); 742 } 743 } 744 745 /** 746 * Returns camera privacy allowlist. 747 * 748 * @return List of automotive driver assistance packages for 749 * privacy allowlisting. 750 * 751 * @hide 752 */ 753 @SystemApi 754 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) 755 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) getCameraPrivacyAllowlist()756 public @NonNull List<String> getCameraPrivacyAllowlist() { 757 synchronized (mLock) { 758 try { 759 return mService.getCameraPrivacyAllowlist(); 760 } catch (RemoteException e) { 761 throw e.rethrowFromSystemServer(); 762 } 763 } 764 } 765 766 /** 767 * Sets camera privacy allowlist. 768 * 769 * @param allowlist List of automotive driver assistance packages for 770 * privacy allowlisting. 771 * 772 * @hide 773 */ 774 @TestApi 775 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) 776 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) setCameraPrivacyAllowlist(@onNull List<String> allowlist)777 public void setCameraPrivacyAllowlist(@NonNull List<String> allowlist) { 778 synchronized (mLock) { 779 try { 780 mService.setCameraPrivacyAllowlist(allowlist); 781 } catch (RemoteException e) { 782 throw e.rethrowFromSystemServer(); 783 } 784 } 785 } 786 787 /** 788 * Sets sensor privacy to the specified state for an individual sensor. 789 * 790 * @param sensor the sensor which to change the state for 791 * @param enable the state to which sensor privacy should be set. 792 * 793 * @hide 794 */ 795 @SystemApi 796 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ensors.Sensor int sensor, boolean enable)797 public void setSensorPrivacy(@Sensors.Sensor int sensor, 798 boolean enable) { 799 setSensorPrivacy(resolveSourceFromCurrentContext(), sensor, enable, 800 UserHandle.USER_CURRENT); 801 } 802 resolveSourceFromCurrentContext()803 private @Sources.Source int resolveSourceFromCurrentContext() { 804 String packageName = mContext.getOpPackageName(); 805 if (Objects.equals(packageName, 806 mContext.getPackageManager().getPermissionControllerPackageName())) { 807 return Sources.SAFETY_CENTER; 808 } 809 return Sources.OTHER; 810 } 811 812 /** 813 * Sets sensor privacy to the specified state for an individual sensor. 814 * 815 * @param sensor the sensor which to change the state for 816 * @param state the state to which sensor privacy should be set. 817 * 818 * @hide 819 */ 820 @SystemApi 821 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) 822 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) setSensorPrivacyState(@ensors.Sensor int sensor, @StateTypes.StateType int state)823 public void setSensorPrivacyState(@Sensors.Sensor int sensor, 824 @StateTypes.StateType int state) { 825 setSensorPrivacyState(resolveSourceFromCurrentContext(), sensor, state); 826 } 827 828 /** 829 * Sets sensor privacy to the specified state for an individual sensor. 830 * 831 * @param sensor the sensor which to change the state for 832 * @param enable the state to which sensor privacy should be set. 833 * 834 * @hide 835 */ 836 @TestApi 837 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable)838 public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, 839 boolean enable) { 840 setSensorPrivacy(source, sensor, enable, UserHandle.USER_CURRENT); 841 } 842 843 /** 844 * Sets sensor privacy to the specified state for an individual sensor. 845 * 846 * @param sensor the sensor which to change the state for 847 * @param enable the state to which sensor privacy should be set. 848 * @param userId the user's id 849 * 850 * @hide 851 */ 852 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId)853 public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, 854 boolean enable, @UserIdInt int userId) { 855 try { 856 mService.setToggleSensorPrivacy(userId, source, sensor, enable); 857 } catch (RemoteException e) { 858 throw e.rethrowFromSystemServer(); 859 } 860 } 861 862 /** 863 * Sets sensor privacy to the specified state for an individual sensor. 864 * 865 * @param source the source using which the sensor is toggled 866 * @param sensor the sensor which to change the state for 867 * @param state the state to which sensor privacy should be set. 868 * 869 * @hide 870 */ 871 @TestApi 872 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) 873 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) setSensorPrivacyState(@ources.Source int source, @Sensors.Sensor int sensor, @StateTypes.StateType int state)874 public void setSensorPrivacyState(@Sources.Source int source, @Sensors.Sensor int sensor, 875 @StateTypes.StateType int state) { 876 try { 877 mService.setToggleSensorPrivacyState(mContext.getUserId(), source, sensor, state); 878 } catch (RemoteException e) { 879 throw e.rethrowFromSystemServer(); 880 } 881 882 } 883 884 /** 885 * Sets sensor privacy to the specified state for an individual sensor for the profile group of 886 * context's user. 887 * 888 * @param source the source using which the sensor is toggled. 889 * @param sensor the sensor which to change the state for 890 * @param enable the state to which sensor privacy should be set. 891 * 892 * @hide 893 */ 894 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacyForProfileGroup(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable)895 public void setSensorPrivacyForProfileGroup(@Sources.Source int source, 896 @Sensors.Sensor int sensor, boolean enable) { 897 setSensorPrivacyForProfileGroup(source , sensor, enable, UserHandle.USER_CURRENT); 898 } 899 900 /** 901 * Sets sensor privacy to the specified state for an individual sensor for the profile group of 902 * context's user. 903 * 904 * @param source the source using which the sensor is toggled. 905 * @param sensor the sensor which to change the state for 906 * @param enable the state to which sensor privacy should be set. 907 * @param userId the user's id 908 * 909 * @hide 910 */ 911 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacyForProfileGroup(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId)912 public void setSensorPrivacyForProfileGroup(@Sources.Source int source, 913 @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId) { 914 try { 915 mService.setToggleSensorPrivacyForProfileGroup(userId, source, sensor, enable); 916 } catch (RemoteException e) { 917 throw e.rethrowFromSystemServer(); 918 } 919 } 920 921 /** 922 * Sets sensor privacy to the specified state for an individual sensor for the profile group of 923 * context's user. 924 * 925 * @param source the source using which the sensor is toggled. 926 * @param sensor the sensor which to change the state for 927 * @param state the state to which sensor privacy should be set. 928 * 929 * @hide 930 */ 931 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) 932 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) setSensorPrivacyStateForProfileGroup(@ources.Source int source, @Sensors.Sensor int sensor, @StateTypes.StateType int state)933 public void setSensorPrivacyStateForProfileGroup(@Sources.Source int source, 934 @Sensors.Sensor int sensor, @StateTypes.StateType int state) { 935 try { 936 mService.setToggleSensorPrivacyStateForProfileGroup(mContext.getUserId(), source, 937 sensor, state); 938 } catch (RemoteException e) { 939 throw e.rethrowFromSystemServer(); 940 } 941 } 942 943 /** 944 * Don't show dialogs to turn off sensor privacy for this package. 945 * 946 * @param suppress Whether to suppress or re-enable. 947 * 948 * @hide 949 */ 950 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) suppressSensorPrivacyReminders(int sensor, boolean suppress)951 public void suppressSensorPrivacyReminders(int sensor, 952 boolean suppress) { 953 suppressSensorPrivacyReminders(sensor, suppress, UserHandle.USER_CURRENT); 954 } 955 956 /** 957 * Don't show dialogs to turn off sensor privacy for this package. 958 * 959 * @param suppress Whether to suppress or re-enable. 960 * @param userId the user's id 961 * 962 * @hide 963 */ 964 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) suppressSensorPrivacyReminders(int sensor, boolean suppress, @UserIdInt int userId)965 public void suppressSensorPrivacyReminders(int sensor, 966 boolean suppress, @UserIdInt int userId) { 967 try { 968 mService.suppressToggleSensorPrivacyReminders(userId, sensor, 969 token, suppress); 970 } catch (RemoteException e) { 971 throw e.rethrowFromSystemServer(); 972 } 973 } 974 975 /** 976 * @return whether the device is required to be unlocked to change software state. 977 * 978 * @hide 979 */ 980 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) requiresAuthentication()981 public boolean requiresAuthentication() { 982 if (mRequiresAuthentication == null) { 983 try { 984 mRequiresAuthentication = mService.requiresAuthentication(); 985 } catch (RemoteException e) { 986 throw e.rethrowFromSystemServer(); 987 } 988 } 989 return mRequiresAuthentication; 990 } 991 992 /** 993 * If sensor privacy for the provided sensor is enabled then this call will show the user the 994 * dialog which is shown when an application attempts to use that sensor. If privacy isn't 995 * enabled then this does nothing. 996 * 997 * This call can only be made by the system uid. 998 * 999 * @throws SecurityException when called by someone other than system uid. 1000 * 1001 * @hide 1002 */ showSensorUseDialog(int sensor)1003 public void showSensorUseDialog(int sensor) { 1004 try { 1005 mService.showSensorUseDialog(sensor); 1006 } catch (RemoteException e) { 1007 Log.e(LOG_TAG, "Received exception while trying to show sensor use dialog", e); 1008 } 1009 } 1010 1011 /** 1012 * A class implementing this interface can register with the {@link 1013 * android.hardware.SensorPrivacyManager} to receive notification when the all-sensor privacy 1014 * state changes. 1015 * 1016 * @hide 1017 */ 1018 public interface OnAllSensorPrivacyChangedListener { 1019 /** 1020 * Callback invoked when the sensor privacy state changes. 1021 * 1022 * @param enabled true if sensor privacy is enabled, false otherwise. 1023 */ onAllSensorPrivacyChanged(boolean enabled)1024 void onAllSensorPrivacyChanged(boolean enabled); 1025 } 1026 1027 /** 1028 * Sets all-sensor privacy to the specified state. 1029 * 1030 * @param enable the state to which sensor privacy should be set. 1031 * 1032 * @hide 1033 */ 1034 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setAllSensorPrivacy(boolean enable)1035 public void setAllSensorPrivacy(boolean enable) { 1036 try { 1037 mService.setSensorPrivacy(enable); 1038 } catch (RemoteException e) { 1039 throw e.rethrowFromSystemServer(); 1040 } 1041 } 1042 1043 /** 1044 * Registers a new listener to receive notification when the state of all-sensor privacy 1045 * changes. 1046 * 1047 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 1048 * all-sensor privacy changes. 1049 * 1050 * @hide 1051 */ 1052 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addAllSensorPrivacyListener( @onNull final OnAllSensorPrivacyChangedListener listener)1053 public void addAllSensorPrivacyListener( 1054 @NonNull final OnAllSensorPrivacyChangedListener listener) { 1055 synchronized (mListeners) { 1056 ISensorPrivacyListener iListener = mListeners.get(listener); 1057 if (iListener == null) { 1058 iListener = new ISensorPrivacyListener.Stub() { 1059 @Override 1060 public void onSensorPrivacyChanged(int toggleType, int sensor, 1061 boolean enabled) { 1062 listener.onAllSensorPrivacyChanged(enabled); 1063 } 1064 1065 @Override 1066 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) 1067 public void onSensorPrivacyStateChanged(int toggleType, int sensor, 1068 int state) { 1069 } 1070 }; 1071 mListeners.put(listener, iListener); 1072 } 1073 1074 try { 1075 mService.addSensorPrivacyListener(iListener); 1076 } catch (RemoteException e) { 1077 throw e.rethrowFromSystemServer(); 1078 } 1079 } 1080 } 1081 1082 /** 1083 * Unregisters the specified listener from receiving notifications when the state of all-sensor 1084 * privacy changes. 1085 * 1086 * @param listener the OnAllSensorPrivacyChangedListener to be unregistered from notifications 1087 * when all-sensor privacy changes. 1088 * 1089 * @hide 1090 */ 1091 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeAllSensorPrivacyListener( @onNull OnAllSensorPrivacyChangedListener listener)1092 public void removeAllSensorPrivacyListener( 1093 @NonNull OnAllSensorPrivacyChangedListener listener) { 1094 synchronized (mListeners) { 1095 ISensorPrivacyListener iListener = mListeners.get(listener); 1096 if (iListener != null) { 1097 mListeners.remove(iListener); 1098 try { 1099 mService.removeSensorPrivacyListener(iListener); 1100 } catch (RemoteException e) { 1101 throw e.rethrowFromSystemServer(); 1102 } 1103 } 1104 } 1105 } 1106 1107 /** 1108 * Returns whether all-sensor privacy is currently enabled. 1109 * 1110 * @return true if all-sensor privacy is currently enabled, false otherwise. 1111 * 1112 * @hide 1113 */ 1114 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isAllSensorPrivacyEnabled()1115 public boolean isAllSensorPrivacyEnabled() { 1116 try { 1117 return mService.isSensorPrivacyEnabled(); 1118 } catch (RemoteException e) { 1119 throw e.rethrowFromSystemServer(); 1120 } 1121 } 1122 1123 } 1124