Exposure Notifications BLE attenuations

The Exposure Notifications framework exposes calibrated attenuations that aim to be device-agnostic. This Bluetooth Low-Energy (BLE) signal strength attenuation, defined as transmit power (TX_power) minus received power (RSSI), can be used as a (noisy) proxy for distance.

Attenuation = TX_power - (RSSI_measured + RSSI_correction)

The Exposure Notifications API refers to attenuations in some of the following locations:

The following sections describe the processing involved in gathering and reporting these attenuations.

Calibration: Per-device TX_power and per-device RSSI correction

To ensure that all participating devices compute attenuations in a consistent manner, both transmit power and received power are subject to calibrations.

  • The calibrated transmitter's TX_power is read from the beacon's encrypted payload. Importantly, it is NOT the same as the (unencrypted) TX power present in the lower-level BLE protocol.

  • The calibrated RSSI is calculated from the measured RSSI by adding a per-device RSSI correction. Importantly, this calibrated RSSI is NOT the same as the (uncalibrated) RSSI reported through the Android Bluetooth framework APIs.

Both transmit and received power calibrations are configurations that are pushed to the devices regularly as more calibration results are received (from Google and partners) and as we refine iPhone-Android consistency. Currently, they depend only on the device model.

For the latest calibration values, download the latest EN Calibration <Date>.csv.

You can also see which calibration values your device uses by first activating Exposure Notifications through the API, then searching for the following keywords in the adb logcat:

  • txPower
  • raw_rssi
  • rssi_calibrated

For more details, refer to the BLE RSSI calibration procedure and the BLE calibration calculation.

Aggregation over a scan: ScanInstance min and average

The Exposure Notifications framework scans for beacons in the background, typically scanning for four seconds every five minutes. Advertisement happens on multiple channels. However, due to an Android BLE framework implementation detail, scanning does not always happen on all three channels. For example, Android devices that use Android versions lower than 9.0 (API version 28) or Exposure Notifications API lower than v1.5 scan only on the first channel (channel 37).

During a scan, a device may detect several identical BLE beacons (up to once every 250 ms), each with their own attenuation. Those duplicates are grouped together into a ScanInstance and represented by two numbers: the minimum attenuation, and the average attenuation. ScanInstances are exposed through the Exposure Notifications API starting in version 1.5.

ExposureInformation attenuations (legacy v1 mode): aggregation over a contact period

The API provides one ExposureInformation per continuous contact with a diagnosis key. This means that if the same key was regularly present over several consecutive four-second scans, all of the corresponding ScanInstances are aggregated into a single ExposureInformation.

AttenuationDurations: three-bucket duration histogram

ExposureInformation exposes a three-bucket histogram of attenuations: getAttenuationDurationsInMinutes returns the durations for which the minimum attenuation of exposures fell in three different buckets:

  • < low threshold

  • Between low threshold and high threshold

  • > high threshold

You can configure the two thresholds using ExposureConfiguration.

If scans happen exactly every five minutes, the durations accumulated in those buckets will be 5 times the number of those exposures' ScanInstances whose attenuation falls in that bucket.

ExposureInformation attenuationValue: duration-weighted averaging

ExposureInformation exposes attenuationValue, a duration-weighted averaging of the ScanInstance minimum attenuation values.

ExposureSummary's attenuationDurations (legacy v1 mode): aggregation over all exposures

ExposureSummary represents a summary over all exposures. Attenuations over all exposures are summarized in getAttenuationDurationsInMinutes as the aggregate of all ExposureInformation's getAttenuationDurations.

If scans happen exactly every five minutes, the durations accumulated in those buckets will be 5 times the number of ScanInstances whose minimum attenuation falls in that bucket.

Note that:

  • Two simultaneous sightings (ScanInstances) of two different keys both count toward the total time.

  • In ExposureSummary, the buckets are currently capped at 30 minutes.

Attenuations as distance proxy

Attenuation is a very noisy proxy of distance. A very low attenuation indicates a very high probability of a short distance, but a high attenuation can be caused by many phenomena and is not always indicative of a long distance. When setting attenuationDurations' thresholds or risk score multipliers, it's necessary to make a tradeoff between precision and recall.