summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java11
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java109
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java15
-rw-r--r--tests/wifitests/src/com/android/server/wifi/MockResources.java15
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java155
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java27
7 files changed, 300 insertions, 35 deletions
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index 15b9cc738..26cb4ff7b 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -136,17 +136,6 @@ public class FrameworkFacade {
return true;
}
- /**
- * Create a new instance of WifiApConfigStore.
- * @param context reference to a Context
- * @param backupManagerProxy reference to a BackupManagerProxy
- * @return an instance of WifiApConfigStore
- */
- public WifiApConfigStore makeApConfigStore(Context context,
- BackupManagerProxy backupManagerProxy) {
- return new WifiApConfigStore(context, backupManagerProxy);
- }
-
public long getTxPackets(String iface) {
return TrafficStats.getTxPackets(iface);
}
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 109c0a7af..d21452c8c 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -17,15 +17,25 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -44,6 +54,10 @@ import java.util.UUID;
*/
public class WifiApConfigStore {
+ // Intent when user has interacted with the softap settings change notification
+ public static final String ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT =
+ "com.android.server.wifi.WifiApConfigStoreUtil.HOTSPOT_CONFIG_USER_TAPPED_CONTENT";
+
private static final String TAG = "WifiApConfigStore";
private static final String DEFAULT_AP_CONFIG_FILE =
@@ -71,19 +85,26 @@ public class WifiApConfigStore {
private ArrayList<Integer> mAllowed2GChannel = null;
private final Context mContext;
+ private final Handler mHandler;
private final String mApConfigFile;
private final BackupManagerProxy mBackupManagerProxy;
+ private final FrameworkFacade mFrameworkFacade;
private boolean mRequiresApBandConversion = false;
- WifiApConfigStore(Context context, BackupManagerProxy backupManagerProxy) {
- this(context, backupManagerProxy, DEFAULT_AP_CONFIG_FILE);
+ WifiApConfigStore(Context context, Looper looper,
+ BackupManagerProxy backupManagerProxy, FrameworkFacade frameworkFacade) {
+ this(context, looper, backupManagerProxy, frameworkFacade, DEFAULT_AP_CONFIG_FILE);
}
WifiApConfigStore(Context context,
+ Looper looper,
BackupManagerProxy backupManagerProxy,
+ FrameworkFacade frameworkFacade,
String apConfigFile) {
mContext = context;
+ mHandler = new Handler(looper);
mBackupManagerProxy = backupManagerProxy;
+ mFrameworkFacade = frameworkFacade;
mApConfigFile = apConfigFile;
String ap2GChannelListStr = mContext.getResources().getString(
@@ -111,8 +132,30 @@ public class WifiApConfigStore {
/* Save the default configuration to persistent storage. */
writeApConfiguration(mApConfigFile, mWifiApConfig);
}
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT);
+ mContext.registerReceiver(
+ mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
}
+ private final BroadcastReceiver mBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // For now we only have one registered listener, but we easily could expand this
+ // to support multiple signals. Starting off with a switch to support trivial
+ // expansion.
+ switch(intent.getAction()) {
+ case ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT:
+ handleUserHotspotConfigTappedContent();
+ break;
+ default:
+ Log.e(TAG, "Unknown action " + intent.getAction());
+ }
+ }
+ };
+
/**
* Return the current soft access point configuration.
*/
@@ -145,6 +188,43 @@ public class WifiApConfigStore {
return mAllowed2GChannel;
}
+ /**
+ * Helper method to create and send notification to user of apBand conversion.
+ *
+ * @param packageName name of the calling app
+ */
+ public void notifyUserOfApBandConversion(String packageName) {
+ Log.w(TAG, "ready to post notification - triggered by " + packageName);
+ Notification notification = createConversionNotification();
+ NotificationManager notificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.notify(SystemMessage.NOTE_SOFTAP_CONFIG_CHANGED, notification);
+ }
+
+ private Notification createConversionNotification() {
+ CharSequence title = mContext.getText(R.string.wifi_softap_config_change);
+ CharSequence contentSummary = mContext.getText(R.string.wifi_softap_config_change_summary);
+ CharSequence content = mContext.getText(R.string.wifi_softap_config_change_detailed);
+ int color = mContext.getResources()
+ .getColor(R.color.system_notification_accent_color, mContext.getTheme());
+
+ return new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS)
+ .setSmallIcon(R.drawable.ic_wifi_settings)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setContentTitle(title)
+ .setContentText(contentSummary)
+ .setContentIntent(getPrivateBroadcast(ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT))
+ .setTicker(title)
+ .setShowWhen(false)
+ .setLocalOnly(true)
+ .setColor(color)
+ .setStyle(new Notification.BigTextStyle().bigText(content)
+ .setBigContentTitle(title)
+ .setSummaryText(contentSummary))
+ .build();
+ }
+
private WifiConfiguration apBandCheckConvert(WifiConfiguration config) {
if (mRequiresApBandConversion) {
// some devices are unable to support 5GHz only operation, check for 5GHz and
@@ -386,4 +466,29 @@ public class WifiApConfigStore {
return true;
}
+
+ /**
+ * Helper method to start up settings on the softap config page.
+ */
+ private void startSoftApSettings() {
+ mContext.startActivity(
+ new Intent("com.android.settings.WIFI_TETHER_SETTINGS")
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+
+ /**
+ * Helper method to trigger settings to open the softap config page
+ */
+ private void handleUserHotspotConfigTappedContent() {
+ startSoftApSettings();
+ NotificationManager notificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.cancel(SystemMessage.NOTE_SOFTAP_CONFIG_CHANGED);
+ }
+
+ private PendingIntent getPrivateBroadcast(String action) {
+ Intent intent = new Intent(action).setPackage("android");
+ return mFrameworkFacade.getBroadcast(
+ mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 199548090..dbf730a73 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -205,7 +205,8 @@ public class WifiInjector {
SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
mContext.getResources()
.getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
- mWifiApConfigStore = new WifiApConfigStore(mContext, mBackupManagerProxy);
+ mWifiApConfigStore = new WifiApConfigStore(
+ mContext, wifiStateMachineLooper, mBackupManagerProxy, mFrameworkFacade);
// WifiConfigManager/Store objects and their dependencies.
// New config store
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index a0bbded9d..cb16efd99 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1583,6 +1583,21 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
/**
+ * Method used to inform user of Ap Configuration conversion due to hardware.
+ */
+ @Override
+ public void notifyUserOfApBandConversion(String packageName) {
+ enforceNetworkSettingsPermission();
+
+ if (mVerboseLoggingEnabled) {
+ mLog.info("notifyUserOfApBandConversion uid=% packageName=%")
+ .c(Binder.getCallingUid()).c(packageName).flush();
+ }
+
+ mWifiApConfigStore.notifyUserOfApBandConversion(packageName);
+ }
+
+ /**
* see {@link android.net.wifi.WifiManager#isScanAlwaysAvailable()}
*/
@Override
diff --git a/tests/wifitests/src/com/android/server/wifi/MockResources.java b/tests/wifitests/src/com/android/server/wifi/MockResources.java
index ab40c6f8d..1a061e22a 100644
--- a/tests/wifitests/src/com/android/server/wifi/MockResources.java
+++ b/tests/wifitests/src/com/android/server/wifi/MockResources.java
@@ -23,11 +23,13 @@ public class MockResources extends android.test.mock.MockResources {
private HashMap<Integer, Boolean> mBooleanValues;
private HashMap<Integer, Integer> mIntegerValues;
private HashMap<Integer, String> mStringValues;
+ private HashMap<Integer, CharSequence> mTextValues;
public MockResources() {
mBooleanValues = new HashMap<Integer, Boolean>();
mIntegerValues = new HashMap<Integer, Integer>();
mStringValues = new HashMap<Integer, String>();
+ mTextValues = new HashMap<Integer, CharSequence>();
}
@Override
@@ -57,6 +59,15 @@ public class MockResources extends android.test.mock.MockResources {
}
}
+ @Override
+ public CharSequence getText(int id) {
+ if (mTextValues.containsKey(id)) {
+ return mTextValues.get(id);
+ } else {
+ return null;
+ }
+ }
+
public void setBoolean(int id, boolean value) {
mBooleanValues.put(id, value);
}
@@ -68,4 +79,8 @@ public class MockResources extends android.test.mock.MockResources {
public void setString(int id, String value) {
mStringValues.put(id, value);
}
+
+ public void setText(int id, CharSequence value) {
+ mTextValues.put(id, value);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 1672dca58..88312ce4c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -19,25 +19,38 @@ package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.os.Build;
+import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.File;
import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Random;
/**
@@ -54,19 +67,34 @@ public class WifiApConfigStoreTest {
private static final String TEST_CONFIGURED_AP_SSID = "ConfiguredAP";
private static final String TEST_DEFAULT_HOTSPOT_SSID = "TestShare";
private static final String TEST_DEFAULT_HOTSPOT_PSK = "TestPassword";
+ private static final String TEST_APCONFIG_CHANGE_NOTIFICATION_TITLE = "Notification title";
+ private static final String TEST_APCONFIG_CHANGE_NOTIFICATION_SUMMARY = "Notification summary";
+ private static final String TEST_APCONFIG_CHANGE_NOTIFICATION_DETAILED =
+ "Notification detailed";
private static final int RAND_SSID_INT_MIN = 1000;
private static final int RAND_SSID_INT_MAX = 9999;
private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789";
- @Mock Context mContext;
- @Mock BackupManagerProxy mBackupManagerProxy;
- File mApConfigFile;
- Random mRandom;
- MockResources mResources;
+ @Mock private Context mContext;
+ private TestLooper mLooper;
+ @Mock private BackupManagerProxy mBackupManagerProxy;
+ @Mock private FrameworkFacade mFrameworkFacade;
+ private File mApConfigFile;
+ private Random mRandom;
+ private MockResources mResources;
+ @Mock private ApplicationInfo mMockApplInfo;
+ private BroadcastReceiver mBroadcastReceiver;
+ @Mock private NotificationManager mNotificationManager;
+ private ArrayList<Integer> mKnownGood2GChannelList;
@Before
public void setUp() throws Exception {
+ mLooper = new TestLooper();
MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mNotificationManager);
+ mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.P;
+ when(mContext.getApplicationInfo()).thenReturn(mMockApplInfo);
/* Create a temporary file for AP config file storage. */
mApConfigFile = File.createTempFile(TEST_AP_CONFIG_FILE_PREFIX, "");
@@ -74,15 +102,24 @@ public class WifiApConfigStoreTest {
/* Setup expectations for Resources to return some default settings. */
mResources = new MockResources();
mResources.setString(R.string.config_wifi_framework_sap_2G_channel_list,
- TEST_DEFAULT_2G_CHANNEL_LIST);
+ TEST_DEFAULT_2G_CHANNEL_LIST);
mResources.setString(R.string.wifi_tether_configure_ssid_default,
- TEST_DEFAULT_AP_SSID);
+ TEST_DEFAULT_AP_SSID);
mResources.setString(R.string.wifi_localhotspot_configure_ssid_default,
- TEST_DEFAULT_HOTSPOT_SSID);
+ TEST_DEFAULT_HOTSPOT_SSID);
/* Default to device that does not require ap band conversion */
mResources.setBoolean(R.bool.config_wifi_convert_apband_5ghz_to_any, false);
+ mResources.setText(R.string.wifi_softap_config_change,
+ TEST_APCONFIG_CHANGE_NOTIFICATION_TITLE);
+ mResources.setText(R.string.wifi_softap_config_change_summary,
+ TEST_APCONFIG_CHANGE_NOTIFICATION_SUMMARY);
+ mResources.setText(R.string.wifi_softap_config_change_detailed,
+ TEST_APCONFIG_CHANGE_NOTIFICATION_DETAILED);
when(mContext.getResources()).thenReturn(mResources);
+ // build the known good 2G channel list: TEST_DEFAULT_2G_CHANNEL_LIST
+ mKnownGood2GChannelList = new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6));
+
mRandom = new Random();
}
@@ -93,6 +130,22 @@ public class WifiApConfigStoreTest {
}
/**
+ * Helper method to create and verify actions for the ApConfigStore used in the following tests.
+ */
+ private WifiApConfigStore createWifiApConfigStore() {
+ WifiApConfigStore store = new WifiApConfigStore(
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
+
+ ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
+ mBroadcastReceiver = broadcastReceiverCaptor.getValue();
+
+ return store;
+ }
+
+ /**
* Generate a WifiConfiguration based on the specified parameters.
*/
private WifiConfiguration setupApConfig(
@@ -149,7 +202,8 @@ public class WifiApConfigStoreTest {
@Test
public void initWithDefaultConfiguration() throws Exception {
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
}
@@ -167,7 +221,8 @@ public class WifiApConfigStoreTest {
40 /* AP channel */);
writeApConfigFile(expectedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
}
@@ -187,7 +242,8 @@ public class WifiApConfigStoreTest {
40 /* AP channel */);
writeApConfigFile(expectedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
store.setApConfiguration(null);
@@ -202,7 +258,8 @@ public class WifiApConfigStoreTest {
public void updateApConfiguration() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
/* Update with a valid configuration. */
@@ -226,7 +283,8 @@ public class WifiApConfigStoreTest {
public void convertSingleModeDeviceAnyTo5Ghz() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
/* Update with a valid configuration. */
@@ -257,7 +315,8 @@ public class WifiApConfigStoreTest {
public void singleModeDevice5GhzNotConverted() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
/* Update with a valid configuration. */
@@ -282,7 +341,8 @@ public class WifiApConfigStoreTest {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
/* Update with a valid configuration. */
@@ -315,7 +375,8 @@ public class WifiApConfigStoreTest {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
/* Update with a valid configuration. */
@@ -353,7 +414,8 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
verify(mBackupManagerProxy).notifyDataChanged();
}
@@ -374,7 +436,8 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(persistedConfig, store.getApConfiguration());
verify(mBackupManagerProxy, never()).notifyDataChanged();
}
@@ -403,7 +466,8 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
verify(mBackupManagerProxy).notifyDataChanged();
}
@@ -426,7 +490,8 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
verifyApConfig(persistedConfig, store.getApConfiguration());
verify(mBackupManagerProxy, never()).notifyDataChanged();
}
@@ -437,7 +502,8 @@ public class WifiApConfigStoreTest {
@Test
public void getDefaultApConfigurationIsValid() {
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mBackupManagerProxy, mApConfigFile.getPath());
+ mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mApConfigFile.getPath());
WifiConfiguration config = store.getApConfiguration();
assertTrue(WifiApConfigStore.validateApWifiConfiguration(config));
}
@@ -597,4 +663,51 @@ public class WifiApConfigStoreTest {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(config));
}
+
+ /**
+ * Verify the default 2GHz channel list is properly returned.
+ */
+ @Test
+ public void testDefault2GHzChannelListReturned() {
+ // first build known good list
+ WifiApConfigStore store = createWifiApConfigStore();
+ ArrayList<Integer> channels = store.getAllowed2GChannel();
+
+ assertEquals(mKnownGood2GChannelList.size(), channels.size());
+ for (int channel : channels) {
+ assertTrue(mKnownGood2GChannelList.contains(channel));
+ }
+ }
+
+ /**
+ * Verify a notification is posted when triggered when the ap config was converted.
+ */
+ @Test
+ public void testNotifyUserOfApBandConversion() throws Exception {
+ WifiApConfigStore store = createWifiApConfigStore();
+ store.notifyUserOfApBandConversion(TAG);
+ // verify the notification is posted
+ ArgumentCaptor<Notification> notificationCaptor =
+ ArgumentCaptor.forClass(Notification.class);
+ verify(mNotificationManager).notify(eq(SystemMessage.NOTE_SOFTAP_CONFIG_CHANGED),
+ notificationCaptor.capture());
+ Notification notification = notificationCaptor.getValue();
+ assertEquals(TEST_APCONFIG_CHANGE_NOTIFICATION_TITLE,
+ notification.extras.getCharSequence(Notification.EXTRA_TITLE));
+ assertEquals(TEST_APCONFIG_CHANGE_NOTIFICATION_DETAILED,
+ notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT));
+ assertEquals(TEST_APCONFIG_CHANGE_NOTIFICATION_SUMMARY,
+ notification.extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT));
+ }
+
+ /**
+ * Verify the posted notification is cleared when the user interacts with it.
+ */
+ @Test
+ public void testNotificationClearedWhenContentIsTapped() throws Exception {
+ WifiApConfigStore store = createWifiApConfigStore();
+ Intent intent = new Intent(WifiApConfigStore.ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT);
+ mBroadcastReceiver.onReceive(mContext, intent);
+ verify(mNotificationManager).cancel(eq(SystemMessage.NOTE_SOFTAP_CONFIG_CHANGED));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 6a248161c..f04f53130 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -2838,4 +2838,31 @@ public class WifiServiceImplTest {
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
verifyNoMoreInteractions(mWifiCountryCode);
}
+
+ /**
+ * Verify calls to notify users of a softap config change check the NETWORK_SETTINGS permission.
+ */
+ @Test
+ public void testNotifyUserOfApBandConversionChecksNetworkSettingsPermission() {
+ mWifiServiceImpl.notifyUserOfApBandConversion(TEST_PACKAGE_NAME);
+ verify(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ verify(mWifiApConfigStore).notifyUserOfApBandConversion(eq(TEST_PACKAGE_NAME));
+ }
+
+ /**
+ * Verify calls to notify users do not trigger a notification when NETWORK_SETTINGS is not held
+ * by the caller.
+ */
+ @Test
+ public void testNotifyUserOfApBandConversionThrowsExceptionWithoutNetworkSettingsPermission() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ try {
+ mWifiServiceImpl.notifyUserOfApBandConversion(TEST_PACKAGE_NAME);
+ fail("Expected Security exception");
+ } catch (SecurityException e) { }
+ }
}