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

Commit 345d4c16 authored by Martijn Coenen's avatar Martijn Coenen Committed by Andreas Gampe
Browse files

Dump top binder proxy interface names in dumpsys.

To facilitate real-time debugging.

Bug: 109888955
Test: builds, adb shell dumpsys activity binder-proxies shows output
Merged-In: Iffcbbb824f4050b6fb8f556c8b4d09115e53da18
Change-Id: Iffcbbb824f4050b6fb8f556c8b4d09115e53da18
parent d659ad62
Loading
Loading
Loading
Loading
+63 −16
Original line number Diff line number Diff line
@@ -225,10 +225,11 @@ public final class BinderProxy implements IBinder {
            }
        }

        /**
         * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps.
         */
        private void dumpProxyInterfaceCounts() {
        private InterfaceCount[] getSortedInterfaceCounts(int maxToReturn) {
            if (maxToReturn < 0) {
                throw new IllegalArgumentException("negative interface count");
            }

            Map<String, Integer> counts = new HashMap<>();
            for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
                if (a != null) {
@@ -258,13 +259,30 @@ public final class BinderProxy implements IBinder {
            }
            Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray(
                    new Map.Entry[counts.size()]);

            Arrays.sort(sorted, (Map.Entry<String, Integer> a, Map.Entry<String, Integer> b)
                    -> b.getValue().compareTo(a.getValue()));
            Log.v(Binder.TAG, "BinderProxy descriptor histogram (top ten):");
            int printLength = Math.min(10, sorted.length);
            for (int i = 0; i < printLength; i++) {
                Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i].getKey() + " x"
                        + sorted[i].getValue());

            int returnCount = Math.min(maxToReturn, sorted.length);
            InterfaceCount[] ifaceCounts = new InterfaceCount[returnCount];
            for (int i = 0; i < returnCount; i++) {
                ifaceCounts[i] = new InterfaceCount(sorted[i].getKey(), sorted[i].getValue());
            }
            return ifaceCounts;
        }

        static final int MAX_NUM_INTERFACES_TO_DUMP = 10;

        /**
         * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps.
         */
        private void dumpProxyInterfaceCounts() {
            final InterfaceCount[] sorted = getSortedInterfaceCounts(MAX_NUM_INTERFACES_TO_DUMP);

            Log.v(Binder.TAG, "BinderProxy descriptor histogram "
                    + "(top " + Integer.toString(MAX_NUM_INTERFACES_TO_DUMP) + "):");
            for (int i = 0; i < sorted.length; i++) {
                Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i]);
            }
        }

@@ -299,10 +317,39 @@ public final class BinderProxy implements IBinder {
    private static ProxyMap sProxyMap = new ProxyMap();

    /**
      * Dump proxy debug information.
     * Simple pair-value class to store number of binder proxy interfaces live in this process.
     */
    public static final class InterfaceCount {
        private final String mInterfaceName;
        private final int mCount;

        InterfaceCount(String interfaceName, int count) {
            mInterfaceName = interfaceName;
            mCount = count;
        }

        @Override
        public String toString() {
            return mInterfaceName + " x" + Integer.toString(mCount);
        }
    }

    /**
     * Get a sorted array with entries mapping proxy interface names to the number
     * of live proxies with those names.
     *
      * Note: this method is not thread-safe; callers must serialize with other
      * accesses to sProxyMap, in particular {@link #getInstance(long, long)}.
     * @param num maximum number of proxy interface counts to return. Use
     *            Integer.MAX_VALUE to retrieve all
     * @hide
     */
    public static InterfaceCount[] getSortedInterfaceCounts(int num) {
        synchronized (sProxyMap) {
            return sProxyMap.getSortedInterfaceCounts(num);
        }
    }

    /**
     * Dump proxy debug information.
     *
     * @hide
     */
+13 −1
Original line number Diff line number Diff line
@@ -318,6 +318,7 @@ import android.net.ProxyInfo;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.BinderProxy;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
@@ -16061,8 +16062,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
            } else if ("binder-proxies".equals(cmd)) {
                if (opti >= args.length) {
                    dumpBinderProxyInterfaceCounts(pw,
                            "Top proxy interface names held by SYSTEM");
                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
                            "Counts of Binder Proxies held by SYSTEM");
                            "Number of proxies per uid held by SYSTEM");
                } else {
                    String uid = args[opti];
                    opti++;
@@ -16565,6 +16568,15 @@ public class ActivityManagerService extends IActivityManager.Stub
        return printed;
    }
    void dumpBinderProxyInterfaceCounts(PrintWriter pw, String header) {
        final BinderProxy.InterfaceCount[] proxyCounts = BinderProxy.getSortedInterfaceCounts(50);
        pw.println(header);
        for (int i = 0; i < proxyCounts.length; i++) {
            pw.println("    #" + (i + 1) + ": " + proxyCounts[i]);
        }
    }
    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
        if(counts != null) {
            pw.println(header);