diff options
8 files changed, 62 insertions, 274 deletions
diff --git a/service/Android.mk b/service/Android.mk index ab005867c..b396214c7 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -48,8 +48,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ android.hardware.wifi.supplicant-V1.2-java \ wifi_service_proto \ ksoap2 \ - libnanohttpd \ - gsf-client + libnanohttpd LOCAL_REQUIRED_MODULES := \ services \ diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 292e902bc..a18760c17 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -959,8 +959,6 @@ public class ClientModeImpl extends StateMachine { mWifiMetrics.getHandler()); mWifiMonitor.registerHandler(mInterfaceName, CMD_TARGET_BSSID, mWifiMetrics.getHandler()); - mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.NETWORK_CONNECTION_EVENT, - mWifiInjector.getWifiLastResortWatchdog().getHandler()); } private void setMulticastFilter(boolean enabled) { @@ -4294,7 +4292,6 @@ public class ClientModeImpl extends StateMachine { } if (mWifiNative.connectToNetwork(mInterfaceName, config)) { - mWifiInjector.getWifiLastResortWatchdog().noteStartConnectTime(); mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT, config); mLastConnectAttemptTimestamp = mClock.getWallClockMillis(); mTargetWifiConfiguration = config; diff --git a/service/java/com/android/server/wifi/GservicesFacade.java b/service/java/com/android/server/wifi/GservicesFacade.java deleted file mode 100644 index a629a584d..000000000 --- a/service/java/com/android/server/wifi/GservicesFacade.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.wifi; - -import android.content.Context; - -import com.google.android.gsf.Gservices; - -import java.util.concurrent.TimeUnit; - -/** - * This class allows getting all configurable flags from Gservices. - */ -public class GservicesFacade { - private static final int DEFAULT_ABNORMAL_CONNECTION_DURATION_MS = - (int) TimeUnit.SECONDS.toMillis(30); - private static final String G_PREFIX = "android.wifi."; - private Context mContext; - - public GservicesFacade(Context context) { - mContext = context; - } - - /** - * Gets the feature flag for reporting abnormally long connections. - */ - public boolean isAbnormalConnectionBugreportEnabled() { - return Gservices.getBoolean(mContext.getContentResolver(), - G_PREFIX + "abnormal_connection_bugreport_enabled", false); - } - - /** - * Gets the threshold for classifying abnormally long connections. - */ - public int getAbnormalConnectionDurationMs() { - return Gservices.getInt(mContext.getContentResolver(), - G_PREFIX + "abnormal_connection_duration_ms", - DEFAULT_ABNORMAL_CONNECTION_DURATION_MS); - } -} diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java index 69c787f48..ee96fb269 100644 --- a/service/java/com/android/server/wifi/HostapdHal.java +++ b/service/java/com/android/server/wifi/HostapdHal.java @@ -39,6 +39,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.NoSuchElementException; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.annotation.concurrent.ThreadSafe; @@ -51,6 +54,8 @@ public class HostapdHal { private static final String TAG = "HostapdHal"; @VisibleForTesting public static final String HAL_INSTANCE_NAME = "default"; + @VisibleForTesting + public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L; private final Object mLock = new Object(); private boolean mVerboseLoggingEnabled = false; @@ -230,11 +235,11 @@ public class HostapdHal { * Link to death for IHostapd object. * @return true on success, false otherwise. */ - private boolean linkToHostapdDeath() { + private boolean linkToHostapdDeath(HwRemoteBinder.DeathRecipient deathRecipient, long cookie) { synchronized (mLock) { if (mIHostapd == null) return false; try { - if (!mIHostapd.linkToDeath(mHostapdDeathRecipient, ++mDeathRecipientCookie)) { + if (!mIHostapd.linkToDeath(deathRecipient, cookie)) { Log.wtf(TAG, "Error on linkToDeath on IHostapd"); hostapdServiceDiedHandler(mDeathRecipientCookie); return false; @@ -282,7 +287,7 @@ public class HostapdHal { Log.e(TAG, "Got null IHostapd service. Stopping hostapd HIDL startup"); return false; } - if (!linkToHostapdDeath()) { + if (!linkToHostapdDeath(mHostapdDeathRecipient, ++mDeathRecipientCookie)) { mIHostapd = null; return false; } @@ -486,10 +491,19 @@ public class HostapdHal { } /** - * Terminate the hostapd daemon. + * Terminate the hostapd daemon & wait for it's death. */ public void terminate() { synchronized (mLock) { + // Register for a new death listener to block until hostapd is dead. + final long waitForDeathCookie = new Random().nextLong(); + final CountDownLatch waitForDeathLatch = new CountDownLatch(1); + linkToHostapdDeath((cookie) -> { + Log.d(TAG, "IHostapd died: cookie=" + cookie); + if (cookie != waitForDeathCookie) return; + waitForDeathLatch.countDown(); + }, waitForDeathCookie); + final String methodStr = "terminate"; if (!checkHostapdAndLogFailure(methodStr)) return; try { @@ -497,6 +511,15 @@ public class HostapdHal { } catch (RemoteException e) { handleRemoteException(e, methodStr); } + + // Now wait for death listener callback to confirm that it's dead. + try { + if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + Log.w(TAG, "Timed out waiting for confirmation of hostapd death"); + } + } catch (InterruptedException e) { + Log.w(TAG, "Failed to wait for hostapd death"); + } } } diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java index bed66d926..86518c761 100644 --- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java +++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java @@ -86,6 +86,9 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -108,6 +111,8 @@ public class SupplicantStaIfaceHal { public static final String INIT_STOP_PROPERTY = "ctl.stop"; @VisibleForTesting public static final String INIT_SERVICE_NAME = "wpa_supplicant"; + @VisibleForTesting + public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L; /** * Regex pattern for extracting the wps device type bytes. * Matches a strings like the following: "<categ>-<OUI>-<subcateg>"; @@ -262,11 +267,12 @@ public class SupplicantStaIfaceHal { } } - private boolean linkToSupplicantDeath() { + private boolean linkToSupplicantDeath( + HwRemoteBinder.DeathRecipient deathRecipient, long cookie) { synchronized (mLock) { if (mISupplicant == null) return false; try { - if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) { + if (!mISupplicant.linkToDeath(deathRecipient, cookie)) { Log.wtf(TAG, "Error on linkToDeath on ISupplicant"); supplicantServiceDiedHandler(mDeathRecipientCookie); return false; @@ -294,7 +300,7 @@ public class SupplicantStaIfaceHal { Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup"); return false; } - if (!linkToSupplicantDeath()) { + if (!linkToSupplicantDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) { return false; } } @@ -645,10 +651,19 @@ public class SupplicantStaIfaceHal { } /** - * Terminate the supplicant daemon. + * Terminate the supplicant daemon & wait for it's death. */ public void terminate() { synchronized (mLock) { + // Register for a new death listener to block until supplicant is dead. + final long waitForDeathCookie = new Random().nextLong(); + final CountDownLatch waitForDeathLatch = new CountDownLatch(1); + linkToSupplicantDeath((cookie) -> { + Log.d(TAG, "ISupplicant died: cookie=" + cookie); + if (cookie != waitForDeathCookie) return; + waitForDeathLatch.countDown(); + }, waitForDeathCookie); + if (isV1_1()) { Log.i(TAG, "Terminating supplicant using HIDL"); terminate_V1_1(); @@ -656,6 +671,15 @@ public class SupplicantStaIfaceHal { Log.i(TAG, "Terminating supplicant using init"); mPropertyService.set(INIT_STOP_PROPERTY, INIT_SERVICE_NAME); } + + // Now wait for death listener callback to confirm that it's dead. + try { + if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + Log.w(TAG, "Timed out waiting for confirmation of supplicant death"); + } + } catch (InterruptedException e) { + Log.w(TAG, "Failed to wait for supplicant death"); + } } } diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index a449ef332..f33c7cf93 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -82,7 +82,6 @@ public class WifiInjector { private final Context mContext; private final FrameworkFacade mFrameworkFacade = new FrameworkFacade(); - private final GservicesFacade mGservicesFacade; private final HandlerThread mWifiServiceHandlerThread; private final HandlerThread mWifiCoreHandlerThread; private final HandlerThread mWifiP2pServiceHandlerThread; @@ -169,7 +168,6 @@ public class WifiInjector { sWifiInjector = this; mContext = context; - mGservicesFacade = new GservicesFacade(mContext); mWifiScoreCard = new WifiScoreCard(mClock, Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID)); mSettingsStore = new WifiSettingsStore(mContext); @@ -607,9 +605,8 @@ public class WifiInjector { mWifiCoreHandlerThread.getLooper(), mFrameworkFacade, mClock, mWifiMetrics, mWifiConfigManager, mWifiConfigStore, clientModeImpl, new ConnectToNetworkNotificationBuilder(mContext, mFrameworkFacade)); - mWifiLastResortWatchdog = new WifiLastResortWatchdog(this, mContext, mClock, - mWifiMetrics, clientModeImpl, clientModeImpl.getHandler().getLooper(), - mGservicesFacade); + mWifiLastResortWatchdog = new WifiLastResortWatchdog(this, mClock, + mWifiMetrics, clientModeImpl, clientModeImpl.getHandler().getLooper()); return new WifiConnectivityManager(mContext, getScoringParams(), clientModeImpl, this, mWifiConfigManager, clientModeImpl.getWifiInfo(), diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java index 868a3e9a5..6889b5016 100644 --- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java +++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java @@ -16,15 +16,10 @@ package com.android.server.wifi; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; @@ -32,8 +27,6 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; -import com.google.android.gsf.Gservices; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.HashMap; @@ -82,10 +75,6 @@ public class WifiLastResortWatchdog { @VisibleForTesting public static final long LAST_TRIGGER_TIMEOUT_MILLIS = 2 * 3600 * 1000; // 2 hours - private int mAbnormalConnectionDurationMs; - private boolean mAbnormalConnectionBugreportEnabled; - - /** * Cached WifiConfigurations of available networks seen within MAX_BSSID_AGE scan results * Key:BSSID, Value:Counters of failure types @@ -113,98 +102,22 @@ public class WifiLastResortWatchdog { private Looper mClientModeImplLooper; private double mBugReportProbability = PROB_TAKE_BUGREPORT_DEFAULT; private Clock mClock; - private Context mContext; - private GservicesFacade mGservicesFacade; // If any connection failure happened after watchdog triggering restart then assume watchdog // did not fix the problem private boolean mWatchdogFixedWifi = true; - private long mLastStartConnectTime = 0; - private Handler mHandler; /** * Local log used for debugging any WifiLastResortWatchdog issues. */ private final LocalLog mLocalLog = new LocalLog(100); - WifiLastResortWatchdog(WifiInjector wifiInjector, Context context, Clock clock, - WifiMetrics wifiMetrics, ClientModeImpl clientModeImpl, Looper clientModeImplLooper, - GservicesFacade gservicesFacade) { + WifiLastResortWatchdog(WifiInjector wifiInjector, Clock clock, WifiMetrics wifiMetrics, + ClientModeImpl clientModeImpl, Looper clientModeImplLooper) { mWifiInjector = wifiInjector; mClock = clock; mWifiMetrics = wifiMetrics; mClientModeImpl = clientModeImpl; mClientModeImplLooper = clientModeImplLooper; - mContext = context; - mGservicesFacade = gservicesFacade; - updateGServicesFlags(); - mHandler = new Handler(clientModeImplLooper) { - public void handleMessage(Message msg) { - processMessage(msg); - } - }; - // Registers a broadcast receiver to change update G service flags - mContext.registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - mHandler.post(() -> { - updateGServicesFlags(); - }); - } - }, - new IntentFilter(Gservices.CHANGED_ACTION)); - } - - private void updateGServicesFlags() { - mAbnormalConnectionBugreportEnabled = - mGservicesFacade.isAbnormalConnectionBugreportEnabled(); - mAbnormalConnectionDurationMs = - mGservicesFacade.getAbnormalConnectionDurationMs(); - logv("updateGServicesFlags: mAbnormalConnectionDurationMs = " - + mAbnormalConnectionDurationMs - + ", mAbnormalConnectionBugreportEnabled = " - + mAbnormalConnectionBugreportEnabled); - } - - /** - * Returns handler for L2 events from supplicant. - * @return Handler - */ - public Handler getHandler() { - return mHandler; - } - - /** - * Refreshes when the last CMD_START_CONNECT is triggered. - */ - public void noteStartConnectTime() { - mLastStartConnectTime = mClock.getElapsedSinceBootMillis(); - } - - private void processMessage(Message msg) { - switch (msg.what) { - case WifiMonitor.NETWORK_CONNECTION_EVENT: - // Trigger bugreport for successful connections that take abnormally long - if (mAbnormalConnectionBugreportEnabled && mLastStartConnectTime > 0) { - long durationMs = mClock.getElapsedSinceBootMillis() - mLastStartConnectTime; - if (durationMs > mAbnormalConnectionDurationMs) { - final String bugTitle = "Wi-Fi Bugreport: Abnormal connection time"; - final String bugDetail = "Expected connection to take less than " - + mAbnormalConnectionDurationMs + " milliseconds. " - + "Actually took " + durationMs + " milliseconds."; - logv("Triggering bug report for abnormal connection time."); - mWifiInjector.getClientModeImplHandler().post(() -> { - mClientModeImpl.takeBugReport(bugTitle, bugDetail); - }); - } - } - // Should reset last connection time after each connection regardless if bugreport - // is enabled or not. - mLastStartConnectTime = 0; - break; - default: - return; - } } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java index 1117339c6..9ae382640 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java @@ -21,24 +21,16 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.*; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.IntentFilter; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiSsid; -import android.os.Handler; import android.os.test.TestLooper; import android.util.Pair; import androidx.test.filters.SmallTest; -import com.google.android.gsf.Gservices; - import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; import org.mockito.Mock; import java.util.ArrayList; @@ -50,8 +42,6 @@ import java.util.List; */ @SmallTest public class WifiLastResortWatchdogTest { - final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = - ArgumentCaptor.forClass(BroadcastReceiver.class); WifiLastResortWatchdog mLastResortWatchdog; @Mock WifiInjector mWifiInjector; @Mock WifiMetrics mWifiMetrics; @@ -59,8 +49,6 @@ public class WifiLastResortWatchdogTest { @Mock ClientModeImpl mClientModeImpl; @Mock Clock mClock; @Mock WifiInfo mWifiInfo; - @Mock Context mContext; - @Mock GservicesFacade mGservicesFacade; private String[] mSsids = {"\"test1\"", "\"test2\"", "\"test3\"", "\"test4\""}; private String[] mBssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "de:ad:ba:b1:e5:55", @@ -73,22 +61,17 @@ public class WifiLastResortWatchdogTest { private boolean[] mHasEverConnected = {false, false, false, false}; private TestLooper mLooper; private static final String TEST_NETWORK_SSID = "\"test_ssid\""; - private static final int DEFAULT_ABNORMAL_CONNECTION_DURATION_MS = 30000; @Before public void setUp() throws Exception { initMocks(this); mLooper = new TestLooper(); when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); - when(mGservicesFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(true); - when(mGservicesFacade.getAbnormalConnectionDurationMs()).thenReturn( - DEFAULT_ABNORMAL_CONNECTION_DURATION_MS); - mLastResortWatchdog = new WifiLastResortWatchdog(mWifiInjector, mContext, mClock, - mWifiMetrics, mClientModeImpl, mLooper.getLooper(), mGservicesFacade); + mLastResortWatchdog = new WifiLastResortWatchdog(mWifiInjector, mClock, mWifiMetrics, + mClientModeImpl, mLooper.getLooper()); mLastResortWatchdog.setBugReportProbability(1); when(mClientModeImpl.getWifiInfo()).thenReturn(mWifiInfo); when(mWifiInfo.getSSID()).thenReturn(TEST_NETWORK_SSID); - when(mWifiInjector.getClientModeImplHandler()).thenReturn(mLastResortWatchdog.getHandler()); } private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids, @@ -2169,98 +2152,4 @@ public class WifiLastResortWatchdogTest { verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogSuccesses(); } - /** - * Verifies that when a connection takes too long (time difference between - * StaEvent.TYPE_CMD_START_CONNECT and StaEvent.TYPE_NETWORK_CONNECTION_EVENT) a bugreport is - * taken. - */ - @Test - public void testAbnormalConnectionTimeTriggersBugreport() throws Exception { - // first verifies that bugreports are not taken when connection takes less than - // DEFAULT_ABNORMAL_CONNECTION_DURATION_MS - when(mClock.getElapsedSinceBootMillis()).thenReturn(1L); - mLastResortWatchdog.noteStartConnectTime(); - when(mClock.getElapsedSinceBootMillis()).thenReturn( - (long) DEFAULT_ABNORMAL_CONNECTION_DURATION_MS); - Handler handler = mLastResortWatchdog.getHandler(); - handler.sendMessage( - handler.obtainMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null)); - mLooper.dispatchAll(); - verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString()); - - // Now verify that bugreport is taken - mLastResortWatchdog.noteStartConnectTime(); - when(mClock.getElapsedSinceBootMillis()).thenReturn( - 2L * DEFAULT_ABNORMAL_CONNECTION_DURATION_MS + 1); - handler.sendMessage( - handler.obtainMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null)); - mLooper.dispatchAll(); - verify(mClientModeImpl).takeBugReport(anyString(), anyString()); - - // Verify additional connections (without more TYPE_CMD_START_CONNECT) don't trigger more - // bugreports. - when(mClock.getElapsedSinceBootMillis()).thenReturn( - 4L * DEFAULT_ABNORMAL_CONNECTION_DURATION_MS); - handler.sendMessage( - handler.obtainMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null)); - mLooper.dispatchAll(); - verify(mClientModeImpl).takeBugReport(anyString(), anyString()); - } - - /** - * Changes |mAbnormalConnectionDurationMs| to a new value, and then verify that a bugreport is - * taken for a connection that takes longer than the new threshold. - * @throws Exception - */ - @Test - public void testGServicesSetDuration() throws Exception { - final int testDurationMs = 10 * 1000; // 10 seconds - // changes the abnormal connection duration to |testDurationMs|. - when(mGservicesFacade.getAbnormalConnectionDurationMs()).thenReturn(testDurationMs); - verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), - (IntentFilter) argThat(new IntentFilterMatcher())); - mBroadcastReceiverCaptor.getValue().onReceive(mContext, null); - - // verifies that bugreport is taken for connections that take longer than |testDurationMs|. - when(mClock.getElapsedSinceBootMillis()).thenReturn(1L); - mLastResortWatchdog.noteStartConnectTime(); - when(mClock.getElapsedSinceBootMillis()).thenReturn((long) testDurationMs + 2); - Handler handler = mLastResortWatchdog.getHandler(); - handler.sendMessage( - handler.obtainMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null)); - mLooper.dispatchAll(); - verify(mClientModeImpl).takeBugReport(anyString(), anyString()); - } - - /** - * Verifies that bugreports are not triggered even when conditions are met after the - * |mAbnormalConnectionBugreportEnabled| flag is changed to false. - * @throws Exception - */ - @Test - public void testGServicesFlagDisable() throws Exception { - // changes |mAbnormalConnectionBugreportEnabled| to false. - when(mGservicesFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(false); - verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), - (IntentFilter) argThat(new IntentFilterMatcher())); - mBroadcastReceiverCaptor.getValue().onReceive(mContext, null); - - // verifies that bugreports are not taken. - when(mClock.getElapsedSinceBootMillis()).thenReturn(1L); - mLastResortWatchdog.noteStartConnectTime(); - when(mClock.getElapsedSinceBootMillis()).thenReturn( - (long) DEFAULT_ABNORMAL_CONNECTION_DURATION_MS + 2); - Handler handler = mLastResortWatchdog.getHandler(); - handler.sendMessage( - handler.obtainMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, null)); - mLooper.dispatchAll(); - verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString()); - } - - private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> { - @Override - public boolean matches(IntentFilter filter) { - return filter.hasAction(Gservices.CHANGED_ACTION); - } - } } |