Each time I have created an Android image I have found something new. Google Assistant and Android Auto were results of Nougat and Oreo, and the changes I found in Google Assistant were a result of Android Pie. Android 10 is no exception. While poking around the OS during the data generation period I found Google’s Digital Wellbeing app was tracking how many times I unlocked the test phone each day, which led me to ask “what else was it tracking?” As it turns out, quite a bit. I shared this information with Alexis Brignoni (more on that later) and got to work on some test data after I created the Android 10 image.
Digital Wellbeing is not new. It was introduced to the Pixel line in Android 9, and slowly rolled out to non-Pixel phones. While not present on every Android device, it is required on newer devices. As of September 3, 2019, Google is requiring Digital Wellbeing-like capabilities on all phones that either launch with or upgrade to Android 9 or 10. This is baked into the Google Mobile Services contract, so OEMs who want to use Google services and apps on their handsets will have to comply. Basically, this means while the specific Digital Wellbeing app is not required, tracking certain activities and making that information available to the user is, so it is possible OEMs may implement their own solutions in order to comply. However, it is more likely they will just use Digital Wellbeing. The point is that regardless of which option OEMs choose, the data will be there…somewhere, and in some fashion.
Google wants users to be able to make informed decisions about their digital well being. In order to do this, users need to know how much time they are spending on their phones and how they are using them. Sometimes examiners and investigators need to know that same information in order to make informed decisions during an investigation. Digital Wellbeing can help with both.
Jessica Hyde (@B1N2H3X), Alexis Brignoni (@AlexisBrignoni), and Yogesh Khatri (@SwiftForensics) have done a lot of great work on Usage Stats in Android and how they can be used to track user activity. My hope for this blog post is that it takes their work one step further.
Digital Wellbeing is a dashboard for the usage data it collects, and it is fairly easy to navigate. It can be accessed from the Android Settings app. Figure 1 shows the landing page for the app.
The part that is of interest here is the top portion, “Your Digital Wellbeing tools.” As you can see the device is tracking the number of unlocks and the amount of notifications received (red box). You can also see the chart that shows the amount of time I spent on the phone at that particular point in the day; I took the screenshot early in the morning, so I had only been on the phone for a few minutes.
Tapping in the middle of the blue circle brings me to the page seen in Figure 2, which is tracking the amount of time I have been active on my screen. The area in the red box is a drop down menu. The other two choices are “Notifications Received” (Figure 3) and “Times Opened” (Figure 4).
At the bottom of Figures 2-4, you can see how the total amount of time breaks down for each app. Figure 4 is a bit misleading, though. The top of the screen is tracking the number of times the phone has been opened and the number of times each app has been opened is detailed at the bottom.
That’s it. This app has other capabilities, but from an investigative standpoint these are the ones to pay attention to.
To generate test data, I wiped my Pixel 3, flashed it with a clean install of Android 10 (January 2020 patch level), and then rooted it with Magisk. When setting up the phone I took all of the defaults. I did not do anything to the Digital Wellbeing app just so I could see what the default data collection looked like, and I imagine most users will do the same as they probably do not care about this feature. I installed two apps from the Google Play Store, Line and WhatsApp, and generated some test data with them along with some default apps.
The best way to forensically describe Digital Wellbeing is “Usage Stats on steroids.” While this is great for Android, it is not quite as thorough as iOS’s knowledgeC, and it is definiately no where near as “clean” as knowledgeC. However, examining it is straight forward for two reasons: 1, it is a SQLite database, and 2, it uses the same event type codes as Usage Stats, which are well documented on the Android developer site. In theory, one could merely extract the database, run a quick SQL query, export to CSV, and sort by time. Voila, you have yourself a timeline, right? Well, not quite.
Before we get to the database, let’s take a quick look at where it is stored. The Digital Wellbeing database is aptly named “app_usage” and is in the path /data/data/com.google.android.apps.wellbeing/databases. See Figure 5.
The table of interest here is “events.” See Figure 6.
This table is simple. Here the timestamps can be seen (in Unix Epoch) along with the event codes for what the app did (column type). Again, these codes are the same as those in Usage Stats, but in Android 10 (API 29) two have been renamed, five new ones have been introduced, and one is not even documented. The codes I have observed in the table are as follows:
1 = ACTIVITY_RESUMED (Formerly MOVE_TO_FOREGROUND)
2 = ACTIVITY_PAUSED (Formerly MOVE_TO_BACKGROUND)
12 = Notification (not documented on the Android Developer site)
18 = KEYGUARD_HIDDEN (indicative of a device unlock-added in Android 9)
19 = FOREGROUND_SERVICE_START (new)
20 = FORGROUND_SERVICE_STOP (new)
23 = ACTIVITY_STOPPED (new)
26 = DEVICE_SHUTDOWN (new)
27 = DEVICE_STARTUP (new)
Some of the names are descriptive enough, but for those that are not you can read about them by visiting the Android Developers page.
The values in the column package_id refer to the values _id in the table packages (Figure 7).
A SQL query will pull the needed values together in one place and convert them to something human-readable. Thanks to Alexis for cooking up the query!
datetime(events.timestamp/1000, “UNIXEPOCH”) as timestamps,
when events.type=1 THEN ‘ACTIVITY_RESUMED’
when events.type=2 THEN ‘ACTIVITY_PAUSED’
when events.type=12 THEN ‘NOTIFICATION’
when events.type=18 THEN ‘KEYGUARD_HIDDEN || DEVICE UNLOCK’
when events.type=19 THEN ‘FOREGROUND_SERVICE START’
when events.type=20 THEN ‘FOREGROUND_SERVICE_STOP’
when events.type=23 THEN ‘ACTIVITY_STOPPED’
when events.type=26 THEN ‘DEVICE_SHUTDOWN’
when events.type=27 THEN ‘DEVICE_STARTUP’
END as eventtype
INNER JOIN packages ON events.package_id=packages._id
ORDER by timestamps
Here you can see the same data as in Figure 6, but this time the package_id is replaced with package_name and there is an extra column, eventtype, that translate the column type.
For purposes of this blog post, I exported the SQL query output to a CSV, added two columns, “Human Readable Time” and “Human Readable Activity.” Then I sorted by time. See Figure 9.
To help decipher this, I have color coded some lines. The orange rows indicate when my device locked, with the package ending in “nexuslauncher” stopping (activity type 23). The next event that shows up is just over two hours later (green rows). In the next two rows (green) you can see nexuslauncher resume (activity type 1), and then the package android appears with the activity type 18 (device unlock). I had locked the phone at 13:32, and then woke it at 15:40 and unlocked it.
The next thing I did a minute later was change the wallpaper. I long-pressed on the home screen and went to the wallpaper gallery. You can see that nexuslauncher paused and then stopped (yellow rows) and then the package ending in “wallpaper” resumed-paused-stopped-resumed (cycled), which is shown in the blue rows. Once I chose my wallpaper I went back to the homescreen (white row), and then the wallpaper package stopped (red rows) since I was done with it.
Looking at the Human Readable Time column you will see that this entire series of actions occur within a minute and a half of each other, and some of those occur at the same second. In that case the sorting is done by the column “_id.” Interestingly enough, I did not find where the values in the _id column were not in chronological order. Not to say that it could not happen, but that I did not find it.
Figure 10 is my next example.
In this figure I had been using the Android Messages app (orange row), and hit the home button to go back to the home screen (blue boxes). I left the phone alone and let the screen timeout on its own (timeout setting was 5 minutes). The phone sat dormant until I unlocked it which took me to the home screen (green rows). I then opened the Line app and started typing (yellow and grey rows).
The red rows are interesting. They all have event ID’s of 12, and they were all written to the database while I was not using the phone (I had left it on my desk with no interaction for over a day). I went back and checked my notes and compared them and this output versus what was in the Digital Wellbeing Notifications dashboard, and, as it turns out, event ID 12 denotes a notification. The thing to note is it could be a notification you can see or cannot see. For example, I had numerous entries for com.android.providers.downloads, however, I have nothing in my notes that indicate I received a notification for that. It is possible Google Play Store downloaded updates in the background and I never saw them (remember I took the defaults at setup). If you looked closely at row 6 in Figure 8 you would see that the setupwizard had a notification. Google’s definition of “notification” may be different than what we traditionally think of for the purpose of Digital Wellbeing. The point here is that care should be taken in how this data point is interpreted. Examiners/investigators should corroborate event ID 12’s with other data points on the device (e.g. the Messages package has an event ID of 12 and there is a message in the Messages database that is received contemporaneously).
All that being said, the last row in Figure 10 (white) does indicate a notification I received from Line indicating I had received a new message. That was in my notes. 🙂
My last example is shown in Figure 11.
In this view, I searched “forensic 4cast awards” from the Google Quick Search Box on the home screen (orange rows). The yellow rows show my navigation to a few web pages, and then returning to the home screen via the home button.
I then initiated a shutdown of the device by using the side button and selecting shutdown. As you can see in the red rows, nexuslauncher is paused, and the event ID code 26 is shown. A little over a minute later I powered on the device (event ID 27).
Once powered on, I was presented with the home screen and prompted for my PIN when I swiped up on the screen. I unlocked the phone (green row) and then started the camera app (white row).
As can be seen by the blue rows, there are other entries for settings, Digital Wellbeing, dialer (phone) and Google Quick Search Box. Those are entries for things that, I believe, start automatically without user intervention. I tested the same shutdown/startup scenario again, and virtually got the same results. Again, corroboration…
A Few Notes
There are a few things to note about this database. First, this database will not keep data about an app after it has been deleted. I generated a bit of test data in WhatsApp and then uninstalled it. The Digital Wellbeing database had no entries for com.whatsapp. Fortunately, Alexis has done plenty of work with deleted apps in Android and found usage stats for apps that have been deleted remain after the app has been deleted. Additionally, newer devices may have Device Personalization Services, which does retain data about user activity in deleted apps, so this may be an option. You can find more about Device Personalization Services in a related blog post.
Second, there is no documentation about how long Digital Wellbeing keeps its data. I will say that when I created the Android 10 image, I did find data in the database all the way back to when I did a clean install on the device (2020/01/29). There was a little over two weeks of data in there, but I have not tested anything beyond that.
The Google Mobile Services contract states that if OEMs opt to implement their own solution, they have to keep at least a week’s worth of historical data. So, depending on the OEM of the phone on your bench, you may have more or less data than I found, but you should have at least one week of historical activity.
Third, as with all things we do, entries in this database should be corroborated with other data points on the phone.
Users can turn Digital Wellbeing off. If that happens, the data will be flushed from the app_usage database within 24 hours. Testing shows that when the database is flushed, everything is flushed; there is not one cell of data in any of the tables. If you have performed your extraction, and, while reviewing the data, you find the digital wellbeing data is non-existent, check the settings. If Digital Wellbeing is off, you can turn it back on and get the last ten (10) days of data, which is better than no data. As always, make sure you document this change in your reporting.
However, if the device has been sitting in storage/an evidence locker for three months (for example) you will not get any data. It appears Android is going by calendar days, and not days of collected data. Again, this was based on my testing only with the phones I have available, so your mileage depending on OEM implementation.
Finally, because of where this database lives, it is only available if your extraction method can pull data from /data/data. I attempted to extract the database using both the Android Backup and Advanced Logical methods in UFED 4PC 7.28, and both failed to extract this data. The latter may be a symptom of my particular phone since it tends to be a bit tougher to get into than others. (UPDATE: Cellebrite Physical Analyzer 7.33 and higher now parses Digital Wellbeing data!)
If you recall, I mentioned I had shared this information with Alexis. Well, as it customary for him, he has created an awesome utility, ALEAPP, to parse this data. I want to thank him for putting in the time with this and his overall contributions to the DFIR community. His scripts and utilities are fantastic, and, if you are not following him, you are missing out.
If you attended the 2020 DFIR Summit and watched the presentation by Alexis Brignoni and myself, you would have seen that there are a few other notable things about Digital Wellbeing, which I thought I would add to this post.
While examining a Samsung Galaxy A30 I discovered Samsung, as is customary, had implemented their own version of Digital Wellbeing, which is named “Digital Wellbeing” (original). An interesting note about Samsung’s implementation: the app icon is not on the screen by default, but the app is still on by default. A user can change the settings to have the app icon appear on the home screen/app tray. There are some other differences, too. The APK for Samsung’s version of Digital Wellbeing is com.samsung.forest, and is found in /data/data. In the databases folder is dwbCommon.db. See Figures 12 and 13.
dwbCommon.db tables are different, too. The two tables of interest are usageEvents and foundPackages. These tables serve the same functions as the events and packages table from Google’s Digital Wellbeing, respectively.
Surprisingly, Samsung’s solution is more descriptive than Google’s. Samsung has opted to use additional codes not seen in the stock Google version. Specifically:
5 = CONFIGURATION_CHANGE
7 = USER_INTERACTION
10 = Notification Panel (not documented)
11 = STANDBY_BUCKET_CHANGED
15 = SCREEN_INTERACTIVE (Screen on for full user interaction)
16 = SCREEN_NON_INTERACTIVE (Screen on in non-interactive state or completely turned off)
17 = KEYGUARD_SHOWN
All of these are documented in the Android developer’s documentation except one: 10. After some testing, I found that 10 corresponds to pulling down the Notification Panel (swipe down from the top edge of the screen).
Two interesting codes are SCREEN_INTERACTIVE and KEYGUARD_SHOWN. The former indicates the screen of the device is on and can accept input, which is in contrast to SCREEN_NON_INTERACTIVE, which indicates the screen is on, but is not able to accept any input (e.g. the phone screen has been awakened by movement, but is not awaiting the passcode). It can also mean the screen is off. Mashing these two states together in one code is not very…convenient…for examiners, so, as with other things, this event type should be evaluated contextually.
Samsung is also documenting screen locks (KEYGUARD_SHOWN). One note about this event type. There is no way to determine if the device locked due to user action (hitting the lock/power button) or if the device locked due to the screen timeout. If you are able to determine the screen timeout settings, you may be able to determine if a manual lock was initiated (e.g. a period of inactivity followed by a SCREEN_NON_INTERACTIVE and KEYGUARD_SHOWN).
Because of these additional codes and differing table names, the SQL query for Samsung Digital Wellbeing is a little different:
datetime(usageEvents.timeStamp/1000, “UNIXEPOCH”) as timestamp,
when usageEvents.eventType=1 THEN ‘ACTIVITY_RESUMED’
when usageEvents.eventType=2 THEN ‘ACTIVITY_PAUSED’
when usageEvents.eventType=5 THEN ‘CONFIGURATION_CHANGE’
when usageEvents.eventType=7 THEN ‘USER_INTERACTION’
when usageEvents.eventType=10 THEN ‘NOTIFICATION PANEL’
when usageEvents.eventType=11 THEN ‘STANDBY_BUCKET_CHANGED’
when usageEvents.eventType=12 THEN ‘NOTIFICATION’
when usageEvents.eventType=15 THEN ‘SCREEN_INTERACTIVE (Screen on for full user interaction)’
when usageEvents.eventType=16 THEN ‘SCREEN_NON_INTERACTIVE (Screen on in Non-interactive state or completely turned off)’
when usageEvents.eventType=17 THEN ‘KEYGUARD_SHOWN || POSSIBLE DEVICE LOCK’
when usageEvents.eventType=18 THEN ‘KEYGUARD_HIDDEN || DEVICE UNLOCK’
when usageEvents.eventType=19 THEN ‘FOREGROUND_SERVICE START’
when usageEvents.eventType=20 THEN ‘FOREGROUND_SERVICE_STOP’
when usageEvents.eventType=23 THEN ‘ACTIVITY_STOPPED’
when usageEvents.eventType=26 THEN ‘DEVICE_SHUTDOWN’
when usageEvents.eventType=27 THEN ‘DEVICE_STARTUP’
END as eventTypeDescription
INNER JOIN foundPackages ON usageEvents.pkgId=foundPackages.pkgId
ORDER BY timestamp
The output can be seen in Figure 16.
This snippet shows just how granular this database (and Google’s solution) is with regards to activity. In the blue box starting at Line 1133 is the start of a sequence in which I locked the phone by pressing the lock/power button. In the red box you can see immediately woke the phone, entered the passcode (line 1144) and then went into the Digital Wellbeing app (last line).
One additional note about Samsung’s Digital Wellbeing. Samsung seems to be strictly adhering to the GMS requirement that in-house digital wellbeing solutions keep one week’s worth of data. I have not been able to get more than one week’s worth of data from my Galaxy A30. Samsung may change this feature via an app update in the future, but for now, examiners are only getting one week.
Another interesting thing about Google’s version of Digital Wellbeing is that it does track a user’s web history…sort of. While Digital Wellbeing is on by default, tracking web history inside of Digital Wellbeing is not. See Figure 17.
The red box in Figure 16 is the “Show Sites” button. If a user hits that button they get the splash screen, also seen in Figure 16. The interesting thing with opting in is that existing web history is imported. So, for example, if a user browses the web for a bit, and then opts in to tracking web history later, that pre-existing web history is imported. I will note this applies to Chrome only as of July of 2020. Firefox, Opera, and Microsoft Edge do not have their histories imported, and there is no option to opt-in.
There are two tables in app_usage that are used to keep tabs on web history: component_events and components. See Figures 18 and 19.
As with the other features, a SQL query will pull the data together for you.
SELECT component_events._id,components.package_id, packages.package_name, components.component_name as website,
datetime(component_events.timestamp/1000, “UNIXEPOCH”) as timestamp,
when component_events.type=1 THEN ‘ACTIVITY_RESUMED’
when component_events.type=2 THEN ‘ACTIVITY_PAUSED’
END as eventType
INNER JOIN components ON component_events.component_id=components._id
INNER JOIN packages ON components.package_id=packages._id
ORDER BY timestamp
Figure 20 shows some sample output.
There are only two event types I have observed in this table: ACTIVITY_RESUMED and ACTIVITY_PAUSED. The interesting thing about this data is that you will not find specific URLs in it; you will only find top-level addresses for websites. In Figure 20 you can see I had navigated to ArsTechnica. When I got there, I clicked on a couple of articles to read, but you do not see those URLs in this query output. It appears Digital Wellbeing is more concerned with how much time you are spending on a site and not necessarily what you are doing while you are there. Obviously, there are other places within Android examiners can go in order to get more specific web history.
One final note here. Samsung’s Digital Wellbeing, as of June of 2020, does not have the capability to track web history. This could change in a future app update, but for now, this appears to be exclusive to Google’s solution.
Alexis Brignoni has already updated ALEAPP to parse both Samsung’s version of Digital Wellbeing, and the web history feature from the Google solution. He even has it parsing Device Personalization Services, which, if you haven’t heard, is also collecting pattern-of-life data. Check out my blog post on that artifact!