diff options
3 files changed, 38 insertions, 8 deletions
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java index 457b68773..03334584b 100644 --- a/service/java/com/android/server/wifi/ActiveModeWarden.java +++ b/service/java/com/android/server/wifi/ActiveModeWarden.java @@ -79,6 +79,7 @@ public class ActiveModeWarden { private boolean mCanRequestMoreClientModeManagers = false; private boolean mCanRequestMoreSoftApManagers = false; + private boolean mIsShuttingdown = false; /** * Called from WifiServiceImpl to register a callback for notifications from SoftApManager @@ -122,7 +123,7 @@ public class ActiveModeWarden { mWifiController = new WifiController(); wifiNative.registerStatusListener(isReady -> { - if (!isReady) { + if (!isReady && !mIsShuttingdown) { mHandler.post(() -> { Log.e(TAG, "One of the native daemons died. Triggering recovery"); wifiDiagnostics.captureBugReportData( @@ -149,6 +150,15 @@ public class ActiveModeWarden { } /** + * Notify that device is shutting down + * Keep it simple and don't add collection access codes + * to avoid concurrentModificationException when it is directly called from a different thread + */ + public void notifyShuttingDown() { + mIsShuttingdown = true; + } + + /** * @return Returns whether we can create more client mode managers or not. */ public boolean canRequestMoreClientModeManagers() { diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 436cb94f3..73fb306f9 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -571,11 +571,17 @@ public class WifiServiceImpl extends BaseWifiService { } private void handleShutDown() { - // There is no explicit disconnection event in clientModeImpl during shutdown. - // Call resetConnectionState() so that connection duration is calculated correctly - // before memory store write triggered by mMemoryStoreImpl.stop(). - mWifiScoreCard.resetConnectionState(); - mMemoryStoreImpl.stop(); + // Direct call to notify ActiveModeWarden as soon as possible with the assumption that + // notifyShuttingDown() doesn't have codes that may cause concurrentModificationException, + // e.g., access to a collection. + mActiveModeWarden.notifyShuttingDown(); + mWifiThreadRunner.post(()-> { + // There is no explicit disconnection event in clientModeImpl during shutdown. + // Call resetConnectionState() so that connection duration is calculated + // before memory store write triggered by mMemoryStoreImpl.stop(). + mWifiScoreCard.resetConnectionState(); + mMemoryStoreImpl.stop(); + }); } private boolean checkNetworkSettingsPermission(int pid, int uid) { diff --git a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java index 701ffb345..db7b4e22f 100644 --- a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java @@ -821,10 +821,11 @@ public class ActiveModeWardenTest extends WifiBaseTest { } /** - * Trigger recovery and a bug report if we see a native failure. + * Trigger recovery and a bug report if we see a native failure + * while the device is not shutting down */ @Test - public void handleWifiNativeFailure() throws Exception { + public void handleWifiNativeFailureDeviceNotShuttingDown() throws Exception { mWifiNativeStatusListener.onStatusChanged(false); mLooper.dispatchAll(); verify(mWifiDiagnostics).captureBugReportData( @@ -833,6 +834,19 @@ public class ActiveModeWardenTest extends WifiBaseTest { } /** + * Verify the device shutting down doesn't trigger recovery or bug report. + */ + @Test + public void handleWifiNativeFailureDeviceShuttingDown() throws Exception { + mActiveModeWarden.notifyShuttingDown(); + mWifiNativeStatusListener.onStatusChanged(false); + mLooper.dispatchAll(); + verify(mWifiDiagnostics, never()).captureBugReportData( + WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE); + verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE)); + } + + /** * Verify an onStatusChanged callback with "true" does not trigger recovery. */ @Test |