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

Commit 8b75e12b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

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

parents 89c061d4 bb0278a3
Loading
Loading
Loading
Loading
+82 −1
Original line number Diff line number Diff line
@@ -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();
        }
    }
}
+149 −0
Original line number Diff line number Diff line
@@ -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();
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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;
+3 −3
Original line number Diff line number Diff line
@@ -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;
+0 −50
Original line number Diff line number Diff line
@@ -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();
        }
    }
}