传感器关闭

在飞行模式下,设备仍然可以访问某些传感器以启用特定功能,例如屏幕旋转和拍照。Android 10 提供了一个开发者选项设置来关闭设备中的所有传感器。此功能可帮助开发者在传感器不可用的情况下测试其应用的功能,并为用户提供了一种控制设备中传感器的方法。

当开发者或用户在开发者选项中启用传感器关闭时(设置 > 系统 > 开发者选项 > 快速设置开发者图块),快速设置托盘中会出现一个新的图块。他们可以使用该图块来阻止应用访问相机、麦克风以及由 SensorManager 类管理的所有传感器。

警告:此选项仅影响通过 `SensorService`、`CameraService` 和 `AudioPolicyService` 访问传感器的应用。电话功能不使用 `AudioPolicyService`,并且在通话期间仍然可以访问麦克风。

实现

Android 10 包含一个参考实现,用于处理相机、麦克风和 SensorManager 传感器。管理传感器关闭状态并通知客户端状态更改的系统服务位于 frameworks/base/services/core/java/com/android/server/SensorPrivacyService.java 中。促进在应用的上下文中访问 SensorPrivacyService 的管理器位于 frameworks/base/core/java/android/hardware/SensorPrivacyManager.java 中。

如果您的设备使用 SensorServiceCameraServiceAudioPolicyService 的默认实现,则无需对参考设计进行额外的自定义。如果您有其他传感器,请参阅自定义,详细了解如何支持此功能。

常见问题

在实现此功能时,有时相机应用无法正确响应 onError 回调,无论是在首次尝试获取相机时还是在相机不再可用时。这通常会导致在启用此图块时应用崩溃,但这可以用作指示该功能按预期运行的信号。

此行为表明应用未正确处理 CameraDevice.StateCallback 中的 onError 回调。当传感器关闭启用时,将使用设置为错误值的 CameraDevice.StateCallback.ERROR_CAMERA_DISABLED 调用 onError 回调。更新任何第一方应用以处理带有此值的 onError 回调,方法是在后续 openCamera 调用成功之前,不对 CameraDevice 进行任何后续调用。

传感器行为

传感器关闭启用时,传感器停止向系统或应用报告任何数据。应用仍然可以请求传感器并在传感器关闭启用时注册监听器,但麦克风会返回静音,或者永远不会为传感器调用 onSensorChanged 回调。一旦禁用该图块,这些相同的监听器将开始接收来自麦克风的实际输出或对 onSensorChanged 的预期回调,而无需执行任何额外的工作。静音传感器的默认行为如下所示。

相机

如果应用在传感器关闭启用时正在使用相机,则会向 onError 回调方法发送错误,并且 CameraDevice 会关闭。

如果应用在传感器关闭启用时尝试访问相机,则会向 onError 回调方法发送错误。

麦克风

传感器关闭 启用后,仍然可以访问麦克风,但只会返回静音。如果当 传感器关闭 启用时应用正在使用麦克风,则不会生成错误,但录音将被静音,并且仅返回一个零数组。如果在应用仍在使用麦克风时禁用 传感器关闭,则会返回预期的音频数据。

如果应用尝试在 传感器关闭 启用时访问麦克风,麦克风将返回静音。

传感器

当应用尝试在 传感器关闭 启用时访问其他传感器时,传感器类型会影响默认行为

  • 持续传感器: 处于此报告模式的传感器会停止分发事件。如果当 传感器关闭 启用时应用正在与持续传感器交互,则该传感器不会向应用发送任何额外数据,直到该功能被禁用。
  • 刷新事件: 当磁贴启用时,可以请求传感器刷新,并且会调用 onFlushComplete 回调来指示请求的刷新已成功完成,但是不会生成新的带有传感器数据的事件并返回到 onSensorChanged 回调。
  • 变化事件:传感器关闭 启用时,不会报告新的变化事件。
  • 触发事件:传感器关闭 启用时,触发事件停止生成。任何现有事件都会完成。

自定义

如果您的设备使用 SensorServiceCameraServiceAudioPolicyService 的默认实现,则参考设计不需要额外的自定义。但是,您可以支持在 SensorManager 之外管理的传感器,从您的设备中移除 传感器关闭,或者更改开发者快速设置磁贴的系统 UI 或 传感器关闭 磁贴的图标。

支持更多传感器

如果您的设备包含在 SensorManager 之外管理的传感器,则应使用 SensorPrivacyServiceSensorPrivacyManager 为它们添加支持。

传感器关闭 磁贴被切换时,SensorPrivacyService 会为所有注册的监听器调用单向回调。当收到此回调时,注册的监听器可以根据磁贴的状态采取必要的步骤。如果启用,则可以终止所有现有连接并返回空数据,并设置标志以阻止新连接。如果禁用,则可以重置标志以允许新连接。以相机服务(platform/frameworks/av/services/camera/libcameraservice/)为例,请按照以下步骤添加对新传感器的支持。

  1. 实现 BnSensorPrivacyListener 接口。有关更多详细信息,请参阅 CameraService.h 中的 SensorPrivacyPolicy,地址为 CameraService.h
  2. SensorPrivacyManager 注册并在启动时获取磁贴的状态。有关更多详细信息,请参阅 CameraService.cpp 中的 SensorPrivacyPolicy::registerSelf,地址为 CameraService.cpp
  3. 在回调中处理 传感器关闭 状态更改。有关更多详细信息,请参阅 CameraService.cpp 中的 SensorPrivacyPolicy::onSensorPrivacyChangedCameraService::blockAllClients,地址为 CameraService.cpp
  4. 当磁贴启用时,阻止访问传感器数据。有关更多详细信息,请参阅 CameraService.cpp 中的 CameraService::validateClientPermissionsLocked 中的传感器隐私策略检查,地址为 CameraService.cpp

移除传感器关闭

作为用于测试的开发者工具,传感器关闭 是隐藏的,因为用户必须首先启用开发者模式,然后选择在设置中启用该磁贴。

如果您不想在设备上支持 传感器关闭,请从 packages/apps/Settings/AndroidManifest.xml 中移除 service 标签。如果您移除 service 标签,则无法从开发者快速设置磁贴页面启用 传感器关闭 磁贴。

更改传感器关闭 UI

传感器关闭 UI 有两个可以自定义的元素:开发者快速设置磁贴显示的图标和磁贴启用时状态栏中显示的图标。要自定义这些图标的外观,请替换以下文件

  • 快速设置磁贴图标:packages/apps/Settings/res/drawable/tile_icon_sensors_off.xml
  • 状态栏图标:frameworks/base/packages/SystemUI/res/drawable/stat_sys_sensors_off.xml

验证

作为一个可选的开发者工具,此功能没有 CTS 测试。

您可以通过从 Google Play 安装一个读取和显示设备所有传感器的应用来手动测试。当您启用 传感器关闭 磁贴时,请确保传感器的所有值均未更改,麦克风音频为静音,并且相机不可访问。