summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff DeCew <jeffdq@google.com> 2023-07-27 17:19:01 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-07-27 17:19:01 +0000
commitc8af8c5cb7a77982ba9ad591891f9d37ece7cc01 (patch)
tree71f01e45aea7fffc1d4b7457fdb2b1e1a8271006
parent336af62f84dd718bf80b9b2660230bdd40207daf (diff)
parent1f89e284a4a6e0d835bfa2263331cae5f0471dbc (diff)
Print when the sysui dump actually starts. am: 1f89e284a4
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24178708 Change-Id: Ib31480204795a6b6b6ca90a1c9674a922d5d74ea Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt131
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt20
3 files changed, 139 insertions, 85 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
index 75284fc18149..ae40f7e8d7c0 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
@@ -16,12 +16,10 @@
package com.android.systemui.dump
-import android.content.Context
+import android.icu.text.SimpleDateFormat
import android.os.SystemClock
import android.os.Trace
-import com.android.systemui.CoreStartable
import com.android.systemui.ProtoDumpable
-import com.android.systemui.R
import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_CRITICAL
import com.android.systemui.dump.DumpHandler.Companion.PRIORITY_ARG_NORMAL
import com.android.systemui.dump.DumpsysEntry.DumpableEntry
@@ -35,8 +33,9 @@ import java.io.BufferedOutputStream
import java.io.FileDescriptor
import java.io.FileOutputStream
import java.io.PrintWriter
+import java.util.Locale
import javax.inject.Inject
-import javax.inject.Provider
+import kotlin.system.measureTimeMillis
/**
* Oversees SystemUI's output during bug reports (and dumpsys in general)
@@ -77,6 +76,7 @@ import javax.inject.Provider
* $ <invocation> dumpables
* $ <invocation> buffers
* $ <invocation> tables
+ * $ <invocation> all
*
* # Finally, the following will simulate what we dump during the CRITICAL and NORMAL sections of a
* # bug report:
@@ -91,10 +91,9 @@ import javax.inject.Provider
class DumpHandler
@Inject
constructor(
- private val context: Context,
private val dumpManager: DumpManager,
private val logBufferEulogizer: LogBufferEulogizer,
- private val startables: MutableMap<Class<*>, Provider<CoreStartable>>,
+ private val config: SystemUIConfigDumpable,
) {
/** Dump the diagnostics! Behavior can be controlled via [args]. */
fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
@@ -109,6 +108,8 @@ constructor(
return
}
+ pw.print("Dump starting: ")
+ pw.println(DATE_FORMAT.format(System.currentTimeMillis()))
when {
parsedArgs.dumpPriority == PRIORITY_ARG_CRITICAL -> dumpCritical(pw, parsedArgs)
parsedArgs.dumpPriority == PRIORITY_ARG_NORMAL && !parsedArgs.proto -> {
@@ -129,6 +130,11 @@ constructor(
"dumpables" -> dumpDumpables(pw, args)
"buffers" -> dumpBuffers(pw, args)
"tables" -> dumpTables(pw, args)
+ "all" -> {
+ dumpDumpables(pw, args)
+ dumpBuffers(pw, args)
+ dumpTables(pw, args)
+ }
"config" -> dumpConfig(pw)
"help" -> dumpHelp(pw)
else -> {
@@ -148,7 +154,6 @@ constructor(
dumpDumpable(target, pw, args.rawArgs)
}
}
- dumpConfig(pw)
}
private fun dumpNormal(pw: PrintWriter, args: ParsedArgs) {
@@ -251,53 +256,8 @@ constructor(
.sortedBy { it.name }
.minByOrNull { it.name.length }
- private fun dumpDumpable(entry: DumpableEntry, pw: PrintWriter, args: Array<String>) {
- pw.preamble(entry)
- entry.dumpable.dump(pw, args)
- }
-
- private fun dumpBuffer(entry: LogBufferEntry, pw: PrintWriter, tailLength: Int) {
- pw.preamble(entry)
- entry.buffer.dump(pw, tailLength)
- }
-
- private fun dumpTableBuffer(buffer: TableLogBufferEntry, pw: PrintWriter, args: Array<String>) {
- pw.preamble(buffer)
- buffer.table.dump(pw, args)
- }
-
private fun dumpConfig(pw: PrintWriter) {
- pw.println("SystemUiServiceComponents configuration:")
- pw.print("vendor component: ")
- pw.println(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
- val services: MutableList<String> =
- startables.keys.map({ cls: Class<*> -> cls.simpleName }).toMutableList()
-
- services.add(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
- dumpServiceList(pw, "global", services.toTypedArray())
- dumpServiceList(pw, "per-user", R.array.config_systemUIServiceComponentsPerUser)
- }
-
- private fun dumpServiceList(pw: PrintWriter, type: String, resId: Int) {
- val services: Array<String> = context.resources.getStringArray(resId)
- dumpServiceList(pw, type, services)
- }
-
- private fun dumpServiceList(pw: PrintWriter, type: String, services: Array<String>?) {
- pw.print(type)
- pw.print(": ")
- if (services == null) {
- pw.println("N/A")
- return
- }
- pw.print(services.size)
- pw.println(" services")
- for (i in services.indices) {
- pw.print(" ")
- pw.print(i)
- pw.print(": ")
- pw.println(services[i])
- }
+ config.dump(pw, arrayOf())
}
private fun dumpHelp(pw: PrintWriter) {
@@ -426,13 +386,6 @@ constructor(
const val DUMPSYS_DUMPABLE_DIVIDER =
"----------------------------------------------------------------------------"
- /**
- * Important: do not change this divider without updating any bug report processing tools
- * (e.g. ABT), since this divider is used to determine boundaries for bug report views
- */
- const val DUMPSYS_BUFFER_DIVIDER =
- "============================================================================"
-
private fun findBestTargetMatch(c: Collection<DumpsysEntry>, target: String) =
c.asSequence().filter { it.name.endsWith(target) }.minByOrNull { it.name.length }
@@ -453,42 +406,71 @@ constructor(
is DumpableEntry,
is TableLogBufferEntry -> {
println()
- println(entry.name)
+ println("${entry.name}:")
println(DUMPSYS_DUMPABLE_DIVIDER)
}
is LogBufferEntry -> {
println()
println()
println("BUFFER ${entry.name}:")
- println(DUMPSYS_BUFFER_DIVIDER)
+ println(DUMPSYS_DUMPABLE_DIVIDER)
}
}
+ private fun PrintWriter.footer(entry: DumpsysEntry, dumpTimeMillis: Long) {
+ if (entry !is DumpableEntry) return
+ println()
+ print(entry.priority)
+ print(" dump took ")
+ print(dumpTimeMillis)
+ print("ms -- ")
+ print(entry.name)
+ if (entry.priority == DumpPriority.CRITICAL && dumpTimeMillis > 25) {
+ print(" -- warning: individual dump time exceeds 5% of total CRITICAL dump time!")
+ }
+ println()
+ }
+
+ private inline fun PrintWriter.wrapSection(entry: DumpsysEntry, block: () -> Unit) {
+ preamble(entry)
+ val dumpTime = measureTimeMillis(block)
+ footer(entry, dumpTime)
+ }
+
/**
- * Zero-arg utility to write a [DumpableEntry] to the given [PrintWriter] in a
+ * Utility to write a [DumpableEntry] to the given [PrintWriter] in a
* dumpsys-appropriate format.
*/
- private fun dumpDumpable(entry: DumpableEntry, pw: PrintWriter) {
- pw.preamble(entry)
- entry.dumpable.dump(pw, arrayOf())
+ private fun dumpDumpable(
+ entry: DumpableEntry,
+ pw: PrintWriter,
+ args: Array<String> = arrayOf(),
+ ) = pw.wrapSection(entry) {
+ entry.dumpable.dump(pw, args)
}
/**
- * Zero-arg utility to write a [LogBufferEntry] to the given [PrintWriter] in a
+ * Utility to write a [LogBufferEntry] to the given [PrintWriter] in a
* dumpsys-appropriate format.
*/
- private fun dumpBuffer(entry: LogBufferEntry, pw: PrintWriter) {
- pw.preamble(entry)
- entry.buffer.dump(pw, 0)
+ private fun dumpBuffer(
+ entry: LogBufferEntry,
+ pw: PrintWriter,
+ tailLength: Int = 0,
+ ) = pw.wrapSection(entry) {
+ entry.buffer.dump(pw, tailLength)
}
/**
- * Zero-arg utility to write a [TableLogBufferEntry] to the given [PrintWriter] in a
+ * Utility to write a [TableLogBufferEntry] to the given [PrintWriter] in a
* dumpsys-appropriate format.
*/
- private fun dumpTableBuffer(entry: TableLogBufferEntry, pw: PrintWriter) {
- pw.preamble(entry)
- entry.table.dump(pw, arrayOf())
+ private fun dumpTableBuffer(
+ entry: TableLogBufferEntry,
+ pw: PrintWriter,
+ args: Array<String> = arrayOf(),
+ ) = pw.wrapSection(entry) {
+ entry.table.dump(pw, args)
}
/**
@@ -510,6 +492,7 @@ constructor(
}
}
+private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
private val PRIORITY_OPTIONS = arrayOf(PRIORITY_ARG_CRITICAL, PRIORITY_ARG_NORMAL)
private val COMMANDS =
diff --git a/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt
new file mode 100644
index 000000000000..b70edcc27254
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dump
+
+import android.content.Context
+import com.android.systemui.CoreStartable
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Provider
+
+@SysUISingleton
+class SystemUIConfigDumpable
+@Inject
+constructor(
+ dumpManager: DumpManager,
+ private val context: Context,
+ private val startables: MutableMap<Class<*>, Provider<CoreStartable>>,
+) : Dumpable {
+ init {
+ dumpManager.registerCriticalDumpable("SystemUiServiceComponents", this)
+ }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>) {
+ pw.println("SystemUiServiceComponents configuration:")
+ pw.print("vendor component: ")
+ pw.println(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
+ val services: MutableList<String> =
+ startables.keys.map { cls: Class<*> -> cls.simpleName }.toMutableList()
+
+ services.add(context.resources.getString(R.string.config_systemUIVendorServiceComponent))
+ dumpServiceList(pw, "global", services.toTypedArray())
+ dumpServiceList(pw, "per-user", R.array.config_systemUIServiceComponentsPerUser)
+ }
+
+ private fun dumpServiceList(pw: PrintWriter, type: String, resId: Int) {
+ val services: Array<String> = context.resources.getStringArray(resId)
+ dumpServiceList(pw, type, services)
+ }
+
+ private fun dumpServiceList(pw: PrintWriter, type: String, services: Array<String>?) {
+ pw.print(type)
+ pw.print(": ")
+ if (services == null) {
+ pw.println("N/A")
+ return
+ }
+ pw.print(services.size)
+ pw.println(" services")
+ for (i in services.indices) {
+ pw.print(" ")
+ pw.print(i)
+ pw.print(": ")
+ pw.println(services[i])
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
index 2830476874ed..840eb468b8c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
@@ -26,10 +26,6 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.google.common.truth.Truth.assertThat
-import java.io.FileDescriptor
-import java.io.PrintWriter
-import java.io.StringWriter
-import javax.inject.Provider
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@@ -37,6 +33,10 @@ import org.mockito.Mockito.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.io.StringWriter
+import javax.inject.Provider
@SmallTest
class DumpHandlerTest : SysuiTestCase() {
@@ -79,14 +79,12 @@ class DumpHandlerTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
- dumpHandler = DumpHandler(
- mContext,
- dumpManager,
- logBufferEulogizer,
- mutableMapOf(
- EmptyCoreStartable::class.java to Provider { EmptyCoreStartable() }
- ),
+ val config = SystemUIConfigDumpable(
+ dumpManager,
+ mContext,
+ mutableMapOf(EmptyCoreStartable::class.java to Provider { EmptyCoreStartable() }),
)
+ dumpHandler = DumpHandler(dumpManager, logBufferEulogizer, config)
}
@Test