Loading core/java/com/android/internal/util/DumpUtils.java +82 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } } } core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java +149 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } } services/core/java/com/android/server/wm/AccessibilityController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading services/core/java/com/android/server/wm/WindowManagerService.java +0 −50 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } } } Loading
core/java/com/android/internal/util/DumpUtils.java +82 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } } }
core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java +149 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } }
services/core/java/com/android/server/wm/AccessibilityController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +0 −50 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } } }