summaryrefslogtreecommitdiff
path: root/libs/WifiTrackerLib/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/WifiTrackerLib/src')
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java62
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkDetailsTracker.java10
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkEntry.java108
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java12
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java9
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java4
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java25
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java12
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java4
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java27
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java130
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java69
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java122
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java31
14 files changed, 448 insertions, 177 deletions
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
index e464090a5..d704d395c 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
@@ -42,7 +42,6 @@ import android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus;
import android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback;
import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
-import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.telephony.SubscriptionManager;
@@ -92,10 +91,8 @@ import java.util.concurrent.Executor;
public class BaseWifiTracker {
private final String mTag;
- private static boolean sVerboseLogging;
-
- public static boolean isVerboseLoggingEnabled() {
- return BaseWifiTracker.sVerboseLogging;
+ public boolean isVerboseLoggingEnabled() {
+ return mInjector.isVerboseLoggingEnabled();
}
private int mWifiState = WifiManager.WIFI_STATE_DISABLED;
@@ -192,18 +189,20 @@ public class BaseWifiTracker {
@WorkerThread
public void onCapabilitiesChanged(@NonNull Network network,
@NonNull NetworkCapabilities networkCapabilities) {
- List<Network> underlyingNetworks =
- networkCapabilities.getUnderlyingNetworks();
+ // If the default network has an underlying Wi-Fi network (e.g. it's
+ // a VPN), treat the Wi-Fi network as the default network.
+ List<Network> underlyingNetworks = BuildCompat.isAtLeastT()
+ ? networkCapabilities.getUnderlyingNetworks() : null;
if (underlyingNetworks != null) {
- Network currentWifiNetwork = mWifiManager.getCurrentNetwork();
- if (underlyingNetworks.contains(currentWifiNetwork)) {
- // If the default network has an underlying Wi-Fi network (e.g. it's
- // a VPN), treat the Wi-Fi network as the default network.
- handleDefaultNetworkCapabilitiesChanged(currentWifiNetwork,
- new NetworkCapabilities.Builder(networkCapabilities)
- .setTransportInfo(mWifiManager.getConnectionInfo())
- .build());
- return;
+ for (Network underlyingNetwork : underlyingNetworks) {
+ NetworkCapabilities underlyingNetworkCapabilities =
+ mConnectivityManager.getNetworkCapabilities(underlyingNetwork);
+ if (underlyingNetworkCapabilities != null
+ && underlyingNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) {
+ handleDefaultNetworkCapabilitiesChanged(
+ underlyingNetwork, underlyingNetworkCapabilities);
+ return;
+ }
}
}
handleDefaultNetworkCapabilitiesChanged(network, networkCapabilities);
@@ -345,9 +344,6 @@ public class BaseWifiTracker {
BaseWifiTracker.this.onDestroy();
}
};
- if (lifecycle != null) {
- lifecycle.addObserver(mLifecycleObserver);
- }
mContext = context;
mWifiManager = wifiManager;
mConnectivityManager = connectivityManager;
@@ -367,12 +363,9 @@ public class BaseWifiTracker {
mScanResultUpdater = new ScanResultUpdater(clock,
maxScanAgeMillis + scanIntervalMillis);
mScanner = new BaseWifiTracker.Scanner(workerHandler.getLooper());
- if (mContext.getResources().getBoolean(
- R.bool.wifitrackerlib_enable_verbose_logging_for_userdebug)
- && Build.TYPE.equals("userdebug")) {
- sVerboseLogging = true;
- } else {
- sVerboseLogging = mWifiManager.isVerboseLoggingEnabled();
+
+ if (lifecycle != null) { // Need to add after mScanner is initialized.
+ lifecycle.addObserver(mLifecycleObserver);
}
}
@@ -383,7 +376,7 @@ public class BaseWifiTracker {
mIsScanningDisabled = true;
// This method indicates SystemUI usage, which shouldn't output verbose logs since it's
// always up.
- sVerboseLogging = false;
+ mInjector.disableVerboseLogging();
}
/**
@@ -838,6 +831,7 @@ public class BaseWifiTracker {
Log.v(mTag, "Issuing scan request from WifiScanner");
}
wifiScanner.startScan(scanSettings, mFirstScanListener);
+ notifyOnScanRequested();
return;
} else {
Log.e(mTag, "Failed to retrieve WifiScanner!");
@@ -872,6 +866,7 @@ public class BaseWifiTracker {
// Remove any pending scanLoops in case possiblyStartScanning was called more than once.
removeCallbacksAndMessages(null);
mWifiManager.startScan();
+ notifyOnScanRequested();
postDelayed(this::scanLoop, mScanIntervalMillis);
}
}
@@ -894,6 +889,16 @@ public class BaseWifiTracker {
}
/**
+ * Posts onScanRequested callback on the main thread.
+ */
+ @WorkerThread
+ private void notifyOnScanRequested() {
+ if (mListener != null) {
+ mMainHandler.post(mListener::onScanRequested);
+ }
+ }
+
+ /**
* Base callback handling Wi-Fi state changes
*
* Subclasses should extend this for their own needs.
@@ -904,5 +909,10 @@ public class BaseWifiTracker {
*/
@MainThread
void onWifiStateChanged();
+
+ @MainThread
+ default void onScanRequested() {
+ // Do nothing.
+ }
}
}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkDetailsTracker.java
index 6b392954f..e223ec403 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkDetailsTracker.java
@@ -112,9 +112,13 @@ public class HotspotNetworkDetailsTracker extends NetworkDetailsTracker {
@Override
protected void handleServiceConnected() {
if (mInjector.isSharedConnectivityFeatureEnabled() && mSharedConnectivityManager != null) {
- mHotspotNetworkData = mSharedConnectivityManager.getHotspotNetworks().stream().filter(
- network -> network.getDeviceId() == mChosenEntry.getHotspotNetworkEntryKey()
- .getDeviceId()).findFirst().orElse(null);
+ List<HotspotNetwork> hotspotNetworks = mSharedConnectivityManager.getHotspotNetworks();
+ if (hotspotNetworks != null) {
+ mHotspotNetworkData = hotspotNetworks.stream().filter(
+ network -> network.getDeviceId()
+ == mChosenEntry.getHotspotNetworkEntryKey().getDeviceId())
+ .findFirst().orElse(null);
+ }
}
if (mHotspotNetworkData == null) {
throw new IllegalArgumentException(
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkEntry.java
index 9da34caa0..67aca3dec 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HotspotNetworkEntry.java
@@ -19,8 +19,10 @@ package com.android.wifitrackerlib;
import static android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS;
import static android.os.Build.VERSION_CODES;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
+import android.icu.text.MessageFormat;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.sharedconnectivity.app.HotspotNetwork;
@@ -37,6 +39,7 @@ import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
+import androidx.core.os.BuildCompat;
import org.json.JSONException;
import org.json.JSONObject;
@@ -45,6 +48,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
/**
@@ -54,6 +59,10 @@ import java.util.Objects;
public class HotspotNetworkEntry extends WifiEntry {
static final String TAG = "HotspotNetworkEntry";
public static final String KEY_PREFIX = "HotspotNetworkEntry:";
+ public static final String EXTRA_KEY_IS_BATTERY_CHARGING = "is_battery_charging";
+
+ private static final String DEVICE_TYPE_KEY = "DEVICE_TYPE";
+ private static final String NETWORK_NAME_KEY = "NETWORK_NAME";
@NonNull private final WifiTrackerInjector mInjector;
@NonNull private final Context mContext;
@@ -61,6 +70,9 @@ public class HotspotNetworkEntry extends WifiEntry {
@Nullable private HotspotNetwork mHotspotNetworkData;
@NonNull private HotspotNetworkEntryKey mKey;
+ @ConnectionStatus
+ private int mLastStatus = HotspotNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN;
+ private boolean mConnectionError = false;
/**
* If editing this IntDef also edit the definition in:
@@ -94,6 +106,8 @@ public class HotspotNetworkEntry extends WifiEntry {
})
public @interface DeviceType {} // TODO(b/271868642): Add IfThisThanThat lint
+ public static final int CONNECTION_STATUS_CONNECTED = 10;
+
/**
* If editing this IntDef also edit the definition in:
* {@link android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus}
@@ -112,6 +126,7 @@ public class HotspotNetworkEntry extends WifiEntry {
HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED,
HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT,
HotspotNetworkConnectionStatus.CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED,
+ CONNECTION_STATUS_CONNECTED,
})
public @interface ConnectionStatus {} // TODO(b/271868642): Add IfThisThanThat lint
@@ -205,10 +220,42 @@ public class HotspotNetworkEntry extends WifiEntry {
if (mCalledConnect) {
return mContext.getString(R.string.wifitrackerlib_hotspot_network_connecting);
}
- return mContext.getString(R.string.wifitrackerlib_hotspot_network_summary,
- BidiFormatter.getInstance().unicodeWrap(mHotspotNetworkData.getNetworkName()),
- BidiFormatter.getInstance().unicodeWrap(
- mHotspotNetworkData.getNetworkProviderInfo().getModelName()));
+ if (mConnectionError) {
+ switch (mLastStatus) {
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_PROVISIONING_FAILED:
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_TETHERING_TIMEOUT:
+ return mContext.getString(
+ R.string.wifitrackerlib_hotspot_network_summary_error_carrier_incomplete,
+ BidiFormatter.getInstance().unicodeWrap(
+ mHotspotNetworkData.getNetworkName()));
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_TETHERING_UNSUPPORTED:
+ return mContext.getString(
+ R.string.wifitrackerlib_hotspot_network_summary_error_carrier_block,
+ BidiFormatter.getInstance().unicodeWrap(
+ mHotspotNetworkData.getNetworkName()));
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_NO_CELL_DATA:
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED:
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT:
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED:
+ MessageFormat msg = new MessageFormat(mContext.getString(
+ R.string.wifitrackerlib_hotspot_network_summary_error_settings));
+ Map<String, Object> args = new HashMap<>();
+ args.put(DEVICE_TYPE_KEY, getDeviceTypeId(
+ mHotspotNetworkData.getNetworkProviderInfo().getDeviceType()));
+ return msg.format(args);
+ case HotspotNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN_ERROR:
+ default:
+ return mContext.getString(
+ R.string.wifitrackerlib_hotspot_network_summary_error_generic);
+ }
+ }
+ MessageFormat msg = new MessageFormat(
+ mContext.getString(R.string.wifitrackerlib_hotspot_network_summary_new));
+ Map<String, Object> args = new HashMap<>();
+ args.put(DEVICE_TYPE_KEY,
+ getDeviceTypeId(mHotspotNetworkData.getNetworkProviderInfo().getDeviceType()));
+ args.put(NETWORK_NAME_KEY, mHotspotNetworkData.getNetworkName());
+ return msg.format(args);
}
/**
@@ -237,6 +284,7 @@ public class HotspotNetworkEntry extends WifiEntry {
@Override
@Nullable
+ @SuppressLint("HardwareIds")
public synchronized String getMacAddress() {
if (mWifiInfo == null) {
return null;
@@ -343,7 +391,14 @@ public class HotspotNetworkEntry extends WifiEntry {
if (mHotspotNetworkData == null) {
return false;
}
- return mHotspotNetworkData.getExtras().getBoolean("is_battery_charging", false);
+ if (BuildCompat.isAtLeastV()
+ && NonSdkApiWrapper.isNetworkProviderBatteryChargingStatusEnabled()
+ && mHotspotNetworkData.getNetworkProviderInfo().isBatteryCharging()) {
+ return true;
+ }
+ // With API flag on we still support either the API or the bundle for compatibility.
+ return mHotspotNetworkData.getNetworkProviderInfo().getExtras().getBoolean(
+ EXTRA_KEY_IS_BATTERY_CHARGING, false);
}
@Override
@@ -371,6 +426,7 @@ public class HotspotNetworkEntry extends WifiEntry {
@Override
public synchronized void disconnect(@Nullable DisconnectCallback callback) {
+ mCalledDisconnect = true;
mDisconnectCallback = callback;
if (mSharedConnectivityManager == null) {
if (callback != null) {
@@ -392,10 +448,11 @@ public class HotspotNetworkEntry extends WifiEntry {
* @param status HotspotNetworkConnectionStatus#ConnectionStatus enum.
*/
public void onConnectionStatusChanged(@ConnectionStatus int status) {
- if (mConnectCallback == null) return;
+ mLastStatus = status;
switch (status) {
case HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT:
mCalledConnect = true;
+ mConnectionError = false;
notifyOnUpdated();
break;
case HotspotNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN_ERROR:
@@ -406,9 +463,27 @@ public class HotspotNetworkEntry extends WifiEntry {
case HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED:
case HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT:
case HotspotNetworkConnectionStatus.CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED:
- mCallbackHandler.post(() -> mConnectCallback.onConnectResult(
- ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN));
+ mCallbackHandler.post(() -> {
+ final ConnectCallback connectCallback = mConnectCallback;
+ if (connectCallback != null) {
+ connectCallback.onConnectResult(
+ ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN);
+ }
+ });
mCalledConnect = false;
+ mConnectionError = true;
+ notifyOnUpdated();
+ break;
+ case CONNECTION_STATUS_CONNECTED:
+ mCallbackHandler.post(() -> {
+ final ConnectCallback connectCallback = mConnectCallback;
+ if (connectCallback != null) {
+ connectCallback.onConnectResult(
+ ConnectCallback.CONNECT_STATUS_SUCCESS);
+ }
+ });
+ mCalledConnect = false;
+ mConnectionError = false;
notifyOnUpdated();
break;
default:
@@ -507,4 +582,21 @@ public class HotspotNetworkEntry extends WifiEntry {
return mScanResultKey;
}
}
+
+ private static String getDeviceTypeId(@DeviceType int deviceType) {
+ switch (deviceType) {
+ case NetworkProviderInfo.DEVICE_TYPE_PHONE:
+ return "PHONE";
+ case NetworkProviderInfo.DEVICE_TYPE_TABLET:
+ return "TABLET";
+ case NetworkProviderInfo.DEVICE_TYPE_LAPTOP:
+ return "COMPUTER";
+ case NetworkProviderInfo.DEVICE_TYPE_WATCH:
+ return "WATCH";
+ case NetworkProviderInfo.DEVICE_TYPE_AUTO:
+ return "VEHICLE";
+ default:
+ return "UNKNOWN";
+ }
+ }
}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java
index 090592dea..78dd65b86 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java
@@ -19,8 +19,9 @@ package com.android.wifitrackerlib;
import static android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS;
import static android.net.wifi.WifiInfo.sanitizeSsid;
-import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription;
+import static com.android.wifitrackerlib.Utils.getVerboseSummary;
+import android.annotation.SuppressLint;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
@@ -62,10 +63,10 @@ public class MergedCarrierEntry extends WifiEntry {
public String getSummary(boolean concise) {
StringJoiner sj = new StringJoiner(mContext.getString(
R.string.wifitrackerlib_summary_separator));
- if (!concise) {
- final String verboseLoggingDescription = getVerboseLoggingDescription(this);
- if (!TextUtils.isEmpty(verboseLoggingDescription)) {
- sj.add(verboseLoggingDescription);
+ if (!concise && isVerboseSummaryEnabled()) {
+ final String verboseSummary = getVerboseSummary(this);
+ if (!TextUtils.isEmpty(verboseSummary)) {
+ sj.add(verboseSummary);
}
}
return sj.toString();
@@ -80,6 +81,7 @@ public class MergedCarrierEntry extends WifiEntry {
}
@Override
+ @SuppressLint("HardwareIds")
public synchronized String getMacAddress() {
if (mWifiInfo != null) {
final String wifiInfoMac = mWifiInfo.getMacAddress();
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java
index 0a71bcbe8..9b61c6646 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java
@@ -16,6 +16,8 @@
package com.android.wifitrackerlib;
+import static com.android.wifi.flags.Flags.networkProviderBatteryChargingStatus;
+
import android.app.admin.DevicePolicyManager;
import android.app.admin.WifiSsidPolicy;
import android.content.Context;
@@ -134,4 +136,11 @@ class NonSdkApiWrapper {
}
return null;
}
+
+ /**
+ * Whether the hotspot network provider battery charging status flag is enabled.
+ */
+ static boolean isNetworkProviderBatteryChargingStatusEnabled() {
+ return networkProviderBatteryChargingStatus();
+ }
}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
index d4c1b4ad1..63db0051f 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java
@@ -156,6 +156,10 @@ public class PasspointNetworkDetailsTracker extends NetworkDetailsTracker {
@WorkerThread
private void updateStartInfo() {
+ // Clear any stale connection info in case we missed any NetworkCallback.onLost() while in
+ // the stopped state.
+ mChosenEntry.clearConnectionInfo();
+
conditionallyUpdateScanResults(true /* lastScanSucceeded */);
conditionallyUpdateConfig();
Network currentNetwork = mWifiManager.getCurrentNetwork();
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
index cb500c23c..22a546b99 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
@@ -30,8 +30,9 @@ import static com.android.wifitrackerlib.Utils.getConnectedDescription;
import static com.android.wifitrackerlib.Utils.getConnectingDescription;
import static com.android.wifitrackerlib.Utils.getDisconnectedDescription;
import static com.android.wifitrackerlib.Utils.getMeteredDescription;
-import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription;
+import static com.android.wifitrackerlib.Utils.getVerboseSummary;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
@@ -181,10 +182,16 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry
connectedStateDescription = getConnectingDescription(mContext, mNetworkInfo);
break;
case CONNECTED_STATE_CONNECTED:
+ if (mNetworkCapabilities == null) {
+ Log.e(TAG, "Tried to get CONNECTED description, but mNetworkCapabilities"
+ + " was unexpectedly null!");
+ connectedStateDescription = null;
+ break;
+ }
connectedStateDescription = getConnectedDescription(mContext,
mWifiConfig,
mNetworkCapabilities,
- mIsDefaultNetwork,
+ isDefaultNetwork(),
isLowQuality(),
mConnectivityReport);
break;
@@ -207,10 +214,10 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry
sj.add(meteredDescription);
}
- if (!concise) {
- String verboseLoggingDescription = getVerboseLoggingDescription(this);
- if (!TextUtils.isEmpty(verboseLoggingDescription)) {
- sj.add(verboseLoggingDescription);
+ if (!concise && isVerboseSummaryEnabled()) {
+ String verboseSummary = getVerboseSummary(this);
+ if (!TextUtils.isEmpty(verboseSummary)) {
+ sj.add(verboseSummary);
}
}
@@ -218,6 +225,11 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry
}
@Override
+ public boolean shouldShowSsid() {
+ return true;
+ }
+
+ @Override
public synchronized String getSsid() {
if (mWifiInfo != null) {
return sanitizeSsid(mWifiInfo.getSSID());
@@ -243,6 +255,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry
}
@Override
+ @SuppressLint("HardwareIds")
public synchronized String getMacAddress() {
if (mWifiInfo != null) {
final String wifiInfoMac = mWifiInfo.getMacAddress();
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
index fa9c320db..63b13aaa3 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
@@ -229,16 +229,14 @@ public class SavedNetworkTracker extends BaseWifiTracker {
return allEntries;
}
- private void clearAllWifiEntries() {
- mStandardWifiEntryCache.clear();
- mPasspointWifiEntryCache.clear();
- }
-
@WorkerThread
@Override
protected void handleOnStart() {
- // Remove stale WifiEntries remaining from the last onStop().
- clearAllWifiEntries();
+ // Clear any stale connection info in case we missed any NetworkCallback.onLost() while in
+ // the stopped state.
+ for (WifiEntry wifiEntry : getAllWifiEntries()) {
+ wifiEntry.clearConnectionInfo();
+ }
// Update configs and scans
updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
index 2accc2321..e21efc464 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
@@ -131,6 +131,10 @@ public class StandardNetworkDetailsTracker extends NetworkDetailsTracker {
@WorkerThread
private void updateStartInfo() {
+ // Clear any stale connection info in case we missed any NetworkCallback.onLost() while in
+ // the stopped state.
+ mChosenEntry.clearConnectionInfo();
+
conditionallyUpdateScanResults(true /* lastScanSucceeded */);
conditionallyUpdateConfig();
handleDefaultSubscriptionChanged(SubscriptionManager.getDefaultDataSubscriptionId());
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
index 1c8e06c2c..246c7b36a 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
@@ -43,7 +43,7 @@ import static com.android.wifitrackerlib.Utils.getMeteredDescription;
import static com.android.wifitrackerlib.Utils.getSecurityTypesFromScanResult;
import static com.android.wifitrackerlib.Utils.getSecurityTypesFromWifiConfiguration;
import static com.android.wifitrackerlib.Utils.getSingleSecurityTypeFromMultipleSecurityTypes;
-import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription;
+import static com.android.wifitrackerlib.Utils.getVerboseSummary;
import android.annotation.SuppressLint;
import android.app.admin.DevicePolicyManager;
@@ -198,10 +198,16 @@ public class StandardWifiEntry extends WifiEntry {
connectedStateDescription = getConnectingDescription(mContext, mNetworkInfo);
break;
case CONNECTED_STATE_CONNECTED:
+ if (mNetworkCapabilities == null) {
+ Log.e(TAG, "Tried to get CONNECTED description, but mNetworkCapabilities was"
+ + " unexpectedly null!");
+ connectedStateDescription = null;
+ break;
+ }
connectedStateDescription = getConnectedDescription(mContext,
mTargetWifiConfig,
mNetworkCapabilities,
- mIsDefaultNetwork,
+ isDefaultNetwork(),
isLowQuality(),
mConnectivityReport);
break;
@@ -223,10 +229,10 @@ public class StandardWifiEntry extends WifiEntry {
sj.add(meteredDescription);
}
- if (!concise) {
- final String verboseLoggingDescription = getVerboseLoggingDescription(this);
- if (!TextUtils.isEmpty(verboseLoggingDescription)) {
- sj.add(verboseLoggingDescription);
+ if (!concise && isVerboseSummaryEnabled()) {
+ final String verboseSummary = getVerboseSummary(this);
+ if (!TextUtils.isEmpty(verboseSummary)) {
+ sj.add(verboseSummary);
}
}
@@ -245,6 +251,7 @@ public class StandardWifiEntry extends WifiEntry {
@Override
@Nullable
+ @SuppressLint("HardwareIds")
public synchronized String getMacAddress() {
if (mWifiInfo != null) {
final String wifiInfoMac = mWifiInfo.getMacAddress();
@@ -281,6 +288,14 @@ public class StandardWifiEntry extends WifiEntry {
}
@Override
+ public boolean needsWifiConfiguration() {
+ List<Integer> securityTypes = getSecurityTypes();
+ return !isSaved() && !isSuggestion()
+ && !securityTypes.contains(SECURITY_TYPE_OPEN)
+ && !securityTypes.contains(SECURITY_TYPE_OWE);
+ }
+
+ @Override
@Nullable
public synchronized WifiConfiguration getWifiConfiguration() {
if (!isSaved()) {
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
index ad5231d4e..af64a589b 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java
@@ -29,6 +29,7 @@ import static android.net.wifi.WifiInfo.SECURITY_TYPE_SAE;
import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
import static java.util.Comparator.comparingInt;
+import static java.util.stream.Collectors.toList;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
@@ -246,82 +247,85 @@ public class Utils {
static String getConnectedDescription(@NonNull Context context,
@Nullable WifiConfiguration wifiConfiguration,
- @Nullable NetworkCapabilities networkCapabilities,
+ @NonNull NetworkCapabilities networkCapabilities,
boolean isDefaultNetwork,
boolean isLowQuality,
@Nullable ConnectivityDiagnosticsManager.ConnectivityReport connectivityReport) {
final StringJoiner sj = new StringJoiner(context.getString(
R.string.wifitrackerlib_summary_separator));
- boolean shouldShowConnected = isDefaultNetwork;
+ boolean isValidated = networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ boolean isCaptivePortal = networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
+ boolean isPartialConnectivity = networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY);
+ boolean isNoInternetExpected = wifiConfiguration != null
+ && wifiConfiguration.isNoInternetAccessExpected();
+ boolean isPrivateDnsBroken = !isValidated && networkCapabilities.isPrivateDnsBroken();
+ boolean isCheckingForInternetAccess = !isValidated && !isPartialConnectivity
+ && connectivityReport == null && !isNoInternetExpected;
+ boolean isOemNetwork = NonSdkApiWrapper.isOemCapabilities(networkCapabilities);
+ String suggestionOrSpecifierLabel = null;
if (wifiConfiguration != null
&& (wifiConfiguration.fromWifiNetworkSuggestion
|| wifiConfiguration.fromWifiNetworkSpecifier)) {
- // For suggestion or specifier networks to show "Connected via ..."
- final String suggestionOrSpecifierLabel =
- getSuggestionOrSpecifierLabel(context, wifiConfiguration);
- if (!TextUtils.isEmpty(suggestionOrSpecifierLabel)) {
- if (isDefaultNetwork || (networkCapabilities != null
- && NonSdkApiWrapper.isOemCapabilities(networkCapabilities))) {
- sj.add(context.getString(R.string.wifitrackerlib_connected_via_app,
- suggestionOrSpecifierLabel));
- } else {
- // Pretend that non-default, non-OEM networks are unconnected.
- sj.add(context.getString(R.string.wifitrackerlib_available_via_app,
- suggestionOrSpecifierLabel));
- }
- shouldShowConnected = false;
+ suggestionOrSpecifierLabel = getSuggestionOrSpecifierLabel(context, wifiConfiguration);
+ }
+ final boolean shouldShowConnected;
+ if (isValidated) {
+ shouldShowConnected = isDefaultNetwork;
+ } else {
+ // Show "Connected" even if we aren't validated specifically for the
+ // "Connected / No internet access" case, and for OEM-specified networks which aren't
+ // expected to be fully validated.
+ shouldShowConnected = !isCheckingForInternetAccess && !isCaptivePortal
+ && !isPrivateDnsBroken && !isNoInternetExpected || isOemNetwork;
+ }
+
+ if (!TextUtils.isEmpty(suggestionOrSpecifierLabel)) {
+ if (shouldShowConnected || (isDefaultNetwork && isPartialConnectivity)) {
+ // "Connected via app"
+ sj.add(context.getString(R.string.wifitrackerlib_connected_via_app,
+ suggestionOrSpecifierLabel));
+ } else {
+ // "Available via app"
+ sj.add(context.getString(R.string.wifitrackerlib_available_via_app,
+ suggestionOrSpecifierLabel));
}
+ } else if (shouldShowConnected) {
+ // "Connected"
+ sj.add(context.getResources().getStringArray(
+ R.array.wifitrackerlib_wifi_status)[DetailedState.CONNECTED.ordinal()]);
}
if (isLowQuality) {
+ // "Low quality"
sj.add(context.getString(R.string.wifi_connected_low_quality));
- shouldShowConnected = false;
- }
-
- // For displaying network capability info, such as captive portal or no internet
- if (networkCapabilities != null) {
- if (networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)) {
- // "Sign in to network"
- sj.add(context.getString(context.getResources()
- .getIdentifier("network_available_sign_in", "string", "android")));
- shouldShowConnected = false;
- } else if (networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY)) {
- // "Limited connection..."
- sj.add(context.getString(
- R.string.wifitrackerlib_wifi_limited_connection));
- shouldShowConnected = false;
- } else if (!networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
- boolean noInternetExpected = wifiConfiguration != null
- && wifiConfiguration.isNoInternetAccessExpected();
- if (connectivityReport == null && !noInternetExpected) {
- // "Checking for internet access..."
- sj.add(context.getString(R.string.wifitrackerlib_checking_for_internet_access));
- shouldShowConnected = false;
- } else if (networkCapabilities.isPrivateDnsBroken()) {
- // "Private DNS server cannot be accessed"
- sj.add(context.getString(R.string.wifitrackerlib_private_dns_broken));
- shouldShowConnected = false;
- } else if (noInternetExpected) {
- // "Connected to device. Can't provide internet."
- sj.add(context.getString(
- R.string.wifitrackerlib_wifi_connected_cannot_provide_internet));
- shouldShowConnected = false;
- } else {
- // "No internet access"
- sj.add(context.getString(R.string.wifitrackerlib_wifi_no_internet));
- }
- }
}
- // Show "Connected" first if we haven't hidden it due to other strings.
- if (shouldShowConnected) {
- return new StringJoiner(context.getString(R.string.wifitrackerlib_summary_separator))
- .add(context.getResources().getStringArray(R.array.wifitrackerlib_wifi_status)
- [DetailedState.CONNECTED.ordinal()]).merge(sj).toString();
+ if (isCaptivePortal) {
+ // "Sign in to network"
+ sj.add(context.getString(context.getResources().getIdentifier(
+ "network_available_sign_in", "string", "android")));
+ } else if (isPartialConnectivity) {
+ // "Limited connection..."
+ sj.add(context.getString(R.string.wifitrackerlib_wifi_limited_connection));
+ } else if (isCheckingForInternetAccess) {
+ // "Checking for internet access..."
+ sj.add(context.getString(R.string.wifitrackerlib_checking_for_internet_access));
+ } else if (isPrivateDnsBroken) {
+ // "Private DNS server cannot be accessed"
+ sj.add(context.getString(R.string.wifitrackerlib_private_dns_broken));
+ } else if (!isValidated) {
+ if (isNoInternetExpected) {
+ // "Connected to device. Can't provide internet."
+ sj.add(context.getString(
+ R.string.wifitrackerlib_wifi_connected_cannot_provide_internet));
+ } else {
+ // "No internet access"
+ sj.add(context.getString(R.string.wifitrackerlib_wifi_no_internet));
+ }
}
return sj.toString();
@@ -522,8 +526,8 @@ public class Utils {
}
}
- static String getVerboseLoggingDescription(@NonNull WifiEntry wifiEntry) {
- if (!BaseWifiTracker.isVerboseLoggingEnabled() || wifiEntry == null) {
+ static String getVerboseSummary(@NonNull WifiEntry wifiEntry) {
+ if (wifiEntry == null) {
return "";
}
@@ -1177,7 +1181,7 @@ public class Utils {
}
List<MloLink> activeMloLinks = wifiInfo.getAssociatedMloLinks().stream()
.filter((link) -> link.getState() == MloLink.MLO_LINK_STATE_ACTIVE)
- .toList();
+ .collect(toList());
if (activeMloLinks.size() <= 1) {
return context.getString(R.string.wifitrackerlib_link_speed_mbps,
wifiInfoSpeedMbps);
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
index 0dea00695..09dfd89e3 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
@@ -244,6 +244,7 @@ public class WifiEntry {
protected NetworkInfo mNetworkInfo;
protected Network mNetwork;
protected NetworkCapabilities mNetworkCapabilities;
+ protected Network mDefaultNetwork;
protected NetworkCapabilities mDefaultNetworkCapabilities;
protected ConnectivityDiagnosticsManager.ConnectivityReport mConnectivityReport;
protected ConnectedInfo mConnectedInfo;
@@ -255,7 +256,6 @@ public class WifiEntry {
protected boolean mCalledConnect = false;
protected boolean mCalledDisconnect = false;
- protected boolean mIsDefaultNetwork;
private Optional<ManageSubscriptionAction> mManageSubscriptionAction = Optional.empty();
@@ -358,7 +358,7 @@ public class WifiEntry {
* Returns whether this network has validated internet access or not.
* Note: This does not necessarily mean the network is the default route.
*/
- public boolean hasInternetAccess() {
+ public synchronized boolean hasInternetAccess() {
return mNetworkCapabilities != null
&& mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
@@ -368,13 +368,13 @@ public class WifiEntry {
* currently being used to provide internet connection).
*/
public boolean isDefaultNetwork() {
- return mIsDefaultNetwork;
+ return mNetwork != null && mNetwork.equals(mDefaultNetwork);
}
/**
* Returns whether this network is the primary Wi-Fi network or not.
*/
- public boolean isPrimaryNetwork() {
+ public synchronized boolean isPrimaryNetwork() {
if (getConnectedState() == CONNECTED_STATE_DISCONNECTED) {
// In case we have mNetworkInfo but the state is disconnected.
return false;
@@ -386,7 +386,7 @@ public class WifiEntry {
/**
* Returns whether this network is considered low quality.
*/
- public boolean isLowQuality() {
+ public synchronized boolean isLowQuality() {
if (!isPrimaryNetwork()) {
return false;
}
@@ -402,6 +402,14 @@ public class WifiEntry {
}
/**
+ * Returns whether this network should display its SSID separately from the title
+ * (e.g. the Network Details page), for networks whose display titles differ from the SSID.
+ */
+ public boolean shouldShowSsid() {
+ return false;
+ }
+
+ /**
* Returns the SSID of the entry, if applicable. Null otherwise.
*/
@Nullable
@@ -486,6 +494,14 @@ public class WifiEntry {
}
/**
+ * Returns whether this entry needs to be configured with a new WifiConfiguration before
+ * connection.
+ */
+ public boolean needsWifiConfiguration() {
+ return false;
+ }
+
+ /**
* Returns the WifiConfiguration of an entry or null if unavailable. This should be used when
* information on the WifiConfiguration needs to be modified and saved via
* {@link WifiManager#save(WifiConfiguration, WifiManager.ActionListener)}.
@@ -740,7 +756,7 @@ public class WifiEntry {
sb.append("hasInternet:")
.append(hasInternetAccess())
.append(", isDefaultNetwork:")
- .append(mIsDefaultNetwork)
+ .append(isDefaultNetwork())
.append(", isLowQuality:")
.append(isLowQuality());
}
@@ -912,10 +928,10 @@ public class WifiEntry {
}
return;
}
- mWifiInfo = primaryWifiInfo;
if (networkInfo != null) {
mNetworkInfo = networkInfo;
}
+ updateWifiInfo(primaryWifiInfo);
notifyOnUpdated();
}
@@ -949,9 +965,20 @@ public class WifiEntry {
// Connection info matches, so the Network/NetworkCapabilities represent this network
// and the network is currently connecting or connected.
- mWifiInfo = wifiInfo;
mNetwork = network;
mNetworkCapabilities = capabilities;
+ updateWifiInfo(wifiInfo);
+ notifyOnUpdated();
+ }
+
+ private synchronized void updateWifiInfo(WifiInfo wifiInfo) {
+ if (wifiInfo == null) {
+ mWifiInfo = null;
+ mConnectedInfo = null;
+ updateSecurityTypes();
+ return;
+ }
+ mWifiInfo = wifiInfo;
final int wifiInfoRssi = mWifiInfo.getRssi();
if (wifiInfoRssi != INVALID_RSSI) {
mLevel = mWifiManager.calculateSignalLevel(wifiInfoRssi);
@@ -976,7 +1003,6 @@ public class WifiEntry {
mConnectedInfo.wifiStandard = mWifiInfo.getWifiStandard();
}
updateSecurityTypes();
- notifyOnUpdated();
}
/**
@@ -987,14 +1013,18 @@ public class WifiEntry {
if (!network.equals(mNetwork)) {
return;
}
-
// Network matches, so this network is disconnected.
- mWifiInfo = null;
+ clearConnectionInfo();
+ }
+
+ /**
+ * Clears any connection info from this entry.
+ */
+ synchronized void clearConnectionInfo() {
+ updateWifiInfo(null);
mNetworkInfo = null;
mNetworkCapabilities = null;
- mConnectedInfo = null;
mConnectivityReport = null;
- mIsDefaultNetwork = false;
if (mCalledDisconnect) {
mCalledDisconnect = false;
mCallbackHandler.post(() -> {
@@ -1005,7 +1035,6 @@ public class WifiEntry {
}
});
}
- updateSecurityTypes();
notifyOnUpdated();
}
@@ -1016,9 +1045,8 @@ public class WifiEntry {
synchronized void onDefaultNetworkCapabilitiesChanged(
@NonNull Network network,
@NonNull NetworkCapabilities capabilities) {
- onNetworkCapabilitiesChanged(network, capabilities);
+ mDefaultNetwork = network;
mDefaultNetworkCapabilities = capabilities;
- mIsDefaultNetwork = network.equals(mNetwork);
notifyOnUpdated();
}
@@ -1026,8 +1054,8 @@ public class WifiEntry {
* Notifies this WifiEntry that the default network was lost.
*/
synchronized void onDefaultNetworkLost() {
+ mDefaultNetwork = null;
mDefaultNetworkCapabilities = null;
- mIsDefaultNetwork = false;
notifyOnUpdated();
}
@@ -1239,4 +1267,11 @@ public class WifiEntry {
*/
void onExecute();
}
+
+ /**
+ * Whether this WifiEntry is using a verbose summary.
+ */
+ public boolean isVerboseSummaryEnabled() {
+ return mInjector.isVerboseSummaryEnabled();
+ }
}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
index 4abffbaf8..3ee9a4dad 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
@@ -60,6 +60,7 @@ import android.util.SparseArray;
import androidx.annotation.AnyThread;
import androidx.annotation.GuardedBy;
+import androidx.annotation.IntDef;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -68,6 +69,8 @@ import androidx.annotation.WorkerThread;
import androidx.core.os.BuildCompat;
import androidx.lifecycle.Lifecycle;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
@@ -92,6 +95,9 @@ public class WifiPickerTracker extends BaseWifiTracker {
private static final String TAG = "WifiPickerTracker";
+ private static final String EXTRA_KEY_CONNECTION_STATUS_CONNECTED =
+ "connection_status_connected";
+
private final WifiPickerTrackerCallback mListener;
// Lock object for data returned by the public API
@@ -293,8 +299,11 @@ public class WifiPickerTracker extends BaseWifiTracker {
@WorkerThread
@Override
protected void handleOnStart() {
- // Remove stale WifiEntries remaining from the last onStop().
- clearAllWifiEntries();
+ // Clear any stale connection info in case we missed any NetworkCallback.onLost() while in
+ // the stopped state.
+ for (WifiEntry wifiEntry : getAllWifiEntries()) {
+ wifiEntry.clearConnectionInfo();
+ }
// Update configs and scans
updateWifiConfigurations(mWifiManager.getPrivilegedConfiguredNetworks());
@@ -341,7 +350,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
checkNotNull(intent, "Intent cannot be null!");
conditionallyUpdateScanResults(
intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true));
- updateWifiEntries();
+ updateWifiEntries(WIFI_ENTRIES_CHANGED_REASON_SCAN_RESULTS);
}
@WorkerThread
@@ -358,17 +367,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
updateWifiConfigurations(mWifiManager.getPrivilegedConfiguredNetworks());
updatePasspointConfigurations(mWifiManager.getPasspointConfigurations());
// Update scans since config changes may result in different entries being shown.
- final List<ScanResult> scanResults = mScanResultUpdater.getScanResults();
- updateStandardWifiEntryScans(scanResults);
- updateNetworkRequestEntryScans(scanResults);
- updatePasspointWifiEntryScans(scanResults);
- updateOsuWifiEntryScans(scanResults);
- if (mInjector.isSharedConnectivityFeatureEnabled() && BuildCompat.isAtLeastU()) {
- updateKnownNetworkEntryScans(scanResults);
- // Updating the hotspot entries here makes the UI more reliable when switching pages or
- // when toggling settings while the internet picker is shown.
- updateHotspotNetworkEntries();
- }
+ conditionallyUpdateScanResults(false /* lastScanSucceeded */);
notifyOnNumSavedNetworksChanged();
notifyOnNumSavedSubscriptionsChanged();
updateWifiEntries();
@@ -483,15 +482,25 @@ public class WifiPickerTracker extends BaseWifiTracker {
updateWifiEntries();
}
}
- @TargetApi(VERSION_CODES.UPSIDE_DOWN_CAKE)
- @WorkerThread
- protected void handleHotspotNetworkConnectionStatusChanged(
- @NonNull HotspotNetworkConnectionStatus status) {
- mHotspotNetworkEntryCache.stream().filter(
- entry -> entry.getHotspotNetworkEntryKey().getDeviceId()
- == status.getHotspotNetwork().getDeviceId()).forEach(
- entry -> entry.onConnectionStatusChanged(status.getStatus()));
- }
+
+ @TargetApi(VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @WorkerThread
+ protected void handleHotspotNetworkConnectionStatusChanged(
+ @NonNull HotspotNetworkConnectionStatus status) {
+ mHotspotNetworkEntryCache.stream()
+ .filter(
+ entry ->
+ entry.getHotspotNetworkEntryKey().getDeviceId()
+ == status.getHotspotNetwork().getDeviceId())
+ .forEach(
+ entry -> {
+ if (status.getExtras().getBoolean(EXTRA_KEY_CONNECTION_STATUS_CONNECTED, false)) {
+ entry.onConnectionStatusChanged(HotspotNetworkEntry.CONNECTION_STATUS_CONNECTED);
+ } else {
+ entry.onConnectionStatusChanged(status.getStatus());
+ }
+ });
+ }
@TargetApi(VERSION_CODES.UPSIDE_DOWN_CAKE)
@WorkerThread
@@ -499,7 +508,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
protected void handleKnownNetworkConnectionStatusChanged(
@NonNull KnownNetworkConnectionStatus status) {
final ScanResultKey key = new ScanResultKey(status.getKnownNetwork().getSsid(),
- status.getKnownNetwork().getSecurityTypes().stream().toList());
+ new ArrayList<>(status.getKnownNetwork().getSecurityTypes()));
mKnownNetworkEntryCache.stream().filter(
entry -> entry.getStandardWifiEntryKey().getScanResultKey().equals(key)).forEach(
entry -> entry.onConnectionStatusChanged(status.getStatus()));
@@ -511,11 +520,22 @@ public class WifiPickerTracker extends BaseWifiTracker {
protected void handleServiceConnected() {
if (mInjector.isSharedConnectivityFeatureEnabled()) {
mKnownNetworkDataCache.clear();
- mKnownNetworkDataCache.addAll(mSharedConnectivityManager.getKnownNetworks());
+ List<KnownNetwork> knownNetworks = mSharedConnectivityManager.getKnownNetworks();
+ if (knownNetworks != null) {
+ mKnownNetworkDataCache.addAll(knownNetworks);
+ }
mHotspotNetworkDataCache.clear();
- mHotspotNetworkDataCache.addAll(mSharedConnectivityManager.getHotspotNetworks());
+ List<HotspotNetwork> hotspotNetworks = mSharedConnectivityManager.getHotspotNetworks();
+ if (hotspotNetworks != null) {
+ mHotspotNetworkDataCache.addAll(hotspotNetworks);
+ }
updateKnownNetworkEntryScans(mScanResultUpdater.getScanResults());
updateHotspotNetworkEntries();
+ HotspotNetworkConnectionStatus status =
+ mSharedConnectivityManager.getHotspotNetworkConnectionStatus();
+ if (status != null) {
+ handleHotspotNetworkConnectionStatusChanged(status);
+ }
updateWifiEntries();
}
}
@@ -533,11 +553,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
}
}
- /**
- * Update the list returned by getWifiEntries() with the current states of the entry caches.
- */
- @WorkerThread
- protected void updateWifiEntries() {
+ protected void updateWifiEntries(@WifiEntriesChangedReason int reason) {
synchronized (mLock) {
mActiveWifiEntries.clear();
mActiveWifiEntries.addAll(mStandardWifiEntryCache);
@@ -646,6 +662,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
}
Collections.sort(mWifiEntries, WifiEntry.WIFI_PICKER_COMPARATOR);
if (isVerboseLoggingEnabled()) {
+ Log.v(TAG, "onWifiEntriesChanged: reason=" + reason);
StringJoiner entryLog = new StringJoiner("\n");
int numEntries = mActiveWifiEntries.size() + mWifiEntries.size();
int index = 1;
@@ -661,7 +678,16 @@ public class WifiPickerTracker extends BaseWifiTracker {
Log.v(TAG, "MergedCarrierEntry: " + mMergedCarrierEntry);
}
}
- notifyOnWifiEntriesChanged();
+ notifyOnWifiEntriesChanged(reason);
+ }
+
+
+ /**
+ * Update the list returned by getWifiEntries() with the current states of the entry caches.
+ */
+ @WorkerThread
+ protected void updateWifiEntries() {
+ updateWifiEntries(WIFI_ENTRIES_CHANGED_REASON_GENERAL);
}
/**
@@ -700,7 +726,7 @@ public class WifiPickerTracker extends BaseWifiTracker {
}
}
}
- notifyOnWifiEntriesChanged();
+ notifyOnWifiEntriesChanged(WIFI_ENTRIES_CHANGED_REASON_GENERAL);
}
/**
@@ -1334,9 +1360,9 @@ public class WifiPickerTracker extends BaseWifiTracker {
* Posts onWifiEntryChanged callback on the main thread.
*/
@WorkerThread
- private void notifyOnWifiEntriesChanged() {
+ private void notifyOnWifiEntriesChanged(@WifiEntriesChangedReason int reason) {
if (mListener != null) {
- mMainHandler.post(mListener::onWifiEntriesChanged);
+ mMainHandler.post(() -> mListener.onWifiEntriesChanged(reason));
}
}
@@ -1360,6 +1386,17 @@ public class WifiPickerTracker extends BaseWifiTracker {
}
}
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ WIFI_ENTRIES_CHANGED_REASON_GENERAL,
+ WIFI_ENTRIES_CHANGED_REASON_SCAN_RESULTS,
+ })
+
+ public @interface WifiEntriesChangedReason {}
+
+ public static final int WIFI_ENTRIES_CHANGED_REASON_GENERAL = 0;
+ public static final int WIFI_ENTRIES_CHANGED_REASON_SCAN_RESULTS = 1;
+
/**
* Listener for changes to the list of visible WifiEntries as well as the number of saved
* networks and subscriptions.
@@ -1374,7 +1411,20 @@ public class WifiPickerTracker extends BaseWifiTracker {
* {@link #getMergedCarrierEntry()}
*/
@MainThread
- void onWifiEntriesChanged();
+ default void onWifiEntriesChanged() {
+ // Do nothing
+ }
+
+ /**
+ * Called when there are changes to
+ * {@link #getConnectedWifiEntry()}
+ * {@link #getWifiEntries()}
+ * {@link #getMergedCarrierEntry()}
+ */
+ @MainThread
+ default void onWifiEntriesChanged(@WifiEntriesChangedReason int reason) {
+ onWifiEntriesChanged();
+ }
/**
* Called when there are changes to
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java
index f9f3eed91..c70a88a41 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java
@@ -18,6 +18,8 @@ package com.android.wifitrackerlib;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.Build;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.util.ArraySet;
@@ -34,13 +36,17 @@ public class WifiTrackerInjector {
@NonNull private final Context mContext;
private final boolean mIsDemoMode;
+ private final WifiManager mWifiManager;
private final UserManager mUserManager;
private final DevicePolicyManager mDevicePolicyManager;
@NonNull private final Set<String> mNoAttributionAnnotationPackages;
+ private boolean mIsUserDebugVerboseLoggingEnabled;
+ private boolean mVerboseLoggingDisabledOverride = false;
// TODO(b/201571677): Migrate the rest of the common objects to WifiTrackerInjector.
WifiTrackerInjector(@NonNull Context context) {
mContext = context;
+ mWifiManager = context.getSystemService(WifiManager.class);
mIsDemoMode = NonSdkApiWrapper.isDemoMode(context);
mUserManager = context.getSystemService(UserManager.class);
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
@@ -50,6 +56,9 @@ public class WifiTrackerInjector {
for (int i = 0; i < noAttributionAnnotationPackages.length; i++) {
mNoAttributionAnnotationPackages.add(noAttributionAnnotationPackages[i]);
}
+ mIsUserDebugVerboseLoggingEnabled = context.getResources().getBoolean(
+ R.bool.wifitrackerlib_enable_verbose_logging_for_userdebug)
+ && Build.TYPE.equals("userdebug");
}
@NonNull Context getContext() {
@@ -79,4 +88,26 @@ public class WifiTrackerInjector {
return DeviceConfig.getBoolean(DEVICE_CONFIG_NAMESPACE,
"shared_connectivity_enabled", false);
}
+
+ /**
+ * Whether verbose logging is enabled.
+ */
+ public boolean isVerboseLoggingEnabled() {
+ return !mVerboseLoggingDisabledOverride
+ && (mWifiManager.isVerboseLoggingEnabled() || mIsUserDebugVerboseLoggingEnabled);
+ }
+
+ /**
+ * Whether verbose summaries should be shown in WifiEntry.
+ */
+ public boolean isVerboseSummaryEnabled() {
+ return !mVerboseLoggingDisabledOverride && mWifiManager.isVerboseLoggingEnabled();
+ }
+
+ /**
+ * Permanently disables verbose logging.
+ */
+ public void disableVerboseLogging() {
+ mVerboseLoggingDisabledOverride = true;
+ }
}