diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-10-05 07:21:03 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-10-05 07:21:03 +0000 |
commit | 07316e8cfcd70d7b5a4ff486b6f8330ee44659e8 (patch) | |
tree | 118004ced9b8ee5072388841d086c177338b4d99 | |
parent | 7db8888d6dcf9971ca83b6c1984d528cdc9a50e3 (diff) | |
parent | 87d7badd662aa84369b2b9893e990cb24197ad24 (diff) | |
download | android_frameworks_opt_net_wifi-07316e8cfcd70d7b5a4ff486b6f8330ee44659e8.tar.gz android_frameworks_opt_net_wifi-07316e8cfcd70d7b5a4ff486b6f8330ee44659e8.tar.bz2 android_frameworks_opt_net_wifi-07316e8cfcd70d7b5a4ff486b6f8330ee44659e8.zip |
Snap for 4378450 from 87d7badd662aa84369b2b9893e990cb24197ad24 to oc-mr1-release
Change-Id: I364d7180d69955561699e4e525cd47880fccaf95
10 files changed, 857 insertions, 111 deletions
diff --git a/libwifi_system/hostapd_manager.cpp b/libwifi_system/hostapd_manager.cpp index 68184e901..658eecdd8 100644 --- a/libwifi_system/hostapd_manager.cpp +++ b/libwifi_system/hostapd_manager.cpp @@ -34,6 +34,7 @@ using android::base::ParseInt; using android::base::ReadFileToString; +using android::base::RemoveFileIfExists; using android::base::StringPrintf; using android::base::WriteStringToFile; using std::string; @@ -103,6 +104,9 @@ bool HostapdManager::StopHostapd() { } bool HostapdManager::WriteHostapdConfig(const string& config) { + // Remove hostapd.conf because its file owner might be system + // in previous OS and chmod fails in that case. + RemoveFileIfExists(kHostapdConfigFilePath); if (!WriteStringToFile(config, kHostapdConfigFilePath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, AID_WIFI, AID_WIFI)) { diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 7e730c838..458f73ae6 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -30,6 +30,8 @@ import android.net.wifi.WifiScanner.PnoSettings; import android.net.wifi.WifiScanner.ScanSettings; import android.os.Handler; import android.os.Looper; +import android.os.Process; +import android.os.WorkSource; import android.util.LocalLog; import android.util.Log; @@ -214,7 +216,7 @@ public class WifiConnectivityManager { @Override public void onAlarm() { - startSingleScan(mIsFullBandScan); + startSingleScan(mIsFullBandScan, WIFI_WORK_SOURCE); } } @@ -741,7 +743,7 @@ public class WifiConnectivityManager { localLog("connectToNetwork: Connect to " + targetAssociationId + " from " + currentAssociationId); } - mStateMachine.startConnectToNetwork(candidate.networkId, targetBssid); + mStateMachine.startConnectToNetwork(candidate.networkId, Process.WIFI_UID, targetBssid); } } @@ -794,7 +796,7 @@ public class WifiConnectivityManager { localLog("start a single scan from watchdogHandler"); scheduleWatchdogTimer(); - startSingleScan(true); + startSingleScan(true, WIFI_WORK_SOURCE); } } @@ -823,7 +825,7 @@ public class WifiConnectivityManager { } mLastPeriodicSingleScanTimeStamp = currentTimeStamp; - startSingleScan(isFullBandScan); + startSingleScan(isFullBandScan, WIFI_WORK_SOURCE); schedulePeriodicScanTimer(mPeriodicSingleScanInterval); // Set up the next scan interval in an exponential backoff fashion. @@ -850,7 +852,7 @@ public class WifiConnectivityManager { } // Start a single scan - private void startSingleScan(boolean isFullBandScan) { + private void startSingleScan(boolean isFullBandScan, WorkSource workSource) { if (!mWifiEnabled || !mWifiConnectivityManagerEnabled) { return; } @@ -875,7 +877,7 @@ public class WifiConnectivityManager { SingleScanListener singleScanListener = new SingleScanListener(isFullBandScan); - mScanner.startScan(settings, singleScanListener, WIFI_WORK_SOURCE); + mScanner.startScan(settings, singleScanListener, workSource); } // Start a periodic scan when screen is on @@ -1132,11 +1134,11 @@ public class WifiConnectivityManager { /** * Handler for on-demand connectivity scan */ - public void forceConnectivityScan() { - localLog("forceConnectivityScan"); + public void forceConnectivityScan(WorkSource workSource) { + localLog("forceConnectivityScan in request of " + workSource); mWaitForFullBandScanResults = true; - startSingleScan(true); + startSingleScan(true, workSource); } /** diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index bb995b7d1..c83f6c6bd 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -1421,7 +1421,7 @@ public class WifiServiceImpl extends IWifiManager.Stub { public void reconnect() { enforceChangePermission(); mLog.info("reconnect uid=%").c(Binder.getCallingUid()).flush(); - mWifiStateMachine.reconnectCommand(); + mWifiStateMachine.reconnectCommand(new WorkSource(Binder.getCallingUid())); } /** diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a3054c92b..ac7d748bb 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1321,7 +1321,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss /** * Initiates connection to a network specified by the user/app. This method checks if the - * requesting app holds the WIFI_CONFIG_OVERRIDE permission. + * requesting app holds the NETWORK_SETTINGS permission. * * @param netId Id network to initiate connection. * @param uid UID of the app requesting the connection. @@ -1350,7 +1350,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss logi("connectToUserSelectNetwork already connecting/connected=" + netId); } else { mWifiConnectivityManager.prepareForForcedConnection(netId); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY); } return true; } @@ -1770,7 +1770,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss uid) == PackageManager.PERMISSION_GRANTED) { result.setMacAddress(mWifiInfo.getMacAddress()); } - if (mWifiPermissionsUtil.canAccessScanResults( + final WifiConfiguration currentWifiConfiguration = getCurrentWifiConfiguration(); + if (mWifiPermissionsUtil.canAccessFullConnectionInfo( + currentWifiConfiguration, callingPackage, uid, Build.VERSION_CODES.O)) { @@ -1873,8 +1875,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss /** * Initiate a reconnection to AP */ - public void reconnectCommand() { - sendMessage(CMD_RECONNECT); + public void reconnectCommand(WorkSource workSource) { + sendMessage(CMD_RECONNECT, workSource); } /** @@ -4535,7 +4537,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mEnableAutoJoinWhenAssociated = allowed; if (!old_state && allowed && mScreenOn && getCurrentState() == mConnectedState) { - mWifiConnectivityManager.forceConnectivityScan(); + mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); } break; case CMD_SELECT_TX_POWER_SCENARIO: @@ -5158,7 +5160,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mPasspointManager.getMatchingOsuProviders((ScanResult) message.obj)); break; case CMD_RECONNECT: - mWifiConnectivityManager.forceConnectivityScan(); + WorkSource workSource = (WorkSource) message.obj; + mWifiConnectivityManager.forceConnectivityScan(workSource); break; case CMD_REASSOCIATE: lastConnectAttemptTimestamp = mClock.getWallClockMillis(); @@ -5178,7 +5181,23 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_START_CONNECT: /* connect command coming from auto-join */ netId = message.arg1; + int uid = message.arg2; bssid = (String) message.obj; + + synchronized (mWifiReqCountLock) { + if (!hasConnectionRequests()) { + if (mNetworkAgent == null) { + loge("CMD_START_CONNECT but no requests and not connected," + + " bailing"); + break; + } else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) { + loge("CMD_START_CONNECT but no requests and connected, but app " + + "does not have sufficient permissions, bailing"); + break; + } + } + } + config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId); logd("CMD_START_CONNECT sup state " + mSupplicantStateTracker.getSupplicantStateName() @@ -5278,7 +5297,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss // start a new connection with the updated credentials. logi("SAVE_NETWORK credential changed for config=" + config.configKey() + ", Reconnecting."); - startConnectToNetwork(netId, SUPPLICANT_BSSID_ANY); + startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY); } else { if (result.hasProxyChanged()) { log("Reconfiguring proxy on connection"); @@ -5978,6 +5997,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_STOP_RSSI_MONITORING_OFFLOAD: stopRssiMonitoringOffload(); break; + case CMD_RECONNECT: + log(" Ignore CMD_RECONNECT request because wifi is already connected"); + break; case CMD_RESET_SIM_NETWORKS: if (message.arg1 == 0 // sim was removed && mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) { @@ -6121,7 +6143,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss WifiConfiguration config = getCurrentWifiConfiguration(); if (shouldEvaluateWhetherToSendExplicitlySelected(config)) { boolean prompt = - mWifiPermissionsUtil.checkConfigOverridePermission(config.lastConnectUid); + mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid); if (mVerboseLoggingEnabled) { log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt); } @@ -6830,6 +6852,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case WifiManager.CONNECT_NETWORK: case CMD_ENABLE_NETWORK: case CMD_RECONNECT: + log(" Ignore CMD_RECONNECT request because wps is running"); + return HANDLED; case CMD_REASSOCIATE: deferMessage(message); break; @@ -7097,14 +7121,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss * Automatically connect to the network specified * * @param networkId ID of the network to connect to + * @param uid UID of the app triggering the connection. * @param bssid BSSID of the network */ - public void startConnectToNetwork(int networkId, String bssid) { - synchronized (mWifiReqCountLock) { - if (hasConnectionRequests()) { - sendMessage(CMD_START_CONNECT, networkId, 0, bssid); - } - } + public void startConnectToNetwork(int networkId, int uid, String bssid) { + sendMessage(CMD_START_CONNECT, networkId, uid, bssid); } /** diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java index 12a0bdee0..ed25e0f67 100644 --- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java +++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java @@ -422,11 +422,22 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call mPendingSingleScanEventHandler = null; } - if ((newScanSettings.backgroundScanActive || newScanSettings.singleScanActive) - && !allFreqs.isEmpty()) { - pauseHwPnoScan(); - Set<Integer> freqs = allFreqs.getScanFreqs(); - boolean success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet); + if (newScanSettings.backgroundScanActive || newScanSettings.singleScanActive) { + boolean success = false; + Set<Integer> freqs; + if (!allFreqs.isEmpty()) { + pauseHwPnoScan(); + freqs = allFreqs.getScanFreqs(); + success = mWifiNative.scan(freqs, hiddenNetworkSSIDSet); + if (!success) { + Log.e(TAG, "Failed to start scan, freqs=" + freqs); + } + } else { + // There is a scan request but no available channels could be scanned for. + // We regard it as a scan failure in this case. + Log.e(TAG, "Failed to start scan because there is " + + "no available channel to scan for"); + } if (success) { // TODO handle scan timeout if (DBG) { @@ -439,7 +450,6 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call mClock.getElapsedSinceBootMillis() + SCAN_TIMEOUT_MS, TIMEOUT_ALARM_TAG, mScanTimeoutListener, mEventHandler); } else { - Log.e(TAG, "Failed to start scan, freqs=" + freqs); // indicate scan failure async mEventHandler.post(new Runnable() { public void run() { diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java index 069e5a823..52c96183e 100644 --- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java +++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java @@ -17,17 +17,23 @@ package com.android.server.wifi.util; import android.Manifest; +import android.annotation.Nullable; import android.app.AppOpsManager; +import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.NetworkScoreManager; +import android.net.NetworkScorerAppData; +import android.net.wifi.WifiConfiguration; import android.os.Binder; import android.os.RemoteException; import android.os.UserManager; import android.provider.Settings; +import android.text.TextUtils; +import com.android.server.wifi.FrameworkFacade; import com.android.server.wifi.WifiInjector; import com.android.server.wifi.WifiLog; import com.android.server.wifi.WifiSettingsStore; @@ -46,6 +52,7 @@ public class WifiPermissionsUtil { private final UserManager mUserManager; private final WifiSettingsStore mSettingsStore; private final NetworkScoreManager mNetworkScoreManager; + private final FrameworkFacade mFrameworkFacade; private WifiLog mLog; public WifiPermissionsUtil(WifiPermissionsWrapper wifiPermissionsWrapper, @@ -58,6 +65,7 @@ public class WifiPermissionsUtil { mSettingsStore = settingsStore; mLog = wifiInjector.makeLog(TAG); mNetworkScoreManager = networkScoreManager; + mFrameworkFacade = wifiInjector.getFrameworkFacade(); } /** @@ -168,10 +176,81 @@ public class WifiPermissionsUtil { } // If the User or profile is current, permission is granted // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. - if (!isCurrentProfile(uid) && !checkInteractAcrossUsersFull(uid)) { + if (!canAccessUserProfile(uid)) { + mLog.tC("Denied: Profile not permitted"); + return false; + } + return true; + } + + /** + * API to determine if the caller has permissions to get a {@link android.net.wifi.WifiInfo} + * instance containing the SSID and BSSID. + * + * + * @param currentConfig the currently connected WiFi config + * @param pkgName package name of the application requesting access + * @param uid The uid of the package + * @param minVersion Minimum app API Version number to enforce location permission + * @return boolean true if the SSID/BSSID can be sent to the user, false if they + * should be hidden/removed. + */ + public boolean canAccessFullConnectionInfo(@Nullable WifiConfiguration currentConfig, + String pkgName, int uid, int minVersion) throws SecurityException { + mAppOps.checkPackage(uid, pkgName); + + // The User or profile must be current or the uid must + // have INTERACT_ACROSS_USERS_FULL permission. + if (!canAccessUserProfile(uid)) { mLog.tC("Denied: Profile not permitted"); return false; } + + // If the caller has scan result access then they can also see the full connection info. + // Otherwise the caller must be the active use open wifi package and the current config + // must be for an open network. + return canAccessScanResults(pkgName, uid, minVersion) + || isUseOpenWifiPackageWithConnectionInfoAccess(currentConfig, pkgName); + + } + + /** + * Returns true if the given WiFi config is for an open network and the package is the active + * use open wifi app. + */ + private boolean isUseOpenWifiPackageWithConnectionInfoAccess( + @Nullable WifiConfiguration currentConfig, String pkgName) { + + // Access is only granted for open networks. + if (currentConfig == null) { + mLog.tC("Denied: WifiConfiguration is NULL."); + return false; + } + + // Access is only granted for open networks. + if (!currentConfig.isOpenNetwork()) { + mLog.tC("Denied: The current config is not for an open network."); + return false; + } + + // The USE_OPEN_WIFI_PACKAGE can access the full connection info details without + // scan result access. + if (!isUseOpenWifiPackage(pkgName)) { + mLog.tC("Denied: caller is not the current USE_OPEN_WIFI_PACKAGE"); + return false; + } + + return true; + } + + /** + * Returns true if the User or profile is current or the + * uid has the INTERACT_ACROSS_USERS_FULL permission. + */ + private boolean canAccessUserProfile(int uid) { + if (!isCurrentProfile(uid) && !checkInteractAcrossUsersFull(uid)) { + return false; + } return true; } @@ -192,6 +271,43 @@ public class WifiPermissionsUtil { } /** + * Returns true if the given package is equal to the setting keyed by + * {@link Settings.Global#USE_OPEN_WIFI_PACKAGE} and the NetworkScoreManager + * has the package name set as the use open wifi package. + */ + private boolean isUseOpenWifiPackage(String packageName) { + if (TextUtils.isEmpty(packageName)) { + return false; + } + + // When the setting is enabled it's set to the package name of the use open wifi app. + final String useOpenWifiPkg = + mFrameworkFacade.getStringSetting(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE); + if (packageName.equals(useOpenWifiPkg)) { + // If the package name matches the setting then also confirm that the scorer is + // active and the package matches the expected use open wifi package from the scorer's + // perspective. The scorer can be active when the use open wifi feature is off so we + // can't rely on this check alone. + // TODO(b/67278755): Refactor this into an API similar to isCallerActiveScorer() + final NetworkScorerAppData appData; + final long token = Binder.clearCallingIdentity(); + try { + appData = mNetworkScoreManager.getActiveScorer(); + } finally { + Binder.restoreCallingIdentity(token); + } + if (appData != null) { + final ComponentName enableUseOpenWifiActivity = + appData.getEnableUseOpenWifiActivity(); + return enableUseOpenWifiActivity != null + && packageName.equals(enableUseOpenWifiActivity.getPackageName()); + } + } + + return false; + } + + /** * Returns true if Wifi scan operation is allowed for this caller * and package. */ diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java index 6420fac88..4fabd9d1e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java @@ -41,6 +41,7 @@ import android.net.wifi.WifiScanner.ScanData; import android.net.wifi.WifiScanner.ScanListener; import android.net.wifi.WifiScanner.ScanSettings; import android.net.wifi.WifiSsid; +import android.os.Process; import android.os.SystemClock; import android.os.WorkSource; import android.os.test.TestLooper; @@ -314,7 +315,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -333,7 +335,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_CONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -353,7 +356,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -373,7 +376,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -400,7 +403,7 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleScreenStateChanged(true); verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -438,7 +441,7 @@ public class WifiConnectivityManagerTest { // Verify that we attempt to connect upto the rate. verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -479,7 +482,7 @@ public class WifiConnectivityManagerTest { // Verify that all the connection attempts went through verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -523,7 +526,7 @@ public class WifiConnectivityManagerTest { // Verify that all the connection attempts went through verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1152,7 +1155,8 @@ public class WifiConnectivityManagerTest { // Verify that WCM receives the scan results and initiates a connection // to the network. - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1174,21 +1178,22 @@ public class WifiConnectivityManagerTest { // Force a connectivity scan which enables WifiConnectivityManager // to wait for full band scan results. - mWifiConnectivityManager.forceConnectivityScan(); + mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); // No roaming because no full band scan results. verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); // Set up as full band scan results. when(mScanData.isAllChannelsScanned()).thenReturn(true); // Force a connectivity scan which enables WifiConnectivityManager // to wait for full band scan results. - mWifiConnectivityManager.forceConnectivityScan(); + mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); // Roaming attempt because full band scan results are available. - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1281,14 +1286,14 @@ public class WifiConnectivityManagerTest { // its blacklist expiration time hasn't reached yet. when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + WifiConnectivityManager.BSSID_BLACKLIST_EXPIRE_TIME_MS / 2); - mWifiConnectivityManager.forceConnectivityScan(); + mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); // Force another connectivity scan at BSSID_BLACKLIST_EXPIRE_TIME_MS from when the // BSSID was blacklisted. Verify that the blacklisted BSSId is freed. when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + WifiConnectivityManager.BSSID_BLACKLIST_EXPIRE_TIME_MS); - mWifiConnectivityManager.forceConnectivityScan(); + mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); // Verify the BSSID is no longer blacklisted. assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); @@ -1441,7 +1446,7 @@ public class WifiConnectivityManagerTest { WifiConnectivityManager.WIFI_STATE_DISCONNECTED); verify(mWifiStateMachine).startConnectToNetwork( - CANDIDATE_NETWORK_ID, WifiStateMachine.SUPPLICANT_BSSID_ANY); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, WifiStateMachine.SUPPLICANT_BSSID_ANY); } /* @@ -1477,7 +1482,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* @@ -1497,7 +1503,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* @@ -1529,7 +1536,8 @@ public class WifiConnectivityManagerTest { mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_DISCONNECTED); - verify(mWifiStateMachine).startConnectToNetwork(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + verify(mWifiStateMachine).startConnectToNetwork( + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /** @@ -1619,7 +1627,7 @@ public class WifiConnectivityManagerTest { WifiConnectivityManager.WIFI_STATE_DISCONNECTED); verify(mWifiStateMachine, times(0)).startConnectToNetwork( - CANDIDATE_NETWORK_ID, CANDIDATE_BSSID); + CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); } /* diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 5b0f59685..69e6070ed 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -47,6 +47,9 @@ import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; import android.net.ConnectivityManager; import android.net.DhcpResults; import android.net.LinkProperties; +import android.net.NetworkCapabilities; +import android.net.NetworkFactory; +import android.net.NetworkRequest; import android.net.dhcp.DhcpClient; import android.net.ip.IpManager; import android.net.wifi.IApInterface; @@ -123,6 +126,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; /** * Unit tests for {@link com.android.server.wifi.WifiStateMachine}. @@ -137,9 +141,11 @@ public class WifiStateMachineTest { (ActivityManager.isLowRamDeviceStatic() ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY : WifiStateMachine.NUM_LOG_RECS_VERBOSE); - private static final int FRAMEWORK_NETWORK_ID = 7; + private static final int FRAMEWORK_NETWORK_ID = 0; private static final int TEST_RSSI = -54; private static final int TEST_NETWORK_ID = 54; + private static final int TEST_VALID_NETWORK_SCORE = 54; + private static final int TEST_OUTSCORED_NETWORK_SCORE = 100; private static final int WPS_SUPPLICANT_NETWORK_ID = 5; private static final int WPS_FRAMEWORK_NETWORK_ID = 10; private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; @@ -230,7 +236,7 @@ public class WifiStateMachineTest { mAlarmManager.getAlarmManager()); when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( - mock(ConnectivityManager.class)); + mConnectivityManager); when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME); @@ -318,6 +324,7 @@ public class WifiStateMachineTest { HandlerThread mP2pThread; HandlerThread mSyncThread; AsyncChannel mWsmAsyncChannel; + AsyncChannel mNetworkFactoryChannel; TestAlarmManager mAlarmManager; MockWifiMonitor mWifiMonitor; TestLooper mLooper; @@ -326,6 +333,7 @@ public class WifiStateMachineTest { FrameworkFacade mFrameworkFacade; IpManager.Callback mIpManagerCallback; PhoneStateListener mPhoneStateListener; + NetworkRequest mDefaultNetworkRequest; final ArgumentCaptor<SoftApManager.Listener> mSoftApManagerListenerCaptor = ArgumentCaptor.forClass(SoftApManager.Listener.class); @@ -361,6 +369,7 @@ public class WifiStateMachineTest { @Mock Clock mClock; @Mock ScanDetailCache mScanDetailCache; @Mock BaseWifiDiagnostics mWifiDiagnostics; + @Mock ConnectivityManager mConnectivityManager; public WifiStateMachineTest() throws Exception { } @@ -449,15 +458,11 @@ public class WifiStateMachineTest { } }).when(mTelephonyManager).listen(any(PhoneStateListener.class), anyInt()); + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); initializeWsm(); } - private void initializeWsm() throws Exception { - mWsm = new WifiStateMachine(mContext, mFrameworkFacade, mLooper.getLooper(), - mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative, - mWrongPasswordNotifier); - mWsmThread = getWsmHandlerThread(mWsm); - + private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger) { final AsyncChannel channel = new AsyncChannel(); Handler handler = new Handler(mLooper.getLooper()) { @Override @@ -465,7 +470,7 @@ public class WifiStateMachineTest { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - mWsmAsyncChannel = channel; + consumer.accept(channel); } else { Log.d(TAG, "Failed to connect Command channel " + this); } @@ -477,15 +482,50 @@ public class WifiStateMachineTest { } }; - channel.connect(mContext, handler, mWsm.getMessenger()); + channel.connect(mContext, handler, messenger); mLooper.dispatchAll(); - /* Now channel is supposed to be connected */ + } + + private void initializeWsm() throws Exception { + mWsm = new WifiStateMachine(mContext, mFrameworkFacade, mLooper.getLooper(), + mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative, + mWrongPasswordNotifier); + mWsmThread = getWsmHandlerThread(mWsm); + + registerAsyncChannel((x) -> { + mWsmAsyncChannel = x; + }, mWsm.getMessenger()); mBinderToken = Binder.clearCallingIdentity(); /* Send the BOOT_COMPLETED message to setup some WSM state. */ mWsm.sendMessage(WifiStateMachine.CMD_BOOT_COMPLETED); mLooper.dispatchAll(); + + /* Simulate the initial NetworkRequest sent in by ConnectivityService. */ + ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class); + verify(mConnectivityManager, atLeast(2)).registerNetworkFactory( + captor.capture(), anyString()); + Messenger networkFactoryMessenger = captor.getAllValues().get(0); + registerAsyncChannel((x) -> { + mNetworkFactoryChannel = x; + }, networkFactoryMessenger); + + mDefaultNetworkRequest = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + sendDefaultNetworkRequest(TEST_VALID_NETWORK_SCORE); + } + + /** + * Helper function to resend the cached network request (id == 0) with the specified score. + * Note: If you need to add a separate network request, don't use the builder to create one + * since the new request object will again default to id == 0. + */ + private void sendDefaultNetworkRequest(int score) { + mNetworkFactoryChannel.sendMessage( + NetworkFactory.CMD_REQUEST_NETWORK, score, 0, mDefaultNetworkRequest); + mLooper.dispatchAll(); } @After @@ -501,6 +541,7 @@ public class WifiStateMachineTest { mSyncThread = null; mWsmAsyncChannel = null; mWsm = null; + mNetworkFactoryChannel = null; } @Test @@ -1043,22 +1084,81 @@ public class WifiStateMachineTest { hiddenNetworkSet); } - @Test - public void connect() throws Exception { - initializeAndAddNetworkAndVerifySuccess(); - when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt())).thenReturn(true); - when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(0), anyInt())).thenReturn(true); + private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception { + when(mWifiConfigManager.enableNetwork(eq(config.networkId), eq(true), anyInt())) + .thenReturn(true); + when(mWifiConfigManager.checkAndUpdateLastConnectUid(eq(config.networkId), anyInt())) + .thenReturn(true); + when(mWifiConfigManager.getConfiguredNetwork(eq(config.networkId))) + .thenReturn(config); + when(mWifiConfigManager.getConfiguredNetworkWithPassword(eq(config.networkId))) + .thenReturn(config); mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); mLooper.dispatchAll(); verify(mWifiNative).removeAllNetworks(); mLooper.startAutoDispatch(); - assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, 0, true)); + assertTrue(mWsm.syncEnableNetwork(mWsmAsyncChannel, config.networkId, true)); mLooper.stopAutoDispatch(); + } - verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); - verify(mWifiConnectivityManager).setUserConnectChoice(eq(0)); + private void validateSuccessfulConnectSequence(WifiConfiguration config) { + verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt()); + verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); + verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); + verify(mWifiConfigManager).getConfiguredNetworkWithPassword(eq(config.networkId)); + verify(mWifiNative).connectToNetwork(eq(config)); + } + + private void validateFailureConnectSequence(WifiConfiguration config) { + verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt()); + verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId)); + verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId)); + verify(mWifiConfigManager, never()).getConfiguredNetworkWithPassword(eq(config.networkId)); + verify(mWifiNative, never()).connectToNetwork(eq(config)); + } + + /** + * Tests the network connection initiation sequence with the default network request pending + * from WifiNetworkFactory. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnect() throws Exception { + loadComponentsInStaMode(); + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID; + setupAndStartConnectSequence(config); + validateSuccessfulConnectSequence(config); + } + + /** + * Tests the network connection initiation sequence with no network request pending from + * from WifiNetworkFactory. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequest() throws Exception { + loadComponentsInStaMode(); + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID; + setupAndStartConnectSequence(config); + validateFailureConnectSequence(config); + } + + /** + * Tests the entire successful network connection flow. + */ + @Test + public void connect() throws Exception { + triggerConnect(); when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) .thenReturn(mScanDetailCache); @@ -1094,6 +1194,54 @@ public class WifiStateMachineTest { assertEquals("ConnectedState", getCurrentState().getName()); } + /** + * Tests the network connection initiation sequence with no network request pending from + * from WifiNetworkFactory when we're already connected to a different network. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequestAndAlreadyConnected() throws Exception { + // Simulate the first connection. + connect(); + + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID + 1; + setupAndStartConnectSequence(config); + validateSuccessfulConnectSequence(config); + verify(mWifiPermissionsUtil, times(2)).checkNetworkSettingsPermission(anyInt()); + } + + /** + * Tests the network connection initiation sequence from a non-privileged app with no network + * request pending from from WifiNetworkFactory when we're already connected to a different + * network. + * This simulates the connect sequence using the public + * {@link WifiManager#enableNetwork(int, boolean)} and ensures that we don't invoke + * {@link WifiNative#connectToNetwork(WifiConfiguration)}. + */ + @Test + public void triggerConnectWithNoNetworkRequestAndAlreadyConnectedButNonPrivilegedApp() + throws Exception { + // Simulate the first connection. + connect(); + + // Change the network score to remove the network request. + sendDefaultNetworkRequest(TEST_OUTSCORED_NETWORK_SCORE); + + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); + + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + config.networkId = FRAMEWORK_NETWORK_ID + 1; + setupAndStartConnectSequence(config); + validateFailureConnectSequence(config); + verify(mWifiPermissionsUtil, times(2)).checkNetworkSettingsPermission(anyInt()); + } + @Test public void connectWithNoEnablePermission() throws Exception { initializeAndAddNetworkAndVerifySuccess(); @@ -2127,8 +2275,8 @@ public class WifiStateMachineTest { assertEquals(sBSSID, wifiInfo.getBSSID()); assertEquals(sWifiSsid, wifiInfo.getWifiSsid()); - when(mWifiPermissionsUtil.canAccessScanResults(anyString(), eq(fakeUid), anyInt())) - .thenReturn(false); + when(mWifiPermissionsUtil.canAccessFullConnectionInfo(any(), anyString(), eq(fakeUid), + anyInt())).thenReturn(false); WifiInfo connectionInfo = mWsm.syncRequestConnectionInfo(mContext.getOpPackageName()); @@ -2160,8 +2308,8 @@ public class WifiStateMachineTest { assertEquals(sBSSID, wifiInfo.getBSSID()); assertEquals(sWifiSsid, wifiInfo.getWifiSsid()); - when(mWifiPermissionsUtil.canAccessScanResults(anyString(), eq(fakeUid), anyInt())) - .thenThrow(new SecurityException()); + when(mWifiPermissionsUtil.canAccessFullConnectionInfo(any(), anyString(), eq(fakeUid), + anyInt())).thenThrow(new SecurityException()); WifiInfo connectionInfo = mWsm.syncRequestConnectionInfo(mContext.getOpPackageName()); @@ -2190,8 +2338,8 @@ public class WifiStateMachineTest { assertEquals(sBSSID, wifiInfo.getBSSID()); assertEquals(sWifiSsid, wifiInfo.getWifiSsid()); - when(mWifiPermissionsUtil.canAccessScanResults(anyString(), eq(fakeUid), anyInt())) - .thenReturn(true); + when(mWifiPermissionsUtil.canAccessFullConnectionInfo(any(), anyString(), eq(fakeUid), + anyInt())).thenReturn(true); WifiInfo connectionInfo = mWsm.syncRequestConnectionInfo(mContext.getOpPackageName()); @@ -2206,6 +2354,35 @@ public class WifiStateMachineTest { } /** + * Test that reconnectCommand() triggers connectivity scan when WifiStateMachine + * is in DisconnectedMode. + */ + @Test + public void testReconnectCommandWhenDisconnected() throws Exception { + // Connect to network with |sBSSID|, |sFreq|, and then disconnect. + disconnect(); + + mWsm.reconnectCommand(WifiStateMachine.WIFI_WORK_SOURCE); + mLooper.dispatchAll(); + verify(mWifiConnectivityManager).forceConnectivityScan(WifiStateMachine.WIFI_WORK_SOURCE); + } + + /** + * Test that reconnectCommand() doesn't trigger connectivity scan when WifiStateMachine + * is in ConnectedMode. + */ + @Test + public void testReconnectCommandWhenConnected() throws Exception { + // Connect to network with |sBSSID|, |sFreq|. + connect(); + + mWsm.reconnectCommand(WifiStateMachine.WIFI_WORK_SOURCE); + mLooper.dispatchAll(); + verify(mWifiConnectivityManager, never()) + .forceConnectivityScan(WifiStateMachine.WIFI_WORK_SOURCE); + } + + /** * Adds the network without putting WifiStateMachine into ConnectMode. */ @Test diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java index ed7c58298..d337cf1cf 100644 --- a/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java @@ -32,6 +32,7 @@ import com.android.server.wifi.ScanDetail; import com.android.server.wifi.ScanResults; import com.android.server.wifi.WifiMonitor; import com.android.server.wifi.WifiNative; +import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; import org.junit.Before; import org.junit.Test; @@ -56,6 +57,39 @@ public class WificondScannerTest extends BaseWifiScannerImplTest { mLooper.getLooper(), mClock); } + /** + * Test that WificondScannerImpl will not issue a scan and report scan failure + * when there is no channel to scan for. + */ + @Test + public void singleScanNotIssuedIfNoAvailableChannels() { + // Use mocked ChannelHelper and ChannelCollection to simulate the scenario + // that no channel is available for this request. + ChannelHelper channelHelper = mock(ChannelHelper.class); + ChannelCollection channelCollection = mock(ChannelCollection.class); + when(channelHelper.createChannelCollection()).thenReturn(channelCollection); + when(channelCollection.isEmpty()).thenReturn(true); + + mScanner = new WificondScannerImpl(mContext, mWifiNative, mWifiMonitor, + channelHelper, mLooper.getLooper(), mClock); + + WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() + .withBasePeriod(10000) // ms + .withMaxApPerScan(10) + .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, + WifiScanner.WIFI_BAND_5_GHZ) + .build(); + WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class); + mScanner.startSingleScan(settings, eventHandler); + + mLooper.dispatchAll(); + + // No scan is issued to WifiNative. + verify(mWifiNative, never()).scan(any(), any(Set.class)); + // A scan failed event must be reported. + verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED); + } + @Test public void backgroundScanSuccessSingleBucket() { WifiNative.ScanSettings settings = new NativeScanSettingsBuilder() diff --git a/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java index 308e26776..7f5a66d0e 100644 --- a/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java @@ -19,6 +19,7 @@ package com.android.server.wifi.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; @@ -27,12 +28,15 @@ import static org.mockito.Mockito.when; import android.Manifest; import android.app.AppOpsManager; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.net.NetworkScoreManager; +import android.net.NetworkScorerAppData; +import android.net.wifi.WifiConfiguration; import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; @@ -41,6 +45,7 @@ import android.provider.Settings; import com.android.server.wifi.BinderUtil; import com.android.server.wifi.FakeWifiLog; +import com.android.server.wifi.FrameworkFacade; import com.android.server.wifi.WifiInjector; import com.android.server.wifi.WifiSettingsStore; @@ -72,8 +77,10 @@ public class WifiPermissionsUtilTest { @Mock private UserManager mMockUserManager; @Mock private WifiSettingsStore mMockWifiSettingsStore; @Mock private ContentResolver mMockContentResolver; - @Mock private NetworkScoreManager mNetworkScoreManager; - @Mock private WifiInjector mWifiInjector; + @Mock private NetworkScoreManager mMockNetworkScoreManager; + @Mock private WifiInjector mMockWifiInjector; + @Mock private FrameworkFacade mMockFrameworkFacade; + @Mock private WifiConfiguration mMockWifiConfig; @Spy private FakeWifiLog mWifiLog; private static final String TEST_PACKAGE_NAME = "com.google.somePackage"; @@ -101,6 +108,10 @@ public class WifiPermissionsUtilTest { private boolean mActiveNwScorer; private Answer<Integer> mReturnPermission; private HashMap<String, Integer> mPermissionsList = new HashMap<String, Integer>(); + private String mUseOpenWifiPackage; + private NetworkScorerAppData mNetworkScorerAppData; + private boolean mGetActiveScorerThrowsSecurityException; + private boolean mConfigIsOpen; /** * Set up Mockito tests @@ -124,8 +135,8 @@ public class WifiPermissionsUtilTest { mUid = MANAGED_PROFILE_UID; // do not really care about this value setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); when(mMockPermissionsWrapper.getOverrideWifiConfigPermission(anyInt())) .thenReturn(PackageManager.PERMISSION_GRANTED); assertTrue(codeUnderTest.checkConfigOverridePermission(mUid)); @@ -139,8 +150,8 @@ public class WifiPermissionsUtilTest { mUid = OTHER_USER_UID; // do not really care about this value setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); when(mMockPermissionsWrapper.getOverrideWifiConfigPermission(anyInt())) .thenReturn(PackageManager.PERMISSION_DENIED); assertFalse(codeUnderTest.checkConfigOverridePermission(mUid)); @@ -154,8 +165,8 @@ public class WifiPermissionsUtilTest { mUid = OTHER_USER_UID; // do not really care about this value setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); doThrow(new RemoteException("Failed to check permissions for " + mUid)) .when(mMockPermissionsWrapper).getOverrideWifiConfigPermission(mUid); assertFalse(codeUnderTest.checkConfigOverridePermission(mUid)); @@ -179,8 +190,8 @@ public class WifiPermissionsUtilTest { mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -207,8 +218,8 @@ public class WifiPermissionsUtilTest { mMockUserInfo.id = mCallingUser; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -230,8 +241,8 @@ public class WifiPermissionsUtilTest { mPermissionsList.put(mMacAddressPermission, mUid); setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -259,8 +270,8 @@ public class WifiPermissionsUtilTest { mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -286,8 +297,8 @@ public class WifiPermissionsUtilTest { mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -312,8 +323,8 @@ public class WifiPermissionsUtilTest { mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -323,6 +334,354 @@ public class WifiPermissionsUtilTest { } /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is for an open network. + * Validate result is true + */ + @Test + public void testCanAccessFullConnectionInfo_PackageIsUseOpenWifiPackage() throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + ComponentName useOpenWifiComponent = new ComponentName(TEST_PACKAGE_NAME, "TestClass"); + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + useOpenWifiComponent, null /*networkAvailableNotificationChannelId*/); + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(true, output); + } + + /** + * Test case setting: Package is valid because the caller has access to scan results. + * Location mode is ON + * User is current + * The current config is not for an open network. + * Validate result is true + */ + @Test + public void testCanAccessFullConnectionInfo_HasAccessToScanResults() throws Exception { + final boolean output; + mThrowSecurityException = false; + mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.GINGERBREAD; + mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; + mCoarseLocationPermission = PackageManager.PERMISSION_GRANTED; + mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED; + mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mConfigIsOpen = false; + + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(true, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User or profile is not current but the uid has + * permission to INTERACT_ACROSS_USERS_FULL + * The current config is for an open network. + * Validate result is true + */ + @Test + public void testCanAccessFullConnectionInfo_UserNotCurrentButHasInteractAcrossUsers() + throws Exception { + final boolean output; + mThrowSecurityException = false; + mUid = MANAGED_PROFILE_UID; + mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid); + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + ComponentName useOpenWifiComponent = new ComponentName(TEST_PACKAGE_NAME, "TestClass"); + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + useOpenWifiComponent, null /*networkAvailableNotificationChannelId*/); + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(true, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User or profile is NOT current + * INTERACT_ACROSS_USERS_FULL NOT granted + * The current config is for an open network. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_UserNotCurrentNoInteractAcrossUsers() + throws Exception { + final boolean output; + mThrowSecurityException = false; + mUid = MANAGED_PROFILE_UID; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is NULL. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_WiFiConfigIsNull() throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + ComponentName useOpenWifiComponent = new ComponentName(TEST_PACKAGE_NAME, "TestClass"); + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + useOpenWifiComponent, null /*networkAvailableNotificationChannelId*/); + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(null /*config*/, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is not for an open network. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_WiFiConfigIsNotOpen() throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + ComponentName useOpenWifiComponent = new ComponentName(TEST_PACKAGE_NAME, "TestClass"); + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + useOpenWifiComponent, null /*networkAvailableNotificationChannelId*/); + mConfigIsOpen = false; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is for an open network. + * There is no active scorer + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_UseOpenWifiPackageIsSetButNoActiveScorer() + throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + mNetworkScorerAppData = null; // getActiveScorer() will return null + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is for an open network. + * The scorer is active but the useOpenWiFi component name doesn't match + * the provided package. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_MismatchBetweenUseOpenWifiPackages() + throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + ComponentName useOpenWifiComponent = + new ComponentName(mUseOpenWifiPackage + ".nomatch", "TestClass"); + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + useOpenWifiComponent, null /*networkAvailableNotificationChannelId*/); + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is valid because it matches the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is for an open network. + * The scorer is active but the useOpenWiFi component name is null. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_UseOpenWifiPackageFromScorerIsNull() + throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + mNetworkScorerAppData = new NetworkScorerAppData(0 /*packageUid*/, + null /*recommendationServiceComp*/, null /*recommendationServiceLabel*/, + null /*useOpenWifiComponent*/, null /*networkAvailableNotificationChannelId*/); + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is invalid because USE_OPEN_WIFI_PACKAGE is an empty string. + * Location mode is ON + * User is current + * The current config is for an open network. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_UseOpenWifiPackageIsEmpty() throws Exception { + final boolean output; + mThrowSecurityException = false; + mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = ""; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: Package is invalid because it does not match the USE_OPEN_WIFI_PACKAGE. + * User is current + * The current config is for an open network. + * Validate result is false + */ + @Test + public void testCanAccessFullConnectionInfo_DoesNotMatchUseOpenWifiPackage() throws Exception { + final boolean output; + mThrowSecurityException = false; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME + ".nomatch"; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + output = codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, + mUid, mTargetVersion); + + assertEquals(false, output); + } + + /** + * Test case setting: The caller is invalid because its UID does not match the provided package. + * + * Validate a SecurityException is thrown. + */ + @Test + public void testCanAccessFullConnectionInfo_UidPackageCheckFails() throws Exception { + mThrowSecurityException = true; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + try { + codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, mUid, + mTargetVersion); + fail("SecurityException not thrown."); + } catch (SecurityException e) { + // expected + } + } + + /** + * Test case setting: The getActiveScorer() call fails with a SecurityException. + * + * Validate a SecurityException is thrown. + */ + @Test + public void testCanAccessFullConnectionInfo_GetActiveScorerFails() throws Exception { + mThrowSecurityException = false; + mGetActiveScorerThrowsSecurityException = true; + mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; + mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; + mUseOpenWifiPackage = TEST_PACKAGE_NAME; + setupTestCase(); + WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); + + try { + codeUnderTest.canAccessFullConnectionInfo(mMockWifiConfig, TEST_PACKAGE_NAME, mUid, + mTargetVersion); + fail("SecurityException not thrown."); + } catch (SecurityException e) { + // expected + } + } + + /** * Test case Setting: Package is valid * Legacy App * Foreground @@ -341,8 +700,8 @@ public class WifiPermissionsUtilTest { mCurrentUser = UserHandle.USER_CURRENT_OR_SELF; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -373,8 +732,8 @@ public class WifiPermissionsUtilTest { mMockUserInfo.id = mCallingUser; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -400,8 +759,8 @@ public class WifiPermissionsUtilTest { mLocationModeSetting = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -419,8 +778,8 @@ public class WifiPermissionsUtilTest { boolean output = false; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); try { output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid, mTargetVersion); } catch (SecurityException e) { @@ -444,8 +803,8 @@ public class WifiPermissionsUtilTest { mMockUserInfo.id = mCallingUser; setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid); } @@ -457,8 +816,8 @@ public class WifiPermissionsUtilTest { public void testEnforceLocationPermissionExpectSecurityException() throws Exception { setupTestCase(); WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper, - mMockContext, mMockWifiSettingsStore, mMockUserManager, mNetworkScoreManager, - mWifiInjector); + mMockContext, mMockWifiSettingsStore, mMockUserManager, mMockNetworkScoreManager, + mMockWifiInjector); codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid); } @@ -500,7 +859,15 @@ public class WifiPermissionsUtilTest { when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); when(mMockContext.getSystemService(Context.USER_SERVICE)) .thenReturn(mMockUserManager); - when(mWifiInjector.makeLog(anyString())).thenReturn(mWifiLog); + when(mMockWifiInjector.makeLog(anyString())).thenReturn(mWifiLog); + when(mMockWifiInjector.getFrameworkFacade()).thenReturn(mMockFrameworkFacade); + if (mGetActiveScorerThrowsSecurityException) { + when(mMockNetworkScoreManager.getActiveScorer()).thenThrow( + new SecurityException("Caller is neither the system process nor a " + + "score requester.")); + } else { + when(mMockNetworkScoreManager.getActiveScorer()).thenReturn(mNetworkScorerAppData); + } } private void initTestVars() { @@ -518,6 +885,10 @@ public class WifiPermissionsUtilTest { mCoarseLocationPermission = PackageManager.PERMISSION_DENIED; mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED; mActiveNwScorer = false; + mUseOpenWifiPackage = null; + mNetworkScorerAppData = null; + mGetActiveScorerThrowsSecurityException = false; + mConfigIsOpen = true; } private void setupMockInterface() { @@ -528,11 +899,14 @@ public class WifiPermissionsUtilTest { anyString(), anyInt()); when(mMockPermissionsWrapper.getCallingUserId(mUid)).thenReturn(mCallingUser); when(mMockPermissionsWrapper.getCurrentUser()).thenReturn(mCurrentUser); - when(mNetworkScoreManager.isCallerActiveScorer(mUid)).thenReturn(mActiveNwScorer); + when(mMockNetworkScoreManager.isCallerActiveScorer(mUid)).thenReturn(mActiveNwScorer); when(mMockPermissionsWrapper.getUidPermission(mManifestStringCoarse, mUid)) .thenReturn(mCoarseLocationPermission); when(mMockWifiSettingsStore.getLocationModeSetting(mMockContext)) .thenReturn(mLocationModeSetting); when(mMockPermissionsWrapper.getTopPkgName()).thenReturn(mPkgNameOfTopActivity); + when(mMockFrameworkFacade.getStringSetting(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(mUseOpenWifiPackage); + when(mMockWifiConfig.isOpenNetwork()).thenReturn(mConfigIsOpen); } } |