Monday, May 20, 2024

Android 14 - Battery Usage and App Usage Events

Moin! :-)

What is this post about?


I've switched my test device from Android 13 to Android 14 - finally - and so I have a lot of new stuff to look into.  I've done some analysis on the battery_usage_v9 database. It was introduced with Android 14.

On Android 12 and 13 there also seems to exist an older version of this database - battery_usage_v4 - Kevin Pagano (stark4n6) wrote a blog post about it and an ALEAPP parser in 2021. His blogpost can be found here.



What type of data to expect?


Like Kevin Pagano already wrote in his post - the data in this databases seems to correlate with the Android Battery Usage and Battery Settings Screens in the Android UI.
Can be found under Settings - Battery in Android and shows something like in the following screen shots to see.


Figure 1: Settings Services - Battery


You can get information on the current battery charging and health status and you can get information on the apps that used the battery, in foreground and in background.
So at least this information should also be in the battery_usage_v9 database.

Okay, let's start digging into the database and its data.

Test device and tested version


Test devices: Fairphone 3 and Fairphone 4
OS: Android 14


The tables


Table: BatteryState

This table already existed in the battery_usage_v4 database. But now it has a different structure. Here is a short overview:

  • mid  - just an iterating id for this table
  • uid  - the uid of the app
  • userId - the id of the user the app is running for (e.g. 0 for default user)
  • packageName - name of the package (e.g. com.android.settings)
  • timestamp - Timestamp event was written in epoch - this only happen every hour by the system
  • consumerType - int value - I have the values 1 and 3 - but I don't know what they mean.
  • isFullChargeCycleStart - Zero or One - in the UI it is said, that only the apps since the last full charge are shown - I guess that this field hold the value if the app shall be shown in UI or not. Double check required.
  • batteryInformation - No idea what this is - Sample data in it: 
CgYIYRACGAIQABi9sscTIg1FdXJvcGUvQmVybGluOhFHb29nbGUgUGxheSBTdG9yZVEAAAAAAAAA
AFkQG44jJZ9DP2EAAAAAAAAAAGj///////////8BcAB4AIEBAAAAAAAAAACJAQAAAAAAAAAAkQEA
AAAAAAAAAJkBAAAAAAAAAACgAQA=
          No idea what this is - when playing a bit with coding/decoding I can recognize                   strings in it after decoding with base64: 
         Europe/Berlin:Google Play StoreQ  
 
  • batteryInformationDebug - here we can find similar information stored like the one in the older database version
# com.android.settings.fuelgauge.batteryusage.BatteryInformation@ffa34700
app_label: "Google Play Store"
background_usage_time_in_ms: 0
boot_timestamp: 41015613
consume_power: 5.988055555555555E-4
device_battery_state {
  battery_health: 2
  battery_level: 97
  battery_status: 2
}
drain_type: -1
foreground_service_usage_time_in_ms: 0
foreground_usage_time_in_ms: 0
zone_id: "Europe/Berlin"
The batteryInformationDebug was empty on my Fairphone 4, but held this information on my FP3 - I don't know exactly why - I read something about new features coming with Android 14 for battery health monitoring and that to use them you need to allow it in the developer options. But I did not do this. Either way - let's go through data what it can mean.

    • app_label - Yeah - the app label - nothing to add from my side
    • background_usage_time_in_ms - the time in ms the app used battery in background
    • boot_timestamp - the time since last reboot of the device in ms
    • consumer_power - consumed power - perhaps in mAH - not sure
    • device_battery_state
      • battery_health - the health status of the battery, I tested three of them (ok/hot/cold) with my test device - and they map to the one from the Android developer guide Android Developer Guide - Battery 
        • 1 = Unknown
        • 2 = Good
        • 3 = Overheat
        • 4 = Dead
        • 5 = Over Voltage
        • 6 = Unspecified Failure
        • 7 = Cold
      • battery_level - Current charging level in percentage value
      • battery_status - Same values like Kevin Pagano described in his post - I come to the same conclusion with my testing
        • 2 = Charging
        • 3 = Discharging
        • 5 = Fully Charged
    • drain_type - No idea what exactly this is. Value is either -1 or between 1 and 16 in my data.
    • foreground_service_usage_time_in_ms - time in foreground in ms - not sure what "service" means - app have either, only foreground service time or foreground time - I don't see both values for the same app
    • foreground_usage_time_in_ms - time in foreground in ms - like written above - not sure what the difference to foreground service is. 
    • zone_id - the time zone set on the device
    • total_power - Missing in the data above - but existent in some others - I don't know the meaning at the moment - in my data the value is either 30 or missing at all
    • is_hidden - Also missing in the data above - but existent in some others - Also here - I am not sure what the value means - it is either True or missing at all

     I've written a parser for ALEAPP for this database and the data in batteryInformationDebug. The output is similar to the one from Kevin Pagano so it is better comparable. Thanks to him - I used part of his code.


Okay, but, there are also other tables in the database. For me one interesting one is the following:

Table AppUsageEventEntity

  • mId - just an iterating id for this table - no correlation found to the other table
  • uid - the uid of the app
  • userId - the id of the user the app is running for (e.g. 0 for default user)
  • timestamp - Timestamp event was written in epoch - but written in real time, not only every hour like in the other table
  • appUsageEventType - I have two values in my test data and found the following meaning by testing
    • 1 = Paused -> Moved to background
    • 2 = Resumed -> Moved to foreground
  • packageName -  name of the package (e.g. com.android.settings)
  • instanceId -> ID of the instance running - I have no idea how it is generated and what it means
  • taskRootPackageName - Package name of the package that started/called this app


 I tested a bit with opening/closing apps and so on. And I can see exactly what I've done in this table.

We already know similar artifacts showing this on Android - but this one was new for me. Always good to know different ways to show things that happened on a device to correlate and verify the data and finding the truth.

I've written a ALEAPP parser for the data from this database too.


The other tables hold also some data - but I cannot makes sense out of them or see any useful data.


How long does the data stay?

Before I forget - for how long is data in the database?

Well - in my cases: Since the last Android Update. For one device it was about 10 days - I did a recheck few days later and it was about 14 days.

But double check is needed here.


Conclusion

As always - it was fun digging into the data.
More work need for some table/fields/data. And, as far as I found information - Google will bring new features for battery monitoring and battery health monitoring for the users. Perhaps that is what I already found in the database - we'll see.


The data in the batteryInformation field drives me crazy - 
CgYIYRACGAIQABi9sscTIg1FdXJvcGUvQmVybGluOhFHb29nbGUgUGxheSBTdG9yZVEAAAAAAAAA
AFkQG44jJZ9DP2EAAAAAAAAAAGj///////////8BcAB4AIEBAAAAAAAAAACJAQAAAAAAAAAAkQEA
AAAAAAAAAJkBAAAAAAAAAACgAQA=

If any hint from you - feel free to contact me - I am happy to learn new things. I found more fields with similar data in them i the other tables.

I hope you had a fun read. As always - thanks for your time and if any questions or suggestions come up - feel free to contact me.

UPDATE 2024-05-20:

Thanks to Kevin Pagano (stark4n6):

The data in batteryInformation is BLOB -> base64 -> protobuf

After decoding we'll have:

{

    "1": {

        "1": 97,

        "2": 2,

        "3": 2

    },

    "2": 0,

    "3": 41015613,

    "4": "Europe/Berlin",

    "7": "Google Play Store",

    "10": 0,

    "11": 4558662229688196000,

    "12": 0,

    "13": 18446744073709552000,

    "14": 0,

    "15": 0,

    "16": 0,

    "17": 0,

    "18": 0,

    "19": 0,

    "20": 0

}


Looks like similar values as in the field batteryInformationDebug.

Thanks a lot - now I can take a further look also into the other fields. Pretty sure I will come with an update soon :-)

UPDATE 2 FROM 2024-05-20:

So, I did some recoding and analyzing for the column "batteryInformation".

Here you can find the mapping from the keys to the decoded data in the column, for a few I currently don't have a mapping or an idea what the values could mean:


{

    "1": { = device_battery_state

        "1": 97, = battery_level

        "2": 2, = battery_status

        "3": 2 = battery_health

    },

    "2": 0, = is_hidden

    "3": 41015613, = boot_timestamp

    "4": "Europe/Berlin", = timezone

    "7": "Google Play Store", = app_label

    "10": 0,

    "11": 4558662229688196000,

    "12": 0,

    "13": 18446744073709552000, = drain_type

    "14": 0, = foreground_time_in_ms

    "15": 0, = background_time_in_ms

    "16": 0,

    "17": 0,

    "18": 0,

    "19": 0,

    "20": 0 = foreground_server_time_in_ms


I've also updated the parser for ALEAPP. Like I have written above - one of my two test devices didn't gave me data in the batteryInformationDebug, only in batteryInformation. But both devices gave me data in batteryInformation. So I decided to write the parser parsing always the batteryInformation.









No comments:

Post a Comment