summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-06-11 07:11:59 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-11 07:11:59 +0000
commit14b418103501f5106632a7af95b067aee7c7b026 (patch)
treefe011daac6ada61fe8226b7a53a0ed716f5dba3b
parent79ad93863288ad115be97db7e85468201183eb5f (diff)
parent8ec0ba59c20b8266d735912fb71575834c991acc (diff)
downloadandroid_frameworks_opt_net_wifi-14b418103501f5106632a7af95b067aee7c7b026.tar.gz
android_frameworks_opt_net_wifi-14b418103501f5106632a7af95b067aee7c7b026.tar.bz2
android_frameworks_opt_net_wifi-14b418103501f5106632a7af95b067aee7c7b026.zip
release-request-276f9f52-87fd-4915-bd79-9a2f0ee77433-for-git_oc-release-4090213 snap-temp-L31600000073091223
Change-Id: If0e4eed6ea22ca45ef260d8de6301f8876fba841
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java11
-rw-r--r--service/java/com/android/server/wifi/WifiBackupRestore.java12
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java17
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java60
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java8
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java22
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java81
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java14
-rw-r--r--tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java62
12 files changed, 200 insertions, 98 deletions
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index 2c3e5f7e0..ba114df8a 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.PendingIntent;
import android.content.Context;
@@ -161,4 +162,14 @@ public class FrameworkFacade {
public boolean inStorageManagerCryptKeeperBounce() {
return StorageManager.inCryptKeeperBounce();
}
+
+ /**
+ * Check if the provided uid is the app in the foreground.
+ * @param uid the uid to check
+ * @return true if the app is in the foreground, false otherwise
+ * @throws RemoteException
+ */
+ public boolean isAppForeground(int uid) throws RemoteException {
+ return ActivityManager.getService().isAppForeground(uid);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index 4095d8283..60c3b488d 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -28,6 +28,7 @@ import android.util.Xml;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.net.IpConfigStore;
import com.android.server.wifi.util.NativeUtil;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
@@ -96,6 +97,7 @@ public class WifiBackupRestore {
private static final String WEP_KEYS_MASK_SEARCH_PATTERN = "(<.*=)(.*)(/>)";
private static final String WEP_KEYS_MASK_REPLACE_PATTERN = "$1*$3";
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
/**
* Verbose logging flag.
*/
@@ -109,6 +111,10 @@ public class WifiBackupRestore {
private byte[] mDebugLastBackupDataRestored;
private byte[] mDebugLastSupplicantBackupDataRestored;
+ public WifiBackupRestore(WifiPermissionsUtil wifiPermissionsUtil) {
+ mWifiPermissionsUtil = wifiPermissionsUtil;
+ }
+
/**
* Retrieve an XML byte stream representing the data that needs to be backed up from the
* provided configurations.
@@ -163,7 +169,9 @@ public class WifiBackupRestore {
if (configuration.isEnterprise() || configuration.isPasspoint()) {
continue;
}
- if (configuration.creatorUid >= Process.FIRST_APPLICATION_UID) {
+ if (!mWifiPermissionsUtil.checkConfigOverridePermission(configuration.creatorUid)) {
+ Log.d(TAG, "Ignoring network from an app with no config override permission: "
+ + configuration.configKey());
continue;
}
// Write this configuration data now.
@@ -702,6 +710,8 @@ public class WifiBackupRestore {
Integer.parseInt(extras.get(
SupplicantStaNetworkHal.ID_STRING_KEY_CREATOR_UID));
if (creatorUid >= Process.FIRST_APPLICATION_UID) {
+ Log.d(TAG, "Ignoring network from non-system app: "
+ + configuration.configKey());
return null;
}
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 90e400cc1..c51778578 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -96,7 +96,7 @@ public class WifiInjector {
private final PropertyService mPropertyService = new SystemPropertyService();
private final BuildProperties mBuildProperties = new SystemBuildProperties();
private final KeyStore mKeyStore = KeyStore.getInstance();
- private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+ private final WifiBackupRestore mWifiBackupRestore;
private final WifiMulticastLockManager mWifiMulticastLockManager;
private final WifiConfigStore mWifiConfigStore;
private final WifiKeyStore mWifiKeyStore;
@@ -150,6 +150,7 @@ public class WifiInjector {
mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE);
mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
mSettingsStore, UserManager.get(mContext), mNetworkScoreManager, this);
+ mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
mBatteryStats = IBatteryStats.Stub.asInterface(mFrameworkFacade.getService(
BatteryStats.SERVICE_NAME));
mWifiStateTracker = new WifiStateTracker(mBatteryStats);
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 385bfccaa..b2fc56e25 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -179,9 +179,9 @@ public class WifiMonitor {
if (mConnected) {
return true;
}
- if (connectTries++ < 5) {
+ if (connectTries++ < 50) {
try {
- Thread.sleep(1000);
+ Thread.sleep(100);
} catch (InterruptedException ignore) {
}
} else {
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index d32a579ac..5c9548a54 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1159,6 +1159,16 @@ public class WifiServiceImpl extends IWifiManager.Stub {
return LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
}
+ // the app should be in the foreground
+ try {
+ if (!mFrameworkFacade.isAppForeground(uid)) {
+ return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
+ }
+ } catch (RemoteException e) {
+ mLog.trace("RemoteException during isAppForeground when calling startLOHS");
+ return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
+ }
+
mLog.trace("startLocalOnlyHotspot uid=% pid=%").c(uid).c(pid).flush();
synchronized (mLocalOnlyHotspotRequests) {
@@ -2511,8 +2521,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
*/
@Override
public byte[] retrieveBackupData() {
- enforceReadCredentialPermission();
- enforceAccessPermission();
+ enforceNetworkSettingsPermission();
mLog.trace("retrieveBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
@@ -2557,7 +2566,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
*/
@Override
public void restoreBackupData(byte[] data) {
- enforceChangePermission();
+ enforceNetworkSettingsPermission();
mLog.trace("restoreBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
@@ -2579,7 +2588,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
* @param ipConfigData Raw byte stream of ipconfig.txt
*/
public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
- enforceChangePermission();
+ enforceNetworkSettingsPermission();
mLog.trace("restoreSupplicantBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mWifiStateMachineChannel == null) {
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 9c1ae94b5..88f189814 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -64,6 +64,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.WifiWakeReasonAndCounts;
+import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.MutableBoolean;
@@ -204,16 +205,23 @@ public class WifiVendorHal {
private IWifiRttController mIWifiRttController;
private final HalDeviceManager mHalDeviceManager;
private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
- private final Looper mLooper;
private final IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
private final IWifiChipEventCallback mIWifiChipEventCallback;
private final RttEventCallback mRttEventCallback;
+ // Plumbing for event handling.
+ //
+ // Being final fields, they can be accessed without synchronization under
+ // some reasonable assumptions. See
+ // https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5
+ private final Looper mLooper;
+ private final Handler mHalEventHandler;
public WifiVendorHal(HalDeviceManager halDeviceManager,
Looper looper) {
mHalDeviceManager = halDeviceManager;
mLooper = looper;
+ mHalEventHandler = new Handler(looper);
mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener();
mIWifiStaIfaceEventCallback = new StaIfaceEventCallback();
mIWifiChipEventCallback = new ChipEventCallback();
@@ -2455,25 +2463,47 @@ public class WifiVendorHal {
WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
//TODO(b/35875078) Reinstate logging when execessive callbacks are fixed
// mVerboseLog.d("onDebugRingBufferDataAvailable " + status);
- WifiNative.WifiLoggerEventHandler eventHandler;
- synchronized (sLock) {
- if (mLogEventHandler == null || status == null || data == null) return;
- eventHandler = mLogEventHandler;
- }
- eventHandler.onRingBufferData(
- ringBufferStatus(status), NativeUtil.byteArrayFromArrayList(data));
+ mHalEventHandler.post(() -> {
+ WifiNative.WifiLoggerEventHandler eventHandler;
+ synchronized (sLock) {
+ if (mLogEventHandler == null || status == null || data == null) return;
+ eventHandler = mLogEventHandler;
+ }
+ // Because |sLock| has been released, there is a chance that we'll execute
+ // a spurious callback (after someone has called resetLogHandler()).
+ //
+ // However, the alternative risks deadlock. Consider:
+ // [T1.1] WifiDiagnostics.captureBugReport()
+ // [T1.2] -- acquire WifiDiagnostics object's intrinsic lock
+ // [T1.3] -> WifiVendorHal.getRingBufferData()
+ // [T1.4] -- acquire WifiVendorHal.sLock
+ // [T2.1] <lambda>()
+ // [T2.2] -- acquire WifiVendorHal.sLock
+ // [T2.3] -> WifiDiagnostics.onRingBufferData()
+ // [T2.4] -- acquire WifiDiagnostics object's intrinsic lock
+ //
+ // The problem here is that the two threads acquire the locks in opposite order.
+ // If, for example, T2.2 executes between T1.2 and 1.4, then T1 and T2
+ // will be deadlocked.
+ eventHandler.onRingBufferData(
+ ringBufferStatus(status), NativeUtil.byteArrayFromArrayList(data));
+ });
}
@Override
public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
mVerboseLog.d("onDebugErrorAlert " + errorCode);
- WifiNative.WifiLoggerEventHandler eventHandler;
- synchronized (sLock) {
- if (mLogEventHandler == null || debugData == null) return;
- eventHandler = mLogEventHandler;
- }
- eventHandler.onWifiAlert(
- errorCode, NativeUtil.byteArrayFromArrayList(debugData));
+ mHalEventHandler.post(() -> {
+ WifiNative.WifiLoggerEventHandler eventHandler;
+ synchronized (sLock) {
+ if (mLogEventHandler == null || debugData == null) return;
+ eventHandler = mLogEventHandler;
+ }
+ // See comment in onDebugRingBufferDataAvailable(), for an explanation
+ // of why this callback is invoked without |sLock| held.
+ eventHandler.onWifiAlert(
+ errorCode, NativeUtil.byteArrayFromArrayList(debugData));
+ });
}
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java b/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
index 0411f3073..e14c10c91 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pMonitor.java
@@ -158,9 +158,9 @@ public class WifiP2pMonitor {
if (mConnected) {
return true;
}
- if (connectTries++ < 5) {
+ if (connectTries++ < 50) {
try {
- Thread.sleep(1000);
+ Thread.sleep(100);
} catch (InterruptedException ignore) {
}
} else {
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 771e336d5..08c9e1359 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -447,7 +447,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private RequestList<ScanSettings> mActiveScans = new RequestList<>();
private RequestList<ScanSettings> mPendingScans = new RequestList<>();
- // Scan results cached from the last full single scan request.
private ScanResult[] mCachedScanResults = new ScanResult[0];
WifiSingleScanStateMachine(Looper looper) {
@@ -880,11 +879,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults);
}
- // Since we use NoBandChannelHelper, as long as a specific band is mentioned, the scan
- // request is treated as full band (WifiScanner.WIFI_BAND_*).
- if (results.isAllChannelsScanned()) {
- mCachedScanResults = results.getResults();
- }
+ // Cache the results here so that apps can retrieve them.
+ mCachedScanResults = results.getResults();
sendScanResultBroadcast(true);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
index 362540517..58b8d394b 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -24,10 +24,13 @@ import android.os.Process;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.net.IpConfigStore;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
@@ -48,11 +51,15 @@ import java.util.Random;
@SmallTest
public class WifiBackupRestoreTest {
- private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+ @Mock WifiPermissionsUtil mWifiPermissionsUtil;
+ private WifiBackupRestore mWifiBackupRestore;
private boolean mCheckDump = true;
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
+ mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
// Enable verbose logging before tests to check the backup data dumps.
mWifiBackupRestore.enableVerboseLogging(1);
}
@@ -361,25 +368,34 @@ public class WifiBackupRestoreTest {
*/
@Test
public void testMultipleNetworksSystemAppBackupRestore() {
+ int systemAppUid = Process.SYSTEM_UID;
+ int nonSystemAppUid = Process.FIRST_APPLICATION_UID + 556;
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(systemAppUid)))
+ .thenReturn(true);
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(eq(nonSystemAppUid)))
+ .thenReturn(false);
+
List<WifiConfiguration> configurations = new ArrayList<>();
List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.creatorUid = systemAppUid;
configurations.add(wepNetwork);
expectedConfigurations.add(wepNetwork);
// These should not be in |expectedConfigurations|.
WifiConfiguration nonSystemAppWepNetwork = WifiConfigurationTestUtil.createWepNetwork();
- nonSystemAppWepNetwork.creatorUid = Process.FIRST_APPLICATION_UID;
+ nonSystemAppWepNetwork.creatorUid = nonSystemAppUid;
configurations.add(nonSystemAppWepNetwork);
WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ pskNetwork.creatorUid = systemAppUid;
configurations.add(pskNetwork);
expectedConfigurations.add(pskNetwork);
// These should not be in |expectedConfigurations|.
WifiConfiguration nonSystemAppPskNetwork = WifiConfigurationTestUtil.createPskNetwork();
- nonSystemAppPskNetwork.creatorUid = Process.FIRST_APPLICATION_UID + 1;
+ nonSystemAppPskNetwork.creatorUid = nonSystemAppUid;
configurations.add(nonSystemAppPskNetwork);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 562143335..d5bfb2045 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -74,6 +74,7 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserManager;
import android.os.WorkSource;
import android.os.test.TestLooper;
@@ -97,6 +98,7 @@ import org.mockito.Spy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.List;
/**
* Unit tests for {@link WifiServiceImpl}.
@@ -760,6 +762,9 @@ public class WifiServiceImplTest {
// allow test to proceed without a permission check failure
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ try {
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ } catch (RemoteException e) { }
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(false);
int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
@@ -812,12 +817,43 @@ public class WifiServiceImplTest {
}
/**
+ * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request.
+ */
+ @Test
+ public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
+ when(mSettingsStore.getLocationModeSetting(mContext))
+ .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
+ TEST_PACKAGE_NAME);
+ assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
+ }
+
+ /**
+ * Do not register the LocalOnlyHotspot request if the caller app cannot be verified as the
+ * foreground app at the time of the request (ie, throws an exception in the check).
+ */
+ @Test
+ public void testStartLocalOnlyHotspotFailsIfForegroundAppCheckThrowsRemoteException()
+ throws Exception {
+ when(mSettingsStore.getLocationModeSetting(mContext))
+ .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenThrow(new RemoteException());
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
+ TEST_PACKAGE_NAME);
+ assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
+ }
+
+ /**
* Only start LocalOnlyHotspot if we are not tethering.
*/
@Test
- public void testHotspotDoesNotStartWhenAlreadyTethering() {
+ public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
@@ -829,9 +865,10 @@ public class WifiServiceImplTest {
* Only start LocalOnlyHotspot if admin setting does not disallow tethering.
*/
@Test
- public void testHotspotDoesNotStartWhenTetheringDisallowed() {
+ public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
when(mSettingsStore.getLocationModeSetting(mContext))
.thenReturn(LOCATION_MODE_HIGH_ACCURACY);
+ when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(true);
int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
@@ -1503,4 +1540,44 @@ public class WifiServiceImplTest {
verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(),
any(PasspointConfiguration.class), anyInt());
}
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from
+ * callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRestoreBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.restoreBackupData(null);
+ verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class));
+ }
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is
+ * only allowed from callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRestoreSupplicantBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.restoreSupplicantBackupData(null, null);
+ verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData(
+ any(byte[].class), any(byte[].class));
+ }
+
+ /**
+ * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from
+ * callers with the signature only NETWORK_SETTINGS permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRetrieveBackupDataNotApprovedCaller() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.retrieveBackupData();
+ verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index 66a55b51a..34ddf2378 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -1679,9 +1679,10 @@ public class WifiVendorHalTest {
new Random().nextBytes(errorData);
// Randomly raise the HIDL callback before we register for the log callback.
- // This should be ignored.
+ // This should be safely ignored. (Not trigger NPE.)
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
@@ -1691,12 +1692,16 @@ public class WifiVendorHalTest {
// Now raise the HIDL callback, this should be properly handled.
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData));
// Now stop the logging and invoke the callback. This should be ignored.
+ reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
mIWifiChipEventCallback.onDebugErrorAlert(
errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
+ verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject());
}
/**
@@ -1714,9 +1719,10 @@ public class WifiVendorHalTest {
new Random().nextBytes(errorData);
// Randomly raise the HIDL callback before we register for the log callback.
- // This should be ignored.
+ // This should be safely ignored. (Not trigger NPE.)
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
@@ -1726,13 +1732,17 @@ public class WifiVendorHalTest {
// Now raise the HIDL callback, this should be properly handled.
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
verify(eventHandler).onRingBufferData(
any(WifiNative.RingBufferStatus.class), eq(errorData));
// Now stop the logging and invoke the callback. This should be ignored.
+ reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mLooper.dispatchAll();
+ verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject());
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
index d9fbb1d28..e7c5fa962 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
@@ -1257,10 +1257,10 @@ public class WifiScanningServiceTest {
}
/**
- * Verify that the newest full scan results are returned by WifiService.getSingleScanResults.
+ * Verify that the newest scan results are returned by WifiService.getSingleScanResults.
*/
@Test
- public void retrieveMostRecentFullSingleScanResults() throws Exception {
+ public void retrieveMostRecentSingleScanResults() throws Exception {
WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
@@ -1312,64 +1312,6 @@ public class WifiScanningServiceTest {
}
/**
- * Verify that the newest partial scan results are not returned by
- * WifiService.getSingleScanResults.
- */
- @Test
- public void doesNotRetrieveMostRecentPartialSingleScanResults() throws Exception {
- WifiScanner.ScanSettings fullRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
- 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
- ScanResults expectedFullResults = ScanResults.create(0, true, 2400, 5150, 5175);
- doSuccessfulSingleScan(fullRequestSettings,
- computeSingleScanNativeSettings(fullRequestSettings),
- expectedFullResults);
-
- Handler handler = mock(Handler.class);
- BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
-
- controlChannel.sendMessage(
- Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
- mLooper.dispatchAll();
- Message response = verifyHandleMessageAndGetMessage(order, handler);
-
- List<ScanResult> results = Arrays.asList(
- ((WifiScanner.ParcelableScanResults) response.obj).getResults());
- assertEquals(results.size(), expectedFullResults.getRawScanResults().length);
-
- // now update with a new scan that only has one result
- int secondScanRequestId = 35;
- WifiScanner.ScanSettings partialRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH,
- 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
- ScanResults expectedPartialResults = ScanResults.create(0, false, 5150);
- sendSingleScanRequest(controlChannel, secondScanRequestId, partialRequestSettings, null);
-
- mLooper.dispatchAll();
- WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
- computeSingleScanNativeSettings(partialRequestSettings));
- verifySuccessfulResponse(order, handler, secondScanRequestId);
-
- // dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
- .thenReturn(expectedPartialResults.getScanData());
- eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
-
- mLooper.dispatchAll();
- verifyScanResultsReceived(order, handler, secondScanRequestId,
- expectedPartialResults.getScanData());
- verifySingleScanCompletedReceived(order, handler, secondScanRequestId);
-
- controlChannel.sendMessage(
- Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
- mLooper.dispatchAll();
- Message response2 = verifyHandleMessageAndGetMessage(order, handler);
-
- List<ScanResult> results2 = Arrays.asList(
- ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
- assertEquals(results2.size(), expectedFullResults.getRawScanResults().length);
- }
-
- /**
* Cached scan results should be cleared after the driver is unloaded.
*/
@Test