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

Commit a1974bbe authored by Andreas Gampe's avatar Andreas Gampe Committed by android-build-merger
Browse files

Merge changes Idbacb6ad,I4e06b3f9,Iffcbbb82 am: 0f9a09d8

am: e15b2d58

Change-Id: I50b0c5785656ba5561083aec8901267baee99c2a
parents 1d1c867a e15b2d58
Loading
Loading
Loading
Loading
+87 −41
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]);
            }
        }

@@ -296,30 +314,57 @@ public final class BinderProxy implements IBinder {
                new ArrayList[MAIN_INDEX_SIZE];
    }

    private static ProxyMap sProxyMap = new ProxyMap();
    @GuardedBy("sProxyMap")
    private static final 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
     */
    private static void dumpProxyDebugInfo() {
    public static void dumpProxyDebugInfo() {
        if (Build.IS_DEBUGGABLE) {
            synchronized (sProxyMap) {
                sProxyMap.dumpProxyInterfaceCounts();
            // Note that we don't call dumpPerUidProxyCounts(); this is because this
            // method may be called as part of the uid limit being hit, and calling
            // back into the UID tracking code would cause us to try to acquire a mutex
            // that is held during that callback.
                sProxyMap.dumpPerUidProxyCounts();
            }
        }
    }

    /**
     * Return a BinderProxy for IBinder.
     * This method is thread-hostile!  The (native) caller serializes getInstance() calls using
     * gProxyLock.
     * If we previously returned a BinderProxy bp for the same iBinder, and bp is still
     * in use, then we return the same bp.
     *
@@ -331,6 +376,7 @@ public final class BinderProxy implements IBinder {
     */
    private static BinderProxy getInstance(long nativeData, long iBinder) {
        BinderProxy result;
        synchronized (sProxyMap) {
            try {
                result = sProxyMap.get(iBinder);
                if (result != null) {
@@ -346,6 +392,7 @@ public final class BinderProxy implements IBinder {
            NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
            // The registry now owns nativeData, even if registration threw an exception.
            sProxyMap.set(iBinder, result);
        }
        return result;
    }

@@ -526,12 +573,11 @@ public final class BinderProxy implements IBinder {
        }
    }

    private static final void sendDeathNotice(DeathRecipient recipient) {
    private static void sendDeathNotice(DeathRecipient recipient) {
        if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
        try {
            recipient.binderDied();
        }
        catch (RuntimeException exc) {
        } catch (RuntimeException exc) {
            Log.w("BinderNative", "Uncaught exception from death notification",
                    exc);
        }
+0 −15
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ static struct binderproxy_offsets_t
    jclass mClass;
    jmethodID mGetInstance;
    jmethodID mSendDeathNotice;
    jmethodID mDumpProxyDebugInfo;

    // Object state.
    jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
@@ -1038,18 +1037,6 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
static void android_os_BinderInternal_proxyLimitcallback(int uid)
{
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    {
        // Calls into BinderProxy must be serialized
        AutoMutex _l(gProxyLock);
        env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
                                    gBinderProxyOffsets.mDumpProxyDebugInfo);
    }
    if (env->ExceptionCheck()) {
        ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
        report_exception(env, excep.get(),
            "*** Uncaught exception in dumpProxyDebugInfo");
    }

    env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
                              gBinderInternalOffsets.mProxyLimitCallback,
                              uid);
@@ -1439,8 +1426,6 @@ static int int_register_android_os_BinderProxy(JNIEnv* env)
            "(JJ)Landroid/os/BinderProxy;");
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");
    gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo",
            "()V");
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

    clazz = FindClassOrDie(env, "java/lang/Class");
+14 −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;
@@ -15247,6 +15248,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        public void onLimitReached(int uid) {
                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
                                    + Process.myUid());
                            BinderProxy.dumpProxyDebugInfo();
                            if (uid == Process.SYSTEM_UID) {
                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
                            } else {
@@ -16098,8 +16100,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++;
@@ -16602,6 +16606,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);