1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.util
18 
19 import android.util.IndentingPrintWriter
20 import android.view.View
21 import com.android.systemui.Dumpable
22 import java.io.PrintWriter
23 
24 /**
25  * Get an [IndentingPrintWriter] which either is or wraps the given [PrintWriter].
26  *
27  * The original [PrintWriter] should not be used until the returned [IndentingPrintWriter] is no
28  * longer being used, to avoid inconsistent writing.
29  */
asIndentingnull30 fun PrintWriter.asIndenting(): IndentingPrintWriter =
31     (this as? IndentingPrintWriter) ?: IndentingPrintWriter(this)
32 
33 /**
34  * Run some code inside a block, with [IndentingPrintWriter.increaseIndent] having been called on
35  * the given argument, and calling [IndentingPrintWriter.decreaseIndent] after completion.
36  */
37 inline fun IndentingPrintWriter.withIncreasedIndent(block: () -> Unit) {
38     this.increaseIndent()
39     try {
40         block()
41     } finally {
42         this.decreaseIndent()
43     }
44 }
45 
46 /**
47  * Run some code inside a block, with [IndentingPrintWriter.increaseIndent] having been called on
48  * the given argument, and calling [IndentingPrintWriter.decreaseIndent] after completion.
49  */
withIncreasedIndentnull50 fun IndentingPrintWriter.withIncreasedIndent(runnable: Runnable) {
51     this.increaseIndent()
52     try {
53         runnable.run()
54     } finally {
55         this.decreaseIndent()
56     }
57 }
58 
59 /** Print a line which is '$label=$value' */
printlnnull60 fun IndentingPrintWriter.println(label: String, value: Any?) =
61     append(label).append('=').println(value)
62 
63 /** Print a section with a header using the given name and an indented body */
64 inline fun IndentingPrintWriter.printSection(sectionName: String, block: () -> Unit) {
65     append(sectionName).println(":")
66     withIncreasedIndent(block)
67 }
68 
69 @JvmOverloads
printCollectionnull70 inline fun <T> IndentingPrintWriter.printCollection(
71     label: String,
72     collection: Collection<T>,
73     printer: IndentingPrintWriter.(T) -> Unit = IndentingPrintWriter::println,
74 ) {
75     append(label).append(": ").println(collection.size)
76     withIncreasedIndent { collection.forEach { printer(it) } }
77 }
78 
dumpCollectionnull79 fun <T : Dumpable> IndentingPrintWriter.dumpCollection(label: String, collection: Collection<T>) {
80     printCollection(label, collection) { it.dump(this, emptyArray()) }
81 }
82 
83 /** Return a readable string for the visibility */
visibilityStringnull84 fun visibilityString(@View.Visibility visibility: Int): String =
85     when (visibility) {
86         View.GONE -> "gone"
87         View.VISIBLE -> "visible"
88         View.INVISIBLE -> "invisible"
89         else -> "unknown:$visibility"
90     }
91