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.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.RequiresPermission; 23 import android.annotation.SystemApi; 24 import android.annotation.SystemService; 25 import android.annotation.TestApi; 26 import android.annotation.UserIdInt; 27 import android.content.Context; 28 import android.os.Binder; 29 import android.os.IBinder; 30 import android.os.RemoteException; 31 import android.os.ServiceManager; 32 import android.os.UserHandle; 33 import android.service.SensorPrivacyIndividualEnabledSensorProto; 34 import android.service.SensorPrivacySensorProto; 35 import android.service.SensorPrivacyToggleSourceProto; 36 import android.util.ArrayMap; 37 import android.util.Log; 38 import android.util.Pair; 39 40 import com.android.internal.annotations.GuardedBy; 41 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.util.Objects; 45 import java.util.concurrent.Executor; 46 47 /** 48 * This class provides information about the microphone and camera toggles. 49 */ 50 @SystemService(Context.SENSOR_PRIVACY_SERVICE) 51 public final class SensorPrivacyManager { 52 53 private static final String LOG_TAG = SensorPrivacyManager.class.getSimpleName(); 54 55 /** 56 * Unique Id of this manager to identify to the service 57 * @hide 58 */ 59 private IBinder token = new Binder(); 60 61 /** 62 * An extra containing a sensor 63 * @hide 64 */ 65 public static final String EXTRA_SENSOR = SensorPrivacyManager.class.getName() 66 + ".extra.sensor"; 67 68 /** 69 * An extra indicating if all sensors are affected 70 * @hide 71 */ 72 public static final String EXTRA_ALL_SENSORS = SensorPrivacyManager.class.getName() 73 + ".extra.all_sensors"; 74 75 /** 76 * Sensor constants which are used in {@link SensorPrivacyManager} 77 */ 78 public static class Sensors { 79 Sensors()80 private Sensors() {} 81 82 /** 83 * Constant for the microphone 84 */ 85 public static final int MICROPHONE = SensorPrivacySensorProto.MICROPHONE; 86 87 /** 88 * Constant for the camera 89 */ 90 public static final int CAMERA = SensorPrivacySensorProto.CAMERA; 91 92 /** 93 * Individual sensors not listed in {@link Sensors} 94 * 95 * @hide 96 */ 97 @IntDef(value = { 98 MICROPHONE, 99 CAMERA 100 }) 101 @Retention(RetentionPolicy.SOURCE) 102 public @interface Sensor {} 103 } 104 105 /** 106 * Source through which Privacy Sensor was toggled. 107 * @hide 108 */ 109 @TestApi 110 public static class Sources { Sources()111 private Sources() {} 112 113 /** 114 * Constant for the Quick Setting Tile. 115 */ 116 public static final int QS_TILE = SensorPrivacyToggleSourceProto.QS_TILE; 117 118 /** 119 * Constant for the Settings. 120 */ 121 public static final int SETTINGS = SensorPrivacyToggleSourceProto.SETTINGS; 122 123 /** 124 * Constant for Dialog. 125 */ 126 public static final int DIALOG = SensorPrivacyToggleSourceProto.DIALOG; 127 128 /** 129 * Constant for SHELL. 130 */ 131 public static final int SHELL = SensorPrivacyToggleSourceProto.SHELL; 132 133 /** 134 * Constant for OTHER. 135 */ 136 public static final int OTHER = SensorPrivacyToggleSourceProto.OTHER; 137 138 /** 139 * Constant for SAFETY_CENTER. 140 */ 141 public static final int SAFETY_CENTER = SensorPrivacyToggleSourceProto.SAFETY_CENTER; 142 143 /** 144 * Source for toggling sensors 145 * 146 * @hide 147 */ 148 @IntDef(value = { 149 QS_TILE, 150 SETTINGS, 151 DIALOG, 152 SHELL, 153 OTHER, 154 SAFETY_CENTER 155 }) 156 @Retention(RetentionPolicy.SOURCE) 157 public @interface Source {} 158 159 } 160 161 162 /** 163 * Constant for software toggle. 164 */ 165 public static final int TOGGLE_TYPE_SOFTWARE = 166 SensorPrivacyIndividualEnabledSensorProto.SOFTWARE; 167 168 /** 169 * Constant for hardware toggle. 170 */ 171 public static final int TOGGLE_TYPE_HARDWARE = 172 SensorPrivacyIndividualEnabledSensorProto.HARDWARE; 173 174 /** 175 * Types of toggles which can exist for sensor privacy 176 * 177 * @hide 178 */ 179 @IntDef(value = { 180 TOGGLE_TYPE_SOFTWARE, 181 TOGGLE_TYPE_HARDWARE 182 }) 183 @Retention(RetentionPolicy.SOURCE) 184 public @interface ToggleType {} 185 186 /** 187 * Types of state which can exist for the sensor privacy toggle 188 * @hide 189 */ 190 public static class StateTypes { StateTypes()191 private StateTypes() {} 192 193 /** 194 * Constant indicating privacy is enabled. 195 */ 196 public static final int ENABLED = SensorPrivacyIndividualEnabledSensorProto.ENABLED; 197 198 /** 199 * Constant indicating privacy is disabled. 200 */ 201 public static final int DISABLED = SensorPrivacyIndividualEnabledSensorProto.DISABLED; 202 203 /** 204 * Types of state which can exist for a sensor privacy toggle 205 * 206 * @hide 207 */ 208 @IntDef(value = { 209 ENABLED, 210 DISABLED 211 }) 212 @Retention(RetentionPolicy.SOURCE) 213 public @interface StateType {} 214 215 } 216 217 /** 218 * A class implementing this interface can register with the {@link 219 * android.hardware.SensorPrivacyManager} to receive notification when the sensor privacy 220 * state changes. 221 * 222 * @hide 223 */ 224 @SystemApi 225 public interface OnSensorPrivacyChangedListener { 226 /** 227 * Callback invoked when the sensor privacy state changes. 228 * 229 * @param params Parameters describing the new state 230 */ onSensorPrivacyChanged(@onNull SensorPrivacyChangedParams params)231 default void onSensorPrivacyChanged(@NonNull SensorPrivacyChangedParams params) { 232 onSensorPrivacyChanged(params.mSensor, params.mEnabled); 233 } 234 235 /** 236 * Callback invoked when the sensor privacy state changes. 237 * 238 * @param sensor the sensor whose state is changing 239 * @param enabled true if sensor privacy is enabled, false otherwise. 240 * 241 * @deprecated Please use 242 * {@link #onSensorPrivacyChanged(SensorPrivacyChangedParams)} 243 */ 244 @Deprecated onSensorPrivacyChanged(int sensor, boolean enabled)245 void onSensorPrivacyChanged(int sensor, boolean enabled); 246 247 /** 248 * A class containing information about what the sensor privacy state has changed to. 249 */ 250 class SensorPrivacyChangedParams { 251 252 private int mToggleType; 253 private int mSensor; 254 private boolean mEnabled; 255 SensorPrivacyChangedParams(int toggleType, int sensor, boolean enabled)256 private SensorPrivacyChangedParams(int toggleType, int sensor, boolean enabled) { 257 mToggleType = toggleType; 258 mSensor = sensor; 259 mEnabled = enabled; 260 } 261 getToggleType()262 public @ToggleType int getToggleType() { 263 return mToggleType; 264 } 265 getSensor()266 public @Sensors.Sensor int getSensor() { 267 return mSensor; 268 } 269 isEnabled()270 public boolean isEnabled() { 271 return mEnabled; 272 } 273 } 274 } 275 276 private static final Object sInstanceLock = new Object(); 277 278 private final Object mLock = new Object(); 279 280 @GuardedBy("sInstanceLock") 281 private static SensorPrivacyManager sInstance; 282 283 @NonNull 284 private final Context mContext; 285 286 @NonNull 287 private final ISensorPrivacyManager mService; 288 289 @GuardedBy("mLock") 290 private final ArrayMap<Pair<Integer, Integer>, Boolean> mToggleSupportCache = new ArrayMap<>(); 291 292 @NonNull 293 private final ArrayMap<OnAllSensorPrivacyChangedListener, ISensorPrivacyListener> mListeners; 294 295 /** Registered listeners */ 296 @GuardedBy("mLock") 297 @NonNull 298 private final ArrayMap<OnSensorPrivacyChangedListener, Executor> mToggleListeners = 299 new ArrayMap<>(); 300 301 /** Listeners registered using the deprecated APIs and which 302 * OnSensorPrivacyChangedListener they're using. */ 303 @GuardedBy("mLock") 304 @NonNull 305 private final ArrayMap<Pair<Integer, OnSensorPrivacyChangedListener>, 306 OnSensorPrivacyChangedListener> mLegacyToggleListeners = new ArrayMap<>(); 307 308 /** The singleton ISensorPrivacyListener for IPC which will be used to dispatch to local 309 * listeners */ 310 @NonNull 311 private final ISensorPrivacyListener mIToggleListener = new ISensorPrivacyListener.Stub() { 312 @Override 313 public void onSensorPrivacyChanged(int toggleType, int sensor, boolean enabled) { 314 synchronized (mLock) { 315 for (int i = 0; i < mToggleListeners.size(); i++) { 316 OnSensorPrivacyChangedListener listener = mToggleListeners.keyAt(i); 317 mToggleListeners.valueAt(i).execute(() -> listener 318 .onSensorPrivacyChanged(new OnSensorPrivacyChangedListener 319 .SensorPrivacyChangedParams(toggleType, sensor, enabled))); 320 } 321 } 322 } 323 }; 324 325 /** Whether the singleton ISensorPrivacyListener has been registered */ 326 @GuardedBy("mLock") 327 @NonNull 328 private boolean mToggleListenerRegistered = false; 329 330 private Boolean mRequiresAuthentication = null; 331 332 /** 333 * Private constructor to ensure only a single instance is created. 334 */ SensorPrivacyManager(Context context, ISensorPrivacyManager service)335 private SensorPrivacyManager(Context context, ISensorPrivacyManager service) { 336 mContext = context; 337 mService = service; 338 mListeners = new ArrayMap<>(); 339 } 340 341 /** 342 * Returns the single instance of the SensorPrivacyManager. 343 * 344 * @hide 345 */ getInstance(Context context)346 public static SensorPrivacyManager getInstance(Context context) { 347 synchronized (sInstanceLock) { 348 if (sInstance == null) { 349 try { 350 IBinder b = ServiceManager.getServiceOrThrow(Context.SENSOR_PRIVACY_SERVICE); 351 ISensorPrivacyManager service = ISensorPrivacyManager.Stub.asInterface(b); 352 sInstance = new SensorPrivacyManager(context, service); 353 } catch (ServiceManager.ServiceNotFoundException e) { 354 throw new IllegalStateException(e); 355 } 356 } 357 return sInstance; 358 } 359 } 360 361 /** 362 * Returns the single instance of the SensorPrivacyManager. 363 * 364 * @hide 365 */ getInstance(Context context, ISensorPrivacyManager service)366 public static SensorPrivacyManager getInstance(Context context, ISensorPrivacyManager service) { 367 synchronized (sInstanceLock) { 368 sInstance = new SensorPrivacyManager(context, service); 369 return sInstance; 370 } 371 } 372 373 /** 374 * Checks if the given toggle is supported on this device 375 * @param sensor The sensor to check 376 * @return whether the toggle for the sensor is supported on this device. 377 */ supportsSensorToggle(@ensors.Sensor int sensor)378 public boolean supportsSensorToggle(@Sensors.Sensor int sensor) { 379 return supportsSensorToggle(TOGGLE_TYPE_SOFTWARE, sensor); 380 } 381 382 /** 383 * Checks if the given toggle is supported on this device 384 * @param sensor The sensor to check 385 * @return whether the toggle for the sensor is supported on this device. 386 * 387 */ supportsSensorToggle(@oggleType int toggleType, @Sensors.Sensor int sensor)388 public boolean supportsSensorToggle(@ToggleType int toggleType, @Sensors.Sensor int sensor) { 389 try { 390 Pair key = new Pair(toggleType, sensor); 391 synchronized (mLock) { 392 Boolean val = mToggleSupportCache.get(key); 393 if (val == null) { 394 val = mService.supportsSensorToggle(toggleType, sensor); 395 mToggleSupportCache.put(key, val); 396 } 397 return val; 398 } 399 } catch (RemoteException e) { 400 throw e.rethrowFromSystemServer(); 401 } 402 } 403 404 /** 405 * 406 * Registers a new listener to receive notification when the state of sensor privacy 407 * changes. 408 * 409 * @param sensor the sensor to listen to changes to 410 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 411 * privacy changes. 412 * 413 * @hide 414 */ 415 @SystemApi 416 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull OnSensorPrivacyChangedListener listener)417 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, 418 @NonNull OnSensorPrivacyChangedListener listener) { 419 addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener); 420 } 421 422 /** 423 * 424 * Registers a new listener to receive notification when the state of sensor privacy 425 * changes. 426 * 427 * @param sensor the sensor to listen to changes to 428 * @param userId the user's id 429 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 430 * privacy changes. 431 * 432 * @hide 433 */ 434 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, int userId, @NonNull OnSensorPrivacyChangedListener listener)435 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, int userId, 436 @NonNull OnSensorPrivacyChangedListener listener) { 437 addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener); 438 } 439 440 /** 441 * 442 * Registers a new listener to receive notification when the state of sensor privacy 443 * changes. 444 * 445 * @param sensor the sensor to listen to changes to 446 * @param executor the executor to dispatch the callback on 447 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of sensor 448 * privacy changes. 449 * 450 * @hide 451 */ 452 @SystemApi 453 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)454 public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor, 455 @NonNull OnSensorPrivacyChangedListener listener) { 456 Pair<Integer, OnSensorPrivacyChangedListener> pair = new Pair(sensor, listener); 457 OnSensorPrivacyChangedListener toggleListener = new OnSensorPrivacyChangedListener() { 458 @Override 459 public void onSensorPrivacyChanged(SensorPrivacyChangedParams params) { 460 if (params.getSensor() == sensor) { 461 listener.onSensorPrivacyChanged(params.getSensor(), params.isEnabled()); 462 } 463 } 464 @Override 465 public void onSensorPrivacyChanged(int sensor, boolean enabled) { 466 } 467 }; 468 469 synchronized (mLock) { 470 mLegacyToggleListeners.put(pair, toggleListener); 471 addSensorPrivacyListenerLocked(executor, toggleListener); 472 } 473 } 474 475 /** 476 * 477 * Registers a new listener to receive notification when the state of sensor privacy 478 * changes. 479 * 480 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 481 * sensor privacy changes. 482 * 483 * @hide 484 */ 485 @SystemApi 486 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@onNull OnSensorPrivacyChangedListener listener)487 public void addSensorPrivacyListener(@NonNull OnSensorPrivacyChangedListener listener) { 488 addSensorPrivacyListener(mContext.getMainExecutor(), listener); 489 } 490 491 /** 492 * 493 * Registers a new listener to receive notification when the state of sensor privacy 494 * changes. 495 * 496 * @param executor the executor to dispatch the callback on 497 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 498 * sensor privacy changes. 499 * 500 * @hide 501 */ 502 @SystemApi 503 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addSensorPrivacyListener(@onNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)504 public void addSensorPrivacyListener(@NonNull Executor executor, 505 @NonNull OnSensorPrivacyChangedListener listener) { 506 synchronized (mLock) { 507 addSensorPrivacyListenerLocked(executor, listener); 508 } 509 } 510 511 @GuardedBy("mLock") addSensorPrivacyListenerLocked(@onNull Executor executor, @NonNull OnSensorPrivacyChangedListener listener)512 private void addSensorPrivacyListenerLocked(@NonNull Executor executor, 513 @NonNull OnSensorPrivacyChangedListener listener) { 514 if (!mToggleListenerRegistered) { 515 try { 516 mService.addToggleSensorPrivacyListener(mIToggleListener); 517 mToggleListenerRegistered = true; 518 } catch (RemoteException e) { 519 e.rethrowFromSystemServer(); 520 } 521 } 522 if (mToggleListeners.containsKey(listener)) { 523 throw new IllegalArgumentException("listener is already registered"); 524 } 525 mToggleListeners.put(listener, executor); 526 } 527 528 /** 529 * Unregisters the specified listener from receiving notifications when the state of any sensor 530 * privacy changes. 531 * 532 * @param listener the OnSensorPrivacyChangedListener to be unregistered from notifications when 533 * sensor privacy changes. 534 * 535 * @hide 536 */ 537 @SystemApi 538 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeSensorPrivacyListener(@ensors.Sensor int sensor, @NonNull OnSensorPrivacyChangedListener listener)539 public void removeSensorPrivacyListener(@Sensors.Sensor int sensor, 540 @NonNull OnSensorPrivacyChangedListener listener) { 541 Pair<Integer, OnSensorPrivacyChangedListener> pair = new Pair(sensor, listener); 542 synchronized (mLock) { 543 OnSensorPrivacyChangedListener onToggleSensorPrivacyChangedListener = 544 mLegacyToggleListeners.remove(pair); 545 if (onToggleSensorPrivacyChangedListener != null) { 546 removeSensorPrivacyListenerLocked(onToggleSensorPrivacyChangedListener); 547 } 548 } 549 } 550 551 /** 552 * Unregisters the specified listener from receiving notifications when the state of any sensor 553 * privacy changes. 554 * 555 * @param listener the {@link OnSensorPrivacyChangedListener} to be unregistered from 556 * notifications when sensor privacy changes. 557 * 558 * @hide 559 */ 560 @SystemApi 561 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeSensorPrivacyListener( @onNull OnSensorPrivacyChangedListener listener)562 public void removeSensorPrivacyListener( 563 @NonNull OnSensorPrivacyChangedListener listener) { 564 synchronized (mLock) { 565 removeSensorPrivacyListenerLocked(listener); 566 } 567 } 568 569 @GuardedBy("mLock") removeSensorPrivacyListenerLocked( @onNull OnSensorPrivacyChangedListener listener)570 private void removeSensorPrivacyListenerLocked( 571 @NonNull OnSensorPrivacyChangedListener listener) { 572 mToggleListeners.remove(listener); 573 if (mToggleListeners.size() == 0) { 574 try { 575 mService.removeToggleSensorPrivacyListener(mIToggleListener); 576 mToggleListenerRegistered = false; 577 } catch (RemoteException e) { 578 e.rethrowFromSystemServer(); 579 } 580 } 581 } 582 583 /** 584 * Returns whether sensor privacy is currently enabled by software control for a specific 585 * sensor. 586 * 587 * @return true if sensor privacy is currently enabled, false otherwise. 588 * 589 * @deprecated Prefer to use {@link #isSensorPrivacyEnabled(int, int)} 590 * 591 * @hide 592 */ 593 @Deprecated 594 @SystemApi 595 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isSensorPrivacyEnabled(@ensors.Sensor int sensor)596 public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) { 597 return isSensorPrivacyEnabled(TOGGLE_TYPE_SOFTWARE, sensor); 598 } 599 600 /** 601 * Returns whether sensor privacy is currently enabled for a specific sensor. 602 * 603 * @return true if sensor privacy is currently enabled, false otherwise. 604 * 605 * @hide 606 */ 607 @SystemApi 608 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isSensorPrivacyEnabled(@oggleType int toggleType, @Sensors.Sensor int sensor)609 public boolean isSensorPrivacyEnabled(@ToggleType int toggleType, 610 @Sensors.Sensor int sensor) { 611 try { 612 return mService.isToggleSensorPrivacyEnabled(toggleType, sensor); 613 } catch (RemoteException e) { 614 throw e.rethrowFromSystemServer(); 615 } 616 } 617 618 /** 619 * Returns whether sensor privacy is currently enabled for a specific sensor. 620 * Combines the state of the SW + HW toggles and returns true if either the 621 * SOFTWARE or the HARDWARE toggles are enabled. 622 * 623 * @return true if sensor privacy is currently enabled, false otherwise. 624 * 625 * @hide 626 */ 627 @SystemApi 628 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) areAnySensorPrivacyTogglesEnabled(@ensors.Sensor int sensor)629 public boolean areAnySensorPrivacyTogglesEnabled(@Sensors.Sensor int sensor) { 630 try { 631 return mService.isCombinedToggleSensorPrivacyEnabled(sensor); 632 } catch (RemoteException e) { 633 throw e.rethrowFromSystemServer(); 634 } 635 } 636 637 /** 638 * Sets sensor privacy to the specified state for an individual sensor. 639 * 640 * @param sensor the sensor which to change the state for 641 * @param enable the state to which sensor privacy should be set. 642 * 643 * @hide 644 */ 645 @SystemApi 646 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ensors.Sensor int sensor, boolean enable)647 public void setSensorPrivacy(@Sensors.Sensor int sensor, 648 boolean enable) { 649 setSensorPrivacy(resolveSourceFromCurrentContext(), sensor, enable, 650 UserHandle.USER_CURRENT); 651 } 652 resolveSourceFromCurrentContext()653 private @Sources.Source int resolveSourceFromCurrentContext() { 654 String packageName = mContext.getOpPackageName(); 655 if (Objects.equals(packageName, 656 mContext.getPackageManager().getPermissionControllerPackageName())) { 657 return Sources.SAFETY_CENTER; 658 } 659 return Sources.OTHER; 660 } 661 662 /** 663 * Sets sensor privacy to the specified state for an individual sensor. 664 * 665 * @param sensor the sensor which to change the state for 666 * @param enable the state to which sensor privacy should be set. 667 * 668 * @hide 669 */ 670 @TestApi 671 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable)672 public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, 673 boolean enable) { 674 setSensorPrivacy(source, sensor, enable, UserHandle.USER_CURRENT); 675 } 676 677 /** 678 * Sets sensor privacy to the specified state for an individual sensor. 679 * 680 * @param sensor the sensor which to change the state for 681 * @param enable the state to which sensor privacy should be set. 682 * @param userId the user's id 683 * 684 * @hide 685 */ 686 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacy(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId)687 public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor, 688 boolean enable, @UserIdInt int userId) { 689 try { 690 mService.setToggleSensorPrivacy(userId, source, sensor, enable); 691 } catch (RemoteException e) { 692 throw e.rethrowFromSystemServer(); 693 } 694 } 695 696 /** 697 * Sets sensor privacy to the specified state for an individual sensor for the profile group of 698 * context's user. 699 * 700 * @param source the source using which the sensor is toggled. 701 * @param sensor the sensor which to change the state for 702 * @param enable the state to which sensor privacy should be set. 703 * 704 * @hide 705 */ 706 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacyForProfileGroup(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable)707 public void setSensorPrivacyForProfileGroup(@Sources.Source int source, 708 @Sensors.Sensor int sensor, boolean enable) { 709 setSensorPrivacyForProfileGroup(source , sensor, enable, UserHandle.USER_CURRENT); 710 } 711 712 /** 713 * Sets sensor privacy to the specified state for an individual sensor for the profile group of 714 * context's user. 715 * 716 * @param source the source using which the sensor is toggled. 717 * @param sensor the sensor which to change the state for 718 * @param enable the state to which sensor privacy should be set. 719 * @param userId the user's id 720 * 721 * @hide 722 */ 723 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setSensorPrivacyForProfileGroup(@ources.Source int source, @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId)724 public void setSensorPrivacyForProfileGroup(@Sources.Source int source, 725 @Sensors.Sensor int sensor, boolean enable, @UserIdInt int userId) { 726 try { 727 mService.setToggleSensorPrivacyForProfileGroup(userId, source, sensor, enable); 728 } catch (RemoteException e) { 729 throw e.rethrowFromSystemServer(); 730 } 731 } 732 733 /** 734 * Don't show dialogs to turn off sensor privacy for this package. 735 * 736 * @param suppress Whether to suppress or re-enable. 737 * 738 * @hide 739 */ 740 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) suppressSensorPrivacyReminders(int sensor, boolean suppress)741 public void suppressSensorPrivacyReminders(int sensor, 742 boolean suppress) { 743 suppressSensorPrivacyReminders(sensor, suppress, UserHandle.USER_CURRENT); 744 } 745 746 /** 747 * Don't show dialogs to turn off sensor privacy for this package. 748 * 749 * @param suppress Whether to suppress or re-enable. 750 * @param userId the user's id 751 * 752 * @hide 753 */ 754 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) suppressSensorPrivacyReminders(int sensor, boolean suppress, @UserIdInt int userId)755 public void suppressSensorPrivacyReminders(int sensor, 756 boolean suppress, @UserIdInt int userId) { 757 try { 758 mService.suppressToggleSensorPrivacyReminders(userId, sensor, 759 token, suppress); 760 } catch (RemoteException e) { 761 throw e.rethrowFromSystemServer(); 762 } 763 } 764 765 /** 766 * @return whether the device is required to be unlocked to change software state. 767 * 768 * @hide 769 */ 770 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) requiresAuthentication()771 public boolean requiresAuthentication() { 772 if (mRequiresAuthentication == null) { 773 try { 774 mRequiresAuthentication = mService.requiresAuthentication(); 775 } catch (RemoteException e) { 776 throw e.rethrowFromSystemServer(); 777 } 778 } 779 return mRequiresAuthentication; 780 } 781 782 /** 783 * If sensor privacy for the provided sensor is enabled then this call will show the user the 784 * dialog which is shown when an application attempts to use that sensor. If privacy isn't 785 * enabled then this does nothing. 786 * 787 * This call can only be made by the system uid. 788 * 789 * @throws SecurityException when called by someone other than system uid. 790 * 791 * @hide 792 */ showSensorUseDialog(int sensor)793 public void showSensorUseDialog(int sensor) { 794 try { 795 mService.showSensorUseDialog(sensor); 796 } catch (RemoteException e) { 797 Log.e(LOG_TAG, "Received exception while trying to show sensor use dialog", e); 798 } 799 } 800 801 /** 802 * A class implementing this interface can register with the {@link 803 * android.hardware.SensorPrivacyManager} to receive notification when the all-sensor privacy 804 * state changes. 805 * 806 * @hide 807 */ 808 public interface OnAllSensorPrivacyChangedListener { 809 /** 810 * Callback invoked when the sensor privacy state changes. 811 * 812 * @param enabled true if sensor privacy is enabled, false otherwise. 813 */ onAllSensorPrivacyChanged(boolean enabled)814 void onAllSensorPrivacyChanged(boolean enabled); 815 } 816 817 /** 818 * Sets all-sensor privacy to the specified state. 819 * 820 * @param enable the state to which sensor privacy should be set. 821 * 822 * @hide 823 */ 824 @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY) setAllSensorPrivacy(boolean enable)825 public void setAllSensorPrivacy(boolean enable) { 826 try { 827 mService.setSensorPrivacy(enable); 828 } catch (RemoteException e) { 829 throw e.rethrowFromSystemServer(); 830 } 831 } 832 833 /** 834 * Registers a new listener to receive notification when the state of all-sensor privacy 835 * changes. 836 * 837 * @param listener the OnSensorPrivacyChangedListener to be notified when the state of 838 * all-sensor privacy changes. 839 * 840 * @hide 841 */ 842 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) addAllSensorPrivacyListener( @onNull final OnAllSensorPrivacyChangedListener listener)843 public void addAllSensorPrivacyListener( 844 @NonNull final OnAllSensorPrivacyChangedListener listener) { 845 synchronized (mListeners) { 846 ISensorPrivacyListener iListener = mListeners.get(listener); 847 if (iListener == null) { 848 iListener = new ISensorPrivacyListener.Stub() { 849 @Override 850 public void onSensorPrivacyChanged(int toggleType, int sensor, 851 boolean enabled) { 852 listener.onAllSensorPrivacyChanged(enabled); 853 } 854 }; 855 mListeners.put(listener, iListener); 856 } 857 858 try { 859 mService.addSensorPrivacyListener(iListener); 860 } catch (RemoteException e) { 861 throw e.rethrowFromSystemServer(); 862 } 863 } 864 } 865 866 /** 867 * Unregisters the specified listener from receiving notifications when the state of all-sensor 868 * privacy changes. 869 * 870 * @param listener the OnAllSensorPrivacyChangedListener to be unregistered from notifications 871 * when all-sensor privacy changes. 872 * 873 * @hide 874 */ 875 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) removeAllSensorPrivacyListener( @onNull OnAllSensorPrivacyChangedListener listener)876 public void removeAllSensorPrivacyListener( 877 @NonNull OnAllSensorPrivacyChangedListener listener) { 878 synchronized (mListeners) { 879 ISensorPrivacyListener iListener = mListeners.get(listener); 880 if (iListener != null) { 881 mListeners.remove(iListener); 882 try { 883 mService.removeSensorPrivacyListener(iListener); 884 } catch (RemoteException e) { 885 throw e.rethrowFromSystemServer(); 886 } 887 } 888 } 889 } 890 891 /** 892 * Returns whether all-sensor privacy is currently enabled. 893 * 894 * @return true if all-sensor privacy is currently enabled, false otherwise. 895 * 896 * @hide 897 */ 898 @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) isAllSensorPrivacyEnabled()899 public boolean isAllSensorPrivacyEnabled() { 900 try { 901 return mService.isSensorPrivacyEnabled(); 902 } catch (RemoteException e) { 903 throw e.rethrowFromSystemServer(); 904 } 905 } 906 907 } 908