This change uses WifiTrackerLib's WifiPickerTracker & WifiEntry to replace SettingLib's WifiTracker & AccessPoint. This change includes 1. WifiScanWorker has the callbacks similar to a lifecycle component but it's not a lifecycle component. Let WifiScanWorker implements LifecycleOwner and provides #getLifecycle() for WifiPickerTracker. 2. Remove captive portal related code because WifiEntry#connect will handle captive portal login if it's necessary. 3. Create WifiSliceItem to wrap WifiEntry because WifiEntry is an abstract object and it does not provide copy constructor. Without copy construcor, Wi-Fi Slice may show unexpected information when a WifiEntry is updated. 4. Use WifiTrackerLib's NetworkDetailsTracker & WifiEntry in WifiDialogActivity because it gets a WifiEntry key from Wi-Fi Slice. NetworkDetailsTracker can get the WifiEntry of th key. Bug: 155613549 Bug: 152571756 Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.wifi.slice make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.wifi Change-Id: I0718f4647cea007a9b701922f3121a388dd43918
203 lines
6.5 KiB
Java
203 lines
6.5 KiB
Java
/*
|
|
* Copyright (C) 2019 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.settings.wifi.slice;
|
|
|
|
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
|
|
|
|
import android.content.Context;
|
|
import android.net.ConnectivityManager;
|
|
import android.net.NetworkScoreManager;
|
|
import android.net.Uri;
|
|
import android.net.wifi.WifiManager;
|
|
import android.os.HandlerThread;
|
|
import android.os.Process;
|
|
import android.os.SimpleClock;
|
|
import android.os.SystemClock;
|
|
import android.text.TextUtils;
|
|
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.lifecycle.Lifecycle;
|
|
import androidx.lifecycle.LifecycleOwner;
|
|
import androidx.lifecycle.LifecycleRegistry;
|
|
|
|
import com.android.settings.slices.SliceBackgroundWorker;
|
|
import com.android.settingslib.utils.ThreadUtils;
|
|
import com.android.wifitrackerlib.WifiEntry;
|
|
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback;
|
|
import com.android.wifitrackerlib.WifiPickerTracker;
|
|
|
|
import java.time.Clock;
|
|
import java.time.ZoneOffset;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* {@link SliceBackgroundWorker} for Wi-Fi, used by {@link WifiSlice}.
|
|
*/
|
|
public class WifiScanWorker extends SliceBackgroundWorker<WifiSliceItem> implements
|
|
WifiPickerTracker.WifiPickerTrackerCallback, LifecycleOwner, WifiEntryCallback {
|
|
|
|
private static final String TAG = "WifiScanWorker";
|
|
|
|
// Max age of tracked WifiEntries.
|
|
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
|
|
// Interval between initiating WifiPickerTracker scans.
|
|
private static final long SCAN_INTERVAL_MILLIS = 10_000;
|
|
|
|
@VisibleForTesting
|
|
final LifecycleRegistry mLifecycleRegistry;
|
|
@VisibleForTesting
|
|
WifiPickerTracker mWifiPickerTracker;
|
|
// Worker thread used for WifiPickerTracker work
|
|
private final HandlerThread mWorkerThread;
|
|
|
|
public WifiScanWorker(Context context, Uri uri) {
|
|
super(context, uri);
|
|
|
|
mLifecycleRegistry = new LifecycleRegistry(this);
|
|
|
|
mWorkerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
|
|
mWorkerThread.start();
|
|
final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
|
|
@Override
|
|
public long millis() {
|
|
return SystemClock.elapsedRealtime();
|
|
}
|
|
};
|
|
mWifiPickerTracker = new WifiPickerTracker(getLifecycle(), context,
|
|
context.getSystemService(WifiManager.class),
|
|
context.getSystemService(ConnectivityManager.class),
|
|
context.getSystemService(NetworkScoreManager.class),
|
|
ThreadUtils.getUiThreadHandler(),
|
|
mWorkerThread.getThreadHandler(),
|
|
elapsedRealtimeClock,
|
|
MAX_SCAN_AGE_MILLIS,
|
|
SCAN_INTERVAL_MILLIS,
|
|
this);
|
|
|
|
mLifecycleRegistry.markState(Lifecycle.State.INITIALIZED);
|
|
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
|
|
}
|
|
|
|
@Override
|
|
protected void onSlicePinned() {
|
|
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
|
|
mLifecycleRegistry.markState(Lifecycle.State.RESUMED);
|
|
updateResults();
|
|
}
|
|
|
|
@Override
|
|
protected void onSliceUnpinned() {
|
|
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
|
|
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
mLifecycleRegistry.markState(Lifecycle.State.DESTROYED);
|
|
mWorkerThread.quit();
|
|
}
|
|
|
|
@Override
|
|
public Lifecycle getLifecycle() {
|
|
return mLifecycleRegistry;
|
|
}
|
|
|
|
/** Called when the state of Wifi has changed. */
|
|
@Override
|
|
public void onWifiStateChanged() {
|
|
updateResults();
|
|
}
|
|
|
|
/**
|
|
* Update the results when data changes
|
|
*/
|
|
@Override
|
|
public void onWifiEntriesChanged() {
|
|
updateResults();
|
|
}
|
|
|
|
/**
|
|
* Indicates the state of the WifiEntry has changed and clients may retrieve updates through
|
|
* the WifiEntry getter methods.
|
|
*/
|
|
@Override
|
|
public void onUpdated() {
|
|
notifySliceChange();
|
|
}
|
|
|
|
protected int getApRowCount() {
|
|
return DEFAULT_EXPANDED_ROW_COUNT;
|
|
}
|
|
|
|
@Override
|
|
public void onNumSavedSubscriptionsChanged() {
|
|
// Do nothing.
|
|
}
|
|
|
|
@Override
|
|
public void onNumSavedNetworksChanged() {
|
|
// Do nothing.
|
|
}
|
|
|
|
/**
|
|
* To get the WifiEntry of key.
|
|
*/
|
|
public WifiEntry getWifiEntry(String key) {
|
|
// Get specified WifiEntry.
|
|
WifiEntry keyWifiEntry = null;
|
|
final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
|
|
if (connectedWifiEntry != null && TextUtils.equals(key, connectedWifiEntry.getKey())) {
|
|
keyWifiEntry = connectedWifiEntry;
|
|
} else {
|
|
for (WifiEntry wifiEntry : mWifiPickerTracker.getWifiEntries()) {
|
|
if (TextUtils.equals(key, wifiEntry.getKey())) {
|
|
keyWifiEntry = wifiEntry;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return keyWifiEntry;
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void updateResults() {
|
|
if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED
|
|
|| mLifecycleRegistry.getCurrentState() != Lifecycle.State.RESUMED) {
|
|
super.updateResults(null);
|
|
return;
|
|
}
|
|
|
|
final List<WifiSliceItem> resultList = new ArrayList<>();
|
|
final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
|
|
if (connectedWifiEntry != null) {
|
|
connectedWifiEntry.setListener(this);
|
|
resultList.add(new WifiSliceItem(getContext(), connectedWifiEntry));
|
|
}
|
|
for (WifiEntry wifiEntry : mWifiPickerTracker.getWifiEntries()) {
|
|
if (resultList.size() >= getApRowCount()) {
|
|
break;
|
|
}
|
|
if (wifiEntry.getLevel() != WifiEntry.WIFI_LEVEL_UNREACHABLE) {
|
|
wifiEntry.setListener(this);
|
|
resultList.add(new WifiSliceItem(getContext(), wifiEntry));
|
|
}
|
|
}
|
|
super.updateResults(resultList);
|
|
}
|
|
}
|