Skip waiting for idle if the message queue is already idle

Bug: 142514365
Change-Id: I22eb94c234766a40eac4c8dcc33d204b2417c2d6
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index 0a4f005..a00a6bd 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -300,8 +300,8 @@
 
     public LooperIdleLock newIdleLock(Object lock) {
         LooperIdleLock idleLock = new LooperIdleLock(lock, Looper.getMainLooper());
-        // If we are not binding, there is no reason to wait for idle.
-        if (mCallbacks.get() == null) {
+        // If we are not binding or if the main looper is already idle, there is no reason to wait
+        if (mCallbacks.get() == null || Looper.getMainLooper().getQueue().isIdle()) {
             idleLock.queueIdle();
         }
         return idleLock;
diff --git a/src/com/android/launcher3/util/LooperIdleLock.java b/src/com/android/launcher3/util/LooperIdleLock.java
index 2896535..f4ccf42 100644
--- a/src/com/android/launcher3/util/LooperIdleLock.java
+++ b/src/com/android/launcher3/util/LooperIdleLock.java
@@ -22,29 +22,30 @@
 /**
  * Utility class to block execution until the UI looper is idle.
  */
-public class LooperIdleLock implements MessageQueue.IdleHandler, Runnable {
+public class LooperIdleLock implements MessageQueue.IdleHandler {
 
     private final Object mLock;
 
     private boolean mIsLocked;
+    private Looper mLooper;
 
     public LooperIdleLock(Object lock, Looper looper) {
         mLock = lock;
+        mLooper = looper;
         mIsLocked = true;
         looper.getQueue().addIdleHandler(this);
     }
 
     @Override
-    public void run() {
-        Looper.myQueue().addIdleHandler(this);
-    }
-
-    @Override
     public boolean queueIdle() {
         synchronized (mLock) {
             mIsLocked = false;
             mLock.notify();
         }
+        // Manually remove from the list in case we're calling this outside of the idle callbacks
+        // (this is Ok in the normal flow as well because MessageQueue makes a copy of all handlers
+        // before calling back)
+        mLooper.getQueue().removeIdleHandler(this);
         return false;
     }