diff options
author | Quang Luong <qal@google.com> | 2020-01-31 18:48:33 -0800 |
---|---|---|
committer | Quang Luong <qal@google.com> | 2020-02-05 13:16:49 -0800 |
commit | edcd0f80c75c7877b1df9511b8eb283ef12ba5ca (patch) | |
tree | 37d0ff127e1665f5669aec82af013108c6ac14e0 /libs | |
parent | 0fbeb8b4e75689b173f910f1ddc8583f363ce8d1 (diff) |
[WifiTrackerLib] Add OSU entries to wifi picker list
Adding entries for Online Sign-Up in the wifi picker list. Future CLs
will handle starting the provisioning flow and showing the OSU entry as
the connected entry.
Test: manual visual verification of picker list, atest WifiPickerTrackerTest
Bug: 70983952
Change-Id: I387ff9a96d63c760bf05be7dc8a1ddb8d4992fab
Diffstat (limited to 'libs')
3 files changed, 343 insertions, 2 deletions
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java new file mode 100644 index 000000000..4e0f373ec --- /dev/null +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wifitrackerlib; + +import static androidx.core.util.Preconditions.checkNotNull; + +import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; + +import android.content.Context; +import android.net.NetworkInfo; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.net.wifi.hotspot2.OsuProvider; +import android.os.Handler; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; + +import java.util.ArrayList; +import java.util.List; + +/** + * WifiEntry representation of an Online Sign-up entry, uniquely identified by FQDN. + */ +class OsuWifiEntry extends WifiEntry { + static final String KEY_PREFIX = "OsuWifiEntry:"; + + @NonNull private final List<ScanResult> mCurrentScanResults = new ArrayList<>(); + + @NonNull private final String mKey; + @NonNull private String mFriendlyName; + @NonNull private final Context mContext; + @NonNull private OsuProvider mOsuProvider; + + private int mLevel = WIFI_LEVEL_UNREACHABLE; + + /** + * Create n OsuWifiEntry with the associated OsuProvider + */ + OsuWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, + @NonNull OsuProvider osuProvider, + @NonNull WifiManager wifiManager) throws IllegalArgumentException { + super(callbackHandler, wifiManager, false /* forSavedNetworksPage */); + + checkNotNull(osuProvider, "Cannot construct with null osuProvider!"); + + mContext = context; + mOsuProvider = osuProvider; + mKey = osuProviderToOsuWifiEntryKey(osuProvider); + } + + @Override + public String getKey() { + return mKey; + } + + @Override + public String getTitle() { + return mOsuProvider.getFriendlyName(); + } + + @Override + public String getSummary() { + return getSummary(true /* concise */); + } + + @Override + public String getSummary(boolean concise) { + // TODO(b/70983952): Fill this method in + return "Osu (Placeholder Text)"; // Placeholder string + } + + @Override + public int getLevel() { + return mLevel; + } + + @Override + public String getSsid() { + // TODO(b/70983952): Fill this method in in case we need the SSID for verbose logging + return ""; + } + + @Override + @Security + public int getSecurity() { + return SECURITY_NONE; + } + + @Override + public String getMacAddress() { + // TODO(b/70983952): Fill this method in in case we need the mac address for verbose logging + return null; + } + + @Override + public boolean isMetered() { + return false; + } + + @Override + public boolean isSaved() { + return false; + } + + @Override + public boolean isSubscription() { + return false; + } + + @Override + public WifiConfiguration getWifiConfiguration() { + return null; + } + + @Override + public boolean canConnect() { + return mLevel != WIFI_LEVEL_UNREACHABLE + && getConnectedState() == CONNECTED_STATE_DISCONNECTED; + } + + @Override + public void connect(@Nullable ConnectCallback callback) { + // TODO(b/70983952): Fill this method in. + } + + // Exiting from the OSU flow should disconnect from the network. + @Override + public boolean canDisconnect() { + return false; + } + + @Override + public void disconnect(@Nullable DisconnectCallback callback) { + } + + @Override + public boolean canForget() { + return false; + } + + @Override + public void forget(@Nullable ForgetCallback callback) { + } + + @Override + public boolean canSignIn() { + return false; + } + + @Override + public void signIn(@Nullable SignInCallback callback) { + return; + } + + @Override + public boolean canShare() { + return false; + } + + @Override + public boolean canEasyConnect() { + return false; + } + + @Override + public String getQrCodeString() { + return null; + } + + @Override + public boolean canSetPassword() { + return false; + } + + @Override + public void setPassword(@NonNull String password) { + // Do nothing. + } + + @Override + @MeteredChoice + public int getMeteredChoice() { + // Metered choice is meaningless for OSU entries + return METERED_CHOICE_AUTO; + } + + @Override + public boolean canSetMeteredChoice() { + return false; + } + + @Override + public void setMeteredChoice(int meteredChoice) { + // Metered choice is meaningless for OSU entries + } + + @Override + @Privacy + public int getPrivacy() { + // MAC Randomization choice is meaningless for OSU entries. + return PRIVACY_UNKNOWN; + } + + @Override + public boolean canSetPrivacy() { + return false; + } + + @Override + public void setPrivacy(int privacy) { + // MAC Randomization choice is meaningless for OSU entries. + } + + @Override + public boolean isAutoJoinEnabled() { + return false; + } + + @Override + public boolean canSetAutoJoinEnabled() { + return false; + } + + @Override + public void setAutoJoinEnabled(boolean enabled) { + } + + @Override + public String getSecurityString(boolean concise) { + return ""; + } + + @Override + public boolean isExpired() { + return false; + } + + @WorkerThread + void updateScanResultInfo(@Nullable List<ScanResult> scanResults) + throws IllegalArgumentException { + if (scanResults == null) scanResults = new ArrayList<>(); + + mCurrentScanResults.clear(); + mCurrentScanResults.addAll(scanResults); + + final ScanResult bestScanResult = getBestScanResultByLevel(mCurrentScanResults); + if (bestScanResult == null) { + mLevel = WIFI_LEVEL_UNREACHABLE; + } else { + mLevel = mWifiManager.calculateSignalLevel(bestScanResult.level); + } + + notifyOnUpdated(); + } + + @NonNull + static String osuProviderToOsuWifiEntryKey(@NonNull OsuProvider osuProvider) { + checkNotNull(osuProvider, "Cannot create key with null OsuProvider!"); + return KEY_PREFIX + osuProvider.getFriendlyName() + "," + + osuProvider.getServerUri().toString(); + } + + @WorkerThread + @Override + protected boolean connectionInfoMatches(@NonNull WifiInfo wifiInfo, + @NonNull NetworkInfo networkInfo) { + // TODO(b/70983952): Fill this method in. + return false; + } + + @Override + String getScanResultDescription() { + // TODO(b/70983952): Fill this method in. + return ""; + } +} diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java index 6423f6fb6..ad386d223 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java @@ -18,6 +18,7 @@ package com.android.wifitrackerlib; import static androidx.core.util.Preconditions.checkNotNull; +import static com.android.wifitrackerlib.OsuWifiEntry.osuProviderToOsuWifiEntryKey; import static com.android.wifitrackerlib.PasspointWifiEntry.fqdnToPasspointWifiEntryKey; import static com.android.wifitrackerlib.StandardWifiEntry.wifiConfigToStandardWifiEntryKey; import static com.android.wifitrackerlib.Utils.mapScanResultsToKey; @@ -39,6 +40,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Handler; import android.util.Log; @@ -93,6 +95,8 @@ public class WifiPickerTracker extends BaseWifiTracker { private final Map<String, PasspointConfiguration> mPasspointConfigCache = new HashMap<>(); // Cache containing visible PasspointWifiEntries. Must be accessed only by the worker thread. private final Map<String, PasspointWifiEntry> mPasspointWifiEntryCache = new HashMap<>(); + // Cache containing visible OsuWifiEntries. Must be accessed only by the worker thread. + private final Map<String, OsuWifiEntry> mOsuWifiEntryCache = new HashMap<>(); /** * Constructor for WifiPickerTracker. @@ -254,6 +258,8 @@ public class WifiPickerTracker extends BaseWifiTracker { entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList())); mWifiEntries.addAll(mPasspointWifiEntryCache.values().stream().filter(entry -> entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList())); + mWifiEntries.addAll(mOsuWifiEntryCache.values().stream().filter(entry -> + entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList())); mConnectedWifiEntry = mStandardWifiEntryCache.values().stream().filter(entry -> { final @WifiEntry.ConnectedState int connectedState = entry.getConnectedState(); return connectedState == CONNECTED_STATE_CONNECTED @@ -347,6 +353,26 @@ public class WifiPickerTracker extends BaseWifiTracker { .removeIf(entry -> entry.getValue().getLevel() == WIFI_LEVEL_UNREACHABLE); } + @WorkerThread + private void updateOsuWifiEntryScans(@NonNull List<ScanResult> scanResults) { + checkNotNull(scanResults, "Scan Result list should not be null!"); + + Map<OsuProvider, List<ScanResult>> osuProviderToScans = + mWifiManager.getMatchingOsuProviders(scanResults); + for (OsuProvider osuProvider : osuProviderToScans.keySet()) { + final String key = osuProviderToOsuWifiEntryKey(osuProvider); + if (!mOsuWifiEntryCache.containsKey(key)) { + mOsuWifiEntryCache.put(key, new OsuWifiEntry(mContext, + mMainHandler, osuProvider, mWifiManager)); + } + mOsuWifiEntryCache.get(key).updateScanResultInfo(osuProviderToScans.get(osuProvider)); + } + + // Remove entries that are now unreachable + mOsuWifiEntryCache.entrySet() + .removeIf(entry -> entry.getValue().getLevel() == WIFI_LEVEL_UNREACHABLE); + } + /** * Conditionally updates the WifiEntry scan results based on the current wifi state and * whether the last scan succeeded or not. @@ -356,6 +382,7 @@ public class WifiPickerTracker extends BaseWifiTracker { if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) { updateStandardWifiEntryScans(Collections.emptyList()); updatePasspointWifiEntryScans(Collections.emptyList()); + updateOsuWifiEntryScans(Collections.emptyList()); return; } @@ -369,8 +396,10 @@ public class WifiPickerTracker extends BaseWifiTracker { scanAgeWindow += mScanIntervalMillis; } - updateStandardWifiEntryScans(mScanResultUpdater.getScanResults(scanAgeWindow)); - updatePasspointWifiEntryScans(mScanResultUpdater.getScanResults(scanAgeWindow)); + List<ScanResult> scanResults = mScanResultUpdater.getScanResults(scanAgeWindow); + updateStandardWifiEntryScans(scanResults); + updatePasspointWifiEntryScans(scanResults); + updateOsuWifiEntryScans(scanResults); } /** diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java index 280ec971d..4f572d562 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java @@ -557,4 +557,22 @@ public class WifiPickerTrackerTest { verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged(); assertThat(wifiPickerTracker.getConnectedWifiEntry().getTitle()).isEqualTo(friendlyName); } + + /** + * Tests that SCAN_RESULTS_AVAILABLE_ACTION calls WifiManager#getMatchingOsuProviders() + */ + @Test + public void testScanResultsAvailableAction_callsGetMatchingOsuProviders() { + final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker(); + wifiPickerTracker.onStart(); + verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(), + any(), any(), any()); + mTestLooper.dispatchAll(); + + + mBroadcastReceiverCaptor.getValue().onReceive(mMockContext, + new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); + + verify(mMockWifiManager, atLeastOnce()).getMatchingOsuProviders(any()); + } } |