Merge "[WifiTrackerLib] Ignore broadcast passpoint wificonfig in Saved Networks" into rvc-dev
diff --git a/service/Android.bp b/service/Android.bp
index 75dff32..d7c16df 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -62,7 +62,7 @@
// need pre-jarjar symbols so that wifi-service can reference the original class names at
// compile time
"framework-wifi-pre-jarjar",
- "framework-statsd-stubs-module_libs_api",
+ "framework-statsd.stubs.module_lib",
"unsupportedappusage",
],
@@ -105,7 +105,7 @@
// need to include `libs` so that Soong doesn't complain about missing classes after jarjaring
libs: [
- "framework-wifi",
+ "framework-wifi.impl",
],
sdk_version: "system_server_current",
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index e36d379..5b616dd 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -368,7 +368,7 @@
private String mTargetBssid = SUPPLICANT_BSSID_ANY;
// This one is used to track the current target network ID. This is used for error
// handling during connection setup since many error message from supplicant does not report
- // SSID Once connected, it will be set to invalid
+ // SSID. Once connected, it will be set to invalid
private int mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
private long mLastDriverRoamAttempt = 0;
private WifiConfiguration mTargetWifiConfiguration = null;
@@ -1211,8 +1211,8 @@
private void connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid
+ ", forceReconnect = " + forceReconnect);
- if (!forceReconnect && mWifiInfo.getNetworkId() == netId) {
- // We're already connected to the user specified network, don't trigger a
+ if (!forceReconnect && (mLastNetworkId == netId || mTargetNetworkId == netId)) {
+ // We're already connecting/connected to the user specified network, don't trigger a
// reconnection unless it was forced.
logi("connectToUserSelectNetwork already connecting/connected=" + netId);
} else {
@@ -2965,6 +2965,20 @@
}
}
+ if (configuration != null
+ && configuration.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ if (level2FailureCode == WifiMetrics.ConnectionEvent.FAILURE_NONE) {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionSuccess();
+ } else if (level2FailureCode
+ == WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE
+ && level2FailureReason
+ != WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE) {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionAuthFailure();
+ } else {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionNonAuthFailure();
+ }
+ }
+
boolean isAssociationRejection = level2FailureCode
== WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION;
boolean isAuthenticationFailure = level2FailureCode
@@ -2983,6 +2997,10 @@
mNetworkFactory.handleConnectionAttemptEnded(level2FailureCode, configuration);
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
level2FailureCode, configuration, getCurrentBSSID());
+ ScanResult candidate = configuration.getNetworkSelectionStatus().getCandidate();
+ if (candidate != null && !TextUtils.equals(candidate.BSSID, getCurrentBSSID())) {
+ mWifiMetrics.incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
+ }
}
handleConnectionAttemptEndForDiagnostics(level2FailureCode);
}
@@ -4146,7 +4164,13 @@
// We switched from DHCP to static or from static to DHCP, or the
// static IP address has changed.
log("Reconfiguring IP on connection");
- transitionTo(mObtainingIpState);
+ WifiConfiguration currentConfig = getCurrentWifiConfiguration();
+ if (currentConfig != null) {
+ transitionTo(mObtainingIpState);
+ } else {
+ Log.w(TAG, "CMD_SAVE_NETWORK Ip change - but no current "
+ + "Wi-Fi config");
+ }
}
}
} else if (mWifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 66495ae..61df519 100644
--- a/service/java/com/android/server/wifi/ClientModeManager.java
+++ b/service/java/com/android/server/wifi/ClientModeManager.java
@@ -19,6 +19,11 @@
import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -28,6 +33,7 @@
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsException;
@@ -45,9 +51,11 @@
import com.android.internal.util.StateMachine;
import com.android.server.wifi.WifiNative.InterfaceCallback;
import com.android.server.wifi.util.WifiHandler;
+import com.android.wifi.resources.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.List;
/**
* Manager WiFi in Client Mode where we connect to configured networks.
@@ -71,6 +79,7 @@
private @Role int mRole = ROLE_UNSPECIFIED;
private DeferStopHandler mDeferStopHandler;
private int mTargetRole = ROLE_UNSPECIFIED;
+ private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
ClientModeManager(Context context, @NonNull Looper looper, Clock clock, WifiNative wifiNative,
Listener listener, WifiMetrics wifiMetrics, SarManager sarManager,
@@ -120,6 +129,8 @@
private final Runnable mRunnable = () -> continueToStopWifi();
private int mMaximumDeferringTimeMillis = 0;
private long mDeferringStartTimeMillis = 0;
+ private NetworkRequest mImsRequest = null;
+ private ConnectivityManager mConnectivityManager = null;
private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
new RegistrationManager.RegistrationCallback() {
@@ -136,10 +147,40 @@
@Override
public void onUnregistered(ImsReasonInfo imsReasonInfo) {
Log.d(TAG, "on IMS unregistered");
- if (mIsDeferring) continueToStopWifi();
+ // Wait for onLost in NetworkCallback
}
};
+ private NetworkCallback mImsNetworkCallback = new NetworkCallback() {
+ private int mRegisteredImsNetworkCount = 0;
+ @Override
+ public void onAvailable(Network network) {
+ synchronized (this) {
+ Log.d(TAG, "IMS network available: " + network);
+ mRegisteredImsNetworkCount++;
+ }
+ }
+
+ @Override
+ public void onLost(Network network) {
+ synchronized (this) {
+ Log.d(TAG, "IMS network lost: " + network
+ + " ,isDeferring: " + mIsDeferring
+ + " ,registered IMS network count: " + mRegisteredImsNetworkCount);
+ mRegisteredImsNetworkCount--;
+ if (mIsDeferring && mRegisteredImsNetworkCount <= 0) {
+ mRegisteredImsNetworkCount = 0;
+ // Add delay for targets where IMS PDN down at modem takes additional delay.
+ int delay = mContext.getResources()
+ .getInteger(R.integer.config_wifiDelayDisconnectOnImsLostMs);
+ if (delay == 0 || !postDelayed(mRunnable, delay)) {
+ continueToStopWifi();
+ }
+ }
+ }
+ }
+ };
+
DeferStopHandler(String tag, Looper looper) {
super(tag, looper);
mLooper = looper;
@@ -156,8 +197,7 @@
return;
}
- mImsMmTelManager = ImsMmTelManager.createForSubscriptionId(
- SubscriptionManager.getDefaultVoiceSubscriptionId());
+ mImsMmTelManager = ImsMmTelManager.createForSubscriptionId(mActiveSubId);
if (mImsMmTelManager == null || !postDelayed(mRunnable, delayMs)) {
// if no delay or failed to add runnable, stop Wifi immediately.
continueToStopWifi();
@@ -166,7 +206,7 @@
mIsDeferring = true;
Log.d(TAG, "Start DeferWifiOff handler with deferring time "
- + delayMs + " ms.");
+ + delayMs + " ms for subId: " + mActiveSubId);
try {
mImsMmTelManager.registerImsRegistrationCallback(
new HandlerExecutor(new Handler(mLooper)),
@@ -174,7 +214,19 @@
} catch (RuntimeException | ImsException e) {
Log.e(TAG, "registerImsRegistrationCallback failed", e);
continueToStopWifi();
+ return;
}
+
+ mImsRequest = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .build();
+
+ mConnectivityManager =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ mConnectivityManager.registerNetworkCallback(mImsRequest, mImsNetworkCallback,
+ new Handler(mLooper));
}
private void continueToStopWifi() {
@@ -212,6 +264,11 @@
Log.e(TAG, "unregisterImsRegistrationCallback failed", e);
}
}
+
+ if (mConnectivityManager != null) {
+ mConnectivityManager.unregisterNetworkCallback(mImsNetworkCallback);
+ }
+
mIsDeferring = false;
}
}
@@ -220,13 +277,35 @@
* Get deferring time before turning off WiFi.
*/
private int getWifiOffDeferringTimeMs() {
- int defaultVoiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
- if (defaultVoiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ SubscriptionManager subscriptionManager = (SubscriptionManager) mContext.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ if (subscriptionManager == null) {
return 0;
}
- ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(
- defaultVoiceSubId);
+ List<SubscriptionInfo> subInfoList = subscriptionManager.getActiveSubscriptionInfoList();
+ if (subInfoList == null) {
+ return 0;
+ }
+
+ // Get the maximum delay for the active subscription latched on IWLAN.
+ int maxDelay = 0;
+ for (SubscriptionInfo subInfo : subInfoList) {
+ int curDelay = getWifiOffDeferringTimeMs(subInfo.getSubscriptionId());
+ if (curDelay > maxDelay) {
+ maxDelay = curDelay;
+ mActiveSubId = subInfo.getSubscriptionId();
+ }
+ }
+ return maxDelay;
+ }
+
+ private int getWifiOffDeferringTimeMs(int subId) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return 0;
+ }
+
+ ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
// If no wifi calling, no delay
if (!imsMmTelManager.isAvailable(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
@@ -236,7 +315,7 @@
TelephonyManager defaultVoiceTelephonyManager =
mContext.getSystemService(TelephonyManager.class)
- .createForSubscriptionId(defaultVoiceSubId);
+ .createForSubscriptionId(subId);
// if LTE is available, no delay needed as IMS will be registered over LTE
if (defaultVoiceTelephonyManager.getVoiceNetworkType()
== TelephonyManager.NETWORK_TYPE_LTE) {
@@ -245,7 +324,7 @@
CarrierConfigManager configManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle config = configManager.getConfigForSubId(defaultVoiceSubId);
+ PersistableBundle config = configManager.getConfigForSubId(subId);
return (config != null)
? config.getInt(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT)
: 0;
diff --git a/service/java/com/android/server/wifi/ConfigurationMap.java b/service/java/com/android/server/wifi/ConfigurationMap.java
index 1f21891..cce8958 100644
--- a/service/java/com/android/server/wifi/ConfigurationMap.java
+++ b/service/java/com/android/server/wifi/ConfigurationMap.java
@@ -21,6 +21,8 @@
import android.os.UserHandle;
import android.os.UserManager;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -41,6 +43,15 @@
mUserManager = userManager;
}
+ /** Dump internal state for debugging. */
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("mPerId=" + mPerID);
+ pw.println("mPerIDForCurrentUser=" + mPerIDForCurrentUser);
+ pw.println("mScanResultMatchInfoMapForCurrentUser="
+ + mScanResultMatchInfoMapForCurrentUser);
+ pw.println("mCurrentUserId=" + mCurrentUserId);
+ }
+
// RW methods:
public WifiConfiguration put(WifiConfiguration config) {
final WifiConfiguration current = mPerID.put(config.networkId, config);
@@ -49,8 +60,12 @@
if (config.shared || currentUser.equals(creatorUser)
|| mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
mPerIDForCurrentUser.put(config.networkId, config);
- mScanResultMatchInfoMapForCurrentUser.put(
- ScanResultMatchInfo.fromWifiConfiguration(config), config);
+ // TODO (b/142035508): Add a more generic fix. This cache should only hold saved
+ // networks.
+ if (!config.fromWifiNetworkSpecifier) {
+ mScanResultMatchInfoMapForCurrentUser.put(
+ ScanResultMatchInfo.fromWifiConfiguration(config), config);
+ }
}
return current;
}
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java
index d25a50a..cfd2ad0 100644
--- a/service/java/com/android/server/wifi/DeviceConfigFacade.java
+++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java
@@ -53,10 +53,14 @@
public static final int DEFAULT_DATA_STALL_TX_PER_THR = 90;
// Default threshold of CCA level above which to trigger a data stall
public static final int DEFAULT_DATA_STALL_CCA_LEVEL_THR = CHANNEL_UTILIZATION_SCALE;
- // Default low threshold of L2 sufficient throughput in Kbps
- public static final int DEFAULT_TPUT_SUFFICIENT_THR_LOW_KBPS = 1000;
- // Default high threshold of L2 sufficient throughput in Kbps
- public static final int DEFAULT_TPUT_SUFFICIENT_THR_HIGH_KBPS = 4000;
+ // Default low threshold of L2 sufficient Tx throughput in Kbps
+ public static final int DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS = 1000;
+ // Default high threshold of L2 sufficient Tx throughput in Kbps
+ public static final int DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS = 4000;
+ // Default low threshold of L2 sufficient Rx throughput in Kbps
+ public static final int DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS = 1000;
+ // Default high threshold of L2 sufficient Rx throughput in Kbps
+ public static final int DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS = 4000;
// Numerator part of default threshold of L2 throughput over L3 throughput ratio
public static final int DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM = 2;
// Denominator part of default threshold of L2 throughput over L3 throughput ratio
@@ -97,6 +101,12 @@
static final int DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO = 2;
// Default overlapping connection duration threshold in ms to trigger bug report
static final int DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS = 75_000;
+ // At low traffic, Tx link speed values below the following threshold
+ // are ignored because it could be due to low rate management frames
+ static final int DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS = 9;
+ // At low traffic, Rx link speed values below the following threshold
+ // are ignored because it could be due to low rate management frames
+ static final int DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS = 9;
// Cached values of fields updated via updateDeviceConfigFlags()
private boolean mIsAbnormalConnectionBugreportEnabled;
@@ -106,8 +116,10 @@
private int mDataStallRxTputThrKbps;
private int mDataStallTxPerThr;
private int mDataStallCcaLevelThr;
- private int mTputSufficientLowThrKbps;
- private int mTputSufficientHighThrKbps;
+ private int mTxTputSufficientLowThrKbps;
+ private int mTxTputSufficientHighThrKbps;
+ private int mRxTputSufficientLowThrKbps;
+ private int mRxTputSufficientHighThrKbps;
private int mTputSufficientRatioThrNum;
private int mTputSufficientRatioThrDen;
private int mTxPktPerSecondThr;
@@ -136,6 +148,8 @@
private int mBugReportThresholdExtraRatio;
private boolean mIsOverlappingConnectionBugreportEnabled;
private int mOverlappingConnectionDurationThresholdMs;
+ private int mTxLinkSpeedLowThresholdMbps;
+ private int mRxLinkSpeedLowThresholdMbps;
public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) {
mContext = context;
@@ -173,10 +187,14 @@
mWifiMetrics.setDataStallTxPerThr(mDataStallTxPerThr);
mWifiMetrics.setDataStallCcaLevelThr(mDataStallCcaLevelThr);
- mTputSufficientLowThrKbps = DeviceConfig.getInt(NAMESPACE,
- "tput_sufficient_low_thr_kbps", DEFAULT_TPUT_SUFFICIENT_THR_LOW_KBPS);
- mTputSufficientHighThrKbps = DeviceConfig.getInt(NAMESPACE,
- "tput_sufficient_high_thr_kbps", DEFAULT_TPUT_SUFFICIENT_THR_HIGH_KBPS);
+ mTxTputSufficientLowThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "tput_sufficient_low_thr_kbps", DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS);
+ mTxTputSufficientHighThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "tput_sufficient_high_thr_kbps", DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
+ mRxTputSufficientLowThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "rx_tput_sufficient_low_thr_kbps", DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS);
+ mRxTputSufficientHighThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "rx_tput_sufficient_high_thr_kbps", DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
mTputSufficientRatioThrNum = DeviceConfig.getInt(NAMESPACE,
"tput_sufficient_ratio_thr_num", DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM);
mTputSufficientRatioThrDen = DeviceConfig.getInt(NAMESPACE,
@@ -254,6 +272,12 @@
mOverlappingConnectionDurationThresholdMs = DeviceConfig.getInt(NAMESPACE,
"overlapping_connection_duration_threshold_ms",
DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS);
+ mTxLinkSpeedLowThresholdMbps = DeviceConfig.getInt(NAMESPACE,
+ "tx_link_speed_low_threshold_mbps",
+ DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS);
+ mRxLinkSpeedLowThresholdMbps = DeviceConfig.getInt(NAMESPACE,
+ "rx_link_speed_low_threshold_mbps",
+ DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS);
}
private Set<String> getUnmodifiableSetQuoted(String key) {
@@ -321,15 +345,29 @@
/**
* Gets the low threshold of L2 throughput below which L2 throughput is always insufficient
*/
- public int getTputSufficientLowThrKbps() {
- return mTputSufficientLowThrKbps;
+ public int getTxTputSufficientLowThrKbps() {
+ return mTxTputSufficientLowThrKbps;
}
/**
* Gets the high threshold of L2 throughput above which L2 throughput is always sufficient
*/
- public int getTputSufficientHighThrKbps() {
- return mTputSufficientHighThrKbps;
+ public int getTxTputSufficientHighThrKbps() {
+ return mTxTputSufficientHighThrKbps;
+ }
+
+ /**
+ * Gets the low threshold of L2 throughput below which L2 Rx throughput is always insufficient
+ */
+ public int getRxTputSufficientLowThrKbps() {
+ return mRxTputSufficientLowThrKbps;
+ }
+
+ /**
+ * Gets the high threshold of L2 throughput above which L2 Rx throughput is always sufficient
+ */
+ public int getRxTputSufficientHighThrKbps() {
+ return mRxTputSufficientHighThrKbps;
}
/**
@@ -531,4 +569,18 @@
public int getOverlappingConnectionDurationThresholdMs() {
return mOverlappingConnectionDurationThresholdMs;
}
+
+ /**
+ * Gets the threshold of link speed below which Tx link speed is ignored at low traffic
+ */
+ public int getTxLinkSpeedLowThresholdMbps() {
+ return mTxLinkSpeedLowThresholdMbps;
+ }
+
+ /**
+ * Gets the threshold of link speed below which Rx link speed is ignored at low traffic
+ */
+ public int getRxLinkSpeedLowThresholdMbps() {
+ return mRxLinkSpeedLowThresholdMbps;
+ }
}
diff --git a/service/java/com/android/server/wifi/MemoryStoreImpl.java b/service/java/com/android/server/wifi/MemoryStoreImpl.java
index 1b819d4..a15ae81 100644
--- a/service/java/com/android/server/wifi/MemoryStoreImpl.java
+++ b/service/java/com/android/server/wifi/MemoryStoreImpl.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.net.IpMemoryStore;
import android.net.ipmemorystore.Blob;
+import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.Status;
import android.util.Log;
@@ -127,6 +128,35 @@
}
}
+ @Override
+ public void setCluster(String key, String cluster) {
+ if (mBroken) return;
+ try {
+ NetworkAttributes attributes = new NetworkAttributes.Builder()
+ .setCluster(cluster)
+ .build();
+ mIpMemoryStore.storeNetworkAttributes(key, attributes, status -> {
+ Log.d(TAG, "Set cluster " + cluster + " for " + key + ": " + status);
+ });
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ }
+
+ @Override
+ public void removeCluster(String cluster) {
+ if (mBroken) return;
+ try {
+ final boolean needWipe = true;
+ mIpMemoryStore.deleteCluster(cluster, needWipe, (status, deletedRecords) -> {
+ Log.d(TAG, "Remove cluster " + cluster + ": " + status
+ + " deleted: " + deletedRecords);
+ });
+ } catch (RuntimeException e) {
+ handleException(e);
+ }
+ }
+
/**
* Starts using IpMemoryStore.
*/
diff --git a/service/java/com/android/server/wifi/WakeupController.java b/service/java/com/android/server/wifi/WakeupController.java
index b003b74..a92bdf7 100644
--- a/service/java/com/android/server/wifi/WakeupController.java
+++ b/service/java/com/android/server/wifi/WakeupController.java
@@ -240,6 +240,10 @@
*/
public void start() {
Log.d(TAG, "start()");
+ if (getGoodSavedNetworksAndSuggestions().isEmpty()) {
+ Log.i(TAG, "Ignore wakeup start since there are no good networks.");
+ return;
+ }
mWifiInjector.getWifiScanner().registerScanListener(
new HandlerExecutor(mHandler), mScanListener);
@@ -343,7 +347,7 @@
}
Set<WifiNetworkSuggestion> networkSuggestions =
- mWifiNetworkSuggestionsManager.getAllNetworkSuggestions();
+ mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions();
for (WifiNetworkSuggestion suggestion : networkSuggestions) {
// TODO(b/127799111): Do we need to filter the list similar to saved networks above?
goodNetworks.add(
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index c55236e..ab46bb6 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -466,6 +466,8 @@
public static final String SUPPLICANT_KEY_SSID = WifiConfiguration.ssidVarName;
public static final String SUPPLICANT_KEY_HIDDEN = WifiConfiguration.hiddenSSIDVarName;
public static final String SUPPLICANT_KEY_KEY_MGMT = WifiConfiguration.KeyMgmt.varName;
+ public static final String SUPPLICANT_KEY_AUTH_ALG =
+ WifiConfiguration.AuthAlgorithm.varName;
public static final String SUPPLICANT_KEY_CLIENT_CERT =
WifiEnterpriseConfig.CLIENT_CERT_KEY;
public static final String SUPPLICANT_KEY_CA_CERT = WifiEnterpriseConfig.CA_CERT_KEY;
@@ -535,6 +537,7 @@
private String mParsedSSIDLine;
private String mParsedHiddenLine;
private String mParsedKeyMgmtLine;
+ private String mParsedAuthAlgLine;
private String mParsedPskLine;
private String[] mParsedWepKeyLines = new String[4];
private String mParsedWepTxKeyIdxLine;
@@ -581,6 +584,8 @@
if (line.contains("EAP")) {
isEap = true;
}
+ } else if (line.startsWith(SUPPLICANT_KEY_AUTH_ALG + "=")) {
+ mParsedAuthAlgLine = line;
} else if (line.startsWith(SUPPLICANT_KEY_CLIENT_CERT + "=")) {
certUsed = true;
} else if (line.startsWith(SUPPLICANT_KEY_CA_CERT + "=")) {
@@ -660,6 +665,16 @@
}
}
}
+ if (mParsedAuthAlgLine != null) {
+ if (mParsedAuthAlgLine.contains("OPEN")) {
+ configuration.allowedAuthAlgorithms.set(
+ WifiConfiguration.AuthAlgorithm.OPEN);
+ }
+ if (mParsedAuthAlgLine.contains("SHARED")) {
+ configuration.allowedAuthAlgorithms.set(
+ WifiConfiguration.AuthAlgorithm.SHARED);
+ }
+ }
if (mParsedPskLine != null) {
configuration.preSharedKey =
mParsedPskLine.substring(mParsedPskLine.indexOf('=') + 1);
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 209044a..6b88f71 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -2364,6 +2364,9 @@
* @param scanDetail ScanDetail instance to use for looking up the network.
* @return WifiConfiguration object representing the network corresponding to the scanDetail,
* null if none exists.
+ *
+ * TODO (b/142035508): This should only return saved networks (and rename to
+ * getSavedNetworkForScanDetail()).
*/
public WifiConfiguration getConfiguredNetworkForScanDetail(ScanDetail scanDetail) {
ScanResult scanResult = scanDetail.getScanResult();
@@ -2391,6 +2394,8 @@
* {@link #mScanDetailCaches} for the retrieved network.
*
* @param scanDetail input a scanDetail from the scan result
+ * TODO (b/142035508): This should only return saved networks (and rename to
+ * updateScanDetailCacheFromScanDetail()).
*/
public void updateScanDetailCacheFromScanDetail(ScanDetail scanDetail) {
WifiConfiguration network = getConfiguredNetworkForScanDetail(scanDetail);
@@ -2407,6 +2412,8 @@
* @param scanDetail input a scanDetail from the scan result
* @return WifiConfiguration object representing the network corresponding to the scanDetail,
* null if none exists.
+ * TODO (b/142035508): This should only return saved networks (and rename to
+ * getSavedNetworkForScanDetailAndCache()).
*/
public WifiConfiguration getConfiguredNetworkForScanDetailAndCache(ScanDetail scanDetail) {
WifiConfiguration network = getConfiguredNetworkForScanDetail(scanDetail);
@@ -3222,6 +3229,9 @@
pw.println(network);
}
pw.println("WifiConfigManager - Configured networks End ----");
+ pw.println("WifiConfigManager - ConfigurationMap Begin ----");
+ mConfiguredNetworks.dump(fd, pw, args);
+ pw.println("WifiConfigManager - ConfigurationMap End ----");
pw.println("WifiConfigManager - Next network ID to be allocated " + mNextNetworkId);
pw.println("WifiConfigManager - Last selected network ID " + mLastSelectedNetworkId);
pw.println("WifiConfigManager - PNO scan frequency culling enabled = "
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 8470d0c..2ce0bc0 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -85,16 +85,6 @@
// it should comply to the minimum scan interval rule.
private static final boolean SCAN_IMMEDIATELY = true;
private static final boolean SCAN_ON_SCHEDULE = false;
- // Initial PNO scan interval in milliseconds when the device is moving. The scan interval backs
- // off from this initial interval on subsequent scans. This scan is performed when screen is
- // off and disconnected.
- @VisibleForTesting
- static final int MOVING_PNO_SCAN_INTERVAL_MS = 20 * 1000; // 20 seconds
- // Initial PNO scan interval in milliseconds when the device is stationary. The scan interval
- // backs off from this initial interval on subsequent scans. This scan is performed when screen
- // is off and disconnected.
- @VisibleForTesting
- static final int STATIONARY_PNO_SCAN_INTERVAL_MS = 60 * 1000; // 1 minute
// PNO scan interval in milli-seconds. This is the scan
// performed when screen is off and connected.
@@ -208,7 +198,6 @@
private int[] mCurrentSingleScanScheduleSec;
private int mCurrentSingleScanScheduleIndex;
- private int mPnoScanIntervalMs;
private WifiChannelUtilization mWifiChannelUtilization;
// Cached WifiCandidates used in high mobility state to avoid connecting to APs that are
// moving relative to the user.
@@ -792,7 +781,6 @@
mClock = clock;
mScoringParams = scoringParams;
mConnectionAttemptTimeStamps = new LinkedList<>();
- mPnoScanIntervalMs = MOVING_PNO_SCAN_INTERVAL_MS;
// Listen to WifiConfigManager network update events
mConfigManager.addOnNetworkUpdateListener(new OnNetworkUpdateListener());
@@ -1321,14 +1309,16 @@
startPeriodicSingleScan();
}
- private static int deviceMobilityStateToPnoScanIntervalMs(@DeviceMobilityState int state) {
+ private int deviceMobilityStateToPnoScanIntervalMs(@DeviceMobilityState int state) {
switch (state) {
case WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN:
case WifiManager.DEVICE_MOBILITY_STATE_LOW_MVMT:
case WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT:
- return MOVING_PNO_SCAN_INTERVAL_MS;
+ return mContext.getResources()
+ .getInteger(R.integer.config_wifiMovingPnoScanIntervalMillis);
case WifiManager.DEVICE_MOBILITY_STATE_STATIONARY:
- return STATIONARY_PNO_SCAN_INTERVAL_MS;
+ return mContext.getResources()
+ .getInteger(R.integer.config_wifiStationaryPnoScanIntervalMillis);
default:
return -1;
}
@@ -1343,16 +1333,18 @@
* @param newState the new device mobility state
*/
public void setDeviceMobilityState(@DeviceMobilityState int newState) {
- mDeviceMobilityState = newState;
+ int oldDeviceMobilityState = mDeviceMobilityState;
localLog("Device mobility state changed. state=" + newState);
- mWifiChannelUtilization.setDeviceMobilityState(newState);
int newPnoScanIntervalMs = deviceMobilityStateToPnoScanIntervalMs(newState);
if (newPnoScanIntervalMs < 0) {
Log.e(TAG, "Invalid device mobility state: " + newState);
return;
}
+ mDeviceMobilityState = newState;
+ mWifiChannelUtilization.setDeviceMobilityState(newState);
- if (newPnoScanIntervalMs == mPnoScanIntervalMs) {
+ int oldPnoScanIntervalMs = deviceMobilityStateToPnoScanIntervalMs(oldDeviceMobilityState);
+ if (newPnoScanIntervalMs == oldPnoScanIntervalMs) {
if (mPnoScanStarted) {
mWifiMetrics.logPnoScanStop();
mWifiMetrics.enterDeviceMobilityState(newState);
@@ -1361,8 +1353,7 @@
mWifiMetrics.enterDeviceMobilityState(newState);
}
} else {
- mPnoScanIntervalMs = newPnoScanIntervalMs;
- Log.d(TAG, "PNO Scan Interval changed to " + mPnoScanIntervalMs + " ms.");
+ Log.d(TAG, "PNO Scan Interval changed to " + newPnoScanIntervalMs + " ms.");
if (mPnoScanStarted) {
Log.d(TAG, "Restarting PNO Scan with new scan interval");
@@ -1400,7 +1391,7 @@
scanSettings.band = getScanBand();
scanSettings.reportEvents = WifiScanner.REPORT_EVENT_NO_BATCH;
scanSettings.numBssidsPerScan = 0;
- scanSettings.periodInMs = mPnoScanIntervalMs;
+ scanSettings.periodInMs = deviceMobilityStateToPnoScanIntervalMs(mDeviceMobilityState);
mPnoScanListener.clearScanDetails();
@@ -1635,7 +1626,7 @@
}
Set<WifiNetworkSuggestion> suggestionsNetworks =
- mWifiNetworkSuggestionsManager.getAllNetworkSuggestions();
+ mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions();
// If total size not equal to 1, then no need to proceed
if (passpointNetworks.size() + savedNetworks.size() + suggestionsNetworks.size() != 1) {
return false;
@@ -1856,6 +1847,7 @@
if (!mWifiEnabled) return;
localLog("forceConnectivityScan in request of " + workSource);
+ clearConnectionAttemptTimeStamps();
mWaitForFullBandScanResults = true;
startForcedSingleScan(true, workSource);
}
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java
index 8dea0df..87b9a1b 100644
--- a/service/java/com/android/server/wifi/WifiDataStall.java
+++ b/service/java/com/android/server/wifi/WifiDataStall.java
@@ -41,9 +41,6 @@
private static final String TAG = "WifiDataStall";
private boolean mVerboseLoggingEnabled = false;
public static final int INVALID_THROUGHPUT = -1;
- // At low traffic, link speed values below the following threshold
- // are ignored because it could be due to low rate management frames
- public static final int LINK_SPEED_LOW_THRESHOLD_MBPS = 9;
// Maximum time gap between two WifiLinkLayerStats to trigger a data stall
public static final int MAX_MS_DELTA_FOR_DATA_STALL = 60 * 1000; // 1 minute
// Maximum time that a data stall start time stays valid.
@@ -306,7 +303,8 @@
if (txLinkSpeedMbps > 0) {
// Exclude update with low rate management frames
- if (isTxTrafficHigh || txLinkSpeedMbps > LINK_SPEED_LOW_THRESHOLD_MBPS) {
+ if (isTxTrafficHigh
+ || txLinkSpeedMbps > mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps()) {
mTxTputKbps = (int) ((long) txLinkSpeedMbps * 1000 * (100 - txPer) / 100
* (CHANNEL_UTILIZATION_SCALE - ccaLevel) / CHANNEL_UTILIZATION_SCALE);
}
@@ -317,7 +315,8 @@
if (rxLinkSpeedMbps > 0) {
// Exclude update with low rate management frames
- if (isRxTrafficHigh || rxLinkSpeedMbps > LINK_SPEED_LOW_THRESHOLD_MBPS) {
+ if (isRxTrafficHigh
+ || rxLinkSpeedMbps > mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps()) {
mRxTputKbps = (int) ((long) rxLinkSpeedMbps * 1000
* (CHANNEL_UTILIZATION_SCALE - ccaLevel) / CHANNEL_UTILIZATION_SCALE);
}
@@ -438,8 +437,8 @@
mLastTxBytes = txBytes;
mLastRxBytes = rxBytes;
- boolean isTxTputSufficient = isL2ThroughputSufficient(l2TxTputKbps, l3TxTputKbps);
- boolean isRxTputSufficient = isL2ThroughputSufficient(l2RxTputKbps, l3RxTputKbps);
+ boolean isTxTputSufficient = isL2ThroughputSufficient(l2TxTputKbps, l3TxTputKbps, false);
+ boolean isRxTputSufficient = isL2ThroughputSufficient(l2RxTputKbps, l3RxTputKbps, true);
isTxTputSufficient = detectAndOverrideFalseInSufficient(
isTxTputSufficient, isTxTrafficHigh, mIsThroughputSufficient);
isRxTputSufficient = detectAndOverrideFalseInSufficient(
@@ -466,17 +465,20 @@
* 3) L3 tput is not low and L2 tput is above its high threshold
* 4) L2 tput is invalid
*/
- private boolean isL2ThroughputSufficient(int l2TputKbps, int l3TputKbps) {
+ private boolean isL2ThroughputSufficient(int l2TputKbps, int l3TputKbps, boolean isForRxTput) {
if (l2TputKbps == INVALID_THROUGHPUT) return true;
+ int tputSufficientLowThrKbps = mDeviceConfigFacade.getTxTputSufficientLowThrKbps();
+ int tputSufficientHighThrKbps = mDeviceConfigFacade.getTxTputSufficientHighThrKbps();
+ if (isForRxTput) {
+ tputSufficientLowThrKbps = mDeviceConfigFacade.getRxTputSufficientLowThrKbps();
+ tputSufficientHighThrKbps = mDeviceConfigFacade.getRxTputSufficientHighThrKbps();
+ }
boolean isL3TputLow = (l3TputKbps * mDeviceConfigFacade.getTputSufficientRatioThrDen())
- < (mDeviceConfigFacade.getTputSufficientLowThrKbps()
- * mDeviceConfigFacade.getTputSufficientRatioThrNum());
- boolean isL2TputAboveLowThr =
- l2TputKbps >= mDeviceConfigFacade.getTputSufficientLowThrKbps();
+ < (tputSufficientLowThrKbps * mDeviceConfigFacade.getTputSufficientRatioThrNum());
+ boolean isL2TputAboveLowThr = l2TputKbps >= tputSufficientLowThrKbps;
if (isL3TputLow) return isL2TputAboveLowThr;
- boolean isL2TputAboveHighThr =
- l2TputKbps >= mDeviceConfigFacade.getTputSufficientHighThrKbps();
+ boolean isL2TputAboveHighThr = l2TputKbps >= tputSufficientHighThrKbps;
boolean isL2L3TputRatioAboveThr =
(l2TputKbps * mDeviceConfigFacade.getTputSufficientRatioThrDen())
>= (l3TputKbps * mDeviceConfigFacade.getTputSufficientRatioThrNum());
diff --git a/service/java/com/android/server/wifi/WifiDiagnostics.java b/service/java/com/android/server/wifi/WifiDiagnostics.java
index 4ac9820..2ba90c9 100644
--- a/service/java/com/android/server/wifi/WifiDiagnostics.java
+++ b/service/java/com/android/server/wifi/WifiDiagnostics.java
@@ -44,6 +44,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.Deflater;
@@ -107,6 +108,9 @@
/** Minimum dump period with same error code */
public static final long MIN_DUMP_TIME_WINDOW_MILLIS = 10 * 60 * 1000; // 10 mins
+ // Timeout for logcat
+ private static final int LOGCAT_TIMEOUT_MILLIS = 500;
+
private long mLastBugReportTime;
@VisibleForTesting public static final String FIRMWARE_DUMP_SECTION_HEADER =
@@ -720,7 +724,7 @@
while ((line = reader.readLine()) != null) {
lines.add(line);
}
- process.waitFor();
+ process.waitFor(LOGCAT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
} catch (InterruptedException|IOException e) {
mLog.dump("Exception while capturing logcat: %").c(e.toString()).flush();
}
diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java
index 27167dc..8ab3a74 100644
--- a/service/java/com/android/server/wifi/WifiHealthMonitor.java
+++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java
@@ -326,6 +326,15 @@
pw.println("WifiHealthMonitor - Log End ----");
}
+ /**
+ * Get current wifi mainline module long version code
+ * @Return a non-zero value if version code is available, 0 otherwise.
+ */
+ public long getWifiStackVersion() {
+ WifiSoftwareBuildInfo currentBuild = getWifiSystemInfoStats().getCurrSoftwareBuildInfo();
+ return (currentBuild == null) ? 0 : currentBuild.getWifiStackVersion();
+ }
+
private synchronized void dailyDetectionHandler() {
logd("Run daily detection");
// Clear daily detection result
@@ -533,12 +542,12 @@
return null;
}
PackageManager packageManager = mContext.getPackageManager();
- int wifiStackVersion = 0;
+ long wifiStackVersion = 0;
try {
wifiStackVersion = packageManager.getPackageInfo(
- WIFI_APK_PACKAGE_NAME, PackageManager.MATCH_APEX).versionCode;
+ WIFI_APK_PACKAGE_NAME, PackageManager.MATCH_APEX).getLongVersionCode();
} catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, " hit PackageManager nameNotFoundException");
+ Log.e(TAG, " Hit PackageManager exception", e);
}
String osBuildVersion = replaceNullByEmptyString(Build.DISPLAY);
if (mWifiNative == null) {
@@ -629,10 +638,10 @@
*/
final class WifiSoftwareBuildInfo {
private String mOsBuildVersion;
- private int mWifiStackVersion;
+ private long mWifiStackVersion;
private String mWifiDriverVersion;
private String mWifiFirmwareVersion;
- WifiSoftwareBuildInfo(@NonNull String osBuildVersion, int wifiStackVersion,
+ WifiSoftwareBuildInfo(@NonNull String osBuildVersion, long wifiStackVersion,
@NonNull String wifiDriverVersion, @NonNull String wifiFirmwareVersion) {
mOsBuildVersion = osBuildVersion;
mWifiStackVersion = wifiStackVersion;
@@ -648,7 +657,7 @@
String getOsBuildVersion() {
return mOsBuildVersion;
}
- int getWifiStackVersion() {
+ long getWifiStackVersion() {
return mWifiStackVersion;
}
String getWifiDriverVersion() {
@@ -842,7 +851,7 @@
@NonNull SoftwareBuildInfo softwareBuildInfo) {
String osBuildVersion = softwareBuildInfo.hasOsBuildVersion()
? softwareBuildInfo.getOsBuildVersion() : "NA";
- int stackVersion = softwareBuildInfo.hasWifiStackVersion()
+ long stackVersion = softwareBuildInfo.hasWifiStackVersion()
? softwareBuildInfo.getWifiStackVersion() : 0;
String driverVersion = softwareBuildInfo.hasWifiDriverVersion()
? softwareBuildInfo.getWifiDriverVersion() : "NA";
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 383659e..e23779e 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -62,6 +62,7 @@
import com.android.server.wifi.p2p.WifiP2pMetrics;
import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.CarrierWifiMetrics;
import com.android.server.wifi.proto.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount;
import com.android.server.wifi.proto.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats;
import com.android.server.wifi.proto.nano.WifiMetricsProto.ExperimentValues;
@@ -500,6 +501,9 @@
private final SoftApConfigLimitationMetrics mSoftApConfigLimitationMetrics =
new SoftApConfigLimitationMetrics();
+ private final CarrierWifiMetrics mCarrierWifiMetrics =
+ new CarrierWifiMetrics();
+
@VisibleForTesting
static class NetworkSelectionExperimentResults {
public static final int MAX_CHOICES = 10;
@@ -1185,6 +1189,38 @@
}
}
+ class CarrierWifiMetrics {
+ public int numConnectionSuccess = 0;
+ public int numConnectionAuthFailure = 0;
+ public int numConnectionNonAuthFailure = 0;
+
+ public WifiMetricsProto.CarrierWifiMetrics toProto() {
+ WifiMetricsProto.CarrierWifiMetrics proto =
+ new WifiMetricsProto.CarrierWifiMetrics();
+ proto.numConnectionSuccess = numConnectionSuccess;
+ proto.numConnectionAuthFailure = numConnectionAuthFailure;
+ proto.numConnectionNonAuthFailure = numConnectionNonAuthFailure;
+ return proto;
+ }
+
+ public void clear() {
+ numConnectionSuccess = 0;
+ numConnectionAuthFailure = 0;
+ numConnectionNonAuthFailure = 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("numConnectionSuccess=")
+ .append(numConnectionSuccess)
+ .append(", numConnectionAuthFailure=")
+ .append(numConnectionAuthFailure)
+ .append(", numConnectionNonAuthFailure")
+ .append(numConnectionNonAuthFailure);
+ return sb.toString();
+ }
+ }
public WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper,
WifiAwareMetrics awareMetrics, RttMetrics rttMetrics,
@@ -3646,6 +3682,8 @@
+ mTxThroughputMbpsHistogramAbove2G);
pw.println("mRxThroughputMbpsHistogramAbove2G:\n"
+ mRxThroughputMbpsHistogramAbove2G);
+ pw.println("mCarrierWifiMetrics:\n"
+ + mCarrierWifiMetrics);
dumpInitPartialScanMetrics(pw);
}
@@ -4321,6 +4359,9 @@
initialPartialScanStats.failedScanChannelCountHistogram =
mInitPartialScanFailureHistogram.toProto();
mWifiLogProto.initPartialScanStats = initialPartialScanStats;
+ mWifiLogProto.carrierWifiMetrics = mCarrierWifiMetrics.toProto();
+ mWifiLogProto.mainlineModuleVersion = mWifiHealthMonitor.getWifiStackVersion();
+
}
}
@@ -4538,6 +4579,7 @@
mInitPartialScanFailureCount = 0;
mInitPartialScanSuccessHistogram.clear();
mInitPartialScanFailureHistogram.clear();
+ mCarrierWifiMetrics.clear();
}
}
@@ -4696,6 +4738,9 @@
staEvent.totalTxBytes = mFacade.getTotalTxBytes();
staEvent.totalRxBytes = mFacade.getTotalRxBytes();
staEvent.screenOn = mScreenOn;
+ if (mWifiDataStall != null) {
+ staEvent.isCellularDataAvailable = mWifiDataStall.isCellularDataAvailable();
+ }
mSupplicantStateChangeBitmask = 0;
mLastPollRssi = -127;
mLastPollFreq = -1;
@@ -4911,6 +4956,7 @@
if (event.totalTxBytes > 0) sb.append(" totalTxBytes=").append(event.totalTxBytes);
if (event.totalRxBytes > 0) sb.append(" totalRxBytes=").append(event.totalRxBytes);
sb.append(" screenOn=").append(event.screenOn);
+ sb.append(" cellularData=").append(event.isCellularDataAvailable);
if (event.supplicantStateChangesBitmask != 0) {
sb.append(", ").append(supplicantStateChangesBitmaskToString(
event.supplicantStateChangesBitmask));
@@ -6448,4 +6494,40 @@
public void noteSoftApClientBlocked(int maxClient) {
mSoftApConfigLimitationMetrics.maxClientSettingWhenReachHistogram.increment(maxClient);
}
+
+ /**
+ * Increment number of connection with different BSSID between framework and firmware selection.
+ */
+ public void incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware() {
+ synchronized (mLock) {
+ mWifiLogProto.numBssidDifferentSelectionBetweenFrameworkAndFirmware++;
+ }
+ }
+
+ /**
+ * Note the carrier wifi network connected successfully.
+ */
+ public void incrementNumOfCarrierWifiConnectionSuccess() {
+ synchronized (mLock) {
+ mCarrierWifiMetrics.numConnectionSuccess++;
+ }
+ }
+
+ /**
+ * Note the carrier wifi network connection authentication failure.
+ */
+ public void incrementNumOfCarrierWifiConnectionAuthFailure() {
+ synchronized (mLock) {
+ mCarrierWifiMetrics.numConnectionAuthFailure++;
+ }
+ }
+
+ /**
+ * Note the carrier wifi network connection non-authentication failure.
+ */
+ public void incrementNumOfCarrierWifiConnectionNonAuthFailure() {
+ synchronized (mLock) {
+ mCarrierWifiMetrics.numConnectionNonAuthFailure++;
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 98ba5bc..9dc89ad 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -146,6 +146,7 @@
private boolean mVerboseLoggingEnabled = false;
private boolean mPeriodicScanTimerSet = false;
private boolean mConnectionTimeoutSet = false;
+ private boolean mIsPeriodicScanEnabled = false;
private boolean mIsPeriodicScanPaused = false;
// We sent a new connection request and are waiting for connection success.
private boolean mPendingConnectionSuccess = false;
@@ -256,6 +257,7 @@
public void onAlarm() {
// Trigger the next scan.
startScan();
+ mPeriodicScanTimerSet = false;
}
}
@@ -264,6 +266,7 @@
public void onAlarm() {
Log.e(TAG, "Timed-out connecting to network");
handleNetworkConnectionFailure(mUserSelectedNetwork);
+ mConnectionTimeoutSet = false;
}
}
@@ -819,6 +822,7 @@
// Cancel the ongoing scans after user selection.
cancelPeriodicScans();
+ mIsPeriodicScanEnabled = false;
// Trigger connection attempts.
handleConnectToNetworkUserSelectionInternal(network);
@@ -918,13 +922,13 @@
public void handleScreenStateChanged(boolean screenOn) {
// If there is no active request or if the user has already selected a network,
// ignore screen state changes.
- if (mActiveSpecificNetworkRequest == null || mUserSelectedNetwork != null) return;
+ if (mActiveSpecificNetworkRequest == null || !mIsPeriodicScanEnabled) return;
// Pause periodic scans when the screen is off & resume when the screen is on.
if (screenOn) {
if (mVerboseLoggingEnabled) Log.v(TAG, "Resuming scans on screen on");
- startScan();
mIsPeriodicScanPaused = false;
+ startScan();
} else {
if (mVerboseLoggingEnabled) Log.v(TAG, "Pausing scans on screen off");
cancelPeriodicScans();
@@ -971,6 +975,7 @@
mActiveSpecificNetworkRequestSpecifier = null;
mUserSelectedNetwork = null;
mUserSelectedNetworkConnectRetryCount = 0;
+ mIsPeriodicScanEnabled = false;
mIsPeriodicScanPaused = false;
mActiveMatchedScanResults = null;
mPendingConnectionSuccess = false;
@@ -1075,6 +1080,7 @@
mScanSettings.hiddenNetworks.add(new WifiScanner.ScanSettings.HiddenNetwork(
addEnclosingQuotes(wns.ssidPatternMatcher.getPath())));
}
+ mIsPeriodicScanEnabled = true;
startScan();
}
@@ -1103,6 +1109,10 @@
Log.e(TAG, "Scan triggered when there is no active network request. Ignoring...");
return;
}
+ if (!mIsPeriodicScanEnabled) {
+ Log.e(TAG, "Scan triggered after user selected network. Ignoring...");
+ return;
+ }
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Starting the next scan for " + mActiveSpecificNetworkRequestSpecifier);
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 7e95fba..f59a50f 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -940,6 +940,9 @@
}
WifiConfiguration config =
mWifiConfigManager.getConfiguredNetwork(choice.candidateKey.networkId);
+ if (config == null) {
+ return;
+ }
if (config.isPasspoint()) {
config.SSID = choice.candidateKey.matchInfo.networkSsid;
mWifiConfigManager.addOrUpdateNetwork(config, config.creatorUid, config.creatorName);
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index f470039..5d5a7d7 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -1254,6 +1254,19 @@
}
/**
+ * Returns a set of all network suggestions across all apps that have been approved by user.
+ */
+ public Set<WifiNetworkSuggestion> getAllApprovedNetworkSuggestions() {
+ final String activeScorerPackage = mNetworkScoreManager.getActiveScorerPackage();
+ return mActiveNetworkSuggestionsPerApp.values()
+ .stream()
+ .filter(e -> e.isApproved(activeScorerPackage))
+ .flatMap(e -> convertToWnsSet(e.extNetworkSuggestions)
+ .stream())
+ .collect(Collectors.toSet());
+ }
+
+ /**
* Get all user approved, non-passpoint networks from suggestion.
*/
public List<WifiConfiguration> getAllScanOptimizationSuggestionNetworks() {
diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java
index 346a8fe..ca77e83 100644
--- a/service/java/com/android/server/wifi/WifiScoreCard.java
+++ b/service/java/com/android/server/wifi/WifiScoreCard.java
@@ -136,6 +136,10 @@
void read(String key, String name, BlobListener blobListener);
/** Requests a write, does not wait for completion */
void write(String key, String name, byte[] value);
+ /** Sets the cluster identifier */
+ void setCluster(String key, String cluster);
+ /** Requests removal of all entries matching the cluster */
+ void removeCluster(String cluster);
}
/** Asynchronous response to a read request */
public interface BlobListener {
@@ -249,9 +253,15 @@
if (perBssid == mDummyPerBssid) {
return new Pair<>(null, null);
}
- final long groupIdHash = computeHashLong(
- perBssid.ssid, mDummyPerBssid.bssid, mL2KeySeed);
- return new Pair<>(perBssid.getL2Key(), groupHintFromLong(groupIdHash));
+ return new Pair<>(perBssid.getL2Key(), groupHintFromSsid(perBssid.ssid));
+ }
+
+ /**
+ * Computes the GroupHint associated with the given ssid.
+ */
+ public @NonNull String groupHintFromSsid(String ssid) {
+ final long groupIdHash = computeHashLong(ssid, mDummyPerBssid.bssid, mL2KeySeed);
+ return groupHintFromLong(groupIdHash);
}
/**
@@ -1447,6 +1457,7 @@
Log.e(TAG, "More answers than we expected!");
}
}
+
/**
* Handles (when convenient) the arrival of previously stored data.
*
@@ -1459,7 +1470,6 @@
return mPendingReadFromStore.getAndSet(null);
}
-
int idFromLong() {
return (int) mHash & 0x7fffffff;
}
@@ -1552,10 +1562,9 @@
return;
}
mApForNetwork.remove(ssid);
+ mApForBssid.entrySet().removeIf(entry -> ssid.equals(entry.getValue().ssid));
if (mMemoryStore == null) return;
- PerNetwork ans = new PerNetwork(ssid);
- byte[] serialized = {};
- mMemoryStore.write(ans.getL2Key(), PER_NETWORK_DATA_NAME, serialized);
+ mMemoryStore.removeCluster(groupHintFromSsid(ssid));
}
void requestReadNetwork(final PerNetwork perNetwork) {
@@ -1586,7 +1595,9 @@
if (perBssid.changed) {
perBssid.finishPendingRead();
byte[] serialized = perBssid.toAccessPoint(/* No BSSID */ true).toByteArray();
+ mMemoryStore.setCluster(perBssid.getL2Key(), groupHintFromSsid(perBssid.ssid));
mMemoryStore.write(perBssid.getL2Key(), PER_BSSID_DATA_NAME, serialized);
+
perBssid.changed = false;
count++;
bytes += serialized.length;
@@ -1606,6 +1617,7 @@
if (perNetwork.changed) {
perNetwork.finishPendingRead();
byte[] serialized = perNetwork.toNetworkStats().toByteArray();
+ mMemoryStore.setCluster(perNetwork.getL2Key(), groupHintFromSsid(perNetwork.ssid));
mMemoryStore.write(perNetwork.getL2Key(), PER_NETWORK_DATA_NAME, serialized);
perNetwork.changed = false;
count++;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 0772b4c..9d12aa0 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -879,6 +879,14 @@
mLog.info("startSoftAp uid=%").c(Binder.getCallingUid()).flush();
+ SoftApConfiguration softApConfig = null;
+ if (wifiConfig != null) {
+ softApConfig = ApConfigUtil.fromWifiConfiguration(wifiConfig);
+ if (softApConfig == null) {
+ return false;
+ }
+ }
+
if (!mTetheredSoftApTracker.setEnablingIfAllowed()) {
mLog.err("Tethering is already active.").flush();
return false;
@@ -890,17 +898,14 @@
mLohsSoftApTracker.stopAll();
}
- if (wifiConfig != null) {
- SoftApConfiguration softApConfig = ApConfigUtil.fromWifiConfiguration(wifiConfig);
- if (softApConfig == null) return false;
- return startSoftApInternal(new SoftApModeConfiguration(
- WifiManager.IFACE_IP_MODE_TETHERED,
- softApConfig, mTetheredSoftApTracker.getSoftApCapability()));
- } else {
- return startSoftApInternal(new SoftApModeConfiguration(
- WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTetheredSoftApTracker.getSoftApCapability()));
+ if (!startSoftApInternal(new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
+ mTetheredSoftApTracker.getSoftApCapability()))) {
+ mTetheredSoftApTracker.setFailedWhileEnabling();
+ return false;
}
+
+ return true;
}
private boolean validateSoftApBand(int apBand) {
@@ -951,11 +956,15 @@
mLohsSoftApTracker.stopAll();
}
- return startSoftApInternal(new SoftApModeConfiguration(
+ if (!startSoftApInternal(new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- mTetheredSoftApTracker.getSoftApCapability()));
- }
+ mTetheredSoftApTracker.getSoftApCapability()))) {
+ mTetheredSoftApTracker.setFailedWhileEnabling();
+ return false;
+ }
+ return true;
+ }
/**
* Internal method to start softap mode. Callers of this method should have already checked
@@ -1053,6 +1062,14 @@
}
}
+ public void setFailedWhileEnabling() {
+ synchronized (mLock) {
+ if (mTetheredSoftApState == WIFI_AP_STATE_ENABLING) {
+ mTetheredSoftApState = WIFI_AP_STATE_FAILED;
+ }
+ }
+ }
+
public List<WifiClient> getConnectedClients() {
synchronized (mLock) {
return mTetheredSoftApConnectedClients;
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 842493c..41933ab 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -372,10 +372,10 @@
if (ApConfigUtil.isWpa3SaeSupported(mContext)) {
pw.println("wifi_softap_wpa3_sae_supported");
}
- break;
+ return 0;
case "settings-reset":
mWifiService.factoryReset(SHELL_PACKAGE_NAME);
- break;
+ return 0;
case "list-scan-results":
List<ScanResult> scanResults =
mWifiService.getScanResults(SHELL_PACKAGE_NAME, null);
@@ -385,10 +385,10 @@
ScanResultUtil.dumpScanResults(pw, scanResults,
SystemClock.elapsedRealtime());
}
- break;
+ return 0;
case "start-scan":
mWifiService.startScan(SHELL_PACKAGE_NAME, null);
- break;
+ return 0;
case "list-networks":
ParceledListSlice<WifiConfiguration> networks =
mWifiService.getConfiguredNetworks(SHELL_PACKAGE_NAME, null);
@@ -414,7 +414,7 @@
securityType));
}
}
- break;
+ return 0;
case "connect-network": {
CountDownLatch countDownLatch = new CountDownLatch(1);
IActionListener.Stub actionListener = new IActionListener.Stub() {
@@ -436,7 +436,7 @@
// wait for status.
countDownLatch.await(500, TimeUnit.MILLISECONDS);
setAutoJoin(pw, config.SSID, config.allowAutojoin);
- break;
+ return 0;
}
case "add-network": {
CountDownLatch countDownLatch = new CountDownLatch(1);
@@ -459,7 +459,7 @@
// wait for status.
countDownLatch.await(500, TimeUnit.MILLISECONDS);
setAutoJoin(pw, config.SSID, config.allowAutojoin);
- break;
+ return 0;
}
case "forget-network": {
String networkId = getNextArgRequired();
@@ -482,21 +482,21 @@
actionListener.hashCode());
// wait for status.
countDownLatch.await(500, TimeUnit.MILLISECONDS);
- break;
+ return 0;
}
case "status":
printStatus(pw);
- break;
+ return 0;
case "set-verbose-logging": {
boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled");
mWifiService.enableVerboseLogging(enabled ? 1 : 0);
- break;
+ return 0;
}
case "add-suggestion": {
WifiNetworkSuggestion suggestion = buildSuggestion(pw);
mWifiService.addNetworkSuggestions(
Arrays.asList(suggestion), SHELL_PACKAGE_NAME, null);
- break;
+ return 0;
}
case "remove-suggestion": {
String ssid = getNextArgRequired();
@@ -512,12 +512,12 @@
}
mWifiService.removeNetworkSuggestions(
Arrays.asList(suggestion), SHELL_PACKAGE_NAME);
- break;
+ return 0;
}
case "remove-all-suggestions":
mWifiService.removeNetworkSuggestions(
Collections.emptyList(), SHELL_PACKAGE_NAME);
- break;
+ return 0;
case "list-suggestions": {
List<WifiNetworkSuggestion> suggestions =
mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME);
@@ -548,7 +548,7 @@
securityType));
}
}
- break;
+ return 0;
}
case "add-request": {
NetworkRequest networkRequest = buildNetworkRequest(pw);
@@ -558,7 +558,7 @@
mConnectivityManager.requestNetwork(networkRequest, networkCallback);
String ssid = getAllArgs()[1];
sActiveRequests.put(ssid, Pair.create(networkRequest, networkCallback));
- break;
+ return 0;
}
case "remove-request": {
String ssid = getNextArgRequired();
@@ -570,7 +570,7 @@
}
pw.println("Removing request: " + nrAndNc.first);
mConnectivityManager.unregisterNetworkCallback(nrAndNc.second);
- break;
+ return 0;
}
case "remove-all-requests":
if (sActiveRequests.isEmpty()) {
@@ -583,7 +583,7 @@
mConnectivityManager.unregisterNetworkCallback(nrAndNc.second);
}
sActiveRequests.clear();
- break;
+ return 0;
case "list-requests":
if (sActiveRequests.isEmpty()) {
pw.println("No active requests");
@@ -596,7 +596,7 @@
entry.getKey(), entry.getValue().first));
}
}
- break;
+ return 0;
case "network-requests-set-user-approved": {
String packageName = getNextArgRequired();
boolean approved = getNextArgRequiredTrueOrFalse("yes", "no");
@@ -667,11 +667,12 @@
}
} catch (IllegalArgumentException e) {
pw.println("Invalid args for " + cmd + ": " + e);
+ return -1;
} catch (Exception e) {
pw.println("Exception while executing WifiShellCommand: ");
e.printStackTrace(pw);
+ return -1;
}
- return -1;
}
private boolean getNextArgRequiredTrueOrFalse(String trueString, String falseString)
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 49ce8ad..e190a24 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -568,12 +568,7 @@
nnri.peerDataMac = mac;
nnri.channelInfo = channelInfo;
- final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder(
- sNetworkCapabilitiesFilter);
- LinkProperties linkProperties = new LinkProperties();
-
- boolean interfaceUsedByAnotherNdp = isInterfaceUpAndUsedByAnotherNdp(nnri);
- if (!interfaceUsedByAnotherNdp) {
+ if (!isInterfaceUpAndUsedByAnotherNdp(nnri)) {
try {
mNetdWrapper.setInterfaceUp(nnri.interfaceName);
mNetdWrapper.enableIpv6(nnri.interfaceName);
@@ -609,59 +604,8 @@
}
}
- try {
- if (nnri.peerIpv6Override == null) {
- nnri.peerIpv6 = Inet6Address.getByAddress(null,
- MacAddress.fromBytes(mac).getLinkLocalIpv6FromEui48Mac().getAddress(),
- NetworkInterface.getByName(nnri.interfaceName));
- } else {
- byte[] addr = new byte[16];
-
- addr[0] = (byte) 0xfe;
- addr[1] = (byte) 0x80;
- addr[8] = nnri.peerIpv6Override[0];
- addr[9] = nnri.peerIpv6Override[1];
- addr[10] = nnri.peerIpv6Override[2];
- addr[11] = nnri.peerIpv6Override[3];
- addr[12] = nnri.peerIpv6Override[4];
- addr[13] = nnri.peerIpv6Override[5];
- addr[14] = nnri.peerIpv6Override[6];
- addr[15] = nnri.peerIpv6Override[7];
-
- nnri.peerIpv6 = Inet6Address.getByAddress(null, addr,
- NetworkInterface.getByName(nnri.interfaceName));
- }
- } catch (SocketException | UnknownHostException e) {
- Log.e(TAG, "onDataPathConfirm: error obtaining scoped IPv6 address -- " + e);
- nnri.peerIpv6 = null;
- }
-
- if (nnri.peerIpv6 != null) {
- final WifiAwareNetworkInfo ni = new WifiAwareNetworkInfo(
- nnri.peerIpv6, nnri.peerPort, nnri.peerTransportProtocol);
- ncBuilder.setTransportInfo(ni);
- if (VDBG) {
- Log.v(TAG, "onDataPathConfirm: AwareNetworkInfo=" + ni);
- }
- }
-
- if (!mNiWrapper.configureAgentProperties(nnri, nnri.equivalentRequests, ndpId,
- ncBuilder, linkProperties)) {
- declareUnfullfillableAndEndDp(nnri, ndpId);
- return networkSpecifier;
- }
-
- final NetworkAgentConfig naConfig = new NetworkAgentConfig.Builder()
- .setLegacyType(ConnectivityManager.TYPE_NONE)
- .setLegacyTypeName(NETWORK_TAG)
- .build();
-
- nnri.networkAgent = new WifiAwareNetworkAgent(mLooper, mContext,
- AGENT_TAG_PREFIX + nnri.ndpId, ncBuilder.build(),
- linkProperties, NETWORK_FACTORY_SCORE_AVAIL,
- naConfig, mNetworkFactory.getProvider(), nnri);
nnri.startValidationTimestamp = mClock.getElapsedSinceBootMillis();
- handleAddressValidation(nnri, linkProperties, ndpId, networkSpecifier.isOutOfBand());
+ handleAddressValidation(nnri, ndpId, networkSpecifier.isOutOfBand(), mac);
} else {
if (VDBG) {
Log.v(TAG, "onDataPathConfirm: data-path for networkSpecifier=" + networkSpecifier
@@ -676,29 +620,81 @@
return networkSpecifier;
}
- private void handleAddressValidation(AwareNetworkRequestInformation nnri,
- LinkProperties linkProperties, int ndpId, boolean isOutOfBand) {
- if (mNiWrapper.isAddressUsable(linkProperties)) {
- mNiWrapper.setConnected(nnri.networkAgent);
-
- mAwareMetrics.recordNdpStatus(NanStatusType.SUCCESS, isOutOfBand, nnri.startTimestamp);
- nnri.startTimestamp = mClock.getElapsedSinceBootMillis(); // update time-stamp
- mAwareMetrics.recordNdpCreation(nnri.uid, nnri.packageName, mNetworkRequestsCache);
- } else {
- if (mClock.getElapsedSinceBootMillis() - nnri.startValidationTimestamp
- > ADDRESS_VALIDATION_TIMEOUT_MS) {
- Log.e(TAG, "Timed-out while waiting for IPv6 address to be usable");
-
- declareUnfullfillableAndEndDp(nnri, ndpId);
- return;
+ private void getInet6Address(AwareNetworkRequestInformation nnri, byte[] mac) {
+ try {
+ byte[] addr;
+ if (nnri.peerIpv6Override == null) {
+ addr = MacAddress.fromBytes(mac).getLinkLocalIpv6FromEui48Mac().getAddress();
+ } else {
+ addr = new byte[16];
+ addr[0] = (byte) 0xfe;
+ addr[1] = (byte) 0x80;
+ addr[8] = nnri.peerIpv6Override[0];
+ addr[9] = nnri.peerIpv6Override[1];
+ addr[10] = nnri.peerIpv6Override[2];
+ addr[11] = nnri.peerIpv6Override[3];
+ addr[12] = nnri.peerIpv6Override[4];
+ addr[13] = nnri.peerIpv6Override[5];
+ addr[14] = nnri.peerIpv6Override[6];
+ addr[15] = nnri.peerIpv6Override[7];
}
+ nnri.peerIpv6 = Inet6Address.getByAddress(null, addr,
+ NetworkInterface.getByName(nnri.interfaceName));
+ } catch (SocketException | UnknownHostException e) {
+ if (mDbg) {
+ Log.d(TAG, "onDataPathConfirm: error obtaining scoped IPv6 address -- " + e);
+ }
+ nnri.peerIpv6 = null;
+ }
+ }
+
+ private void handleAddressValidation(AwareNetworkRequestInformation nnri, int ndpId,
+ boolean isOutOfBand, byte[] mac) {
+ final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder(
+ sNetworkCapabilitiesFilter);
+ LinkProperties linkProperties = new LinkProperties();
+ getInet6Address(nnri, mac);
+ if (nnri.peerIpv6 != null) {
+ final WifiAwareNetworkInfo ni = new WifiAwareNetworkInfo(
+ nnri.peerIpv6, nnri.peerPort, nnri.peerTransportProtocol);
+ ncBuilder.setTransportInfo(ni);
+ if (VDBG) {
+ Log.v(TAG, "onDataPathConfirm: AwareNetworkInfo=" + ni);
+ }
+ }
+ if (!(mNiWrapper.configureAgentProperties(nnri, nnri.equivalentRequests, ndpId,
+ ncBuilder, linkProperties) && mNiWrapper.isAddressUsable(linkProperties))) {
if (VDBG) {
Log.d(TAG, "Failed address validation");
}
- mHandler.postDelayed(() -> {
- handleAddressValidation(nnri, linkProperties, ndpId, isOutOfBand);
- }, ADDRESS_VALIDATION_RETRY_INTERVAL_MS);
+ if (!isAddressValidationExpired(nnri, ndpId)) {
+ mHandler.postDelayed(() -> {
+ handleAddressValidation(nnri, ndpId, isOutOfBand, mac);
+ }, ADDRESS_VALIDATION_RETRY_INTERVAL_MS);
+ }
+ return;
}
+ final NetworkAgentConfig naConfig = new NetworkAgentConfig.Builder()
+ .setLegacyType(ConnectivityManager.TYPE_NONE)
+ .setLegacyTypeName(NETWORK_TAG)
+ .build();
+ nnri.networkAgent = new WifiAwareNetworkAgent(mLooper, mContext,
+ AGENT_TAG_PREFIX + nnri.ndpId, ncBuilder.build(), linkProperties,
+ NETWORK_FACTORY_SCORE_AVAIL, naConfig, mNetworkFactory.getProvider(), nnri);
+ mNiWrapper.setConnected(nnri.networkAgent);
+ mAwareMetrics.recordNdpStatus(NanStatusType.SUCCESS, isOutOfBand, nnri.startTimestamp);
+ nnri.startTimestamp = mClock.getElapsedSinceBootMillis(); // update time-stamp
+ mAwareMetrics.recordNdpCreation(nnri.uid, nnri.packageName, mNetworkRequestsCache);
+ }
+
+ private boolean isAddressValidationExpired(AwareNetworkRequestInformation nnri, int ndpId) {
+ if (mClock.getElapsedSinceBootMillis() - nnri.startValidationTimestamp
+ > ADDRESS_VALIDATION_TIMEOUT_MS) {
+ Log.e(TAG, "Timed-out while waiting for IPv6 address to be usable");
+ declareUnfullfillableAndEndDp(nnri, ndpId);
+ return true;
+ }
+ return false;
}
private void declareUnfullfillableAndEndDp(AwareNetworkRequestInformation nnri, int ndpId) {
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index ad52af1..349543d 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -706,6 +706,15 @@
// User reaction to the carrier or suggestion app approval UI.
optional UserReactionToApprovalUiEvent user_reaction_to_approval_ui_event = 198;
+
+ // Number of connection with different BSSID between framework and firmware selection.
+ optional int32 num_bssid_different_selection_between_framework_and_firmware = 199;
+
+ // Metrics about carrier wifi network.
+ optional CarrierWifiMetrics carrier_wifi_metrics = 200;
+
+ // Long version code of wifi mainline module, 0 means not available.
+ optional int64 mainline_module_version = 201;
}
// Information that gets logged for every WiFi connection.
@@ -1438,6 +1447,9 @@
// Whether screen is on when the event happens
optional bool screen_on = 24;
+
+ // Whether cellular data network is available
+ optional bool is_cellular_data_available = 25;
}
// Wi-Fi Aware metrics
@@ -3289,3 +3301,11 @@
// Event of user reaction to the carrier approval UI.
repeated UserReaction user_approval_carrier_ui_reaction = 2;
}
+
+message CarrierWifiMetrics {
+ // Number of successful network connection using Carrier ID
+ optional int32 num_connection_success = 1;
+ // Number of failed authentication from network connection using Carrier ID
+ optional int32 num_connection_auth_failure = 2;
+ optional int32 num_connection_non_auth_failure = 3;
+}
diff --git a/service/proto/src/scorecard.proto b/service/proto/src/scorecard.proto
index ad5822c..d351c56 100644
--- a/service/proto/src/scorecard.proto
+++ b/service/proto/src/scorecard.proto
@@ -146,7 +146,7 @@
// Android OS build version
optional string os_build_version = 1;
// WiFi stack APK version, 0 means not available.
- optional int32 wifi_stack_version = 2;
+ optional int64 wifi_stack_version = 2;
// WiFi driver version
optional string wifi_driver_version = 3;
// WiFi firmware version
diff --git a/service/res/values-el/strings.xml b/service/res/values-el/strings.xml
index 9fa523b..0e3dd9e 100644
--- a/service/res/values-el/strings.xml
+++ b/service/res/values-el/strings.xml
@@ -47,7 +47,7 @@
<string name="wifi_watchdog_network_disabled" msgid="688248897654073438">"Δεν είναι δυνατή η σύνδεση στο Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="2946200607682633112">" έχει κακή σύνδεση Διαδικτύου."</string>
<string name="wifi_connect_alert_title" msgid="6144470472092017636">"Να επιτρέπεται η σύνδεση;"</string>
- <string name="wifi_connect_alert_message" msgid="3123801378559831220">"Η εφαρμογή %1$s θα ήθελε να συνδεθεί με το δίκτυο WiFi %2$s"</string>
+ <string name="wifi_connect_alert_message" msgid="3123801378559831220">"Η εφαρμογή %1$s θα ήθελε να συνδεθεί με το δίκτυο Wi-Fi %2$s"</string>
<string name="wifi_connect_default_application" msgid="6164721692891325243">"Μια εφαρμογή"</string>
<string name="accept" msgid="5931271886782610829">"Αποδοχή"</string>
<string name="decline" msgid="6874256900873707640">"Απόρριψη"</string>
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index dc2538c..8813738 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -417,4 +417,20 @@
<!-- Wifi driver Automatic channel selection (ACS) for softap to include DFS channels -->
<bool translatable="false" name="config_wifiSoftapAcsIncludeDfs">false</bool>
+
+ <!-- Initial PNO scan interval, in milliseconds, when the device is moving (i.e.
+ WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN, WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT, or
+ WifiManager.DEVICE_MOBILITY_STATE_LOW_MVMT).
+ The scan interval backs off from this initial interval on subsequent scans.
+ This scan is performed when screen is off and disconnected. -->
+ <integer translatable="false" name="config_wifiMovingPnoScanIntervalMillis">20000</integer>
+
+ <!-- Initial PNO scan interval, in milliseconds, when the device is stationary (i.e.
+ WifiManager.DEVICE_MOBILITY_STATE_STATIONARY).
+ The scan interval backs off from this initial interval on subsequent scans.
+ This scan is performed when screen is off and disconnected. -->
+ <integer translatable="false" name="config_wifiStationaryPnoScanIntervalMillis">60000</integer>
+
+ <!-- integer indicating additional disconnect delay (in ms) after IMS onLost() indication is received -->
+ <integer translatable="false" name="config_wifiDelayDisconnectOnImsLostMs">0</integer>
</resources>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 52ef09e..7b77da5 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -131,6 +131,9 @@
<item type="integer" name="config_wifiMaxNativeFailureSelfRecoveryPerHour" />
<item type="bool" name="config_wifiIgnoreOpenSavedNetworkWhenSecureSuggestionAvailable" />
<item type="bool" name="config_wifiSoftapAcsIncludeDfs" />
+ <item type="integer" name="config_wifiMovingPnoScanIntervalMillis" />
+ <item type="integer" name="config_wifiStationaryPnoScanIntervalMillis" />
+ <item type="integer" name="config_wifiDelayDisconnectOnImsLostMs" />
<!-- Params from config.xml that can be overlayed -->
<!-- Params from strings.xml that can be overlayed -->
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 8195117..bc29d34 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -997,6 +997,8 @@
@Test
public void connect() throws Exception {
triggerConnect();
+ WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID);
+ config.carrierId = CARRIER_ID_1;
when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
.thenReturn(mScanDetailCache);
@@ -1045,6 +1047,7 @@
assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
verify(mWifiStateTracker).updateState(eq(WifiStateTracker.CONNECTED));
assertEquals("ConnectedState", getCurrentState().getName());
+ verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionSuccess();
verify(mWifiLockManager).updateWifiClientConnected(true);
verify(mWifiNative).getConnectionCapabilities(any());
verify(mThroughputPredictor).predictMaxTxThroughput(any());
@@ -1535,6 +1538,60 @@
}
/**
+ * If caller tries to connect to a network that is already connecting, the connection request
+ * should succeed.
+ *
+ * Test: Create and trigger connect to a network, then try to reconnect to the same network.
+ * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did not trigger a
+ * new connection.
+ */
+ @Test
+ public void reconnectToConnectingNetwork() throws Exception {
+ triggerConnect();
+
+ // try to reconnect to the same network (before connection is established).
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0,
+ Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ // Verify that we didn't trigger a second connection.
+ verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any());
+ }
+
+ /**
+ * If caller tries to connect to a network that is already connecting, the connection request
+ * should succeed.
+ *
+ * Test: Create and trigger connect to a network, then try to reconnect to the same network.
+ * Verify that connection request returns with CONNECT_NETWORK_SUCCEEDED and did trigger a new
+ * connection.
+ */
+ @Test
+ public void reconnectToConnectingNetworkWithCredentialChange() throws Exception {
+ triggerConnect();
+
+ // try to reconnect to the same network with a credential changed (before connection is
+ // established).
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = FRAMEWORK_NETWORK_ID;
+ NetworkUpdateResult networkUpdateResult =
+ new NetworkUpdateResult(false /* ip */, false /* proxy */, true /* credential */);
+ networkUpdateResult.setNetworkId(FRAMEWORK_NETWORK_ID);
+ when(mWifiConfigManager.addOrUpdateNetwork(eq(config), anyInt()))
+ .thenReturn(networkUpdateResult);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(config, WifiConfiguration.INVALID_NETWORK_ID, mock(Binder.class),
+ connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ // Verify that we triggered a second connection.
+ verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), any());
+ }
+
+ /**
* If caller tries to connect to a new network while still provisioning the current one,
* the connection attempt should succeed.
*/
@@ -1703,6 +1760,7 @@
WifiConfiguration config = new WifiConfiguration();
config.SSID = sSSID;
config.getNetworkSelectionStatus().setHasEverConnected(false);
+ config.carrierId = CARRIER_ID_1;
when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(config);
mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT,
@@ -1712,7 +1770,7 @@
verify(mWrongPasswordNotifier).onWrongPasswordError(eq(sSSID));
verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(),
eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD));
-
+ verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionAuthFailure();
assertEquals("DisconnectedState", getCurrentState().getName());
}
@@ -2944,6 +3002,8 @@
*/
@Test
public void testReportConnectionEventIsCalledAfterAssociationFailure() throws Exception {
+ mConnectedNetwork.getNetworkSelectionStatus()
+ .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult());
// Setup CONNECT_MODE & a WifiConfiguration
initializeAndAddNetworkAndVerifySuccess();
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
@@ -2962,6 +3022,8 @@
verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded(
eq(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION),
any(WifiConfiguration.class), eq(null));
+ verify(mWifiMetrics, never())
+ .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
verifyConnectionEventTimeoutDoesNotOccur();
}
@@ -2973,6 +3035,8 @@
*/
@Test
public void testReportConnectionEventIsCalledAfterAuthenticationFailure() throws Exception {
+ mConnectedNetwork.getNetworkSelectionStatus()
+ .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult());
// Setup CONNECT_MODE & a WifiConfiguration
initializeAndAddNetworkAndVerifySuccess();
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
@@ -2991,6 +3055,8 @@
verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded(
eq(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE),
any(WifiConfiguration.class), eq(null));
+ verify(mWifiMetrics, never())
+ .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
verifyConnectionEventTimeoutDoesNotOccur();
}
@@ -3069,6 +3135,8 @@
@Test
public void testAssociationRejectionUpdatesWatchdog() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(FRAMEWORK_NETWORK_ID);
+ config.carrierId = CARRIER_ID_1;
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 0, sBSSID);
mLooper.dispatchAll();
@@ -3076,6 +3144,7 @@
anyString(), anyString(), anyInt());
verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(sBSSID, sSSID,
BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION, false);
+ verify(mWifiMetrics).incrementNumOfCarrierWifiConnectionNonAuthFailure();
}
/**
@@ -3165,6 +3234,8 @@
*/
@Test
public void testReportConnectionEventIsCalledAfterDhcpFailure() throws Exception {
+ mConnectedNetwork.getNetworkSelectionStatus()
+ .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult());
testDhcpFailure();
verify(mWifiDiagnostics, atLeastOnce()).reportConnectionEvent(
eq(WifiDiagnostics.CONNECTION_EVENT_FAILED));
@@ -3175,6 +3246,8 @@
verify(mWifiNetworkSuggestionsManager, atLeastOnce()).handleConnectionAttemptEnded(
eq(WifiMetrics.ConnectionEvent.FAILURE_DHCP), any(WifiConfiguration.class),
any(String.class));
+ verify(mWifiMetrics, never())
+ .incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
verifyConnectionEventTimeoutDoesNotOccur();
}
@@ -3186,8 +3259,9 @@
*/
@Test
public void testReportConnectionEventIsCalledAfterSuccessfulConnection() throws Exception {
+ mConnectedNetwork.getNetworkSelectionStatus()
+ .setCandidate(getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq).getScanResult());
connect();
-
ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class);
verify(mConnectivityManager).registerNetworkAgent(messengerCaptor.capture(),
any(NetworkInfo.class), any(LinkProperties.class), any(NetworkCapabilities.class),
@@ -3209,6 +3283,8 @@
verify(mWifiNetworkSuggestionsManager).handleConnectionAttemptEnded(
eq(WifiMetrics.ConnectionEvent.FAILURE_NONE), any(WifiConfiguration.class),
any(String.class));
+ // BSSID different, record this connection.
+ verify(mWifiMetrics).incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
verifyConnectionEventTimeoutDoesNotOccur();
}
@@ -3235,8 +3311,8 @@
*/
@Test
public void testScoreCardNoteConnectionComplete() throws Exception {
- Pair<String, String> l2KeyAndGroupHint = Pair.create("Wad", "Gab");
- when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(l2KeyAndGroupHint);
+ Pair<String, String> l2KeyAndCluster = Pair.create("Wad", "Gab");
+ when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(l2KeyAndCluster);
connect();
mLooper.dispatchAll();
verify(mWifiScoreCard).noteIpConfiguration(any());
@@ -3245,7 +3321,7 @@
verify(mIpClient, atLeastOnce()).updateLayer2Information(captor.capture());
final Layer2InformationParcelable info = captor.getValue();
assertEquals(info.l2Key, "Wad");
- assertEquals(info.groupHint, "Gab");
+ assertEquals(info.cluster, "Gab");
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
index 182e8e4..b733ec0 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
@@ -40,11 +40,16 @@
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.NetworkRequest;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsMmTelManager;
@@ -52,6 +57,8 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
+import com.android.wifi.resources.R;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -61,6 +68,7 @@
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -73,6 +81,7 @@
private static final String TEST_INTERFACE_NAME = "testif0";
private static final String OTHER_INTERFACE_NAME = "notTestIf";
private static final int TEST_WIFI_OFF_DEFERRING_TIME_MS = 4000;
+ private static final int TEST_ACTIVE_SUBSCRIPTION_ID = 1;
TestLooper mLooper;
@@ -90,12 +99,20 @@
@Mock CarrierConfigManager mCarrierConfigManager;
@Mock PersistableBundle mCarrierConfigBundle;
@Mock ImsMmTelManager mImsMmTelManager;
+ @Mock ConnectivityManager mConnectivityManager;
+ @Mock SubscriptionManager mSubscriptionManager;
+ @Mock SubscriptionInfo mActiveSubscriptionInfo;
private RegistrationManager.RegistrationCallback mImsMmTelManagerRegistrationCallback = null;
private @RegistrationManager.ImsRegistrationState int mCurrentImsRegistrationState =
RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
private @AccessNetworkConstants.TransportType int mCurrentImsConnectionType =
AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+ private NetworkRequest mImsRequest = null;
+ private NetworkCallback mImsNetworkCallback = null;
+ private Handler mImsNetworkCallbackHandler = null;
private long mElapsedSinceBootMillis = 0L;
+ private List<SubscriptionInfo> mSubscriptionInfoList = new ArrayList<>();
+ private MockResources mResources;
private MockitoSession mStaticMockSession = null;
@@ -110,6 +127,11 @@
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
.thenReturn(mCarrierConfigManager);
+ when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
+ .thenReturn(mSubscriptionManager);
+ when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
+ .thenReturn(mConnectivityManager);
+ when(mContext.getResources()).thenReturn(mResources);
}
/*
@@ -124,6 +146,12 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+
+ // Prepare data
+ mResources = new MockResources();
+ mResources.setInteger(R.integer.config_wifiDelayDisconnectOnImsLostMs, 0);
+ mSubscriptionInfoList.add(mActiveSubscriptionInfo);
+
setUpSystemServiceForContext();
/**
@@ -136,11 +164,9 @@
.mockStatic(ImsMmTelManager.class)
.mockStatic(SubscriptionManager.class)
.startMocking();
- lenient().when(ImsMmTelManager.createForSubscriptionId(anyInt()))
+ lenient().when(ImsMmTelManager.createForSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID)))
.thenReturn(mImsMmTelManager);
- lenient().when(SubscriptionManager.getDefaultVoiceSubscriptionId())
- .thenReturn(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
- lenient().when(SubscriptionManager.isValidSubscriptionId(anyInt()))
+ lenient().when(SubscriptionManager.isValidSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID)))
.thenReturn(true);
doAnswer(new AnswerWithArguments() {
public void answer(Executor executor, RegistrationManager.RegistrationCallback c) {
@@ -169,7 +195,11 @@
any(RegistrationManager.RegistrationCallback.class));
when(mImsMmTelManager.isAvailable(anyInt(), anyInt())).thenReturn(false);
- when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+ when(mActiveSubscriptionInfo.getSubscriptionId()).thenReturn(TEST_ACTIVE_SUBSCRIPTION_ID);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(mSubscriptionInfoList);
+ when(mTelephonyManager.createForSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID)))
+ .thenReturn(mTelephonyManager);
when(mTelephonyManager.getVoiceNetworkType())
.thenReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN);
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfigBundle);
@@ -177,6 +207,18 @@
.getInt(eq(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT)))
.thenReturn(0);
doAnswer(new AnswerWithArguments() {
+ public void answer(NetworkRequest req, NetworkCallback callback, Handler handler) {
+ mImsRequest = req;
+ mImsNetworkCallback = callback;
+ mImsNetworkCallbackHandler = handler;
+ }
+ }).when(mConnectivityManager).registerNetworkCallback(any(), any(), any());
+ doAnswer(new AnswerWithArguments() {
+ public void answer(NetworkCallback callback) {
+ if (mImsNetworkCallback == callback) mImsNetworkCallback = null;
+ }
+ }).when(mConnectivityManager).unregisterNetworkCallback(any(NetworkCallback.class));
+ doAnswer(new AnswerWithArguments() {
public long answer() {
return mElapsedSinceBootMillis;
}
@@ -369,6 +411,7 @@
ClientModeImpl.SCAN_ONLY_MODE, TEST_INTERFACE_NAME);
verify(mSarManager, times(2)).setScanOnlyWifiState(WIFI_STATE_ENABLED);
+ verify(mContext).getSystemService(anyString());
verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
@@ -686,12 +729,15 @@
// Notify wifi service IMS service is de-registered.
assertNotNull(mImsMmTelManagerRegistrationCallback);
mImsMmTelManagerRegistrationCallback.onUnregistered(null);
+ assertNotNull(mImsNetworkCallback);
+ mImsNetworkCallback.onLost(null);
mLooper.dispatchAll();
// Now Wifi could be turned off actually.
verify(mImsMmTelManager).unregisterImsRegistrationCallback(
any(RegistrationManager.RegistrationCallback.class));
assertNull(mImsMmTelManagerRegistrationCallback);
+ assertNull(mImsNetworkCallback);
verify(mListener).onStopped();
verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
@@ -1003,6 +1049,8 @@
// Notify wifi service IMS service is de-registered.
assertNotNull(mImsMmTelManagerRegistrationCallback);
mImsMmTelManagerRegistrationCallback.onUnregistered(null);
+ assertNotNull(mImsNetworkCallback);
+ mImsNetworkCallback.onLost(null);
mLooper.dispatchAll();
// Now Wifi could be switched to scan mode actually.
@@ -1010,6 +1058,7 @@
verify(mImsMmTelManager).unregisterImsRegistrationCallback(
any(RegistrationManager.RegistrationCallback.class));
assertNull(mImsMmTelManagerRegistrationCallback);
+ assertNull(mImsNetworkCallback);
verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java b/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
index b433d94..02994ec 100644
--- a/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
@@ -333,4 +333,23 @@
mConfigs.clear();
assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
}
+
+ @Test
+ public void testScanResultDoesNotMatchForWifiNetworkSpecifier() {
+ // Add regular saved network, this should create a scan result match info cache entry.
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ ScanResult scanResult = createScanResultForNetwork(config);
+ config.networkId = 5;
+ mConfigs.put(config);
+ assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
+
+ mConfigs.clear();
+
+ // Create WifiNetworkSpecifier network, this should not create a scan result match info
+ // cache entry.
+ config.ephemeral = true;
+ config.fromWifiNetworkSpecifier = true;
+ mConfigs.put(config);
+ assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
index e6b1699..ce3eed0 100644
--- a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
@@ -124,10 +124,14 @@
mDeviceConfigFacade.getDataStallTxPerThr());
assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_CCA_LEVEL_THR,
mDeviceConfigFacade.getDataStallCcaLevelThr());
- assertEquals(DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_THR_LOW_KBPS,
- mDeviceConfigFacade.getTputSufficientLowThrKbps());
- assertEquals(DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_THR_HIGH_KBPS,
- mDeviceConfigFacade.getTputSufficientHighThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS,
+ mDeviceConfigFacade.getTxTputSufficientLowThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS,
+ mDeviceConfigFacade.getTxTputSufficientHighThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS,
+ mDeviceConfigFacade.getRxTputSufficientLowThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS,
+ mDeviceConfigFacade.getRxTputSufficientHighThrKbps());
assertEquals(DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM,
mDeviceConfigFacade.getTputSufficientRatioThrNum());
assertEquals(DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_RATIO_THR_DEN,
@@ -179,6 +183,10 @@
assertEquals(false, mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled());
assertEquals(DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS,
mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs());
+ assertEquals(DeviceConfigFacade.DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS,
+ mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS,
+ mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps());
}
/**
@@ -205,6 +213,10 @@
anyInt())).thenReturn(4000);
when(DeviceConfig.getInt(anyString(), eq("tput_sufficient_high_thr_kbps"),
anyInt())).thenReturn(8000);
+ when(DeviceConfig.getInt(anyString(), eq("rx_tput_sufficient_low_thr_kbps"),
+ anyInt())).thenReturn(5000);
+ when(DeviceConfig.getInt(anyString(), eq("rx_tput_sufficient_high_thr_kbps"),
+ anyInt())).thenReturn(9000);
when(DeviceConfig.getInt(anyString(), eq("tput_sufficient_ratio_thr_num"),
anyInt())).thenReturn(3);
when(DeviceConfig.getInt(anyString(), eq("tput_sufficient_ratio_thr_den"),
@@ -261,6 +273,10 @@
anyBoolean())).thenReturn(true);
when(DeviceConfig.getInt(anyString(), eq("overlapping_connection_duration_threshold_ms"),
anyInt())).thenReturn(50000);
+ when(DeviceConfig.getInt(anyString(), eq("tx_link_speed_low_threshold_mbps"),
+ anyInt())).thenReturn(9);
+ when(DeviceConfig.getInt(anyString(), eq("rx_link_speed_low_threshold_mbps"),
+ anyInt())).thenReturn(10);
mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
@@ -275,8 +291,10 @@
assertEquals(1500, mDeviceConfigFacade.getDataStallRxTputThrKbps());
assertEquals(95, mDeviceConfigFacade.getDataStallTxPerThr());
assertEquals(80, mDeviceConfigFacade.getDataStallCcaLevelThr());
- assertEquals(4000, mDeviceConfigFacade.getTputSufficientLowThrKbps());
- assertEquals(8000, mDeviceConfigFacade.getTputSufficientHighThrKbps());
+ assertEquals(4000, mDeviceConfigFacade.getTxTputSufficientLowThrKbps());
+ assertEquals(8000, mDeviceConfigFacade.getTxTputSufficientHighThrKbps());
+ assertEquals(5000, mDeviceConfigFacade.getRxTputSufficientLowThrKbps());
+ assertEquals(9000, mDeviceConfigFacade.getRxTputSufficientHighThrKbps());
assertEquals(3, mDeviceConfigFacade.getTputSufficientRatioThrNum());
assertEquals(2, mDeviceConfigFacade.getTputSufficientRatioThrDen());
assertEquals(10, mDeviceConfigFacade.getTxPktPerSecondThr());
@@ -306,5 +324,7 @@
assertEquals(1000, mDeviceConfigFacade.getBugReportMinWindowMs());
assertEquals(true, mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled());
assertEquals(50000, mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs());
+ assertEquals(9, mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps());
+ assertEquals(10, mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps());
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
index ed2ccce..3ac4adc 100644
--- a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
@@ -103,6 +103,10 @@
.thenReturn(new int[]{DFS_CHANNEL_FREQ});
when(mWifiSettingsStore.handleWifiToggled(anyBoolean())).thenReturn(true);
+ // Saved network needed to start wake.
+ WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ openNetwork.getNetworkSelectionStatus().setHasEverConnected(true);
+ when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(openNetwork));
mLooper = new TestLooper();
@@ -255,6 +259,19 @@
verify(mWifiWakeMetrics, never()).recordStartEvent(anyInt());
}
+
+ /**
+ * Verify that start does not set the wakeup lock when feature is disabled.
+ */
+ @Test
+ public void startDoesNotSetWakeupLockWhenNoSavedNetworksOrSuggestions() {
+ when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Collections.emptyList());
+ initializeWakeupController(false /* enabled */);
+ mWakeupController.start();
+ verify(mWakeupLock, never()).setLock(any());
+ verify(mWifiWakeMetrics, never()).recordStartEvent(anyInt());
+ }
+
/**
* If the controller is already active, verify that start() is ignored and no setup is done.
*/
@@ -373,7 +390,7 @@
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
WifiNetworkSuggestion wepNetworkSuggestion =
new WifiNetworkSuggestion(wepNetwork, null, false, false, true, true);
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(new HashSet<>(Arrays.asList(
openNetworkSuggestion, wepNetworkSuggestion)));
@@ -415,7 +432,7 @@
WifiConfiguration oweNetwork = WifiConfigurationTestUtil.createOweNetwork(quotedSsid2);
WifiNetworkSuggestion oweNetworkSuggestion =
new WifiNetworkSuggestion(oweNetwork, null, false, false, true, true);
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(new HashSet<>(Arrays.asList(oweNetworkSuggestion)));
// scan results from most recent scan
@@ -513,7 +530,7 @@
.createOpenNetwork(ScanResultUtil.createQuotedSSID(SAVED_SSID));
WifiNetworkSuggestion openNetworkSuggestion =
new WifiNetworkSuggestion(openNetwork, null, false, false, true, true);
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(new HashSet<>(Collections.singletonList(openNetworkSuggestion)));
initializeWakeupController(true /* enabled */);
@@ -537,8 +554,7 @@
*/
@Test
public void onResultsUpdatesWakeupLockWithOnlySavedNetworks() {
- // no saved configs
- when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Collections.emptyList());
+ // no matching saved configs
initializeWakeupController(true /* enabled */);
mWakeupController.start();
@@ -713,7 +729,6 @@
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L,
(long) (0.8 * WakeupController.LAST_DISCONNECT_TIMEOUT_MILLIS));
ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(mTestScanResult);
- when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Collections.emptyList());
when(mWifiScanner.getSingleScanResults()).thenReturn(Collections.emptyList());
initializeWakeupController(true);
@@ -739,7 +754,6 @@
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L,
(long) (1.2 * WakeupController.LAST_DISCONNECT_TIMEOUT_MILLIS));
ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(mTestScanResult);
- when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Collections.emptyList());
when(mWifiScanner.getSingleScanResults()).thenReturn(Collections.emptyList());
initializeWakeupController(true);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
index a2a1a45..6b01f8e 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -832,11 +832,13 @@
List<WifiConfiguration> configurations = new ArrayList<>();
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wepNetwork.setIpConfiguration(
WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
configurations.add(wepNetwork);
WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ pskNetwork.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
pskNetwork.setIpConfiguration(
WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
configurations.add(pskNetwork);
@@ -1113,10 +1115,10 @@
throws IOException {
out.write("network={\n");
out.write(" " + "ssid=" + configuration.SSID + "\n");
- String allowedKeyManagement = "";
if (configuration.hiddenSSID) {
out.write(" " + "scan_ssid=1" + "\n");
}
+ String allowedKeyManagement = "";
if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
allowedKeyManagement += "NONE";
}
@@ -1130,6 +1132,14 @@
allowedKeyManagement += "IEEE8021X ";
}
out.write(" " + "key_mgmt=" + allowedKeyManagement + "\n");
+ String allowedAuthAlgorithm = "";
+ if (configuration.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.OPEN)) {
+ allowedAuthAlgorithm += "OPEN ";
+ }
+ if (configuration.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.SHARED)) {
+ allowedAuthAlgorithm += "SHARED ";
+ }
+ out.write(" " + "auth_alg=" + allowedAuthAlgorithm + "\n");
if (configuration.preSharedKey != null) {
out.write(" " + "psk=" + configuration.preSharedKey + "\n");
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index b01f2be..ba1c4f9 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -109,7 +109,7 @@
when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
when(mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList())
.thenReturn(new ArrayList<>());
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(new HashSet<>());
when(mWifiInjector.getBssidBlocklistMonitor()).thenReturn(mBssidBlocklistMonitor);
when(mWifiInjector.getWifiChannelUtilizationScan()).thenReturn(mWifiChannelUtilization);
@@ -160,6 +160,10 @@
HIGH_MVMT_RSSI_DELTA);
resources.setInteger(R.integer.config_wifiInitialPartialScanChannelCacheAgeMins,
CHANNEL_CACHE_AGE_MINS);
+ resources.setInteger(R.integer.config_wifiMovingPnoScanIntervalMillis,
+ MOVING_PNO_SCAN_INTERVAL_MILLIS);
+ resources.setInteger(R.integer.config_wifiStationaryPnoScanIntervalMillis,
+ STATIONARY_PNO_SCAN_INTERVAL_MILLIS);
}
/**
@@ -244,6 +248,8 @@
private static final int TEMP_BSSID_BLOCK_DURATION_MS = 10 * 1000; // 10 seconds
private static final int TEST_CONNECTED_NETWORK_ID = 55;
private static final int CHANNEL_CACHE_AGE_MINS = 14400;
+ private static final int MOVING_PNO_SCAN_INTERVAL_MILLIS = 20_000;
+ private static final int STATIONARY_PNO_SCAN_INTERVAL_MILLIS = 60_000;
Context mockContext() {
Context context = mock(Context.class);
@@ -601,6 +607,50 @@
}
/**
+ * Multiple back to back connection attempts after a force connectivity scan should not be rate
+ * limited.
+ *
+ * Expected behavior: WifiConnectivityManager calls ClientModeImpl.startConnectToNetwork()
+ * with the expected candidate network ID and BSSID for only the expected number of times within
+ * the given interval.
+ */
+ @Test
+ public void connectionAttemptNotRateLimitedWhenScreenOffForceConnectivityScan() {
+ int maxAttemptRate = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_RATE;
+ int timeInterval = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS;
+ int numAttempts = 0;
+ int connectionAttemptIntervals = timeInterval / maxAttemptRate;
+
+ mWifiConnectivityManager.handleScreenStateChanged(false);
+
+ // First attempt the max rate number of connections within the rate interval.
+ long currentTimeStamp = 0;
+ for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
+ currentTimeStamp += connectionAttemptIntervals;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
+ // Set WiFi to disconnected state to trigger PNO scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ numAttempts++;
+ }
+
+ mWifiConnectivityManager.forceConnectivityScan(new WorkSource());
+
+ for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
+ currentTimeStamp += connectionAttemptIntervals;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
+ // Set WiFi to disconnected state to trigger PNO scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ numAttempts++;
+ }
+
+ // Verify that all the connection attempts went through
+ verify(mClientModeImpl, times(numAttempts)).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ }
+
+ /**
* Multiple back to back connection attempts after a user selection should not be rate limited.
*
* Expected behavior: WifiConnectivityManager calls ClientModeImpl.startConnectToNetwork()
@@ -1497,7 +1547,7 @@
when(mWifiNetworkSuggestion.getWifiConfiguration()).thenReturn(mSuggestionConfig);
Set<WifiNetworkSuggestion> suggestionNetworks = new HashSet<WifiNetworkSuggestion>();
suggestionNetworks.add(mWifiNetworkSuggestion);
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(suggestionNetworks);
// Prepare for no saved networks
@@ -1548,7 +1598,7 @@
when(mWifiNetworkSuggestion.getWifiConfiguration()).thenReturn(mSuggestionConfig);
Set<WifiNetworkSuggestion> suggestionNetworks = new HashSet<WifiNetworkSuggestion>();
suggestionNetworks.add(mWifiNetworkSuggestion);
- when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
+ when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
.thenReturn(suggestionNetworks);
// Prepare for a single passpoint network
@@ -2730,8 +2780,7 @@
inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
scanSettingsCaptor.capture(), any(), any(), any());
- assertEquals(scanSettingsCaptor.getValue().periodInMs,
- WifiConnectivityManager.MOVING_PNO_SCAN_INTERVAL_MS);
+ assertEquals(scanSettingsCaptor.getValue().periodInMs, MOVING_PNO_SCAN_INTERVAL_MILLIS);
// initial connectivity state uses moving PNO scan interval, now set it to stationary
mWifiConnectivityManager.setDeviceMobilityState(
@@ -2740,8 +2789,7 @@
inOrder.verify(mWifiScanner).stopPnoScan(any());
inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
scanSettingsCaptor.capture(), any(), any(), any());
- assertEquals(scanSettingsCaptor.getValue().periodInMs,
- WifiConnectivityManager.STATIONARY_PNO_SCAN_INTERVAL_MS);
+ assertEquals(scanSettingsCaptor.getValue().periodInMs, STATIONARY_PNO_SCAN_INTERVAL_MILLIS);
verify(mScoringParams, times(2)).getEntryRssi(ScanResult.BAND_6_GHZ_START_FREQ_MHZ);
verify(mScoringParams, times(2)).getEntryRssi(ScanResult.BAND_5_GHZ_START_FREQ_MHZ);
verify(mScoringParams, times(2)).getEntryRssi(ScanResult.BAND_24_GHZ_START_FREQ_MHZ);
@@ -2766,8 +2814,7 @@
inOrder.verify(mWifiScanner, never()).stopPnoScan(any());
inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
scanSettingsCaptor.capture(), any(), any(), any());
- assertEquals(scanSettingsCaptor.getValue().periodInMs,
- WifiConnectivityManager.MOVING_PNO_SCAN_INTERVAL_MS);
+ assertEquals(scanSettingsCaptor.getValue().periodInMs, MOVING_PNO_SCAN_INTERVAL_MILLIS);
mWifiConnectivityManager.setDeviceMobilityState(
WifiManager.DEVICE_MOBILITY_STATE_LOW_MVMT);
@@ -2805,8 +2852,7 @@
scanSettingsCaptor.capture(), any(), any(), any());
// check that now the PNO scan uses the stationary interval, even though it was set before
// the PNO scan started
- assertEquals(scanSettingsCaptor.getValue().periodInMs,
- WifiConnectivityManager.STATIONARY_PNO_SCAN_INTERVAL_MS);
+ assertEquals(scanSettingsCaptor.getValue().periodInMs, STATIONARY_PNO_SCAN_INTERVAL_MILLIS);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
index cfe1ee8..e374a90 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
@@ -107,10 +107,14 @@
DeviceConfigFacade.DEFAULT_DATA_STALL_TX_PER_THR);
when(mDeviceConfigFacade.getDataStallCcaLevelThr()).thenReturn(
DeviceConfigFacade.DEFAULT_DATA_STALL_CCA_LEVEL_THR);
- when(mDeviceConfigFacade.getTputSufficientLowThrKbps()).thenReturn(
- DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_THR_LOW_KBPS);
- when(mDeviceConfigFacade.getTputSufficientHighThrKbps()).thenReturn(
- DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_THR_HIGH_KBPS);
+ when(mDeviceConfigFacade.getTxTputSufficientLowThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS);
+ when(mDeviceConfigFacade.getTxTputSufficientHighThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
+ when(mDeviceConfigFacade.getRxTputSufficientLowThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS);
+ when(mDeviceConfigFacade.getRxTputSufficientHighThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
when(mDeviceConfigFacade.getTputSufficientRatioThrNum()).thenReturn(
DeviceConfigFacade.DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM);
when(mDeviceConfigFacade.getTputSufficientRatioThrDen()).thenReturn(
@@ -119,6 +123,10 @@
DeviceConfigFacade.DEFAULT_TX_PACKET_PER_SECOND_THR);
when(mDeviceConfigFacade.getRxPktPerSecondThr()).thenReturn(
DeviceConfigFacade.DEFAULT_RX_PACKET_PER_SECOND_THR);
+ when(mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS);
+ when(mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS);
when(mWifiInfo.getLinkSpeed()).thenReturn(10);
when(mWifiInfo.getRxLinkSpeedMbps()).thenReturn(10);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
index 0660e5e..264fe90 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
@@ -110,6 +110,7 @@
private WifiConfiguration mWifiConfig;
private String mDriverVersion;
private String mFirmwareVersion;
+ private static final long MODULE_VERSION = 1L;
private TestAlarmManager mAlarmManager;
private TestLooper mLooper = new TestLooper();
private List<WifiConfiguration> mConfiguredNetworks;
@@ -152,7 +153,7 @@
mDriverVersion = "build 1.1";
mFirmwareVersion = "HW 1.1";
- mPackageInfo.versionCode = 1;
+ when(mPackageInfo.getLongVersionCode()).thenReturn(MODULE_VERSION);
when(mContext.getPackageName()).thenReturn("WifiAPK");
when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
@@ -310,6 +311,7 @@
// trigger extractCurrentSoftwareBuildInfo() call to update currSoftwareBuildInfo
mWifiHealthMonitor.installMemoryStoreSetUpDetectionAlarm(mMemoryStore);
mWifiHealthMonitor.setWifiEnabled(true);
+ assertEquals(0, mWifiHealthMonitor.getWifiStackVersion());
millisecondsPass(5000);
mWifiScanner.startScan(mScanSettings, mScanListener);
mAlarmManager.dispatch(WifiHealthMonitor.POST_BOOT_DETECTION_TIMER_TAG);
@@ -332,6 +334,14 @@
mKeys.add(key);
mBlobs.add(value);
}
+
+ @Override
+ public void setCluster(String key, String cluster) {
+ }
+
+ @Override
+ public void removeCluster(String cluster) {
+ }
});
mBlobListeners.get(0).onBlobRetrieved(serialized);
@@ -357,6 +367,7 @@
.getWifiFirmwareVersion());
assertEquals(mFirmwareVersion, wifiSystemInfoStats.getPrevSoftwareBuildInfo()
.getWifiFirmwareVersion());
+ assertEquals(MODULE_VERSION, mWifiHealthMonitor.getWifiStackVersion());
// Check write
String writtenHex = hexStringFromByteArray(mBlobs.get(mKeys.size() - 1));
@@ -387,8 +398,7 @@
SystemInfoStats systemInfoStats = SystemInfoStats.parseFrom(serialized);
WifiSoftwareBuildInfo currSoftwareBuildInfoFromMemory = wifiSystemInfoStats
.fromSoftwareBuildInfo(systemInfoStats.getCurrSoftwareBuildInfo());
- assertEquals(mPackageInfo.versionCode,
- currSoftwareBuildInfoFromMemory.getWifiStackVersion());
+ assertEquals(MODULE_VERSION, currSoftwareBuildInfoFromMemory.getWifiStackVersion());
assertEquals(mDriverVersion, currSoftwareBuildInfoFromMemory.getWifiDriverVersion());
assertEquals(mFirmwareVersion, currSoftwareBuildInfoFromMemory.getWifiFirmwareVersion());
assertEquals(Build.DISPLAY, currSoftwareBuildInfoFromMemory.getOsBuildVersion());
@@ -688,11 +698,20 @@
public void read(String key, String name, WifiScoreCard.BlobListener listener) {
mBlobListeners.add(listener);
}
+
@Override
public void write(String key, String name, byte[] value) {
mKeys.add(key);
mBlobs.add(value);
}
+
+ @Override
+ public void setCluster(String key, String cluster) {
+ }
+
+ @Override
+ public void removeCluster(String cluster) {
+ }
});
mBlobListeners.get(0).onBlobRetrieved(serialized);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 04730bb..ca5ae26 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -440,6 +440,8 @@
private static final int NUM_NETWORK_ABNORMAL_ASSOC_REJECTION = 2;
private static final int NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY = 4;
private static final int NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS = 5;
+ private static final int NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE = 3;
+ private static final long WIFI_MAINLINE_MODULE_VERSION = 123456L;
/** Number of notifications per "Connect to Network" notification type. */
private static final int[] NUM_CONNECT_TO_NETWORK_NOTIFICATIONS = {0, 10, 20, 30, 40};
@@ -909,6 +911,9 @@
for (int i = 0; i < NUM_PNO_FOUND_NETWORK_EVENTS; i++) {
mWifiMetrics.incrementPnoFoundNetworkEventCount();
}
+ for (int i = 0; i < NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE; i++) {
+ mWifiMetrics.incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
+ }
// set and increment "connect to network" notification metrics
for (int i = 0; i < NUM_CONNECT_TO_NETWORK_NOTIFICATIONS.length; i++) {
@@ -1006,6 +1011,7 @@
metrics.numNetworkSufficientRecentStatsOnly = NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY;
metrics.numNetworkSufficientRecentPrevStats = NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS;
when(mWifiHealthMonitor.buildProto()).thenReturn(metrics);
+ when(mWifiHealthMonitor.getWifiStackVersion()).thenReturn(WIFI_MAINLINE_MODULE_VERSION);
}
private void addSoftApEventsToMetrics() {
@@ -1324,6 +1330,8 @@
mDecodedProto.numPasspointProviderWithSelfSignedRootCa);
assertEquals(NUM_PASSPOINT_PROVIDERS_WITH_EXPIRATION_DATE,
mDecodedProto.numPasspointProviderWithSubscriptionExpiration);
+ assertEquals(NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE,
+ mDecodedProto.numBssidDifferentSelectionBetweenFrameworkAndFirmware);
assertEquals(NUM_RADIO_MODE_CHANGE_TO_MCC, mDecodedProto.numRadioModeChangeToMcc);
assertEquals(NUM_RADIO_MODE_CHANGE_TO_SCC, mDecodedProto.numRadioModeChangeToScc);
@@ -1406,6 +1414,7 @@
mDecodedProto.numConnectRequestWithFilsAkm);
assertEquals(NUM_L2_CONNECTION_THROUGH_FILS_AUTHENTICATION,
mDecodedProto.numL2ConnectionThroughFilsAuthentication);
+ assertEquals(WIFI_MAINLINE_MODULE_VERSION, mDecodedProto.mainlineModuleVersion);
}
@@ -2285,6 +2294,7 @@
}
mTestLooper.dispatchAll();
wifiMetrics.setScreenState(true);
+ when(mWifiDataStall.isCellularDataAvailable()).thenReturn(true);
for (int i = 0; i < mTestStaLogInts.length; i++) {
int[] lia = mTestStaLogInts[i];
wifiMetrics.logStaEvent(lia[0], lia[1], lia[2] == 1 ? mTestWifiConfig : null);
@@ -2324,6 +2334,7 @@
assertConfigInfoEqualsWifiConfig(
evs[7] == 1 ? mTestWifiConfig : null, event.configInfo);
assertEquals(true, event.screenOn);
+ assertEquals(true, event.isCellularDataAvailable);
j++;
}
assertEquals(mExpectedValues.length, j);
@@ -4967,4 +4978,21 @@
assertEquals(0, mWifiMetrics.startConnectionEvent(mTestWifiConfig, "TestNetwork",
WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE));
}
+
+ @Test
+ public void testCarrierWifiConnectionEvent() throws Exception {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionSuccess();
+ for (int i = 0; i < 2; i++) {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionAuthFailure();
+ }
+ for (int i = 0; i < 3; i++) {
+ mWifiMetrics.incrementNumOfCarrierWifiConnectionNonAuthFailure();
+ }
+
+ dumpProtoAndDeserialize();
+
+ assertEquals(1, mDecodedProto.carrierWifiMetrics.numConnectionSuccess);
+ assertEquals(2, mDecodedProto.carrierWifiMetrics.numConnectionAuthFailure);
+ assertEquals(3, mDecodedProto.carrierWifiMetrics.numConnectionNonAuthFailure);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 25aaeff..5f9e033 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -644,6 +644,35 @@
}
/**
+ * Verify the periodic scan back off to find a network matching the network specifier
+ * is cancelled when the user selects a network.
+ */
+ @Test
+ public void testPeriodicScanCancelOnUserSelectNetwork() throws Exception {
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
+ TEST_CALLBACK_IDENTIFIER);
+ verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
+ mNetworkRequestUserSelectionCallback.capture());
+
+ verifyPeriodicScans(0,
+ PERIODIC_SCAN_INTERVAL_MS, // 10s
+ PERIODIC_SCAN_INTERVAL_MS); // 10s
+
+ // Now trigger user selection to one of the network.
+ mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ mSelectedNetwork.SSID = "\"" + TEST_SSID_1 + "\"";
+ sendUserSelectionSelect(mNetworkRequestUserSelectionCallback.getValue(), mSelectedNetwork);
+ mLooper.dispatchAll();
+
+ // Cancel the alarm set for the next scan.
+ verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
+ }
+
+
+ /**
* Verify callback registration/unregistration.
*/
@Test
@@ -1345,7 +1374,7 @@
}
mInOrder = inOrder(mAlarmManager, mClientModeImpl);
- validateConnectionRetryAttempts();
+ validateConnectionRetryAttempts(true);
// Fail the request after all the retries are exhausted.
verify(mNetworkRequestMatchCallback).onAbort();
@@ -1373,7 +1402,7 @@
mLooper.dispatchAll();
mInOrder = inOrder(mAlarmManager, mClientModeImpl);
- validateConnectionRetryAttempts();
+ validateConnectionRetryAttempts(false);
// Fail the request after all the retries are exhausted.
verify(mNetworkRequestMatchCallback).onAbort();
@@ -1407,7 +1436,7 @@
}
mInOrder = inOrder(mAlarmManager, mClientModeImpl);
- validateConnectionRetryAttempts();
+ validateConnectionRetryAttempts(false);
verify(mNetworkRequestMatchCallback).onAbort();
// Verify that we sent the connection failure callback.
@@ -1453,7 +1482,7 @@
}
mInOrder = inOrder(mAlarmManager, mClientModeImpl);
- validateConnectionRetryAttempts();
+ validateConnectionRetryAttempts(false);
// Verify that we sent the connection failure callback.
verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
@@ -2783,11 +2812,13 @@
}
}
- private void validateConnectionRetryAttempts() {
+ private void validateConnectionRetryAttempts(boolean onTimeout) {
for (int i = 0; i < WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
- // Cancel the existing connection timeout.
- mInOrder.verify(mAlarmManager).cancel(
- mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+ if (!onTimeout) {
+ // Cancel the existing connection timeout.
+ mInOrder.verify(mAlarmManager).cancel(
+ mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+ }
// Trigger new connection.
mInOrder.verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1),
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 897dca3..e7e8660 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -4018,6 +4018,53 @@
}
/**
+ * Verify that we only return user approved suggestions.
+ */
+ @Test
+ public void testGetApprovedNetworkSuggestions() {
+ WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
+ WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
+ wifiConfiguration, null, false, false, true, true);
+ // Reuse the same network credentials to ensure they both match.
+ WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
+ wifiConfiguration, null, false, false, true, true);
+
+ List<WifiNetworkSuggestion> networkSuggestionList1 =
+ new ArrayList<WifiNetworkSuggestion>() {{
+ add(networkSuggestion1);
+ }};
+ List<WifiNetworkSuggestion> networkSuggestionList2 =
+ new ArrayList<WifiNetworkSuggestion>() {{
+ add(networkSuggestion2);
+ }};
+
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1,
+ TEST_PACKAGE_1, TEST_FEATURE));
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(networkSuggestionList2, TEST_UID_2,
+ TEST_PACKAGE_2, TEST_FEATURE));
+
+ // nothing approved, return empty.
+ assertTrue(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions().isEmpty());
+
+ mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
+ // only app 1 approved.
+ assertEquals(new HashSet<WifiNetworkSuggestion>() {{
+ add(networkSuggestion1);
+ }},
+ mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions());
+
+ mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_2);
+ // both app 1 & 2 approved.
+ assertEquals(new HashSet<WifiNetworkSuggestion>() {{
+ add(networkSuggestion1);
+ add(networkSuggestion2);
+ }},
+ mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions());
+ }
+
+ /**
* Helper function for creating a test configuration with user credential.
*
* @return {@link PasspointConfiguration}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
index e5525c4..1ad767c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
@@ -688,6 +688,14 @@
public void write(String key, String name, byte[] value) {
// ignore for now
}
+ @Override
+ public void setCluster(String key, String cluster) {
+ // ignore for now
+ }
+ @Override
+ public void removeCluster(String cluster) {
+ // ignore for now
+ }
});
// Now make some changes
@@ -724,6 +732,13 @@
mKeys.add(key);
mBlobs.add(value);
}
+ @Override
+ public void setCluster(String key, String cluster) {
+ }
+ @Override
+ public void removeCluster(String cluster) {
+ // ignore for now
+ }
});
// Make some changes
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index d91dffb..603a4d8 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -1324,6 +1324,24 @@
}
/**
+ * Verify that startSoftAp() with valid config succeeds after a failed call
+ */
+ @Test
+ public void testStartSoftApWithValidConfigSucceedsAfterFailure() {
+ // First initiate a failed call
+ assertFalse(mWifiServiceImpl.startSoftAp(mApConfig));
+ verify(mActiveModeWarden, never()).startSoftAp(any());
+
+ // Next attempt a valid config
+ WifiConfiguration config = createValidWifiApConfiguration();
+ assertTrue(mWifiServiceImpl.startSoftAp(config));
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
+ WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
+ config,
+ mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
+ }
+
+ /**
* Verify caller with proper permission can call startTetheredHotspot.
*/
@Test
@@ -1497,6 +1515,22 @@
}
/**
+ * Verify a valied call to startTetheredHotspot succeeds after a failed call.
+ */
+ @Test
+ public void testStartTetheredHotspotWithValidConfigSucceedsAfterFailedCall() {
+ // First issue an invalid call
+ assertFalse(mWifiServiceImpl.startTetheredHotspot(
+ new SoftApConfiguration.Builder().build()));
+ verify(mActiveModeWarden, never()).startSoftAp(any());
+
+ // Now attempt a successful call
+ assertTrue(mWifiServiceImpl.startTetheredHotspot(null));
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
+ assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ }
+
+ /**
* Verify caller with proper permission can call stopSoftAp.
*/
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
index df74173..f496b1c 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -1394,9 +1394,15 @@
mMockLooper.dispatchAll();
// (2) get confirmation OR timeout
+ boolean timeout = false;
if (getConfirmation) {
+ int numConfigureAgentPropertiesFail = 0;
if (numAddrValidationRetries > 0) {
when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(false);
+ when(mMockNetworkInterface.configureAgentProperties(any(), any(), anyInt(),
+ any(), any())).thenReturn(false);
+ // First retry will be ConfigureAgentProperties failure.
+ numConfigureAgentPropertiesFail = 1;
}
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
@@ -1406,35 +1412,41 @@
inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(), anyInt(),
any(), any());
- inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(), any(), any(),
- netCapCaptor.capture(), anyInt(), any(), anyInt());
-
- inOrder.verify(mMockNetworkInterface).isAddressUsable(any());
- boolean timedout = false;
+ if (numAddrValidationRetries <= 0) {
+ inOrder.verify(mMockNetworkInterface).isAddressUsable(any());
+ }
for (int i = 0; i < numAddrValidationRetries; ++i) {
+ if (i == numConfigureAgentPropertiesFail) {
+ when(mMockNetworkInterface.configureAgentProperties(any(), any(), anyInt(),
+ any(), any())).thenReturn(true);
+ }
if (i == numAddrValidationRetries - 1) {
when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(true);
}
-
long currentTime = (i + 1L)
* WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS;
when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime);
mMockLooper.moveTimeForward(
WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS + 1);
mMockLooper.dispatchAll();
+ inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(),
+ anyInt(), any(), any());
+ if (i < numConfigureAgentPropertiesFail) {
+ continue;
+ }
inOrder.verify(mMockNetworkInterface).isAddressUsable(any());
-
if (currentTime > WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS) {
- timedout = true;
+ timeout = true;
break;
}
}
-
- if (timedout) {
+ if (timeout) {
verifyRequestDeclaredUnfullfillable(nr);
inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
} else {
+ inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(), any(),
+ any(), netCapCaptor.capture(), anyInt(), any(), anyInt());
inOrder.verify(mMockNetworkInterface).setConnected(any());
inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
eq(useDirect), anyLong());
@@ -1458,7 +1470,7 @@
}
// (3) end data-path (unless didn't get confirmation)
- if (getConfirmation) {
+ if (getConfirmation && !timeout) {
Message endNetworkReqMsg = Message.obtain();
endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
endNetworkReqMsg.obj = nr;