Prevent frozenBinderTransactionDetected() storm

Although system_server is never frozen, its async binder buffer might
still be exhausted in some extreme conditions. In such a case, this
async call itself would fail, triggering endless loop. Throttle this
callback function to fix it.

Bug: 336171553
Bug: 333508040
Bug: 328423444
Test: frozenBinderTransactionDetected is throttled
Change-Id: Ibe475f7f9699921a1555ab937e5f67ddcf502f58
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bc66127..68cc17b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -353,6 +353,9 @@
 
     private static final String DEFAULT_FULL_BACKUP_AGENT = "android.app.backup.FullBackupAgent";
 
+    private static final long BINDER_CALLBACK_THROTTLE = 10_100L;
+    private long mBinderCallbackLast = -1;
+
     /**
      * Denotes the sequence number of the process state change for which the main thread needs
      * to block until the network rules are updated for it.
@@ -7525,6 +7528,12 @@
         Binder.setTransactionCallback(new IBinderCallback() {
             @Override
             public void onTransactionError(int pid, int code, int flags, int err) {
+                final long now = SystemClock.uptimeMillis();
+                if (now < mBinderCallbackLast + BINDER_CALLBACK_THROTTLE) {
+                    Slog.d(TAG, "Too many transaction errors, throttling freezer binder callback.");
+                    return;
+                }
+                mBinderCallbackLast = now;
                 try {
                     mgr.frozenBinderTransactionDetected(pid, code, flags, err);
                 } catch (RemoteException ex) {