Walking the Android (time)line. Using Android’s Digital Wellbeing to timeline Android activity.

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.

Visually Speaking

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.

Figure 1
Figure 1.  Digital Wellbeing landing page.

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).

Figure 2
Figure 2.  Screen time.
Figure 3
Figure 3.  Notifications received.
Figure 4
Figure 4.  Times opened.

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.

Forensically Speaking

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.

Figure 5
Figure 5.  The app_usage database.

The table of interest here is “events.”  See Figure 6.

Figure 6.png
Figure 6.  The events table.

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:

12 = Notification (not documented on the Android Developer site)
18 = KEYGUARD_HIDDEN (indicative of a device unlock-added in Android 9)

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).

Figure 7
Figure 7.  The packages table.

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!

SELECT events._id,
datetime(events.timestamp/1000, “UNIXEPOCH”) as timestamps,
packages.package_name, events.type,
when events.type=1 THEN ‘ACTIVITY_RESUMED’
when events.type=2 THEN ‘ACTIVITY_PAUSED’
when events.type=12 THEN ‘NOTIFICATION’
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’
else events.type
END as eventtype
FROM events
INNER JOIN packages ON events.package_id=packages._id

Figure 8
Figure 8.  SQL query output.

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.

Figure 9
Figure 9.  Color-coded excerpt of CSV output.

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.

Figure 10
Figure 10.  Second color-coded excerpt of CSV output.

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.

Figure 11.png
Figure 11.  Third color-coded excerpt of CSV output.

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.

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.

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.

And Finally

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.

Head over to his blog for Part 2 of this post.  #TEAMWORK

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s