Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c4c8014 authored by Jernej Virag's avatar Jernej Virag
Browse files

Use table logging for Notification memory use

Using table logger creates a much more readable output in ABT and its
much easier to glance.

Bug: 235451049
Test: manual

Change-Id: Ide23cbc970b27156fb85240dbad12073a0bca299
parent ccac5626
Loading
Loading
Loading
Loading
+110 −63
Original line number Original line Diff line number Diff line
@@ -18,9 +18,12 @@
package com.android.systemui.statusbar.notification.logging
package com.android.systemui.statusbar.notification.logging


import android.stats.sysui.NotificationEnums
import android.stats.sysui.NotificationEnums
import android.util.Log
import com.android.systemui.Dumpable
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import java.io.PrintWriter
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Inject
@@ -33,6 +36,7 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin


    fun init() {
    fun init() {
        dumpManager.registerNormalDumpable(javaClass.simpleName, this)
        dumpManager.registerNormalDumpable(javaClass.simpleName, this)
        Log.i("NotificationMemory", "Registered dumpable.")
    }
    }


    override fun dump(pw: PrintWriter, args: Array<out String>) {
    override fun dump(pw: PrintWriter, args: Array<out String>) {
@@ -45,25 +49,34 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin


    /** Renders a table of notification object usage into passed [PrintWriter]. */
    /** Renders a table of notification object usage into passed [PrintWriter]. */
    private fun dumpNotificationObjects(pw: PrintWriter, memoryUse: List<NotificationMemoryUsage>) {
    private fun dumpNotificationObjects(pw: PrintWriter, memoryUse: List<NotificationMemoryUsage>) {
        pw.println("Notification Object Usage")
        val columns =
        pw.println("-----------")
            listOf(
        pw.println(
                "Package",
            "Package".padEnd(35) +
                "Small Icon",
                "\t\tSmall\tLarge\t${"Style".padEnd(15)}\t\tStyle\tBig\tExtend.\tExtras\tCustom"
                "Large Icon",
                "Style",
                "Style Icon",
                "Big Picture",
                "Extender",
                "Extras",
                "Custom View",
                "Key"
            )
            )
        pw.println("".padEnd(35) + "\t\tIcon\tIcon\t${"".padEnd(15)}\t\tIcon\tPicture\t \t \tView")
        val rows: List<Row> =
        pw.println()
            memoryUse.map {

                listOf(
        memoryUse.forEach { use ->
                    it.packageName,
            pw.println(
                    toKb(it.objectUsage.smallIcon),
                use.packageName.padEnd(35) +
                    toKb(it.objectUsage.largeIcon),
                    "\t\t" +
                    styleEnumToString(it.objectUsage.style),
                    "${use.objectUsage.smallIcon}\t${use.objectUsage.largeIcon}\t" +
                    toKb(it.objectUsage.styleIcon),
                    (styleEnumToString(use.objectUsage.style).take(15) ?: "").padEnd(15) +
                    toKb(it.objectUsage.bigPicture),
                    "\t\t${use.objectUsage.styleIcon}\t" +
                    toKb(it.objectUsage.extender),
                    "${use.objectUsage.bigPicture}\t${use.objectUsage.extender}\t" +
                    toKb(it.objectUsage.extras),
                    "${use.objectUsage.extras}\t${use.objectUsage.hasCustomView}\t" +
                    it.objectUsage.hasCustomView.toString(),
                    use.notificationKey
                    // | is a  field delimiter in the output format so we need to replace
                    // it to avoid breakage.
                    it.notificationKey.replace('|', '│')
                )
                )
            }
            }


@@ -88,18 +101,23 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin
                t
                t
            }
            }


        pw.println()
        val totalsRow: List<Row> =
        pw.println("TOTALS")
            listOf(
        pw.println(
                listOf(
            "".padEnd(35) +
                    "TOTALS",
                "\t\t" +
                    toKb(totals.smallIcon),
                "${toKb(totals.smallIcon)}\t${toKb(totals.largeIcon)}\t" +
                    toKb(totals.largeIcon),
                "".padEnd(15) +
                    "",
                "\t\t${toKb(totals.styleIcon)}\t" +
                    toKb(totals.styleIcon),
                "${toKb(totals.bigPicture)}\t${toKb(totals.extender)}\t" +
                    toKb(totals.bigPicture),
                toKb(totals.extras)
                    toKb(totals.extender),
                    toKb(totals.extras),
                    "",
                    ""
                )
                )
        pw.println()
            )
        val tableLogger = DumpsysTableLogger("Notification Object Usage", columns, rows + totalsRow)
        tableLogger.printTableData(pw)
    }
    }


    /** Renders a table of notification view usage into passed [PrintWriter] */
    /** Renders a table of notification view usage into passed [PrintWriter] */
@@ -116,40 +134,65 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin
            var softwareBitmapsPenalty: Int = 0,
            var softwareBitmapsPenalty: Int = 0,
        )
        )


        val totals = Totals()
        val columns =
        pw.println("Notification View Usage")
            listOf(
        pw.println("-----------")
                "Package",
        pw.println("View Type".padEnd(24) + "\tSmall\tLarge\tStyle\tCustom\tSoftware")
                "View Type",
        pw.println("".padEnd(24) + "\tIcon\tIcon\tUse\tView\tBitmaps")
                "Small Icon",
        pw.println()
                "Large Icon",
                "Style Use",
                "Custom View",
                "Software Bitmaps",
                "Key"
            )
        val rows =
            memoryUse
            memoryUse
                .filter { it.viewUsage.isNotEmpty() }
                .filter { it.viewUsage.isNotEmpty() }
            .forEach { use ->
                .flatMap { use ->
                pw.println(use.packageName + " " + use.notificationKey)
                    use.viewUsage.map { view ->
                use.viewUsage.forEach { view ->
                        listOf(
                    pw.println(
                            use.packageName,
                        "  ${view.viewType.toString().padEnd(24)}\t${view.smallIcon}" +
                            view.viewType.toString(),
                            "\t${view.largeIcon}\t${view.style}" +
                            toKb(view.smallIcon),
                            "\t${view.customViews}\t${view.softwareBitmapsPenalty}"
                            toKb(view.largeIcon),
                            toKb(view.style),
                            toKb(view.customViews),
                            toKb(view.softwareBitmapsPenalty),
                            // | is a  field delimiter in the output format so we need to replace
                            // it to avoid breakage.
                            use.notificationKey.replace('|', '│')
                        )
                        )
                    }
                }


                    if (view.viewType == ViewType.TOTAL) {
        val totals = Totals()
        memoryUse
            .filter { it.viewUsage.isNotEmpty() }
            .map { it.viewUsage.firstOrNull { view -> view.viewType == ViewType.TOTAL } }
            .filterNotNull()
            .forEach { view ->
                totals.smallIcon += view.smallIcon
                totals.smallIcon += view.smallIcon
                totals.largeIcon += view.largeIcon
                totals.largeIcon += view.largeIcon
                totals.style += view.style
                totals.style += view.style
                totals.customViews += view.customViews
                totals.customViews += view.customViews
                totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
                totals.softwareBitmapsPenalty += view.softwareBitmapsPenalty
            }
            }
                }

            }
        val totalsRow: List<Row> =
        pw.println()
            listOf(
        pw.println("TOTALS")
                listOf(
        pw.println(
                    "TOTALS",
            "  ${"".padEnd(24)}\t${toKb(totals.smallIcon)}" +
                    "",
                "\t${toKb(totals.largeIcon)}\t${toKb(totals.style)}" +
                    toKb(totals.smallIcon),
                "\t${toKb(totals.customViews)}\t${toKb(totals.softwareBitmapsPenalty)}"
                    toKb(totals.largeIcon),
                    toKb(totals.style),
                    toKb(totals.customViews),
                    toKb(totals.softwareBitmapsPenalty),
                    ""
                )
                )
        pw.println()
            )
        val tableLogger = DumpsysTableLogger("Notification View Usage", columns, rows + totalsRow)
        tableLogger.printTableData(pw)
    }
    }


    private fun styleEnumToString(styleEnum: Int): String =
    private fun styleEnumToString(styleEnum: Int): String =
@@ -168,6 +211,10 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin
        }
        }


    private fun toKb(bytes: Int): String {
    private fun toKb(bytes: Int): String {
        return (bytes / 1024).toString() + " KB"
        if (bytes == 0) {
            return "--"
        }

        return "%.2f KB".format(bytes / 1024f)
    }
    }
}
}