Merge "Added methods to dump a SparseArray on DumpUtils." into udc-dev

This commit is contained in:
Treehugger Robot
2023-04-11 00:02:52 +00:00
committed by Android (Google) Code Review
5 changed files with 236 additions and 56 deletions

View File

@@ -25,6 +25,7 @@ import android.os.Binder;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -312,5 +313,85 @@ public final class DumpUtils {
|| cn.flattenToString().toLowerCase().contains(filterString.toLowerCase());
};
}
}
/**
* Lambda used to dump a key (and its index) while iterating though a collection.
*/
public interface KeyDumper {
/** Dumps the index and key.*/
void dump(int index, int key);
}
/**
* Lambda used to dump a value while iterating though a collection.
*
* @param <T> type of the value.
*/
public interface ValueDumper<T> {
/** Dumps the value.*/
void dump(T value);
}
/**
* Dumps a sparse array.
*/
public static void dumpSparseArray(PrintWriter pw, String prefix, SparseArray<?> array,
String name) {
dumpSparseArray(pw, prefix, array, name, /* keyDumper= */ null, /* valueDumper= */ null);
}
/**
* Dumps the values of a sparse array.
*/
public static <T> void dumpSparseArrayValues(PrintWriter pw, String prefix,
SparseArray<T> array, String name) {
dumpSparseArray(pw, prefix, array, name, (i, k) -> {
pw.printf("%s%s", prefix, prefix);
}, /* valueDumper= */ null);
}
/**
* Dumps a sparse array, customizing each line.
*/
public static <T> void dumpSparseArray(PrintWriter pw, String prefix, SparseArray<T> array,
String name, @Nullable KeyDumper keyDumper, @Nullable ValueDumper<T> valueDumper) {
int size = array.size();
if (size == 0) {
pw.print(prefix);
pw.print("No ");
pw.print(name);
pw.println("s");
return;
}
pw.print(prefix);
pw.print(size);
pw.print(' ');
pw.print(name);
pw.println("(s):");
String prefix2 = prefix + prefix;
for (int i = 0; i < size; i++) {
int key = array.keyAt(i);
T value = array.valueAt(i);
if (keyDumper != null) {
keyDumper.dump(i, key);
} else {
pw.print(prefix2);
pw.print(i);
pw.print(": ");
pw.print(key);
pw.print("->");
}
if (value == null) {
pw.print("(null)");
} else if (valueDumper != null) {
valueDumper.dump(value);
} else {
pw.print(value);
}
pw.println();
}
}
}

View File

@@ -23,16 +23,25 @@ import static com.android.internal.util.DumpUtils.isPlatformCriticalPackage;
import static com.android.internal.util.DumpUtils.isPlatformNonCriticalPackage;
import static com.android.internal.util.DumpUtils.isPlatformPackage;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.ComponentName;
import android.util.SparseArray;
import junit.framework.TestCase;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Run with:
atest FrameworksCoreTests:DumpUtilsTest
*/
public class DumpUtilsTest extends TestCase {
private final StringWriter mStringWriter = new StringWriter();
private final PrintWriter mPrintWriter = new PrintWriter(mStringWriter);
private static ComponentName cn(String componentName) {
if (componentName == null) {
return null;
@@ -168,4 +177,144 @@ public class DumpUtilsTest extends TestCase {
Integer.toHexString(System.identityHashCode(component))).test(
wcn("com.google/.abc")));
}
public void testDumpSparseArray_empty() {
SparseArray<String> array = new SparseArray<>();
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ "...", array, "whatever");
String output = flushPrintWriter();
assertWithMessage("empty array dump").that(output).isEqualTo("...No whatevers\n");
}
public void testDumpSparseArray_oneElement() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "number");
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".1 number(s):\n"
+ "..0: 1->uno\n");
}
public void testDumpSparseArray_oneNullElement() {
SparseArray<String> array = new SparseArray<>();
array.put(1, null);
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "NULL");
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".1 NULL(s):\n"
+ "..0: 1->(null)\n");
}
public void testDumpSparseArray_multipleElements() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
array.put(2, "duo");
array.put(42, null);
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "number");
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".3 number(s):\n"
+ "..0: 1->uno\n"
+ "..1: 2->duo\n"
+ "..2: 42->(null)\n");
}
public void testDumpSparseArray_keyDumperOnly() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
array.put(2, "duo");
array.put(42, null);
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "number",
(i, k) -> {
mPrintWriter.printf("_%d=%d_", i, k);
}, /* valueDumper= */ null);
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".3 number(s):\n"
+ "_0=1_uno\n"
+ "_1=2_duo\n"
+ "_2=42_(null)\n");
}
public void testDumpSparseArray_valueDumperOnly() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
array.put(2, "duo");
array.put(42, null);
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "number",
/* keyDumper= */ null,
s -> {
mPrintWriter.print(s.toUpperCase());
});
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".3 number(s):\n"
+ "..0: 1->UNO\n"
+ "..1: 2->DUO\n"
+ "..2: 42->(null)\n");
}
public void testDumpSparseArray_keyAndValueDumpers() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
array.put(2, "duo");
array.put(42, null);
DumpUtils.dumpSparseArray(mPrintWriter, /* prefix= */ ".", array, "number",
(i, k) -> {
mPrintWriter.printf("_%d=%d_", i, k);
},
s -> {
mPrintWriter.print(s.toUpperCase());
});
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".3 number(s):\n"
+ "_0=1_UNO\n"
+ "_1=2_DUO\n"
+ "_2=42_(null)\n");
}
public void testDumpSparseArrayValues() {
SparseArray<String> array = new SparseArray<>();
array.put(1, "uno");
array.put(2, "duo");
array.put(42, null);
DumpUtils.dumpSparseArrayValues(mPrintWriter, /* prefix= */ ".", array, "number");
String output = flushPrintWriter();
assertWithMessage("dump of %s", array).that(output).isEqualTo(""
+ ".3 numbers:\n"
+ "..uno\n"
+ "..duo\n"
+ "..(null)\n");
}
private String flushPrintWriter() {
mPrintWriter.flush();
return mStringWriter.toString();
}
}

View File

@@ -25,6 +25,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFI
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static com.android.internal.util.DumpUtils.dumpSparseArray;
import static com.android.internal.util.DumpUtils.dumpSparseArrayValues;
import static com.android.server.accessibility.AccessibilityTraceFileProto.ENTRY;
import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER;
import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER_H;
@@ -44,8 +46,6 @@ import static com.android.server.accessibility.AccessibilityTraceProto.WHERE;
import static com.android.server.accessibility.AccessibilityTraceProto.WINDOW_MANAGER_SERVICE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.dumpSparseArray;
import static com.android.server.wm.WindowManagerService.dumpSparseArrayValues;
import static com.android.server.wm.WindowTracing.WINSCOPE_EXT;
import android.accessibilityservice.AccessibilityTrace;

View File

@@ -16,8 +16,9 @@
package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.ValueDumper;
import static com.android.server.wm.WindowManagerService.dumpSparseArray;
import static com.android.internal.util.DumpUtils.KeyDumper;
import static com.android.internal.util.DumpUtils.ValueDumper;
import static com.android.internal.util.DumpUtils.dumpSparseArray;
import static com.android.server.wm.utils.RegionUtils.forEachRect;
import android.annotation.NonNull;
@@ -41,7 +42,6 @@ import android.view.WindowManager;
import android.window.WindowInfosListener;
import com.android.internal.annotations.GuardedBy;
import com.android.server.wm.WindowManagerService.KeyDumper;
import java.io.PrintWriter;
import java.util.ArrayList;

View File

@@ -235,7 +235,6 @@ import android.util.EventLog;
import android.util.MergedConfiguration;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
@@ -9460,53 +9459,4 @@ public class WindowManagerService extends IWindowManager.Stub
return List.copyOf(notifiedApps);
}
}
// TODO(b/271188189): move dump stuff below to common code / add unit tests
interface ValueDumper<T> {
void dump(T value);
}
interface KeyDumper{
void dump(int index, int key);
}
static void dumpSparseArray(PrintWriter pw, String prefix, SparseArray<?> array, String name) {
dumpSparseArray(pw, prefix, array, name, /* keyDumper= */ null, /* valuedumper= */ null);
}
static <T> void dumpSparseArrayValues(PrintWriter pw, String prefix, SparseArray<T> array,
String name) {
dumpSparseArray(pw, prefix, array, name, (i, k) -> {}, /* valueDumper= */ null);
}
static <T> void dumpSparseArray(PrintWriter pw, String prefix, SparseArray<T> array,
String name, @Nullable KeyDumper keyDumper, @Nullable ValueDumper<T> valueDumper) {
int size = array.size();
if (size == 0) {
pw.print(prefix); pw.print("No "); pw.print(name); pw.println("s");
return;
}
pw.print(prefix); pw.print(size); pw.print(' ');
pw.print(name); pw.print(size > 1 ? "s" : ""); pw.println(':');
String prefix2 = prefix + " ";
for (int i = 0; i < size; i++) {
int key = array.keyAt(i);
T value = array.valueAt(i);
if (keyDumper != null) {
keyDumper.dump(i, key);
} else {
pw.print(prefix2); pw.print(i); pw.print(": "); pw.print(key); pw.print("->");
}
if (value == null) {
pw.print("(null)");
} else if (valueDumper != null) {
valueDumper.dump(value);
} else {
pw.print(value);
}
pw.println();
}
}
}