summaryrefslogtreecommitdiffstats
path: root/tests/wifitests/src/com/android/server
diff options
context:
space:
mode:
authorxshu <xshu@google.com>2019-11-12 16:04:50 -0800
committerxshu <xshu@google.com>2019-12-10 12:02:54 -0800
commit491c22553879a8d56d761c218177dec6afa80aa9 (patch)
tree7fd89e447f0618ebd9e8ae1d34e14724d5f8d964 /tests/wifitests/src/com/android/server
parent45448ffb610477fc7ac2406c33276f461288bb91 (diff)
downloadandroid_frameworks_opt_net_wifi-491c22553879a8d56d761c218177dec6afa80aa9.tar.gz
android_frameworks_opt_net_wifi-491c22553879a8d56d761c218177dec6afa80aa9.tar.bz2
android_frameworks_opt_net_wifi-491c22553879a8d56d761c218177dec6afa80aa9.zip
Notification to set MAC randomization setting
Launches a notification, which when tapped will show a dialog that explains to the user why the connection is potentially failing and provides an option to fix the problem by disabling MAC randomization. Bug: 144172117 Test: atest FrameworksWifiTests Test: manaully verified on a device: notification is trigger at the right time, and the dialogue is successfully disabling MAC randomization. Test: verified on device that the fallback path works as expected if the user removes the network before tapping on the notification. Change-Id: Id02c56a96b7cba49880b29518d29f79c76db982c Merged-In: Id02c56a96b7cba49880b29518d29f79c76db982c (cherry picked from 3f656193a2c6d6ae6b6ba81d1450c813ad1cbbb0)
Diffstat (limited to 'tests/wifitests/src/com/android/server')
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java42
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ConnectionFailureNotifierTest.java184
2 files changed, 225 insertions, 1 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 9eb88b637..afb3ef5f4 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -384,7 +384,7 @@ public class ClientModeImplTest {
@Mock AsyncChannel mNullAsyncChannel;
@Mock CarrierNetworkConfig mCarrierNetworkConfig;
@Mock Handler mNetworkAgentHandler;
-
+ @Mock ConnectionFailureNotifier mConnectionFailureNotifier;
final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -441,6 +441,8 @@ public class ClientModeImplTest {
when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard);
when(mWifiInjector.getWifiLockManager()).thenReturn(mWifiLockManager);
when(mWifiInjector.getCarrierNetworkConfig()).thenReturn(mCarrierNetworkConfig);
+ when(mWifiInjector.makeConnectionFailureNotifier(any()))
+ .thenReturn(mConnectionFailureNotifier);
when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any()))
.thenReturn(Pair.create(Process.INVALID_UID, ""));
when(mWifiNative.initialize()).thenReturn(true);
@@ -2816,6 +2818,44 @@ public class ClientModeImplTest {
}
/**
+ * Verifies that a notification is posted when a connection failure happens on a network
+ * in the hotlist. Then verify that tapping on the notification launches an dialog, which
+ * could be used to set the randomization setting for a network to "Trusted".
+ */
+ @Test
+ public void testConnectionFailureSendRandomizationSettingsNotification() throws Exception {
+ when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true);
+ // Setup CONNECT_MODE & a WifiConfiguration
+ initializeAndAddNetworkAndVerifySuccess();
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, sBSSID);
+ mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT,
+ WifiManager.ERROR_AUTH_FAILURE_TIMEOUT);
+ mLooper.dispatchAll();
+
+ WifiConfiguration config = mCmi.getCurrentWifiConfiguration();
+ verify(mConnectionFailureNotifier)
+ .showFailedToConnectDueToNoRandomizedMacSupportNotification(FRAMEWORK_NETWORK_ID);
+ }
+
+ /**
+ * Verifies that a notification is not posted when a wrong password failure happens on a
+ * network in the hotlist.
+ */
+ @Test
+ public void testNotCallingIsInFlakyRandomizationSsidHotlistOnWrongPassword() throws Exception {
+ when(mWifiConfigManager.isInFlakyRandomizationSsidHotlist(anyInt())).thenReturn(true);
+ // Setup CONNECT_MODE & a WifiConfiguration
+ initializeAndAddNetworkAndVerifySuccess();
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, FRAMEWORK_NETWORK_ID, 0, sBSSID);
+ mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT,
+ WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD);
+ mLooper.dispatchAll();
+
+ verify(mConnectionFailureNotifier, never())
+ .showFailedToConnectDueToNoRandomizedMacSupportNotification(anyInt());
+ }
+
+ /**
* Verifies that CMD_START_CONNECT make WifiDiagnostics report
* CONNECTION_EVENT_STARTED
* @throws Exception
diff --git a/tests/wifitests/src/com/android/server/wifi/ConnectionFailureNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/ConnectionFailureNotifierTest.java
new file mode 100644
index 000000000..8bf07b8c3
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/ConnectionFailureNotifierTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.wifi.WifiConfiguration;
+import android.os.Handler;
+import android.os.Process;
+import android.os.test.TestLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link ConnectionFailureNotifier}.
+ */
+@SmallTest
+public class ConnectionFailureNotifierTest {
+ @Mock private Context mContext;
+ @Mock private WifiInjector mWifiInjector;
+ @Mock private Resources mResources;
+ @Mock private FrameworkFacade mFrameworkFacade;
+ @Mock private WifiConfigManager mWifiConfigManager;
+ @Mock private WifiConnectivityManager mWifiConnectivityManager;
+ @Mock private NotificationManager mNotificationManager;
+ @Mock private ConnectionFailureNotificationBuilder mConnectionFailureNotificationBuilder;
+ @Mock private Notification mNotification;
+ @Mock private AlertDialog mAlertDialog;
+
+ final ArgumentCaptor<BroadcastReceiver> mBroadCastReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ private ConnectionFailureNotifier mConnectionFailureNotifier;
+ TestLooper mLooper;
+
+ /** Initialize objects before each test run. */
+ @Before
+ public void setUp() throws Exception {
+ // Ensure looper exists
+ mLooper = new TestLooper();
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mWifiInjector.getNotificationManager()).thenReturn(mNotificationManager);
+ when(mWifiInjector.getConnectionFailureNotificationBuilder())
+ .thenReturn(mConnectionFailureNotificationBuilder);
+ when(mConnectionFailureNotificationBuilder
+ .buildNoMacRandomizationSupportNotification(any())).thenReturn(mNotification);
+ when(mConnectionFailureNotificationBuilder.buildChangeMacRandomizationSettingDialog(any(),
+ any())).thenReturn(mAlertDialog);
+ mConnectionFailureNotifier = new ConnectionFailureNotifier(mContext, mWifiInjector,
+ mFrameworkFacade, mWifiConfigManager, mWifiConnectivityManager,
+ new Handler(mLooper.getLooper()));
+
+ verify(mContext).registerReceiver(mBroadCastReceiverCaptor.capture(), any());
+ }
+
+ private class DisableMacRandomizationMatcher implements ArgumentMatcher<WifiConfiguration> {
+ @Override
+ public boolean matches(WifiConfiguration config) {
+ return config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_NONE;
+ }
+ }
+
+ // Returns an intent that simulates the broadcast which is received when the user tap
+ // on the notification to change MAC randomization settings.
+ private Intent buildBroadcastForRandomizationSettingsDialog(WifiConfiguration config) {
+ Intent intent = mock(Intent.class);
+ when(intent.getAction()).thenReturn(ConnectionFailureNotificationBuilder
+ .ACTION_SHOW_SET_RANDOMIZATION_DETAILS);
+ when(intent.getIntExtra(eq(ConnectionFailureNotificationBuilder
+ .RANDOMIZATION_SETTINGS_NETWORK_ID), anyInt())).thenReturn(config.networkId);
+ when(intent.getStringExtra(
+ eq(ConnectionFailureNotificationBuilder.RANDOMIZATION_SETTINGS_NETWORK_SSID)))
+ .thenReturn(config.getSsidAndSecurityTypeString());
+ return intent;
+ }
+
+ /**
+ * Verify that a notification is posted when a connection failure happens on a network
+ * in the hotlist. Then verify that tapping on the notification launches an dialog, which
+ * could be used to set the randomization setting for a network to "Trusted".
+ */
+ @Test
+ public void testConnectionFailureSendRandomizationSettingsNotification() {
+ // Verify that the network is using randomized MAC at the start.
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ when(mWifiConfigManager.getConfiguredNetwork(config.networkId)).thenReturn(config);
+ assertEquals(WifiConfiguration.RANDOMIZATION_PERSISTENT, config.macRandomizationSetting);
+
+ mConnectionFailureNotifier.showFailedToConnectDueToNoRandomizedMacSupportNotification(
+ config.networkId);
+ // verify that a notification is sent
+ verify(mNotificationManager).notify(
+ eq(ConnectionFailureNotifier.NO_RANDOMIZED_MAC_SUPPORT_NOTIFICATION_ID),
+ eq(mNotification));
+
+ // sets up the intent that simulates the user tapping on the notification.
+ Intent intent = buildBroadcastForRandomizationSettingsDialog(config);
+
+ // simulate the user tapping on the notification, then verify the dialog shows up, and
+ // the appropriate callback is registered
+ ArgumentCaptor<DialogInterface.OnClickListener> onClickListenerArgumentCaptor =
+ ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
+ mBroadCastReceiverCaptor.getValue().onReceive(mContext, intent);
+ verify(mConnectionFailureNotificationBuilder).buildChangeMacRandomizationSettingDialog(
+ eq(config.SSID), onClickListenerArgumentCaptor.capture());
+
+ // simulate the user tapping on the option to reset MAC address to factory MAC
+ onClickListenerArgumentCaptor.getValue().onClick(null, 0);
+ mLooper.dispatchAll();
+
+ // verify the WifiConfiguration is updated properly.
+ verify(mWifiConfigManager).addOrUpdateNetwork(
+ argThat(new DisableMacRandomizationMatcher()), eq(Process.SYSTEM_UID));
+ // verify that we try to connect to the updated network.
+ verify(mWifiConnectivityManager).forceConnectivityScan(any());
+ }
+
+ /**
+ * Verify that if the WifiConfiguration if not found (may have been deleted by the timed the
+ * notification is tapped), then the AlertDialog does not show up.
+ */
+ @Test
+ public void testWifiConfigurationMismatch() {
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ when(mWifiConfigManager.getConfiguredNetwork(config.networkId)).thenReturn(config);
+ mConnectionFailureNotifier.showFailedToConnectDueToNoRandomizedMacSupportNotification(
+ config.networkId);
+ // verify that a notification is sent
+ verify(mNotificationManager).notify(
+ eq(ConnectionFailureNotifier.NO_RANDOMIZED_MAC_SUPPORT_NOTIFICATION_ID),
+ any());
+
+ // sets up the intent that simulates the user tapping on the notification.
+ Intent intent = buildBroadcastForRandomizationSettingsDialog(config);
+
+ // the WifiConfiguration that is found doesn't match with the one received from broadcast.
+ when(mWifiConfigManager.getConfiguredNetwork(anyInt()))
+ .thenReturn(WifiConfigurationTestUtil.createOpenNetwork());
+ mBroadCastReceiverCaptor.getValue().onReceive(mContext, intent);
+
+ // verify that the AlertDialog is not launched in this case
+ verify(mConnectionFailureNotificationBuilder, never())
+ .buildChangeMacRandomizationSettingDialog(any(), any());
+
+ verify(mFrameworkFacade, never()).makeAlertDialogBuilder(any());
+ // instead we are showings a toast due to failing to find the network
+ verify(mFrameworkFacade).showToast(any(), any());
+ }
+}