Merge "Repeat proxy limit callbacks if we keep going above the limit."
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 55566e2..1100d72 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -36,7 +36,8 @@
 // ---------------------------------------------------------------------------
 
 Mutex BpBinder::sTrackingLock;
-std::unordered_map<int32_t,uint32_t> BpBinder::sTrackingMap;
+std::unordered_map<int32_t, uint32_t> BpBinder::sTrackingMap;
+std::unordered_map<int32_t, uint32_t> BpBinder::sLastLimitCallbackMap;
 int BpBinder::sNumTrackedUids = 0;
 std::atomic_bool BpBinder::sCountByUidEnabled(false);
 binder_proxy_limit_callback BpBinder::sLimitCallback;
@@ -47,6 +48,10 @@
 // Another arbitrary value a binder count needs to drop below before another callback will be called
 uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
 
+// Once the limit has been exceeded, keep calling the limit callback for every this many new proxies
+// created over the limit.
+constexpr uint32_t REPEAT_LIMIT_CALLBACK_INTERVAL = 1000;
+
 enum {
     LIMIT_REACHED_MASK = 0x80000000,        // A flag denoting that the limit has been reached
     COUNTING_VALUE_MASK = 0x7FFFFFFF,       // A mask of the remaining bits for the count value
@@ -120,12 +125,24 @@
             if (sBinderProxyThrottleCreate) {
                 return nullptr;
             }
+            trackedValue = trackedValue & COUNTING_VALUE_MASK;
+            uint32_t lastLimitCallbackAt = sLastLimitCallbackMap[trackedUid];
+
+            if (trackedValue > lastLimitCallbackAt &&
+                (trackedValue - lastLimitCallbackAt > REPEAT_LIMIT_CALLBACK_INTERVAL)) {
+                ALOGE("Still too many binder proxy objects sent to uid %d from uid %d (%d proxies "
+                      "held)",
+                      getuid(), trackedUid, trackedValue);
+                if (sLimitCallback) sLimitCallback(trackedUid);
+                sLastLimitCallbackMap[trackedUid] = trackedValue;
+            }
         } else {
             if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
                 ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
                       getuid(), trackedUid, trackedValue);
                 sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
                 if (sLimitCallback) sLimitCallback(trackedUid);
+                sLastLimitCallbackMap[trackedUid] = trackedValue & COUNTING_VALUE_MASK;
                 if (sBinderProxyThrottleCreate) {
                     ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
                           " count drops below %d",
@@ -465,8 +482,9 @@
                 ((trackedValue & COUNTING_VALUE_MASK) <= sBinderProxyCountLowWatermark)
                 )) {
                 ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
-                                   getuid(), mTrackedUid, sBinderProxyCountLowWatermark);
+                      getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
                 sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
+                sLastLimitCallbackMap.erase(mTrackedUid);
             }
             if (--sTrackingMap[mTrackedUid] == 0) {
                 sTrackingMap.erase(mTrackedUid);
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index a6d35c7..b58cb7e 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -194,6 +194,7 @@
     static uint32_t                             sBinderProxyCountHighWatermark;
     static uint32_t                             sBinderProxyCountLowWatermark;
     static bool                                 sBinderProxyThrottleCreate;
+    static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
 };
 
 } // namespace android