diff options
Diffstat (limited to 'libs/WifiTrackerLib/src')
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; + } } |