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

Commit 18a23f2f authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Log excessive remote callbacks

Bug: 36778087
Test: N/A
Change-Id: Ifb02fe09e3c0869f7f6c741f886421064e5c1b8a
parent c01dd791
Loading
Loading
Loading
Loading
+28 −1
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.os;
package android.os;


import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.Slog;


import java.util.function.Consumer;
import java.util.function.Consumer;


@@ -49,11 +50,14 @@ import java.util.function.Consumer;
 * implements the {@link #onCallbackDied} method.
 * implements the {@link #onCallbackDied} method.
 */
 */
public class RemoteCallbackList<E extends IInterface> {
public class RemoteCallbackList<E extends IInterface> {
    private static final String TAG = "RemoteCallbackList";

    /*package*/ ArrayMap<IBinder, Callback> mCallbacks
    /*package*/ ArrayMap<IBinder, Callback> mCallbacks
            = new ArrayMap<IBinder, Callback>();
            = new ArrayMap<IBinder, Callback>();
    private Object[] mActiveBroadcast;
    private Object[] mActiveBroadcast;
    private int mBroadcastCount = -1;
    private int mBroadcastCount = -1;
    private boolean mKilled = false;
    private boolean mKilled = false;
    private StringBuilder mRecentCallers;


    private final class Callback implements IBinder.DeathRecipient {
    private final class Callback implements IBinder.DeathRecipient {
        final E mCallback;
        final E mCallback;
@@ -111,6 +115,8 @@ public class RemoteCallbackList<E extends IInterface> {
            if (mKilled) {
            if (mKilled) {
                return false;
                return false;
            }
            }
            // Flag unusual case that could be caused by a leak. b/36778087
            logExcessiveCallbacks();
            IBinder binder = callback.asBinder();
            IBinder binder = callback.asBinder();
            try {
            try {
                Callback cb = new Callback(callback, cookie);
                Callback cb = new Callback(callback, cookie);
@@ -392,4 +398,25 @@ public class RemoteCallbackList<E extends IInterface> {
            return mCallbacks.valueAt(index).mCookie;
            return mCallbacks.valueAt(index).mCookie;
        }
        }
    }
    }

    private void logExcessiveCallbacks() {
        final long size = mCallbacks.size();
        final long TOO_MANY = 3000;
        final long MAX_CHARS = 1000;
        if (size >= TOO_MANY) {
            if (size == TOO_MANY && mRecentCallers == null) {
                mRecentCallers = new StringBuilder();
            }
            if (mRecentCallers != null && mRecentCallers.length() < MAX_CHARS) {
                mRecentCallers.append(Debug.getCallers(5));
                mRecentCallers.append('\n');
                if (mRecentCallers.length() >= MAX_CHARS) {
                    Slog.wtf(TAG, "More than "
                            + TOO_MANY + " remote callbacks registered. Recent callers:\n"
                            + mRecentCallers.toString());
                    mRecentCallers = null;
                }
            }
        }
    }
}
}