Merge "Replace limited connectivity notification after detecting it"
diff --git a/core/java/android/net/util/DnsUtils.java b/core/java/android/net/util/DnsUtils.java
index e6abd50..7908353 100644
--- a/core/java/android/net/util/DnsUtils.java
+++ b/core/java/android/net/util/DnsUtils.java
@@ -141,14 +141,17 @@
      */
     public static @NonNull List<InetAddress> rfc6724Sort(@Nullable Network network,
             @NonNull List<InetAddress> answers) {
-        List<SortableAddress> sortableAnswerList = new ArrayList<>();
-        answers.forEach(addr -> sortableAnswerList.add(
-                new SortableAddress(addr, findSrcAddress(network, addr))));
+        final ArrayList<SortableAddress> sortableAnswerList = new ArrayList<>();
+        for (InetAddress addr : answers) {
+            sortableAnswerList.add(new SortableAddress(addr, findSrcAddress(network, addr)));
+        }
 
         Collections.sort(sortableAnswerList, sRfc6724Comparator);
 
         final List<InetAddress> sortedAnswers = new ArrayList<>();
-        sortableAnswerList.forEach(ans -> sortedAnswers.add(ans.address));
+        for (SortableAddress ans : sortableAnswerList) {
+            sortedAnswers.add(ans.address);
+        }
 
         return sortedAnswers;
     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4b2d481..cdab8c6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -169,6 +169,7 @@
 import com.android.internal.util.WakeupMessage;
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.BatteryStatsService;
+import com.android.server.connectivity.AutodestructReference;
 import com.android.server.connectivity.DataConnectionStats;
 import com.android.server.connectivity.DnsManager;
 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
@@ -2761,29 +2762,31 @@
     }
 
     private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
-        private final NetworkAgentInfo mNai;
+        private final int mNetId;
+        private final AutodestructReference<NetworkAgentInfo> mNai;
 
         private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
-            mNai = nai;
+            mNetId = nai.network.netId;
+            mNai = new AutodestructReference(nai);
         }
 
         @Override
         public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
             mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
-                    new Pair<>(mNai, networkMonitor)));
+                    new Pair<>(mNai.getAndDestroy(), networkMonitor)));
         }
 
         @Override
         public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(EVENT_NETWORK_TESTED,
-                    testResult, mNai.network.netId, redirectUrl));
+                    testResult, mNetId, redirectUrl));
         }
 
         @Override
         public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
                     EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
-                    0, mNai.network.netId, PrivateDnsConfig.fromParcel(config)));
+                    0, mNetId, PrivateDnsConfig.fromParcel(config)));
         }
 
         @Override
@@ -2801,15 +2804,13 @@
             }
             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
-                    mNai.network.netId,
-                    pendingIntent));
+                    mNetId, pendingIntent));
         }
 
         @Override
         public void hideProvisioningNotification() {
             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
-                    EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE,
-                    mNai.network.netId));
+                    EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
         }
 
         @Override
diff --git a/services/core/java/com/android/server/connectivity/AutodestructReference.java b/services/core/java/com/android/server/connectivity/AutodestructReference.java
new file mode 100644
index 0000000..009a43e
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/AutodestructReference.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import android.annotation.NonNull;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A ref that autodestructs at the first usage of it.
+ * @param <T> The type of the held object
+ * @hide
+ */
+public class AutodestructReference<T> {
+    private final AtomicReference<T> mHeld;
+    public AutodestructReference(@NonNull T obj) {
+        if (null == obj) throw new NullPointerException("Autodestruct reference to null");
+        mHeld = new AtomicReference<>(obj);
+    }
+
+    /** Get the ref and destruct it. NPE if already destructed. */
+    @NonNull
+    public T getAndDestroy() {
+        final T obj = mHeld.getAndSet(null);
+        if (null == obj) throw new NullPointerException("Already autodestructed");
+        return obj;
+    }
+}
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 306cc51..eb25acf 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -10,6 +10,7 @@
         "framework-protos",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
+        "net-tests-utils",
         "platform-test-annotations",
         "services.core",
         "services.net",
diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/tests/net/java/android/net/nsd/NsdManagerTest.java
index 2d2bccb..cf7587a 100644
--- a/tests/net/java/android/net/nsd/NsdManagerTest.java
+++ b/tests/net/java/android/net/nsd/NsdManagerTest.java
@@ -16,8 +16,6 @@
 
 package android.net.nsd;
 
-import static com.android.internal.util.TestUtils.waitForIdleHandler;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -40,6 +38,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.AsyncChannel;
+import com.android.testutils.HandlerUtilsKt;
 
 import org.junit.After;
 import org.junit.Before;
@@ -74,7 +73,7 @@
 
     @After
     public void tearDown() throws Exception {
-        mServiceHandler.waitForIdle(mTimeoutMs);
+        HandlerUtilsKt.waitForIdle(mServiceHandler, mTimeoutMs);
         mServiceHandler.chan.disconnect();
         mServiceHandler.stop();
         if (mManager != null) {
@@ -334,7 +333,7 @@
     }
 
     int verifyRequest(int expectedMessageType) {
-        mServiceHandler.waitForIdle(mTimeoutMs);
+        HandlerUtilsKt.waitForIdle(mServiceHandler, mTimeoutMs);
         verify(mServiceHandler, timeout(mTimeoutMs)).handleMessage(any());
         reset(mServiceHandler);
         Message received = mServiceHandler.getLastMessage();
@@ -366,10 +365,6 @@
             lastMessage.copyFrom(msg);
         }
 
-        void waitForIdle(long timeoutMs) {
-            waitForIdleHandler(this, timeoutMs);
-        }
-
         @Override
         public void handleMessage(Message msg) {
             setLastMessage(msg);
diff --git a/tests/net/java/android/net/util/DnsUtilsTest.java b/tests/net/java/android/net/util/DnsUtilsTest.java
index 42e340b..b626db8 100644
--- a/tests/net/java/android/net/util/DnsUtilsTest.java
+++ b/tests/net/java/android/net/util/DnsUtilsTest.java
@@ -57,24 +57,38 @@
     @Test
     public void testRfc6724Comparator() {
         final List<DnsUtils.SortableAddress> test = Arrays.asList(
-                makeSortableAddress("216.58.200.36"),             // Ipv4
-                makeSortableAddress("2404:6800:4008:801::2004"),  // global
-                makeSortableAddress("::1"),                       // loop back
-                makeSortableAddress("fe80::c46f:1cff:fe04:39b4"), // link local
-                makeSortableAddress("::ffff:192.168.95.3"),       // IPv4-mapped IPv6
-                makeSortableAddress("2001::47c1"),                // teredo tunneling
-                makeSortableAddress("::216.58.200.36"),           // IPv4-compatible
-                makeSortableAddress("3ffe::1234:5678"));          // 6bone
+                // Ipv4
+                makeSortableAddress("216.58.200.36", "192.168.1.1"),
+                // global with different scope src
+                makeSortableAddress("2404:6800:4008:801::2004", "fe80::1111:2222"),
+                // global without src addr
+                makeSortableAddress("2404:6800:cafe:801::1"),
+                // loop back
+                makeSortableAddress("::1", "::1"),
+                // link local
+                makeSortableAddress("fe80::c46f:1cff:fe04:39b4", "fe80::1"),
+                // teredo tunneling
+                makeSortableAddress("2001::47c1", "2001::2"),
+                // 6bone without src addr
+                makeSortableAddress("3ffe::1234:5678"),
+                // IPv4-compatible
+                makeSortableAddress("::216.58.200.36", "::216.58.200.9"),
+                // 6bone
+                makeSortableAddress("3ffe::1234:5678", "3ffe::1234:1"),
+                // IPv4-mapped IPv6
+                makeSortableAddress("::ffff:192.168.95.7", "::ffff:192.168.95.1"));
 
         final List<InetAddress> expected = Arrays.asList(
                 stringToAddress("::1"),                       // loop back
                 stringToAddress("fe80::c46f:1cff:fe04:39b4"), // link local
-                stringToAddress("2404:6800:4008:801::2004"),  // global
                 stringToAddress("216.58.200.36"),             // Ipv4
-                stringToAddress("::ffff:192.168.95.3"),       // IPv4-mapped IPv6
+                stringToAddress("::ffff:192.168.95.7"),       // IPv4-mapped IPv6
                 stringToAddress("2001::47c1"),                // teredo tunneling
-                stringToAddress("::216.58.200.36"),            // IPv4-compatible
-                stringToAddress("3ffe::1234:5678"));          // 6bone
+                stringToAddress("::216.58.200.36"),           // IPv4-compatible
+                stringToAddress("3ffe::1234:5678"),           // 6bone
+                stringToAddress("2404:6800:4008:801::2004"),  // global with different scope src
+                stringToAddress("2404:6800:cafe:801::1"),     // global without src addr
+                stringToAddress("3ffe::1234:5678"));          // 6bone without src addr
 
         Collections.sort(test, new DnsUtils.Rfc6724Comparator());
 
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index cb774ba..1a8d905 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -68,10 +68,6 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
-import static com.android.internal.util.TestUtils.waitForIdleHandler;
-import static com.android.internal.util.TestUtils.waitForIdleLooper;
-import static com.android.internal.util.TestUtils.waitForIdleSerialExecutor;
-
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -196,6 +192,7 @@
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.testutils.HandlerUtilsKt;
 
 import org.junit.After;
 import org.junit.Before;
@@ -375,19 +372,19 @@
 
     public void waitForIdle(int timeoutMsAsInt) {
         long timeoutMs = timeoutMsAsInt;
-        waitForIdleHandler(mService.mHandlerThread, timeoutMs);
+        HandlerUtilsKt.waitForIdle(mService.mHandlerThread, timeoutMs);
         waitForIdle(mCellNetworkAgent, timeoutMs);
         waitForIdle(mWiFiNetworkAgent, timeoutMs);
         waitForIdle(mEthernetNetworkAgent, timeoutMs);
-        waitForIdleHandler(mService.mHandlerThread, timeoutMs);
-        waitForIdleLooper(ConnectivityThread.getInstanceLooper(), timeoutMs);
+        HandlerUtilsKt.waitForIdle(mService.mHandlerThread, timeoutMs);
+        HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), timeoutMs);
     }
 
     public void waitForIdle(MockNetworkAgent agent, long timeoutMs) {
         if (agent == null) {
             return;
         }
-        waitForIdleHandler(agent.mHandlerThread, timeoutMs);
+        HandlerUtilsKt.waitForIdle(agent.mHandlerThread, timeoutMs);
     }
 
     private void waitForIdle() {
@@ -1220,7 +1217,7 @@
         }
 
         public void waitForIdle(int timeoutMs) {
-            waitForIdleHandler(mHandlerThread, timeoutMs);
+            HandlerUtilsKt.waitForIdle(mHandlerThread, timeoutMs);
         }
 
         public void waitForIdle() {
@@ -4107,7 +4104,7 @@
         }
 
         public void assertNoCallback() {
-            waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
+            HandlerUtilsKt.waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
             CallbackValue cv = mCallbacks.peek();
             assertNull("Unexpected callback: " + cv, cv);
         }
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 2cae250..ce50bef 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -727,94 +727,4 @@
                 "::/1", "8000::/2", "c000::/3", "e000::/4", "f000::/5", "f800::/6",
                 "fe00::/8", "2605:ef80:e:af1d::/64");
     }
-
-    @Test
-    public void testProvidesRoutesToMostDestinations() {
-        final LinkProperties lp = new LinkProperties();
-
-        // Default route provides routes to all IPv4 destinations.
-        lp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0")));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        // Empty LP provides routes to no destination
-        lp.clear();
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-
-        // All IPv4 routes except for local networks. This is the case most relevant
-        // to this function. It provides routes to almost the entire space.
-        // (clone the stream so that we can reuse it later)
-        publicIpV4Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s))));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        // Removing a 16-bit prefix, which is 65536 addresses. This is still enough to
-        // provide routes to "most" destinations.
-        lp.removeRoute(new RouteInfo(new IpPrefix("192.169.0.0/16")));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        // Remove the /2 route, which represent a quarter of the available routing space.
-        // This LP does not provides routes to "most" destinations any more.
-        lp.removeRoute(new RouteInfo(new IpPrefix("64.0.0.0/2")));
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-
-        lp.clear();
-        publicIpV6Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s))));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        lp.removeRoute(new RouteInfo(new IpPrefix("::/1")));
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-
-        // V6 does not provide sufficient coverage but v4 does
-        publicIpV4Routes().forEach(s -> lp.addRoute(new RouteInfo(new IpPrefix(s))));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        // V4 still does
-        lp.removeRoute(new RouteInfo(new IpPrefix("192.169.0.0/16")));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        // V4 does not any more
-        lp.removeRoute(new RouteInfo(new IpPrefix("64.0.0.0/2")));
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-
-        // V4 does not, but V6 has sufficient coverage again
-        lp.addRoute(new RouteInfo(new IpPrefix("::/1")));
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-
-        lp.clear();
-        // V4-unreachable route should not be treated as sufficient coverage
-        lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-
-        lp.clear();
-        // V6-unreachable route should not be treated as sufficient coverage
-        lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
-        assertFalse(Vpn.providesRoutesToMostDestinations(lp));
-    }
-
-    @Test
-    public void testDoesNotLockUpWithTooManyRoutes() {
-        final LinkProperties lp = new LinkProperties();
-        final byte[] ad = new byte[4];
-        // Actually evaluating this many routes under 1500ms is impossible on
-        // current hardware and for some time, as the algorithm is O(n²).
-        // Make sure the system has a safeguard against this and does not
-        // lock up.
-        final int MAX_ROUTES = 4000;
-        final long MAX_ALLOWED_TIME_MS = 1500;
-        for (int i = 0; i < MAX_ROUTES; ++i) {
-            ad[0] = (byte)((i >> 24) & 0xFF);
-            ad[1] = (byte)((i >> 16) & 0xFF);
-            ad[2] = (byte)((i >> 8) & 0xFF);
-            ad[3] = (byte)(i & 0xFF);
-            try {
-                lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.getByAddress(ad), 32)));
-            } catch (UnknownHostException e) {
-                // UnknownHostException is only thrown for an address of illegal length,
-                // which can't happen in the case above.
-            }
-        }
-        final long start = SystemClock.currentThreadTimeMillis();
-        assertTrue(Vpn.providesRoutesToMostDestinations(lp));
-        final long end = SystemClock.currentThreadTimeMillis();
-        assertTrue(end - start < MAX_ALLOWED_TIME_MS);
-    }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
index 6e725dd..858358c 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
@@ -161,7 +161,7 @@
     }
 
     private void setHasCarrierPrivileges(boolean hasPrivileges) {
-        when(mTm.checkCarrierPrivilegesForPackage(TEST_PKG)).thenReturn(
+        when(mTm.checkCarrierPrivilegesForPackageAnyPhone(TEST_PKG)).thenReturn(
                 hasPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
                         : TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
     }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index 43a3803..9a47f35 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -28,8 +28,6 @@
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
-import static com.android.internal.util.TestUtils.waitForIdleHandler;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -56,6 +54,7 @@
 
 import com.android.internal.net.VpnInfo;
 import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
+import com.android.testutils.HandlerUtilsKt;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -457,7 +456,7 @@
     }
 
     private void waitForObserverToIdle() {
-        waitForIdleHandler(mObserverHandlerThread, WAIT_TIMEOUT_MS);
-        waitForIdleHandler(mHandler, WAIT_TIMEOUT_MS);
+        HandlerUtilsKt.waitForIdle(mObserverHandlerThread, WAIT_TIMEOUT_MS);
+        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT_MS);
     }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index e35c34a..07b5ba4 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -52,7 +52,6 @@
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 
-import static com.android.internal.util.TestUtils.waitForIdleHandler;
 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
 
 import static org.junit.Assert.assertEquals;
@@ -105,6 +104,7 @@
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
+import com.android.testutils.HandlerUtilsKt;
 
 import libcore.io.IoUtils;
 
@@ -1321,8 +1321,6 @@
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
-
-
         // Register and verify request and that binder was called
         DataUsageRequest request =
                 mService.registerUsageCallback(mServiceContext.getOpPackageName(), inputRequest,
@@ -1334,14 +1332,11 @@
 
         // Send dummy message to make sure that any previous message has been handled
         mHandler.sendMessage(mHandler.obtainMessage(-1));
-        waitForIdleHandler(mHandler, WAIT_TIMEOUT);
-
-
+        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
 
         // Make sure that the caller binder gets connected
         verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
 
-
         // modify some number on wifi, and trigger poll event
         // not enough traffic to call data usage callback
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -1674,7 +1669,7 @@
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
         // Send dummy message to make sure that any previous message has been handled
         mHandler.sendMessage(mHandler.obtainMessage(-1));
-        waitForIdleHandler(mHandler, WAIT_TIMEOUT);
+        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
     }
 
     static class LatchedHandler extends Handler {