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