ABTraceTogether Android Background Capability Analysis
The ABTraceTogether COVID contact tracing app also doesn’t work well on Android devices. Let’s dig in and see.
This research was originally published on Google Docs (ABTraceTogether Android Background Capability Analysis) on November 14, 2020, with a short summary described on Twitter. The tweets and research notes are archived and reproduced here with some formatting edits.
Executive Summary
(Reproduced from Twitter)
Today I continued testing ABTraceTogether, focusing on the exposures collected on an Android. There is some defect. It failed to record an Android in close proximity. I don’t know whether it’s an flaw related to one of my devices, or general problem.
Throughout my testing, I had an iPhone and two Android devices in physical proximity. The iPhone was recorded by the Android pretty consistently. Overnight, a second iPhone nearby was also recorded. A good start!
But the Android-to-Android data was so sparse that I revised my test protocol a few times to try to figure it out. No overnight data recorded. 8 hours of the phones snuggled, and they didn’t see each other at all?
I guessed that maybe ABTraceTogether detected that they had registered with the same phone number, and that blocked recording. I didn’t see that in the source code, but, maybe? I borrowed a friend’s spare phone number (thanks Mike). No difference in another hour of testing.
I found that one of my Android devices had automatically configured the ABTraceTogether app to “Intelligent Control” battery optimization. Well, that could have some impact, right? So, I tweaked that to “Don’t Optimize”. Another hour of testing, and no exposures recorded.
I added a third Android device to the test, and I started getting a few Android-to-Android traces. So; maybe one Android device just didn’t work? Despite saying “ABTraceTogether is scanning to keep you safe!” all the time?
Another theory… Android-to-Android only stores data a few times for an exposure (3), and then ignores new records. But… only Android/Android, no other combo? And that won’t allow exposures to age out of the DB accurately. And… the Open Source repo doesn’t do that.
So, I’m stumped for now. I have a few old Android devices; maybe I’ll dust off more and see if this is a single device problem. Unluckily it’s my primary day-to-day phone. 😰
Which I guess is still an interesting result; ABTraceTogether can appear to be working, and not work.
Overview
(Special thanks to my collaborator and iPhone contributor: Amanda Fenniak 😘, and my collaborator and phone number contributor: Mike Roest 😎)
On November 11th, an analysis of ABTraceTogether’s background contact tracing capabilities was conducted with a specific focus on iPhone interactions (https://mathieu.fenniak.net/abtracetogether-iphone-background-capability-analysis/). This allowed investigation of all data that was collected by an iPhone, but not the data that was collected by an Android phone in proximity to other phones.
In this document, testing and analysis is performed on the data collected from an Android phone using ABTraceTogether.
Test Protocol
- ABTraceTogether was installed on two Android phones, and one iPhone
- ABTraceTogether was run, other applications were opened so that ABTraceTogether was in the “background”, and then the phones were locked
- All phones were kept within close proximity for a 12 hour period; less than 1 meter separation
- Data collected from one Android was analyzed
- See Appendix for more detailed information on the data collection procedure
Test Details
Dates and times are in Mountain Standard Time
- iPhone #1:
- iPhone 11 Pro
- iOS 14.2
- ABTraceTogether version 1.4.0 installed from the Apple App Store; registered with phone number #1
- iPhone #1 was a nearby phone during the test, but it is not the iPhone that was specifically kept in physical proximity; it would have varied between 3m and 20m distance throughout the test
- iPhone #2:
- iPhone 6s
- iOS 14.1
- ABTraceTogether version 1.4.0 installed from the Apple App Store; registered with phone number #2
- Kept within 1m of Android #2 throughout test
- Android #1:
- OnePlus 7T
- OxygenOS (Android) 10.0.14.HD65AA
- ABTraceTogether version 1.4.0 installed from the Google Play Store; registered with phone number #3
- Kept within 1m of Android #2 throughout test
- Android #2:
- Google Nexus 5
- LineageOS 17.1; Android 10
- ABTraceTogether version 1.4.0 installed from the Google Play Store
- Originally registered with phone number #3
- Registered with phone number #4 in test #2 and later
- Android #3:
- Introduced only in later tests
- Amazon Fire HD 10 (9th generation)
- FireOS 7.3.1.6 (Android)
- ABTraceTogether version 1.40 installed from the Google Play Store; registered with phone number #3
- 2020-11-13
- 6:52pm
- Android #2, Android #1, and iPhone #2 have been placed in close physical proximity, had the ABTraceTogether app run, and then put into the background by hitting the home button within the past 2 minutes.
- All phones are running on battery power.
- ~10:00pm
- iPhone #1 & Android #1 are connected to power
- 6:52pm
- 2020-11-14
- 5:30am
- iPhone #1 & Android #1 are disconnected from power
- 6:27am
- Android #2 is connected to power
- Android #2’s ABTraceTogether database is cloned for analysis
- 5:30am
- Test period #1: 2020-11-13 6:52pm -> 2020-11-14 6:27am
- Following the completion of the test, data extraction, and analysis above, a second test was conducted to rule out a possible explanation for unexpected results
- Possible flaw in testing: Android #1 and Android #2 were registered to ABTraceTogether with the same phone number
- ABTraceTogether was deleted from Android #2
- ABTraceTogether was installed in Android #2, and re-registered with a fourth phone number, distinct from iPhone #1, #2, and Android #1
- All devices were charged to >90% battery before test period #2 began
- 2020-11-14
- 10:49am
- Test phones Android #1, Android #2, and iPhone #2 are placed in close proximity
- ABTraceTogether is run in the foreground on the three test phones
- Continual interactions are required on Android devices to keep screen & app active
- 11:00am
- ABTraceTogether is sent to the background on the three test phones by hitting the home button, and locking the phones
- 12:07pm
- End of test period; data to be collected at 12:55pm
- 10:49am
- Test period #2: 2020-11-14 10:49am -> 12:07pm
- Following the completion of the test, data extraction, and analysis above, a third test was conducted to rule out a possible explanation for unexpected results
- Android #1 was explicitly configured so that ABTraceTogether app was set to “Don’t Optimize” for battery options
- Android #3 was introduced into the test environment
- 2020-11-14
- 1:46pm
- Android #3: ABTraceTogether installed and registered
- 1:48pm
- ABTraceTogether is sent to the background on the four test device sby hitting the home button, and locking the phones
- 2:34pm
- End of test period; data collected immediately
- 1:46pm
- Test period #3: 2020-11-14 1:48pm -> 2:34pm
Data & Analysis
- Raw data from both data sets is available in the below spreadsheet
- Original analysis format was Google Sheets
- An archive of the same spreadsheet is available in a Microsoft Excel and OpenDocument format.
- ABTraceTogether Android collects all exposures in a table named record_table with the following fields:
- id INTEGER PRIMARY KEY
- Analysis: sequentially incrementing primary key of the record
- timestamp INTEGER
- Analysis: epoch-milliseconds; that is, a timestamp in UTC represented by the number of milliseconds past since midnight 1970-01-01
- v INTEGER
- Analysis: always contains the value 2
- msg VARCHAR
- Data: 61 bytes of BASE64 encoded data; repeated multiple times for each exposure
- Analysis: This is the exposure ID of the target device; there seems to be no confidential information in the base64 decoded data
- The data published in this spreadsheet has been trimmed to the first 30 characters in the unlikely event that confidential or sensitive information is contained in the token
- org TEXT
- Data: String “CA_AB”
- Analysis: Possible future expansion to multiple regions, or integration with other OpenTrace-supported applications
- modelC VARCHAR
- Data: “iPhone” or “Android”
- Analysis: In the Bluetooth protocol, “central” devices are host devices, and “peripheral” devices connect to central devices. The “C” suffix indicates that this suggests which type of device was the “central” device in this exposure.
- modelP VARCHAR
- Data: “iPhone” or “Android”
- Analysis: As per field modelC, this is believed to be the model of the peripheral device.
- rssi INTEGER
- Analysis: measurement of the received signal strength indicator, likely in dBm; the values range from -12 to -100
- txPower INTEGER
- Data: NULL
- id INTEGER PRIMARY KEY
Test Period #1
- Data collected
- 339 exposures were collected
- Msg: avuP1VvHjDRWCuoVFoAAdTOW2TACdp
- 58 exposures
- iPhone central device, Android #2 is peripheral
- Exposures recorded between 7:07pm and 5:51am
- Time between exposure:
- Average: 11 minutes
- Maximum: 67 minutes
- RSSI: -100 to -58
- Msg: KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA
- 67 exposures
- iPhone central device, Android #2 is peripheral
- Exposures recorded between 6:57pm and 5:51am
- Time between exposure:
- Average: 9 minutes
- Maximum: 26 minutes
- RSSI: -70 to -15
- Msg: odarSPFz7coBgKtf0mmLFRw7ODGt5O
- 131 exposures
- Android #2 central device, iPhone ? is peripheral
- Exposures recorded between 8:56pm and 5:51am
- Time between exposure:
- Average: 4 minutes
- Maximum: 18 minutes
- RSSI: -47 to -18
- Msg: TgT0cEg2mZm6YMd5ejPMv7KRpDVzoK
- 42 exposures
- Android #2 is central device, iPhone ? is peripheral
- Exposures recorded between 9:10pm and 5:51am
- Time between exposure:
- Average: 12 minutes
- Maximum: 71 minutes
- RSSI: -93 to -60
- Msg: U00y/jHqnbDh7+wIkl4zCY+D1C99e3
- 33 exposures
- Android #2 is central device, iPhone ? is peripheral
- Exposures recorded between 6:35pm and 8:52pm; includes time before the test began
- Time between exposure:
- Average: 4 minutes
- Maximum: 15 minutes
- RSSI: -96 to -12
- Msg: wOPJa8pn/iB8wN6Gawd6olHKeHREfy
- 1 exposure
- Android - Android; cannot distinguish the central or peripheral
- Occurred at 6:49pm; this is before all phones were in the background configuration at the start of the test
- RSSI: -89
- Msg: IHGhpOV5XP0sqGfXVlKIaEjzQm+j8z
- 2 exposures
- Android - Android; cannot distinguish the central or peripheral
- All exposures occurred at 6:59pm
- RSSI: -68 to -47
- Msg: jhWnG4TnzYe1XOqVej37NWKx2QTgK+
- 5 exposures
- Android #2 is central device, iPhone ? is peripheral
- Exposures recorded between 6:35pm and 8:45pm; includes time before the test began
- Time between exposure:
- Average: 32 minutes
- Maximum: 96 minutes
- RSSI: -91 to -81
- Analysis
- On iPhone / Android interactions:
- TgT0cEg2mZm6YMd5ejPMv7KRpDVzoK & avuP1VvHjDRWCuoVFoAAdTOW2TACdp
- One of these messages was Android central, other iPhone central
- Messages had similar start & end times
- 7:07pm to 5:51am
- 9:10pm to 5:51am
- Messages had similar RSSI ranges
- -93 to -60
- -100 to -58
- Given the long-term overnight exposure, this is likely to be either iPhone #1 or iPhone #2 communicating with Android #2
- Considering the lower RSSI values, which would correlate with greater physical distance between the phones, it is plausible that this is iPhone #1 to Android #2
- KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA & odarSPFz7coBgKtf0mmLFRw7ODGt5O
- One of these messages was Android central, other iPhone central
- Messages had similar start & end times
- 6:57pm to 5:51am
- 8:56pm to 5:51am
- Messages had similar RSSI ranges
- -70 to -15
- -47 to -18
- Given the long-term overnight exposure, this is likely to be either iPhone #1 or iPhone #2 communicating with Android #2
- Considering the higher RSSI values, which would correlate with shorter physical distance between the phones, it is plausible that this is iPhone #2 to Android #2
- Note: Although the above message pairs look like they may be mismatched based upon the timestamps, the RSSI signal strength matches better, and all the exposures that started in the 7pm timeframe were iPhone central devices; these messages need to be paired central/peripheral, which they can’t be if the pairing was adjusted. Regardless the results of the analysis are not impacted by the specific messages that identify a device.
- U00y/jHqnbDh7+wIkl4zCY+D1C99e3
- Unidentified iPhone peripheral between 6:35pm and 8:52pm
- RSSI values were surprisingly strong for an unidentified phone
- 8:52pm roughly corresponds to Android #2 being moved within the home test environment; my best explanation is that this was a neighbour’s iPhone and we were in close physical proximity, but this explanation seems questionable
- jhWnG4TnzYe1XOqVej37NWKx2QTgK+
- Unidentified iPhone peripheral between 6:35pm and 8:45pm
- RSSI values are weaker than U00y
- If it weren’t for this device also showing an Android central, it would be likely that this is the inverse relationship of the U00y message above; considering both show the Android central device, this is unexplained
- TgT0cEg2mZm6YMd5ejPMv7KRpDVzoK & avuP1VvHjDRWCuoVFoAAdTOW2TACdp
- On Android / Android interactions:
- Messages wOPJa8pn/iB8wN6Gawd6olHKeHREfy & IHGhpOV5XP0sqGfXVlKIaEjzQm+j8z
- Both occurred in the same time window, 6:49pm - 6:59pm
- Only 3 exposures occurred, and in a small time period
- RSSI values are not strongly correlated between the exposures, but the number of exposures is so low that this can’t be correlated well
- Messages wOPJa8pn/iB8wN6Gawd6olHKeHREfy & IHGhpOV5XP0sqGfXVlKIaEjzQm+j8z
- Strong interactions between iPhone and Android was recorded throughout the experiment, with a high probability that a 10 minute physical exposure would result in a recorded ABTraceTogether exposure
- Android-Android interactions appear to be effectively absent from the dataset; despite 12 hours of physical exposure, only 10 minutes of recording between the devices was recorded
- Part of this exposure recording is outside of the “background” time window in the test, as well; exposures occurred at 6:49pm while the test was being configured and either device may run the application in the foreground
- On iPhone / Android interactions:
Test Period #2
- Data collected
- 52 exposures were collected
- 23 exposures were within the test time period; the remaining exposures occurred and were recorded while all devices were being recharged between tests
- Non-eligible exposures are coloured grey in the spreadsheet
- Test period #2: 2020-11-14 10:49am -> 12:07pm
- Msg: h5Cjy32U67/0fnQeeq05K+NStEElVG
- 19 exposures
- Android #2 central device, iPhone #2 is peripheral
- Exposures recorded between 10:52am and 11:55am
- Time between exposure:
- Average: 3 minutes
- Maximum: 10 minutes
- RSSI: -47 to -28
- Msg: KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA
- 9 exposures
- iPhone central device, Android #2 is peripheral
- Exposures recorded between 10:50am and 11:49am
- Time between exposure:
- Average: 7 minutes
- Maximum: 11 minutes
- RSSI: -77 to -62
- Analysis
- On iPhone / Android interactions:
- KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA & h5Cjy32U67/0fnQeeq05K+NStEElVG
- One of these messages was Android central, other iPhone central
- Messages had similar start & end times
- 10:52am and 11:55am
- 10:50am and 11:49am
- When iPhone is central device, the msg code KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA is the same as the code previously identified as iPhone #2; this is consistent with iPhone #2 being the only iPhone present during test period #2
- KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA & h5Cjy32U67/0fnQeeq05K+NStEElVG
- On Android / Android interactions:
- No Android/Android interactions were recorded during the test period, including both the foreground and background execution time
- On iPhone / Android interactions:
- 52 exposures were collected
Test Period #3
- Data collected
- An additional 8 exposures were collected on top of Test Period #2
- Non-eligible exposures from outside of this test period are coloured grey in the spreadsheet
- Test period #3: 2020-11-14 1:48pm -> 2:34pm
- Msg: mIT1/+vA/XhDRFt51WqXtw0pFOy0bK
- 3 exposures
- Android - Android; cannot distinguish the central or peripheral
- Exposures recorded between 1:55pm and 1:59pm
- Average: 1 minute time between exposure; however very few exposures are captured in this time window
- RSSI: -61 to -61
- An additional 8 exposures were collected on top of Test Period #2
- Msg: KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA
- 5 exposures
- iPhone central device, Android #2 is peripheral
- Exposures recorded between 1:55pm and 2:28pm
- Average: 8 minutes time between exposure; however very few exposures are captured in this time window
- RSSI: -53 to -50
- Analysis
- On iPhone / Android interactions:
- KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA
- Consistent with Test Period #2, this appears to be iPhone #2 being recorded from Android #2
- KPZfd0ip8lGWMSUA/IdTeB/ZBZfpGA
- On Android / Android interactions:
- A new Android/Android interaction was recorded during the test period
- Data is inconclusive as to whether Android #2 was the central or peripheral device
- Data is inconclusive as to whether the other partner in the device was Android #1 or Android #3
- Regardless of whether Android #1 or #3 was the pair device, the absence of an additional signal indicates that one of the two Android devices did not record within the 46 minute test window
- On iPhone / Android interactions:
Multi-Test Analysis
- ABTraceTogether failed to record exposures from a nearby Android device during the initial 12 hour test period.
- During a shorter 78 minute Android-Android test, ABTraceTogether failed to record exposures from the Android device.
- Android #2 was reconfigured to a distinct phone number from Android #1.
- This change appears to have had no impact.
- During a third 46 minute Android-Android test, one of two Android devices were detected.
- Android #1 had been reconfigured to disable battery optimization on ABTraceTogether.
- Android #3 was introduced into the experiment.
- One of these two changes caused exposures to be recorded, but only to one device.
- Zero Android-to-Android captures would have indicated that Android #2 is unable to receive Android exposures correctly.
- Two Android-to-Android captures would have indicated that the battery optimization on Android #1 had been successful, and Android #3 was working as expected.
- One Android-to-Android capture could theoretically be either change, but, for it to be the battery optimization of Android #1 would be the more complex explanation, as it would indicate Android #3 was not working properly for a new, unexplained reason.
- It isn’t clear why not all test devices are being recognized.
Conclusion
From the perspective of an Android device in close proximity to iPhone devices, ABTraceTogether effectively records the presence of an iPhone. A ten minute physical exposure would very likely result in a recorded ABTraceTogether exposure.
There appears to be a condition in which Android-to-Android exposure detection will fail to be recorded during continuous exposure. However, experimentation has only been able to show the absence of expected functionality, but not the cause of this failure.
ABTraceTogether displays a message on Android continuously that reads “ABTraceTogether is scanning to keep you safe!” and “Restart phone if this notification disappears.” The condition in which Android/Android exposure was not functioning occurred despite this comforting message on all Android devices.
Follow-Up Work
The results of analyzing Android recorded data is not consistent with observed over-the-air Bluetooth traffic generated from ABTraceTogether on an Android. Further theories on the possible fault with Android/Android tracing are welcome to be contributed; however future tests that are required are not yet clear.
The experimental testing occurring with phones in an uncontrolled environment has resulted in aberrant, unexpected exposures. A radio frequency isolating environment would be a great addition to the test configuration, allowing for the removal of all unexpected exposures, and simplifying the analysis of the recorded data. A short experiment with three phones in a microwave, which is a 2.4GHz isolating container, resulted in zero communication between the three devices. Further experimentation with an environment that isolates the devices but does not interfere with their communication would be warranted.
Appendix
Collecting Android Exposure Database
ABTraceTogether on an Android stores data in an App-specific file location, which is not typically readable from an external tool. In order to collect an Android database, it was necessary to configure a device with root-level administrative access.
A Nexus 5 device was chosen from a library of unused Android phones. The following steps were required to get the device available to use ABTraceTogether, and be able to access the recording database:
- Bootloader unlocked – this allowed the installation of a custom recovery tool
- Installation of TWRP – this is a flexible recovery operating system for Android devices
- Repartitioning of Nexus 5 system & data partitions
- Additional storage was required on the system partition
- The Nexus 5 system partition was expanded by 1 GB, by reallocating the data partition space
- Installation of LineageOS 17.1 built for Nexus 5 via TWRP
- Installation of Magisk (https://github.com/topjohnwu/Magisk) via TWRP
- Installation of OpenGApps via TWRP
- OpenGApps was found to be required to supply Google services, which were required for the successful registration of the ABTraceTogether application
- “Nano” installation was used
- Android system setup
- Configuration of Developer Tools via Android Settings
- Remote root access by enabling USB debugging and root debugging via Developer Tools
- Installation of ABTraceTogether via Google Play Store
- Registration of ABTraceTogether
Following all that messy work, retrieving the ABTraceTogether exposure database was performed by USB debugging the Android device, and using the “adb” tool to extract the DB via the command: adb pull /data/data/ca.albertahealthservices.contacttracing/databases/record_database .
The database extracted was a SQLite 3.x database, user version 1, last written using SQLite version 3022000.