diff options
author | Quang Luong <qal@google.com> | 2021-06-08 15:46:49 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-06-08 15:46:49 +0000 |
commit | f8d99bf8646d694efb1fdd556e0346744cb79a1d (patch) | |
tree | ca0bb763b34ac749aad593b2a8f139f53c16ec1a | |
parent | 11591024add201769052b5a39644534cc3210b33 (diff) | |
parent | c1d95c9fcb2c0e375c17dc557cee8c928ddfed7c (diff) | |
download | wifi-f8d99bf8646d694efb1fdd556e0346744cb79a1d.tar.gz |
Merge "Synchronize WifiEntry methods" into sc-dev
5 files changed, 229 insertions, 209 deletions
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java index a7f38effe..e0dc65bd9 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/MergedCarrierEntry.java @@ -77,7 +77,7 @@ public class MergedCarrierEntry extends WifiEntry { } @Override - public String getSsid() { + public synchronized String getSsid() { if (mWifiInfo != null) { return mWifiInfo.getSSID(); } @@ -85,7 +85,7 @@ public class MergedCarrierEntry extends WifiEntry { } @Override - public String getMacAddress() { + public synchronized String getMacAddress() { if (mWifiInfo != null) { final String wifiInfoMac = mWifiInfo.getMacAddress(); if (!TextUtils.isEmpty(wifiInfoMac) @@ -97,20 +97,24 @@ public class MergedCarrierEntry extends WifiEntry { } @Override - public boolean canConnect() { + public synchronized boolean canConnect() { return getConnectedState() == CONNECTED_STATE_DISCONNECTED && !mIsCellDefaultRoute; } @Override - public void connect(@Nullable ConnectCallback callback) { + public synchronized void connect(@Nullable ConnectCallback callback) { mConnectCallback = callback; mWifiManager.startRestrictingAutoJoinToSubscriptionId(mSubscriptionId); Toast.makeText(mContext, R.string.wifitrackerlib_wifi_wont_autoconnect_for_now, Toast.LENGTH_SHORT).show(); if (mConnectCallback != null) { - mCallbackHandler.post(() -> - mConnectCallback.onConnectResult( - ConnectCallback.CONNECT_STATUS_SUCCESS)); + mCallbackHandler.post(() -> { + synchronized (this) { + if (mConnectCallback != null) { + mConnectCallback.onConnectResult(ConnectCallback.CONNECT_STATUS_SUCCESS); + } + } + }); } } @@ -120,14 +124,19 @@ public class MergedCarrierEntry extends WifiEntry { } @Override - public void disconnect(@Nullable DisconnectCallback callback) { + public synchronized void disconnect(@Nullable DisconnectCallback callback) { mDisconnectCallback = callback; mWifiManager.stopRestrictingAutoJoinToSubscriptionId(); mWifiManager.startScan(); if (mDisconnectCallback != null) { - mCallbackHandler.post(() -> - mDisconnectCallback.onDisconnectResult( - DisconnectCallback.DISCONNECT_STATUS_SUCCESS)); + mCallbackHandler.post(() -> { + synchronized (this) { + if (mDisconnectCallback != null) { + mDisconnectCallback.onDisconnectResult( + DisconnectCallback.DISCONNECT_STATUS_SUCCESS); + } + } + }); } } @@ -155,7 +164,7 @@ public class MergedCarrierEntry extends WifiEntry { return mSubscriptionId; } - /* package */ void updateIsCellDefaultRoute(boolean isCellDefaultRoute) { + /* package */ synchronized void updateIsCellDefaultRoute(boolean isCellDefaultRoute) { mIsCellDefaultRoute = isCellDefaultRoute; notifyOnUpdated(); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java index 9483b4f08..67fa79f84 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java @@ -37,7 +37,6 @@ import android.os.Handler; import android.text.TextUtils; import android.util.Pair; -import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -53,14 +52,12 @@ import java.util.Map; class OsuWifiEntry extends WifiEntry { static final String KEY_PREFIX = "OsuWifiEntry:"; - private final Object mLock = new Object(); // Scan result list must be thread safe for generating the verbose scan summary - @GuardedBy("mLock") @NonNull private final List<ScanResult> mCurrentScanResults = new ArrayList<>(); @NonNull private final String mKey; @NonNull private final Context mContext; - @NonNull private OsuProvider mOsuProvider; + @NonNull private final OsuProvider mOsuProvider; private String mSsid; private String mOsuStatusString; private boolean mIsAlreadyProvisioned = false; @@ -88,7 +85,7 @@ class OsuWifiEntry extends WifiEntry { } @Override - public String getTitle() { + public synchronized String getTitle() { final String friendlyName = mOsuProvider.getFriendlyName(); if (!TextUtils.isEmpty(friendlyName)) { return friendlyName; @@ -104,7 +101,7 @@ class OsuWifiEntry extends WifiEntry { } @Override - public String getSummary(boolean concise) { + public synchronized String getSummary(boolean concise) { // TODO(b/70983952): Add verbose summary if (mOsuStatusString != null) { return mOsuStatusString; @@ -118,7 +115,7 @@ class OsuWifiEntry extends WifiEntry { } @Override - public String getSsid() { + public synchronized String getSsid() { return mSsid; } @@ -129,13 +126,13 @@ class OsuWifiEntry extends WifiEntry { } @Override - public boolean canConnect() { + public synchronized boolean canConnect() { return mLevel != WIFI_LEVEL_UNREACHABLE && getConnectedState() == CONNECTED_STATE_DISCONNECTED; } @Override - public void connect(@Nullable ConnectCallback callback) { + public synchronized void connect(@Nullable ConnectCallback callback) { mConnectCallback = callback; mWifiManager.stopRestrictingAutoJoinToSubscriptionId(); mWifiManager.startSubscriptionProvisioning(mOsuProvider, mContext.getMainExecutor(), @@ -143,14 +140,12 @@ class OsuWifiEntry extends WifiEntry { } @WorkerThread - void updateScanResultInfo(@Nullable List<ScanResult> scanResults) + synchronized void updateScanResultInfo(@Nullable List<ScanResult> scanResults) throws IllegalArgumentException { if (scanResults == null) scanResults = new ArrayList<>(); - synchronized (mLock) { - mCurrentScanResults.clear(); - mCurrentScanResults.addAll(scanResults); - } + mCurrentScanResults.clear(); + mCurrentScanResults.addAll(scanResults); final ScanResult bestScanResult = getBestScanResultByLevel(scanResults); if (bestScanResult != null) { @@ -189,26 +184,30 @@ class OsuWifiEntry extends WifiEntry { return mOsuProvider; } - boolean isAlreadyProvisioned() { + synchronized boolean isAlreadyProvisioned() { return mIsAlreadyProvisioned; } - void setAlreadyProvisioned(boolean isAlreadyProvisioned) { + synchronized void setAlreadyProvisioned(boolean isAlreadyProvisioned) { mIsAlreadyProvisioned = isAlreadyProvisioned; } class OsuWifiEntryProvisioningCallback extends ProvisioningCallback { @Override @MainThread public void onProvisioningFailure(int status) { - if (TextUtils.equals( - mOsuStatusString, mContext.getString( - R.string.wifitrackerlib_osu_completing_sign_up))) { - mOsuStatusString = mContext.getString(R.string.wifitrackerlib_osu_sign_up_failed); - } else { - mOsuStatusString = mContext.getString(R.string.wifitrackerlib_osu_connect_failed); - } - if (mConnectCallback != null) { - mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + synchronized (OsuWifiEntry.this) { + if (TextUtils.equals( + mOsuStatusString, mContext.getString( + R.string.wifitrackerlib_osu_completing_sign_up))) { + mOsuStatusString = + mContext.getString(R.string.wifitrackerlib_osu_sign_up_failed); + } else { + mOsuStatusString = + mContext.getString(R.string.wifitrackerlib_osu_connect_failed); + } + if (mConnectCallback != null) { + mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + } } notifyOnUpdated(); } @@ -236,16 +235,20 @@ class OsuWifiEntry extends WifiEntry { R.string.wifitrackerlib_osu_completing_sign_up); break; } - boolean updated = !TextUtils.equals(mOsuStatusString, newStatusString); - mOsuStatusString = newStatusString; - if (updated) { - notifyOnUpdated(); + synchronized (OsuWifiEntry.this) { + boolean updated = !TextUtils.equals(mOsuStatusString, newStatusString); + mOsuStatusString = newStatusString; + if (updated) { + notifyOnUpdated(); + } } } @Override @MainThread public void onProvisioningComplete() { - mOsuStatusString = mContext.getString(R.string.wifitrackerlib_osu_sign_up_complete); + synchronized (OsuWifiEntry.this) { + mOsuStatusString = mContext.getString(R.string.wifitrackerlib_osu_sign_up_complete); + } notifyOnUpdated(); PasspointConfiguration passpointConfig = mWifiManager @@ -253,8 +256,10 @@ class OsuWifiEntry extends WifiEntry { .get(mOsuProvider); if (passpointConfig == null) { // Failed to find the config we just provisioned - if (mConnectCallback != null) { - mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + synchronized (OsuWifiEntry.this) { + if (mConnectCallback != null) { + mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + } } return; } @@ -282,8 +287,10 @@ class OsuWifiEntry extends WifiEntry { } // Failed to find the network we provisioned for - if (mConnectCallback != null) { - mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + synchronized (OsuWifiEntry.this) { + if (mConnectCallback != null) { + mConnectCallback.onConnectResult(CONNECT_STATUS_FAILURE_UNKNOWN); + } } } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java index 63f63dd51..7c5bbf81e 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java @@ -50,7 +50,6 @@ import android.os.Handler; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -70,16 +69,12 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry static final String TAG = "PasspointWifiEntry"; public static final String KEY_PREFIX = "PasspointWifiEntry:"; - private final Object mLock = new Object(); - // Scan result list must be thread safe for generating the verbose scan summary - @GuardedBy("mLock") private final List<ScanResult> mCurrentHomeScanResults = new ArrayList<>(); - @GuardedBy("mLock") private final List<ScanResult> mCurrentRoamingScanResults = new ArrayList<>(); @NonNull private final String mKey; - @NonNull private String mFqdn; - @NonNull private String mFriendlyName; + @NonNull private final String mFqdn; + @NonNull private final String mFriendlyName; @NonNull private final Context mContext; @Nullable private PasspointConfiguration mPasspointConfig; @@ -155,7 +150,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry @Override @ConnectedState - public int getConnectedState() { + public synchronized int getConnectedState() { if (isExpired()) { if (super.getConnectedState() == CONNECTED_STATE_DISCONNECTED && mOsuWifiEntry != null) { @@ -171,7 +166,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public String getSummary(boolean concise) { + public synchronized String getSummary(boolean concise) { StringJoiner sj = new StringJoiner(mContext.getString( R.string.wifitrackerlib_summary_separator)); @@ -237,13 +232,13 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public CharSequence getSecondSummary() { + public synchronized CharSequence getSecondSummary() { return getConnectedState() == CONNECTED_STATE_CONNECTED ? getImsiProtectionDescription(mContext, mWifiConfig) : ""; } @Override - public String getSsid() { + public synchronized String getSsid() { if (mWifiInfo != null) { return sanitizeSsid(mWifiInfo.getSSID()); } @@ -252,12 +247,12 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public List<Integer> getSecurityTypes() { - return mTargetSecurityTypes; + public synchronized List<Integer> getSecurityTypes() { + return new ArrayList<>(mTargetSecurityTypes); } @Override - public String getMacAddress() { + public synchronized String getMacAddress() { if (mWifiInfo != null) { final String wifiInfoMac = mWifiInfo.getMacAddress(); if (!TextUtils.isEmpty(wifiInfoMac) @@ -276,23 +271,23 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean isMetered() { + public synchronized boolean isMetered() { return getMeteredChoice() == METERED_CHOICE_METERED || (mWifiConfig != null && mWifiConfig.meteredHint); } @Override - public boolean isSuggestion() { + public synchronized boolean isSuggestion() { return mWifiConfig != null && mWifiConfig.fromWifiNetworkSuggestion; } @Override - public boolean isSubscription() { + public synchronized boolean isSubscription() { return mPasspointConfig != null; } @Override - public boolean canConnect() { + public synchronized boolean canConnect() { if (isExpired()) { return mOsuWifiEntry != null && mOsuWifiEntry.canConnect(); } @@ -302,7 +297,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public void connect(@Nullable ConnectCallback callback) { + public synchronized void connect(@Nullable ConnectCallback callback) { if (isExpired()) { if (mOsuWifiEntry != null) { mOsuWifiEntry.connect(callback); @@ -328,14 +323,16 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public void disconnect(@Nullable DisconnectCallback callback) { + public synchronized void disconnect(@Nullable DisconnectCallback callback) { if (canDisconnect()) { mCalledDisconnect = true; mDisconnectCallback = callback; mCallbackHandler.postDelayed(() -> { - if (callback != null && mCalledDisconnect) { - callback.onDisconnectResult( - DisconnectCallback.DISCONNECT_STATUS_FAILURE_UNKNOWN); + synchronized (this) { + if (callback != null && mCalledDisconnect) { + callback.onDisconnectResult( + DisconnectCallback.DISCONNECT_STATUS_FAILURE_UNKNOWN); + } } }, 10_000 /* delayMillis */); mWifiManager.disableEphemeralNetwork(mFqdn); @@ -344,12 +341,12 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean canForget() { + public synchronized boolean canForget() { return !isSuggestion() && mPasspointConfig != null; } @Override - public void forget(@Nullable ForgetCallback callback) { + public synchronized void forget(@Nullable ForgetCallback callback) { if (!canForget()) { return; } @@ -361,7 +358,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry @Override @MeteredChoice - public int getMeteredChoice() { + public synchronized int getMeteredChoice() { if (mMeteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) { return METERED_CHOICE_METERED; } else if (mMeteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) { @@ -371,13 +368,13 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean canSetMeteredChoice() { + public synchronized boolean canSetMeteredChoice() { return !isSuggestion() && mPasspointConfig != null; } @Override - public void setMeteredChoice(int meteredChoice) { - if (!canSetMeteredChoice()) { + public synchronized void setMeteredChoice(int meteredChoice) { + if (mPasspointConfig == null || !canSetMeteredChoice()) { return; } @@ -400,13 +397,13 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean canSetPrivacy() { + public synchronized boolean canSetPrivacy() { return !isSuggestion() && mPasspointConfig != null; } @Override @Privacy - public int getPrivacy() { + public synchronized int getPrivacy() { if (mPasspointConfig == null) { return PRIVACY_RANDOMIZED_MAC; } @@ -416,8 +413,8 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public void setPrivacy(int privacy) { - if (!canSetPrivacy()) { + public synchronized void setPrivacy(int privacy) { + if (mPasspointConfig == null || !canSetPrivacy()) { return; } @@ -427,7 +424,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean isAutoJoinEnabled() { + public synchronized boolean isAutoJoinEnabled() { // Suggestion network; use WifiConfig instead if (mPasspointConfig != null) { return mPasspointConfig.isAutojoinEnabled(); @@ -439,12 +436,12 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean canSetAutoJoinEnabled() { + public synchronized boolean canSetAutoJoinEnabled() { return mPasspointConfig != null || mWifiConfig != null; } @Override - public void setAutoJoinEnabled(boolean enabled) { + public synchronized void setAutoJoinEnabled(boolean enabled) { if (mPasspointConfig != null) { mWifiManager.allowAutojoinPasspoint(mPasspointConfig.getHomeSp().getFqdn(), enabled); } else if (mWifiConfig != null) { @@ -458,7 +455,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean isExpired() { + public synchronized boolean isExpired() { if (mSubscriptionExpirationTimeInMillis <= 0) { // Expiration time not specified. return false; @@ -468,10 +465,9 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @WorkerThread - void updatePasspointConfig(@Nullable PasspointConfiguration passpointConfig) { + synchronized void updatePasspointConfig(@Nullable PasspointConfiguration passpointConfig) { mPasspointConfig = passpointConfig; if (mPasspointConfig != null) { - mFriendlyName = passpointConfig.getHomeSp().getFriendlyName(); mSubscriptionExpirationTimeInMillis = passpointConfig.getSubscriptionExpirationTimeMillis(); mMeteredOverride = passpointConfig.getMeteredOverride(); @@ -480,21 +476,19 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @WorkerThread - void updateScanResultInfo(@Nullable WifiConfiguration wifiConfig, + synchronized void updateScanResultInfo(@Nullable WifiConfiguration wifiConfig, @Nullable List<ScanResult> homeScanResults, @Nullable List<ScanResult> roamingScanResults) throws IllegalArgumentException { mIsRoaming = false; mWifiConfig = wifiConfig; - synchronized (mLock) { - mCurrentHomeScanResults.clear(); - mCurrentRoamingScanResults.clear(); - if (homeScanResults != null) { - mCurrentHomeScanResults.addAll(homeScanResults); - } - if (roamingScanResults != null) { - mCurrentRoamingScanResults.addAll(roamingScanResults); - } + mCurrentHomeScanResults.clear(); + mCurrentRoamingScanResults.clear(); + if (homeScanResults != null) { + mCurrentHomeScanResults.addAll(homeScanResults); + } + if (roamingScanResults != null) { + mCurrentRoamingScanResults.addAll(roamingScanResults); } if (mWifiConfig != null) { List<ScanResult> currentScanResults = new ArrayList<>(); @@ -523,7 +517,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - protected void updateSecurityTypes() { + protected synchronized void updateSecurityTypes() { if (mWifiInfo != null) { final int wifiInfoSecurity = mWifiInfo.getCurrentSecurityType(); if (wifiInfoSecurity != SECURITY_TYPE_UNKNOWN) { @@ -534,18 +528,16 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @WorkerThread - void onScoreCacheUpdated() { + synchronized void onScoreCacheUpdated() { if (mWifiInfo != null) { mSpeed = getSpeedFromWifiInfo(mScoreCache, mWifiInfo); } else { - synchronized (mLock) { - // Average speed is used to prevent speed label flickering from multiple APs. - if (!mCurrentHomeScanResults.isEmpty()) { - mSpeed = getAverageSpeedFromScanResults(mScoreCache, mCurrentHomeScanResults); - } else { - mSpeed = getAverageSpeedFromScanResults(mScoreCache, - mCurrentRoamingScanResults); - } + // Average speed is used to prevent speed label flickering from multiple APs. + if (!mCurrentHomeScanResults.isEmpty()) { + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mCurrentHomeScanResults); + } else { + mSpeed = getAverageSpeedFromScanResults(mScoreCache, + mCurrentRoamingScanResults); } } notifyOnUpdated(); @@ -565,7 +557,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry @WorkerThread @Override - void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { + synchronized void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { super.updateNetworkCapabilities(capabilities); // Auto-open an available captive portal if the user manually connected to this network. @@ -588,12 +580,12 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - String getNetworkSelectionDescription() { + synchronized String getNetworkSelectionDescription() { return Utils.getNetworkSelectionDescription(mWifiConfig); } /** Pass a reference to a matching OsuWifiEntry for expiration handling */ - void setOsuWifiEntry(OsuWifiEntry osuWifiEntry) { + synchronized void setOsuWifiEntry(OsuWifiEntry osuWifiEntry) { mOsuWifiEntry = osuWifiEntry; if (mOsuWifiEntry != null) { mOsuWifiEntry.setListener(this); @@ -607,7 +599,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry } @Override - public boolean canSignIn() { + public synchronized boolean canSignIn() { return mNetworkCapabilities != null && mNetworkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java index be95468a7..994331a69 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java @@ -68,7 +68,6 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; -import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -104,7 +103,6 @@ public class StandardWifiEntry extends WifiEntry { @NonNull private final Context mContext; - private final Object mLock = new Object(); // Map of security type to matching scan results @NonNull private final Map<Integer, List<ScanResult>> mMatchingScanResults = new HashMap<>(); // Map of security type to matching WifiConfiguration @@ -115,8 +113,6 @@ public class StandardWifiEntry extends WifiEntry { // security from all of the matched WifiConfigurations. // If no WifiConfigurations are available, then these should match the most appropriate security // type (e.g. PSK for an PSK/SAE entry, OWE for an Open/OWE entry). - // Note: Must be thread safe for generating the verbose scan summary - @GuardedBy("mLock") @NonNull private final List<ScanResult> mTargetScanResults = new ArrayList<>(); // Target WifiConfiguration for connection and displaying WifiConfiguration info private WifiConfiguration mTargetWifiConfig; @@ -176,7 +172,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public String getSummary(boolean concise) { + public synchronized String getSummary(boolean concise) { StringJoiner sj = new StringJoiner(mContext.getString( R.string.wifitrackerlib_summary_separator)); @@ -245,12 +241,12 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public List<Integer> getSecurityTypes() { - return mTargetSecurityTypes; + public synchronized List<Integer> getSecurityTypes() { + return new ArrayList<>(mTargetSecurityTypes); } @Override - public String getMacAddress() { + public synchronized String getMacAddress() { if (mWifiInfo != null) { final String wifiInfoMac = mWifiInfo.getMacAddress(); if (!TextUtils.isEmpty(wifiInfoMac) @@ -269,24 +265,24 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public boolean isMetered() { + public synchronized boolean isMetered() { return getMeteredChoice() == METERED_CHOICE_METERED || (mTargetWifiConfig != null && mTargetWifiConfig.meteredHint); } @Override - public boolean isSaved() { + public synchronized boolean isSaved() { return mTargetWifiConfig != null && !mTargetWifiConfig.fromWifiNetworkSuggestion && !mTargetWifiConfig.isEphemeral(); } @Override - public boolean isSuggestion() { + public synchronized boolean isSuggestion() { return mTargetWifiConfig != null && mTargetWifiConfig.fromWifiNetworkSuggestion; } @Override - public WifiConfiguration getWifiConfiguration() { + public synchronized WifiConfiguration getWifiConfiguration() { if (!isSaved()) { return null; } @@ -294,12 +290,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public ConnectedInfo getConnectedInfo() { - return mConnectedInfo; - } - - @Override - public boolean canConnect() { + public synchronized boolean canConnect() { if (mLevel == WIFI_LEVEL_UNREACHABLE || getConnectedState() != CONNECTED_STATE_DISCONNECTED) { return false; @@ -332,7 +323,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void connect(@Nullable ConnectCallback callback) { + public synchronized void connect(@Nullable ConnectCallback callback) { mConnectCallback = callback; // We should flag this network to auto-open captive portal since this method represents // the user manually connecting to a network (i.e. not auto-join). @@ -387,7 +378,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void disconnect(@Nullable DisconnectCallback callback) { + public synchronized void disconnect(@Nullable DisconnectCallback callback) { if (canDisconnect()) { mCalledDisconnect = true; mDisconnectCallback = callback; @@ -408,7 +399,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void forget(@Nullable ForgetCallback callback) { + public synchronized void forget(@Nullable ForgetCallback callback) { if (canForget()) { mForgetCallback = callback; mWifiManager.forget(mTargetWifiConfig.networkId, new ForgetActionListener()); @@ -416,7 +407,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public boolean canSignIn() { + public synchronized boolean canSignIn() { return mNetworkCapabilities != null && mNetworkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); @@ -437,7 +428,7 @@ public class StandardWifiEntry extends WifiEntry { * See https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11 */ @Override - public boolean canShare() { + public synchronized boolean canShare() { if (getWifiConfiguration() == null) { return false; } @@ -460,7 +451,7 @@ public class StandardWifiEntry extends WifiEntry { * See https://www.wi-fi.org/discover-wi-fi/wi-fi-easy-connect */ @Override - public boolean canEasyConnect() { + public synchronized boolean canEasyConnect() { if (getWifiConfiguration() == null) { return false; } @@ -476,9 +467,9 @@ public class StandardWifiEntry extends WifiEntry { @Override @MeteredChoice - public int getMeteredChoice() { - if (getWifiConfiguration() != null) { - final int meteredOverride = getWifiConfiguration().meteredOverride; + public synchronized int getMeteredChoice() { + if (!isSuggestion() && mTargetWifiConfig != null) { + final int meteredOverride = mTargetWifiConfig.meteredOverride; if (meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) { return METERED_CHOICE_METERED; } else if (meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) { @@ -494,7 +485,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void setMeteredChoice(int meteredChoice) { + public synchronized void setMeteredChoice(int meteredChoice) { if (!canSetMeteredChoice()) { return; } @@ -516,7 +507,7 @@ public class StandardWifiEntry extends WifiEntry { @Override @Privacy - public int getPrivacy() { + public synchronized int getPrivacy() { if (mTargetWifiConfig != null && mTargetWifiConfig.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_NONE) { @@ -527,7 +518,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void setPrivacy(int privacy) { + public synchronized void setPrivacy(int privacy) { if (!canSetPrivacy()) { return; } @@ -538,7 +529,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public boolean isAutoJoinEnabled() { + public synchronized boolean isAutoJoinEnabled() { if (mTargetWifiConfig == null) { return false; } @@ -552,8 +543,8 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public void setAutoJoinEnabled(boolean enabled) { - if (!canSetAutoJoinEnabled()) { + public synchronized void setAutoJoinEnabled(boolean enabled) { + if (mTargetWifiConfig == null || !canSetAutoJoinEnabled()) { return; } @@ -561,7 +552,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public String getSecurityString(boolean concise) { + public synchronized String getSecurityString(boolean concise) { if (mTargetSecurityTypes.size() == 0) { return concise ? "" : mContext.getString(R.string.wifitrackerlib_wifi_security_none); } @@ -633,7 +624,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - public boolean shouldEditBeforeConnect() { + public synchronized boolean shouldEditBeforeConnect() { WifiConfiguration wifiConfig = getWifiConfiguration(); if (wifiConfig == null) { return false; @@ -655,7 +646,7 @@ public class StandardWifiEntry extends WifiEntry { } @WorkerThread - void updateScanResultInfo(@Nullable List<ScanResult> scanResults) + synchronized void updateScanResultInfo(@Nullable List<ScanResult> scanResults) throws IllegalArgumentException { if (scanResults == null) scanResults = new ArrayList<>(); @@ -687,7 +678,7 @@ public class StandardWifiEntry extends WifiEntry { notifyOnUpdated(); } - private void updateTargetScanResultInfo() { + private synchronized void updateTargetScanResultInfo() { // Update the level using the scans matching the target security type final ScanResult bestScanResult = getBestScanResultByLevel(mTargetScanResults); @@ -695,16 +686,14 @@ public class StandardWifiEntry extends WifiEntry { mLevel = bestScanResult != null ? mWifiManager.calculateSignalLevel(bestScanResult.level) : WIFI_LEVEL_UNREACHABLE; - synchronized (mLock) { - // Average speed is used to prevent speed label flickering from multiple APs. - mSpeed = getAverageSpeedFromScanResults(mScoreCache, mTargetScanResults); - } + // Average speed is used to prevent speed label flickering from multiple APs. + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mTargetScanResults); } } @WorkerThread @Override - void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { + synchronized void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { super.updateNetworkCapabilities(capabilities); // Auto-open an available captive portal if the user manually connected to this network. @@ -715,20 +704,18 @@ public class StandardWifiEntry extends WifiEntry { } @WorkerThread - void onScoreCacheUpdated() { + synchronized void onScoreCacheUpdated() { if (mWifiInfo != null) { mSpeed = getSpeedFromWifiInfo(mScoreCache, mWifiInfo); } else { - synchronized (mLock) { - // Average speed is used to prevent speed label flickering from multiple APs. - mSpeed = getAverageSpeedFromScanResults(mScoreCache, mTargetScanResults); - } + // Average speed is used to prevent speed label flickering from multiple APs. + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mTargetScanResults); } notifyOnUpdated(); } @WorkerThread - void updateConfig(@Nullable List<WifiConfiguration> wifiConfigs) + synchronized void updateConfig(@Nullable List<WifiConfiguration> wifiConfigs) throws IllegalArgumentException { if (wifiConfigs == null) { wifiConfigs = Collections.emptyList(); @@ -778,7 +765,7 @@ public class StandardWifiEntry extends WifiEntry { } @Override - protected void updateSecurityTypes() { + protected synchronized void updateSecurityTypes() { mTargetSecurityTypes.clear(); if (mWifiInfo != null) { final int wifiInfoSecurity = mWifiInfo.getCurrentSecurityType(); @@ -828,17 +815,15 @@ public class StandardWifiEntry extends WifiEntry { targetScanResultSet.addAll(mMatchingScanResults.get(security)); } } - synchronized (mLock) { - mTargetScanResults.clear(); - mTargetScanResults.addAll(targetScanResultSet); - } + mTargetScanResults.clear(); + mTargetScanResults.addAll(targetScanResultSet); } /** * Sets whether the suggested config for this entry is shareable to the user or not. */ @WorkerThread - void setUserShareable(boolean isUserShareable) { + synchronized void setUserShareable(boolean isUserShareable) { mIsUserShareable = isUserShareable; } @@ -846,12 +831,12 @@ public class StandardWifiEntry extends WifiEntry { * Returns whether the suggested config for this entry is shareable to the user or not. */ @WorkerThread - boolean isUserShareable() { + synchronized boolean isUserShareable() { return mIsUserShareable; } @WorkerThread - protected boolean connectionInfoMatches(@NonNull WifiInfo wifiInfo, + protected synchronized boolean connectionInfoMatches(@NonNull WifiInfo wifiInfo, @NonNull NetworkInfo networkInfo) { if (wifiInfo.isPasspointAp() || wifiInfo.isOsuAp()) { return false; @@ -864,7 +849,7 @@ public class StandardWifiEntry extends WifiEntry { return false; } - private void updateRecommendationServiceLabel() { + private synchronized void updateRecommendationServiceLabel() { final NetworkScorerAppData scorer = ((NetworkScoreManager) mContext .getSystemService(Context.NETWORK_SCORE_SERVICE)).getActiveScorer(); if (scorer != null) { @@ -888,11 +873,9 @@ public class StandardWifiEntry extends WifiEntry { } @Override - protected String getScanResultDescription() { - synchronized (mLock) { - if (mTargetScanResults.size() == 0) { - return ""; - } + protected synchronized String getScanResultDescription() { + if (mTargetScanResults.size() == 0) { + return ""; } final StringBuilder description = new StringBuilder(); @@ -905,15 +888,12 @@ public class StandardWifiEntry extends WifiEntry { return description.toString(); } - private String getScanResultDescription(int minFrequency, int maxFrequency) { - final List<ScanResult> scanResults; - synchronized (mLock) { - scanResults = mTargetScanResults.stream() - .filter(scanResult -> scanResult.frequency >= minFrequency - && scanResult.frequency <= maxFrequency) - .sorted(Comparator.comparingInt(scanResult -> -1 * scanResult.level)) - .collect(Collectors.toList()); - } + private synchronized String getScanResultDescription(int minFrequency, int maxFrequency) { + final List<ScanResult> scanResults = mTargetScanResults.stream() + .filter(scanResult -> scanResult.frequency >= minFrequency + && scanResult.frequency <= maxFrequency) + .sorted(Comparator.comparingInt(scanResult -> -1 * scanResult.level)) + .collect(Collectors.toList()); final int scanResultCount = scanResults.size(); if (scanResultCount == 0) { @@ -933,7 +913,7 @@ public class StandardWifiEntry extends WifiEntry { return description.toString(); } - private String getScanResultDescription(ScanResult scanResult, long nowMs) { + private synchronized String getScanResultDescription(ScanResult scanResult, long nowMs) { final StringBuilder description = new StringBuilder(); description.append(" \n{"); description.append(scanResult.BSSID); diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java index 295e5a708..87273dfe3 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java @@ -226,7 +226,7 @@ public class WifiEntry implements Comparable<WifiEntry> { // Callback associated with this WifiEntry. Subclasses should call its methods appropriately. private WifiEntryCallback mListener; - protected Handler mCallbackHandler; + protected final Handler mCallbackHandler; protected int mLevel = WIFI_LEVEL_UNREACHABLE; protected int mSpeed = SPEED_NONE; @@ -270,7 +270,7 @@ public class WifiEntry implements Comparable<WifiEntry> { /** Returns connection state of the network defined by the CONNECTED_STATE constants */ @ConnectedState - public int getConnectedState() { + public synchronized int getConnectedState() { if (mNetworkInfo == null) { return CONNECTED_STATE_DISCONNECTED; } @@ -447,12 +447,12 @@ public class WifiEntry implements Comparable<WifiEntry> { * Returns null if getConnectedState() != CONNECTED_STATE_CONNECTED. */ @Nullable - public ConnectedInfo getConnectedInfo() { + public synchronized ConnectedInfo getConnectedInfo() { if (getConnectedState() != CONNECTED_STATE_CONNECTED) { return null; } - return mConnectedInfo; + return new ConnectedInfo(mConnectedInfo); } /** @@ -468,6 +468,26 @@ public class WifiEntry implements Comparable<WifiEntry> { public String gateway; public String subnetMask; public int wifiStandard = ScanResult.WIFI_STANDARD_UNKNOWN; + + /** + * Creates an empty ConnectedInfo + */ + public ConnectedInfo() { + } + + /** + * Creates a ConnectedInfo with all fields copied from an input ConnectedInfo + */ + public ConnectedInfo(@NonNull ConnectedInfo other) { + frequencyMhz = other.frequencyMhz; + dnsServers = new ArrayList<>(dnsServers); + linkSpeedMbps = other.linkSpeedMbps; + ipAddress = other.ipAddress; + ipv6Addresses = new ArrayList<>(other.ipv6Addresses); + gateway = other.gateway; + subnetMask = other.subnetMask; + wifiStandard = other.wifiStandard; + } } // User actions on a network @@ -660,7 +680,7 @@ public class WifiEntry implements Comparable<WifiEntry> { * Sets the callback listener for WifiEntryCallback methods. * Subsequent calls will overwrite the previous listener. */ - public void setListener(WifiEntryCallback listener) { + public synchronized void setListener(WifiEntryCallback listener) { mListener = listener; } @@ -681,10 +701,10 @@ public class WifiEntry implements Comparable<WifiEntry> { protected void notifyOnUpdated() { if (mListener != null) { mCallbackHandler.post(() -> { - final WifiEntryCallback listener = mListener; - // Check for null again since it may change before this runnable is run - if (listener != null) { - listener.onUpdated(); + synchronized (this) { + if (mListener != null) { + mListener.onUpdated(); + } } }); } @@ -799,7 +819,8 @@ public class WifiEntry implements Comparable<WifiEntry> { * unconnected. */ @WorkerThread - void updateConnectionInfo(@Nullable WifiInfo wifiInfo, @Nullable NetworkInfo networkInfo) { + synchronized void updateConnectionInfo( + @Nullable WifiInfo wifiInfo, @Nullable NetworkInfo networkInfo) { if (wifiInfo != null && networkInfo != null && connectionInfoMatches(wifiInfo, networkInfo)) { // Connection info matches, so the WifiInfo/NetworkInfo represent this network and @@ -859,7 +880,7 @@ public class WifiEntry implements Comparable<WifiEntry> { // Method for WifiTracker to update the link properties, which is valid for all WifiEntry types. @WorkerThread - void updateLinkProperties(@Nullable LinkProperties linkProperties) { + synchronized void updateLinkProperties(@Nullable LinkProperties linkProperties) { if (linkProperties == null || getConnectedState() != CONNECTED_STATE_CONNECTED) { mConnectedInfo = null; notifyOnUpdated(); @@ -905,19 +926,19 @@ public class WifiEntry implements Comparable<WifiEntry> { } @WorkerThread - void setIsDefaultNetwork(boolean isDefaultNetwork) { + synchronized void setIsDefaultNetwork(boolean isDefaultNetwork) { mIsDefaultNetwork = isDefaultNetwork; notifyOnUpdated(); } @WorkerThread - void setIsLowQuality(boolean isLowQuality) { + synchronized void setIsLowQuality(boolean isLowQuality) { mIsLowQuality = isLowQuality; } // Method for WifiTracker to update a connected WifiEntry's network capabilities. @WorkerThread - void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { + synchronized void updateNetworkCapabilities(@Nullable NetworkCapabilities capabilities) { mNetworkCapabilities = capabilities; if (mConnectedInfo == null) { return; @@ -927,7 +948,7 @@ public class WifiEntry implements Comparable<WifiEntry> { notifyOnUpdated(); } - String getWifiInfoDescription() { + synchronized String getWifiInfoDescription() { final StringJoiner sj = new StringJoiner(" "); if (getConnectedState() == CONNECTED_STATE_CONNECTED && mWifiInfo != null) { sj.add("f = " + mWifiInfo.getFrequency()); @@ -949,14 +970,18 @@ public class WifiEntry implements Comparable<WifiEntry> { protected class ConnectActionListener implements WifiManager.ActionListener { @Override public void onSuccess() { - mCalledConnect = true; + synchronized (WifiEntry.this) { + mCalledConnect = true; + } // If we aren't connected to the network after 10 seconds, trigger the failure callback mCallbackHandler.postDelayed(() -> { - if (mConnectCallback != null && mCalledConnect - && getConnectedState() == CONNECTED_STATE_DISCONNECTED) { - mConnectCallback.onConnectResult( - ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN); - mCalledConnect = false; + synchronized (WifiEntry.this) { + if (mConnectCallback != null && mCalledConnect + && getConnectedState() == CONNECTED_STATE_DISCONNECTED) { + mConnectCallback.onConnectResult( + ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN); + mCalledConnect = false; + } } }, 10_000 /* delayMillis */); } @@ -964,9 +989,11 @@ public class WifiEntry implements Comparable<WifiEntry> { @Override public void onFailure(int i) { mCallbackHandler.post(() -> { - if (mConnectCallback != null) { - mConnectCallback.onConnectResult( - mConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN); + synchronized (WifiEntry.this) { + if (mConnectCallback != null) { + mConnectCallback.onConnectResult( + mConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN); + } } }); } @@ -976,8 +1003,10 @@ public class WifiEntry implements Comparable<WifiEntry> { @Override public void onSuccess() { mCallbackHandler.post(() -> { - if (mForgetCallback != null) { - mForgetCallback.onForgetResult(ForgetCallback.FORGET_STATUS_SUCCESS); + synchronized (WifiEntry.this) { + if (mForgetCallback != null) { + mForgetCallback.onForgetResult(ForgetCallback.FORGET_STATUS_SUCCESS); + } } }); } @@ -985,8 +1014,11 @@ public class WifiEntry implements Comparable<WifiEntry> { @Override public void onFailure(int i) { mCallbackHandler.post(() -> { - if (mForgetCallback != null) { - mForgetCallback.onForgetResult(ForgetCallback.FORGET_STATUS_FAILURE_UNKNOWN); + synchronized (WifiEntry.this) { + if (mForgetCallback != null) { + mForgetCallback.onForgetResult( + ForgetCallback.FORGET_STATUS_FAILURE_UNKNOWN); + } } }); } |