summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorxshu <xshu@google.com>2020-08-19 17:07:03 -0700
committerxshu <xshu@google.com>2020-09-02 16:31:02 -0700
commitda1b2e9ed28829fd434cd2bedd5932961696e479 (patch)
tree02347a64047af513995142ad2e1c19a06d592f67 /service
parent6aa15665ac75806ff5c688cff47e8dd671130b1f (diff)
Adding network disabled status to user action metrics
(cherry-picked from acd5659d05dacf1de79489c7740c87e95cbf5b03) When a user action is triggered, take note of the reasons WifiConfigurations and BSSIDs are disabled. This information will be used to gain insight why we did not auto-connect to manaually selected networks. Updated-PDD: true Bug: 165118962 Test: com.android.server.wifi Test: Manual verification with dumpsys log Change-Id: I7d3a0a933e4f9f45b20019ace3013e1661212fad Merged-In: I7d3a0a933e4f9f45b20019ace3013e1661212fad
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/BssidBlocklistMonitor.java17
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java53
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java11
-rw-r--r--service/java/com/android/server/wifi/util/MetricsUtils.java65
-rw-r--r--service/proto/src/metrics.proto55
5 files changed, 196 insertions, 5 deletions
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
index bc41aa929..d96fdb39e 100644
--- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
@@ -37,6 +37,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -60,7 +61,7 @@ public class BssidBlocklistMonitor {
public static final int REASON_EAP_FAILURE = 3;
// Other association rejection failures
public static final int REASON_ASSOCIATION_REJECTION = 4;
- // Associated timeout failures, when the RSSI is good
+ // Association timeout failures.
public static final int REASON_ASSOCIATION_TIMEOUT = 5;
// Other authentication failures
public static final int REASON_AUTHENTICATION_FAILURE = 6;
@@ -528,6 +529,20 @@ public class BssidBlocklistMonitor {
}
/**
+ * Gets the list of block reasons for BSSIDs currently in the blocklist.
+ * @return The set of unique reasons for blocking BSSIDs with this SSID.
+ */
+ public Set<Integer> getFailureReasonsForSsid(@NonNull String ssid) {
+ if (ssid == null) {
+ return Collections.emptySet();
+ }
+ return mBssidStatusMap.values().stream()
+ .filter(entry -> entry.isInBlocklist && ssid.equals(entry.ssid))
+ .map(entry -> entry.blockReason)
+ .collect(Collectors.toSet());
+ }
+
+ /**
* Attempts to re-enable BSSIDs that likely experienced failures due to low RSSI.
* @param scanDetails
*/
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index a5771f7e3..1ac361ef3 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -29,6 +29,7 @@ import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -74,6 +75,7 @@ import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.Experi
import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount;
import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkSpeedCount;
import com.android.server.wifi.proto.nano.WifiMetricsProto.MeteredNetworkStats;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkDisableReason;
import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions;
import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProfileTypeCount;
import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProvisionStats;
@@ -114,6 +116,7 @@ import org.json.JSONObject;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.HashMap;
@@ -808,6 +811,35 @@ public class WifiMetrics {
}
}
+ private NetworkDisableReason convertToNetworkDisableReason(
+ WifiConfiguration config, Set<Integer> bssidBlocklistReasons) {
+ NetworkSelectionStatus status = config.getNetworkSelectionStatus();
+ NetworkDisableReason result = new NetworkDisableReason();
+ if (config.allowAutojoin) {
+ if (!status.isNetworkEnabled()) {
+ result.disableReason =
+ MetricsUtils.convertNetworkSelectionDisableReasonToWifiProtoEnum(
+ status.getNetworkSelectionDisableReason());
+ if (status.isNetworkPermanentlyDisabled()) {
+ result.configPermanentlyDisabled = true;
+ } else {
+ result.configTemporarilyDisabled = true;
+ }
+ }
+ } else {
+ result.disableReason = NetworkDisableReason.REASON_AUTO_JOIN_DISABLED;
+ result.configPermanentlyDisabled = true;
+ }
+
+ int[] convertedBssidBlockReasons = bssidBlocklistReasons.stream()
+ .mapToInt(i -> MetricsUtils.convertBssidBlocklistReasonToWifiProtoEnum(i))
+ .toArray();
+ if (convertedBssidBlockReasons.length > 0) {
+ result.bssidDisableReasons = convertedBssidBlockReasons;
+ }
+ return result;
+ }
+
class UserActionEventWithTime {
private UserActionEvent mUserActionEvent;
private long mWallClockTimeMs = 0; // wall clock time for debugging only
@@ -830,6 +862,8 @@ public class WifiMetrics {
networkInfo.isEphemeral = config.isEphemeral();
networkInfo.isPasspoint = config.isPasspoint();
mUserActionEvent.targetNetworkInfo = networkInfo;
+ mUserActionEvent.networkDisableReason = convertToNetworkDisableReason(
+ config, mBssidBlocklistMonitor.getFailureReasonsForSsid(config.SSID));
}
}
}
@@ -890,7 +924,24 @@ public class WifiMetrics {
}
WifiStatus wifiStatus = mUserActionEvent.wifiStatus;
if (wifiStatus != null) {
- sb.append("\nWifiStatus=" + wifiStatus.toString());
+ sb.append("\nWifiStatus: isConnected=").append(wifiStatus.isConnected);
+ sb.append(" isValidated=").append(wifiStatus.isValidated);
+ sb.append(" lastRssi=").append(wifiStatus.lastRssi);
+ sb.append(" estimatedTxKbps=").append(wifiStatus.estimatedTxKbps);
+ sb.append(" estimatedRxKbps=").append(wifiStatus.estimatedRxKbps);
+ sb.append(" isStuckDueToUserConnectChoice=")
+ .append(wifiStatus.isStuckDueToUserConnectChoice);
+ }
+ NetworkDisableReason disableReason = mUserActionEvent.networkDisableReason;
+ if (disableReason != null) {
+ sb.append("\nNetworkDisableReason: DisableReason=")
+ .append(disableReason.disableReason);
+ sb.append(" configTemporarilyDisabled=")
+ .append(disableReason.configTemporarilyDisabled);
+ sb.append(" configPermanentlyDisabled=")
+ .append(disableReason.configPermanentlyDisabled);
+ sb.append(" bssidDisableReasons=")
+ .append(Arrays.toString(disableReason.bssidDisableReasons));
}
return sb.toString();
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 20aea050a..5019f54e8 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -802,8 +802,13 @@ public class WifiServiceImpl extends BaseWifiService {
Binder.restoreCallingIdentity(ident);
}
if (mWifiPermissionsUtil.checkNetworkSettingsPermission(Binder.getCallingUid())) {
- mWifiMetrics.logUserActionEvent(enable ? UserActionEvent.EVENT_TOGGLE_WIFI_ON
- : UserActionEvent.EVENT_TOGGLE_WIFI_OFF);
+ if (enable) {
+ mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
+ } else {
+ WifiInfo wifiInfo = mClientModeImpl.syncRequestConnectionInfo();
+ mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_OFF,
+ wifiInfo == null ? -1 : wifiInfo.getNetworkId());
+ }
}
mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
mActiveModeWarden.wifiToggled();
@@ -4118,7 +4123,6 @@ public class WifiServiceImpl extends BaseWifiService {
throw new SecurityException(TAG + ": Permission denied");
}
mLog.info("connect uid=%").c(uid).flush();
- mClientModeImpl.connect(config, netId, binder, callback, callbackIdentifier, uid);
if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
if (config == null) {
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_MANUAL_CONNECT, netId);
@@ -4127,6 +4131,7 @@ public class WifiServiceImpl extends BaseWifiService {
UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK, config.networkId);
}
}
+ mClientModeImpl.connect(config, netId, binder, callback, callbackIdentifier, uid);
}
/**
diff --git a/service/java/com/android/server/wifi/util/MetricsUtils.java b/service/java/com/android/server/wifi/util/MetricsUtils.java
index 2c9c7f741..4c87aa237 100644
--- a/service/java/com/android/server/wifi/util/MetricsUtils.java
+++ b/service/java/com/android/server/wifi/util/MetricsUtils.java
@@ -16,8 +16,12 @@
package com.android.server.wifi.util;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.util.SparseIntArray;
+import com.android.server.wifi.BssidBlocklistMonitor;
+import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkDisableReason;
+
/**
* Utilities for Metrics collections.
*/
@@ -188,4 +192,65 @@ public class MetricsUtils {
return protoArray;
}
+
+ /**
+ * Converts NetworkSelectionStatus.NetworkSelectionDisableReason to
+ * WifiMetricsProto.NetworkDisableReason.DisableReason
+ */
+ public static int convertNetworkSelectionDisableReasonToWifiProtoEnum(int reason) {
+ switch (reason) {
+ case NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION:
+ return NetworkDisableReason.REASON_ASSOCIATION_REJECTION;
+ case NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
+ return NetworkDisableReason.REASON_AUTHENTICATION_FAILURE;
+ case NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
+ return NetworkDisableReason.REASON_DHCP_FAILURE;
+ case NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY:
+ case NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT:
+ return NetworkDisableReason.REASON_NETWORK_VALIDATION_FAILURE;
+ case NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS:
+ return NetworkDisableReason.REASON_AUTHENTICATION_NO_CREDENTIALS;
+ case NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
+ return NetworkDisableReason.REASON_WRONG_PASSWORD;
+ case NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_SUBSCRIPTION:
+ return NetworkDisableReason.REASON_AUTHENTICATION_NO_SUBSCRIPTION;
+ default:
+ return NetworkDisableReason.REASON_UNKNOWN;
+ }
+ }
+
+ /**
+ * Converts BssidBlocklistMonitor.FailureReason to
+ * WifiMetricsProto.NetworkDisableReason.DisableReason
+ */
+ public static int convertBssidBlocklistReasonToWifiProtoEnum(int reason) {
+ switch (reason) {
+ case BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA:
+ return NetworkDisableReason.REASON_AP_UNABLE_TO_HANDLE_NEW_STA;
+ case BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE:
+ return NetworkDisableReason.REASON_NETWORK_VALIDATION_FAILURE;
+ case BssidBlocklistMonitor.REASON_WRONG_PASSWORD:
+ return NetworkDisableReason.REASON_WRONG_PASSWORD;
+ case BssidBlocklistMonitor.REASON_EAP_FAILURE:
+ return NetworkDisableReason.REASON_EAP_FAILURE;
+ case BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION:
+ return NetworkDisableReason.REASON_ASSOCIATION_REJECTION;
+ case BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT:
+ return NetworkDisableReason.REASON_ASSOCIATION_TIMEOUT;
+ case BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE:
+ return NetworkDisableReason.REASON_AUTHENTICATION_FAILURE;
+ case BssidBlocklistMonitor.REASON_DHCP_FAILURE:
+ return NetworkDisableReason.REASON_DHCP_FAILURE;
+ case BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT:
+ return NetworkDisableReason.REASON_ABNORMAL_DISCONNECT;
+ case BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_MBO_OCE:
+ return NetworkDisableReason.REASON_FRAMEWORK_DISCONNECT_MBO_OCE;
+ case BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT:
+ return NetworkDisableReason.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT;
+ case BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE:
+ return NetworkDisableReason.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE;
+ default:
+ return NetworkDisableReason.REASON_UNKNOWN;
+ }
+ }
}
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index a9c759e7e..a7f706fb8 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -3172,6 +3172,11 @@ message UserActionEvent {
// Information about the currently connected network.
optional WifiStatus wifi_status = 4;
+
+ // Reasons why the network applicable for this user action is disabled.
+ // Normally this should be referring to the currently connected network.
+ // For a manual connection, this is referring to the user selected networks.
+ optional NetworkDisableReason network_disable_reason = 5;
}
message WifiStatus {
@@ -3203,6 +3208,56 @@ message TargetNetworkInfo {
optional bool is_passpoint = 2;
}
+// Reasons why a configuration or BSSID is disabled.
+message NetworkDisableReason {
+ enum DisableReason {
+ // Default value, should not be used.
+ REASON_UNKNOWN = 0;
+ // AP unable to accept more clients, a special kind of association rejection failure.
+ REASON_AP_UNABLE_TO_HANDLE_NEW_STA = 1;
+ // No internet
+ REASON_NETWORK_VALIDATION_FAILURE = 2;
+ // Password is incorrect, a special kind of authentication failure.
+ REASON_WRONG_PASSWORD = 3;
+ // Incorrect EAP credentials.
+ REASON_EAP_FAILURE = 4;
+ // Other association rejection failures.
+ REASON_ASSOCIATION_REJECTION = 5;
+ // Associated timeout failures.
+ REASON_ASSOCIATION_TIMEOUT = 6;
+ // Other authentication failures.
+ REASON_AUTHENTICATION_FAILURE = 7;
+ // DHCP failures.
+ REASON_DHCP_FAILURE = 8;
+ // Device disconnected shortly after connection.
+ REASON_ABNORMAL_DISCONNECT = 9;
+ // AP initiated disconnect for a given duration.
+ REASON_FRAMEWORK_DISCONNECT_MBO_OCE = 10;
+ // Avoid connecting to the failed AP when trying to reconnect on other available candidates.
+ REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT = 11;
+ // The connected scorer has disconnected this network.
+ REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE = 12;
+ // The network is disabled due to absence of user credentials
+ REASON_AUTHENTICATION_NO_CREDENTIALS = 13;
+ // The network is disabled because service is not subscribed, a special kind of EAP failure.
+ REASON_AUTHENTICATION_NO_SUBSCRIPTION = 14;
+ // User disabled auto-join for this network.
+ REASON_AUTO_JOIN_DISABLED = 15;
+ }
+
+ // The reason for disabling a network.
+ optional DisableReason disable_reason = 1;
+
+ // The configuration is temporarily disabled.
+ optional bool config_temporarily_disabled = 2;
+
+ // The configuration is disabled until the user manually re-enables it.
+ optional bool config_permanently_disabled = 3;
+
+ // Reasons why 1 or more BSSIDs are temporarily disabled.
+ repeated DisableReason bssid_disable_reasons = 4;
+}
+
// Number of networks with a large change of connection/disconnection
// failure rate or high failure rate at high RSSI
message HealthMonitorFailureStats {