Search code examples
regexbashsedgrepactivity-manager

How can I improve this bash command to get UI rendering times from ActivityManager?


I'm working on a sample app based on Fire App Builder and would like to programatically measure how long (in milliseconds) it takes for an Activity to be drawn. This information is included in the ActivityManager logs:

I/ActivityManager( 1843): Displayed com.amazon.android.calypso/com.amazon.android.tv.tenfoot.ui.activities.ContentBrowseActivity: +656ms

Times above one second look like this:

I/ActivityManager( 1843): Displayed com.amazon.android.calypso/com.amazon.android.tv.tenfoot.ui.activities.ContentBrowseActivity: +1s001ms

However, Android is designed such that apps can only read their own logs. As such, Runtime.getRuntime().exec("logcat -d ActivityManager:I *:S") won't show anything. I can read the logs using a shell command, but my regular expression isn't giving me what I want.

The following command

adb logcat -d ActivityManager:I *:S | sed -n 's/ContentBrowseActivity:\s+\+\([0-9].*\)ms/\1/p'

matches, but because sed doesn't support non-greedy expressions, the whole line is printed:

I/ActivityManager( 1843): Displayed com.amazon.android.calypso/com.amazon.android.tv.tenfoot.ui.activities.656

I want to get just the time. Tacking on another grep command gets the data:

adb logcat -d ActivityManager:I *:S | sed -n 's/ContentBrowseActivity:\s+\+\([0-9].*\)ms/\1/p' | grep -Po [0-9]+

For times above one second, I want to simply multiply the first number by 1,000 and add it to the second.

However, this is extremely hacky and also captures the number in I/ActivityManager(####). Another know of a more elegant solution?


Solution

  • $ echo 'I/ActivityManager( 1843): Displayed com.amazon.android.calypso/com.amazon.android.tv.tenfoot.ui.activities.ContentBrowseActivity: +1s001ms' | sed -e 's/^.*: +\(.*\)ms$/\1/' -e 's/s//'
    1001