diff --git a/res/values/strings.xml b/res/values/strings.xml
index b49557ec291..00cdf40bd6f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2195,6 +2195,8 @@
Wi\u2011Fi turned on
Connected to %1$s
+
+ Connecting to %1$s
Connecting\u2026
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
index 9f0023aa15c..3b75ebf420e 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
@@ -40,7 +40,6 @@ import com.android.settings.core.InstrumentedFragment;
import com.android.settings.homepage.contextualcards.slices.BluetoothUpdateWorker;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.wifi.slice.ContextualWifiScanWorker;
public class ContextualCardsFragment extends InstrumentedFragment implements
FocusRecyclerView.FocusListener {
@@ -80,7 +79,6 @@ public class ContextualCardsFragment extends InstrumentedFragment implements
super.onStart();
registerScreenOffReceiver();
registerKeyEventReceiver();
- ContextualWifiScanWorker.newVisibleUiSession();
mContextualCardManager.loadContextualCards(LoaderManager.getInstance(this),
sRestartLoaderNeeded);
sRestartLoaderNeeded = false;
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 7e17e380e79..31dc21fea29 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -32,6 +32,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.wifi.dpp.WifiDppQrCodeScannerFragment;
import com.android.settings.wifi.dpp.WifiDppUtils;
/**
@@ -116,7 +117,7 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
}
final WifiConfiguration config = data.getParcelableExtra(
- WifiDialogActivity.KEY_WIFI_CONFIGURATION);
+ WifiDppQrCodeScannerFragment.KEY_WIFI_CONFIGURATION);
successfullyFinish(config);
}
}
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 77827867630..b25d13f7520 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -16,51 +16,56 @@
package com.android.settings.wifi;
-import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
-import android.net.NetworkInfo;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.ActionListener;
import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.os.SimpleClock;
+import android.os.SystemClock;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.wifi.dpp.WifiDppUtils;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.core.lifecycle.ObservableActivity;
+import com.android.wifitrackerlib.NetworkDetailsTracker;
+import com.android.wifitrackerlib.WifiEntry;
import com.google.android.setupcompat.util.WizardManagerHelper;
-public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialogListener,
- DialogInterface.OnDismissListener {
+import java.time.Clock;
+import java.time.ZoneOffset;
+
+/**
+ * The activity shows a CONNECT_MODE Wi-fi editor dialog.
+ */
+public class WifiDialogActivity extends ObservableActivity implements
+ WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener {
private static final String TAG = "WifiDialogActivity";
- public static final String KEY_ACCESS_POINT_STATE = "access_point_state";
-
- /**
- * Boolean extra indicating whether this activity should connect to an access point on the
- * caller's behalf. If this is set to false, the caller should check
- * {@link #KEY_WIFI_CONFIGURATION} in the result data and save that using
- * {@link WifiManager#connect(WifiConfiguration, ActionListener)}. Default is true.
- */
- @VisibleForTesting
- static final String KEY_CONNECT_FOR_CALLER = "connect_for_caller";
-
- public static final String KEY_WIFI_CONFIGURATION = "wifi_configuration";
+ public static final String KEY_CHOSEN_WIFIENTRY_KEY = "key_chosen_wifientry_key";
private static final int RESULT_CONNECTED = RESULT_FIRST_USER;
private static final int RESULT_FORGET = RESULT_FIRST_USER + 1;
private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0;
- private WifiDialog mDialog;
+ // Max age of tracked WifiEntries.
+ private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+ // Interval between initiating NetworkDetailsTracker scans.
+ private static final long SCAN_INTERVAL_MILLIS = 10_000;
+ private WifiDialog2 mDialog;
private Intent mIntent;
+ private NetworkDetailsTracker mNetworkDetailsTracker;
+ private HandlerThread mWorkerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -71,18 +76,43 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
super.onCreate(savedInstanceState);
- final Bundle accessPointState = mIntent.getBundleExtra(KEY_ACCESS_POINT_STATE);
- AccessPoint accessPoint = null;
- if (accessPointState != null) {
- accessPoint = new AccessPoint(this, accessPointState);
+ mWorkerThread = new HandlerThread(
+ TAG + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ mWorkerThread.start();
+ final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
+ @Override
+ public long millis() {
+ return SystemClock.elapsedRealtime();
+ }
+ };
+ mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
+ getLifecycle(),
+ this,
+ getSystemService(WifiManager.class),
+ getSystemService(ConnectivityManager.class),
+ getSystemService(NetworkScoreManager.class),
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ if (mDialog != null) {
+ return;
}
if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
- mDialog = WifiDialog.createModal(this, this, accessPoint,
- WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
+ mDialog = WifiDialog2.createModal(this, this, mNetworkDetailsTracker.getWifiEntry(),
+ WifiConfigUiBase2.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
} else {
- mDialog = WifiDialog.createModal(
- this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
+ mDialog = WifiDialog2.createModal(this, this, mNetworkDetailsTracker.getWifiEntry(),
+ WifiConfigUiBase2.MODE_CONNECT);
}
mDialog.show();
mDialog.setOnDismissListener(this);
@@ -90,82 +120,44 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
@Override
public void finish() {
- super.finish();
overridePendingTransition(0, 0);
+
+ super.finish();
}
@Override
public void onDestroy() {
- super.onDestroy();
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
mDialog = null;
}
+ mWorkerThread.quit();
+
+ super.onDestroy();
}
@Override
- public void onForget(WifiDialog dialog) {
- final WifiManager wifiManager = getSystemService(WifiManager.class);
- final AccessPoint accessPoint = dialog.getController().getAccessPoint();
- if (accessPoint != null) {
- if (!accessPoint.isSaved()) {
- if (accessPoint.getNetworkInfo() != null &&
- accessPoint.getNetworkInfo().getState() != NetworkInfo.State.DISCONNECTED) {
- // Network is active but has no network ID - must be ephemeral.
- wifiManager.disableEphemeralNetwork(
- AccessPoint.convertToQuotedString(accessPoint.getSsidStr()));
- } else {
- // Should not happen, but a monkey seems to trigger it
- Log.e(TAG, "Failed to forget invalid network " + accessPoint.getConfig());
- }
- } else {
- wifiManager.forget(accessPoint.getConfig().networkId, null /* listener */);
- }
+ public void onForget(WifiDialog2 dialog) {
+ final WifiEntry wifiEntry = dialog.getController().getWifiEntry();
+ if (wifiEntry != null && wifiEntry.canForget()) {
+ wifiEntry.forget(null /* callback */);
}
- Intent resultData = new Intent();
- if (accessPoint != null) {
- Bundle accessPointState = new Bundle();
- accessPoint.saveWifiState(accessPointState);
- resultData.putExtra(KEY_ACCESS_POINT_STATE, accessPointState);
- }
setResult(RESULT_FORGET);
finish();
}
@Override
- public void onSubmit(WifiDialog dialog) {
+ public void onSubmit(WifiDialog2 dialog) {
+ final WifiEntry wifiEntry = dialog.getController().getWifiEntry();
final WifiConfiguration config = dialog.getController().getConfig();
- final AccessPoint accessPoint = dialog.getController().getAccessPoint();
- final WifiManager wifiManager = getSystemService(WifiManager.class);
-
- if (getIntent().getBooleanExtra(KEY_CONNECT_FOR_CALLER, true)) {
- if (config == null) {
- if (accessPoint != null && accessPoint.isSaved()) {
- wifiManager.connect(accessPoint.getConfig(), null /* listener */);
- }
- } else {
- wifiManager.save(config, null /* listener */);
- if (accessPoint != null) {
- // accessPoint is null for "Add network"
- NetworkInfo networkInfo = accessPoint.getNetworkInfo();
- if (networkInfo == null || !networkInfo.isConnected()) {
- wifiManager.connect(config, null /* listener */);
- }
- }
- }
+ if (config == null && wifiEntry != null && wifiEntry.canConnect()) {
+ wifiEntry.connect(null /* callback */);
+ } else {
+ getSystemService(WifiManager.class).connect(config, null /* listener */);
}
- Intent resultData = new Intent();
- if (accessPoint != null) {
- Bundle accessPointState = new Bundle();
- accessPoint.saveWifiState(accessPointState);
- resultData.putExtra(KEY_ACCESS_POINT_STATE, accessPointState);
- }
- if (config != null) {
- resultData.putExtra(KEY_WIFI_CONFIGURATION, config);
- }
- setResult(RESULT_CONNECTED, resultData);
+ setResult(RESULT_CONNECTED);
finish();
}
@@ -176,7 +168,7 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo
}
@Override
- public void onScan(WifiDialog dialog, String ssid) {
+ public void onScan(WifiDialog2 dialog, String ssid) {
Intent intent = WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid);
WizardManagerHelper.copyWizardManagerExtras(mIntent, intent);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index accef12364f..cee3ccdeb08 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -57,7 +57,6 @@ import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.ViewModelProviders;
import com.android.settings.R;
-import com.android.settings.wifi.WifiDialogActivity;
import com.android.settings.wifi.qrcode.QrCamera;
import com.android.settings.wifi.qrcode.QrDecorateView;
import com.android.wifitrackerlib.WifiEntry;
@@ -91,7 +90,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
// Key for Bundle usage
private static final String KEY_IS_CONFIGURATOR_MODE = "key_is_configurator_mode";
private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code";
- private static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
+ public static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
private static final int ARG_RESTART_CAMERA = 1;
@@ -689,8 +688,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
@Override
public void onSuccess() {
final Intent resultIntent = new Intent();
- resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION,
- mEnrolleeWifiConfiguration);
+ resultIntent.putExtra(KEY_WIFI_CONFIGURATION, mEnrolleeWifiConfiguration);
final Activity hostActivity = getActivity();
hostActivity.setResult(Activity.RESULT_OK, resultIntent);
diff --git a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
index 5c92d81da22..779a57e40f3 100644
--- a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
+++ b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
@@ -19,61 +19,74 @@ package com.android.settings.wifi.slice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
+import android.text.TextUtils;
+import android.widget.Toast;
import androidx.annotation.VisibleForTesting;
-import com.android.settings.wifi.WifiConnectListener;
+import com.android.settings.R;
+import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.wifi.WifiDialogActivity;
-import com.android.settings.wifi.WifiUtils;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
/**
* This receiver helps connect to Wi-Fi network
*/
public class ConnectToWifiHandler extends BroadcastReceiver {
+ static final String KEY_CHOSEN_WIFIENTRY_KEY = "key_chosen_wifientry_key";
+ static final String KEY_WIFI_SLICE_URI = "key_wifi_slice_uri";
+
@Override
public void onReceive(Context context, Intent intent) {
if (context == null || intent == null) {
return;
}
-
- final Network network = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
- final Bundle accessPointState = intent.getBundleExtra(
- WifiDialogActivity.KEY_ACCESS_POINT_STATE);
-
- if (network != null) {
- WifiScanWorker.clearClickedWifi();
- final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
- // start captive portal app to sign in to network
- cm.startCaptivePortalApp(network);
- } else if (accessPointState != null) {
- connect(context, new AccessPoint(context, accessPointState));
+ final String key = intent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY);
+ if (TextUtils.isEmpty(key)) {
+ return;
}
+ if (intent.getParcelableExtra(KEY_WIFI_SLICE_URI) == null) {
+ return;
+ }
+ final WifiScanWorker worker = getWifiScanWorker(intent);
+ if (worker == null) {
+ return;
+ }
+ final WifiEntry wifiEntry = worker.getWifiEntry(key);
+ if (wifiEntry == null) {
+ return;
+ }
+ wifiEntry.connect(new WifiEntryConnectCallback(context, wifiEntry));
}
@VisibleForTesting
- void connect(Context context, AccessPoint accessPoint) {
- ContextualWifiScanWorker.saveSession();
- WifiScanWorker.saveClickedWifi(accessPoint);
+ WifiScanWorker getWifiScanWorker(Intent intent) {
+ return SliceBackgroundWorker.getInstance(intent.getParcelableExtra(KEY_WIFI_SLICE_URI));
+ }
- final WifiConnectListener connectListener = new WifiConnectListener(context);
- switch (WifiUtils.getConnectingType(accessPoint)) {
- case WifiUtils.CONNECT_TYPE_OSU_PROVISION:
- accessPoint.startOsuProvisioning(connectListener);
- break;
+ @VisibleForTesting
+ static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback {
+ final Context mContext;
+ final WifiEntry mWifiEntry;
- case WifiUtils.CONNECT_TYPE_OPEN_NETWORK:
- accessPoint.generateOpenNetworkConfig();
+ WifiEntryConnectCallback(Context context, WifiEntry connectWifiEntry) {
+ mContext = context;
+ mWifiEntry = connectWifiEntry;
+ }
- case WifiUtils.CONNECT_TYPE_SAVED_NETWORK:
- final WifiManager wifiManager = context.getSystemService(WifiManager.class);
- wifiManager.connect(accessPoint.getConfig(), connectListener);
- break;
+ @Override
+ public void onConnectResult(@ConnectStatus int status) {
+ if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
+ final Intent intent = new Intent(mContext, WifiDialogActivity.class)
+ .putExtra(WifiDialogActivity.KEY_CHOSEN_WIFIENTRY_KEY, mWifiEntry.getKey());
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
+ Toast.makeText(mContext, R.string.wifi_failed_connect_message,
+ Toast.LENGTH_SHORT).show();
+ }
}
}
}
diff --git a/src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java b/src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java
index 616c92fb33a..aa73a179d39 100644
--- a/src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/ContextualWifiScanWorker.java
@@ -18,7 +18,6 @@ package com.android.settings.wifi.slice;
import android.content.Context;
import android.net.Uri;
-import android.os.SystemClock;
import com.android.settings.slices.SliceBackgroundWorker;
@@ -27,44 +26,12 @@ import com.android.settings.slices.SliceBackgroundWorker;
*/
public class ContextualWifiScanWorker extends WifiScanWorker {
- private static long sVisibleUiSessionToken;
- private static long sActiveSession;
-
public ContextualWifiScanWorker(Context context, Uri uri) {
super(context, uri);
}
- /**
- * Starts a new visible UI session for the purpose of automatically starting captive portal.
- *
- * A visible UI session is defined as a duration of time when a UI screen is visible to user.
- * Going to a sub-page and coming out breaks the continuation, leaving the page and coming back
- * breaks it too.
- */
- public static void newVisibleUiSession() {
- sVisibleUiSessionToken = SystemClock.elapsedRealtime();
- }
-
- static void saveSession() {
- sActiveSession = sVisibleUiSessionToken;
- }
-
- @Override
- protected void clearClickedWifiOnSliceUnpinned() {
- // Do nothing for contextual Wi-Fi slice
- }
-
- @Override
- protected boolean isSessionValid() {
- if (sVisibleUiSessionToken != sActiveSession) {
- clearClickedWifi();
- return false;
- }
- return true;
- }
-
@Override
protected int getApRowCount() {
return ContextualWifiSlice.getApRowCount();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/wifi/slice/ContextualWifiSlice.java b/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
index ea9a7452202..4806573bf1e 100644
--- a/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
+++ b/src/com/android/settings/wifi/slice/ContextualWifiSlice.java
@@ -18,10 +18,8 @@ package com.android.settings.wifi.slice;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -37,7 +35,7 @@ import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.wifitrackerlib.WifiEntry;
/**
* {@link CustomSliceable} for Wi-Fi, used by contextual homepage.
@@ -52,8 +50,12 @@ public class ContextualWifiSlice extends WifiSlice {
@VisibleForTesting
static boolean sApRowCollapsed;
+ private final ConnectivityManager mConnectivityManager;
+
public ContextualWifiSlice(Context context) {
super(context);
+
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
}
@Override
@@ -84,16 +86,17 @@ public class ContextualWifiSlice extends WifiSlice {
}
@Override
- protected ListBuilder.RowBuilder getHeaderRow(boolean isWifiEnabled, AccessPoint accessPoint) {
- final ListBuilder.RowBuilder builder = super.getHeaderRow(isWifiEnabled, accessPoint);
- builder.setTitleItem(getHeaderIcon(isWifiEnabled, accessPoint), ListBuilder.ICON_IMAGE);
+ protected ListBuilder.RowBuilder getHeaderRow(boolean isWifiEnabled,
+ WifiSliceItem wifiSliceItem) {
+ final ListBuilder.RowBuilder builder = super.getHeaderRow(isWifiEnabled, wifiSliceItem);
+ builder.setTitleItem(getHeaderIcon(isWifiEnabled, wifiSliceItem), ListBuilder.ICON_IMAGE);
if (sApRowCollapsed) {
- builder.setSubtitle(getSubtitle(accessPoint));
+ builder.setSubtitle(getHeaderSubtitle(wifiSliceItem));
}
return builder;
}
- private IconCompat getHeaderIcon(boolean isWifiEnabled, AccessPoint accessPoint) {
+ private IconCompat getHeaderIcon(boolean isWifiEnabled, WifiSliceItem wifiSliceItem) {
final Drawable drawable;
final int tint;
if (!isWifiEnabled) {
@@ -103,7 +106,8 @@ public class ContextualWifiSlice extends WifiSlice {
} else {
// get icon of medium signal strength
drawable = mContext.getDrawable(com.android.settingslib.Utils.getWifiIconResource(2));
- if (isNetworkConnected(accessPoint)) {
+ if (wifiSliceItem != null
+ && wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
tint = Utils.getColorAccentDefaultColor(mContext);
} else {
tint = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal);
@@ -113,49 +117,16 @@ public class ContextualWifiSlice extends WifiSlice {
return Utils.createIconWithDrawable(drawable);
}
- private boolean isNetworkConnected(AccessPoint accessPoint) {
- if (accessPoint == null) {
- return false;
- }
-
- final NetworkInfo networkInfo = accessPoint.getNetworkInfo();
- if (networkInfo == null) {
- return false;
- }
-
- return networkInfo.getState() == State.CONNECTED;
- }
-
- private CharSequence getSubtitle(AccessPoint accessPoint) {
- if (isCaptivePortal()) {
- final int id = mContext.getResources()
- .getIdentifier("network_available_sign_in", "string", "android");
- return mContext.getText(id);
- }
-
- if (accessPoint == null) {
+ private CharSequence getHeaderSubtitle(WifiSliceItem wifiSliceItem) {
+ if (wifiSliceItem == null
+ || wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_DISCONNECTED) {
return mContext.getText(R.string.disconnected);
}
-
- final NetworkInfo networkInfo = accessPoint.getNetworkInfo();
- if (networkInfo == null) {
- return mContext.getText(R.string.disconnected);
+ if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTING) {
+ return mContext.getString(R.string.wifi_connecting_to_message,
+ wifiSliceItem.getTitle());
}
-
- final State state = networkInfo.getState();
- DetailedState detailedState;
- if (state == State.CONNECTING) {
- detailedState = DetailedState.CONNECTING;
- } else if (state == State.CONNECTED) {
- detailedState = DetailedState.CONNECTED;
- } else {
- detailedState = networkInfo.getDetailedState();
- }
-
- final String[] formats = mContext.getResources().getStringArray(
- R.array.wifi_status_with_ssid);
- final int index = detailedState.ordinal();
- return String.format(formats[index], accessPoint.getTitle());
+ return mContext.getString(R.string.wifi_connected_to_message, wifiSliceItem.getTitle());
}
private boolean hasWorkingNetwork() {
diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java
index 9d0f8210624..631faac18ef 100644
--- a/src/com/android/settings/wifi/slice/WifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java
@@ -16,243 +16,187 @@
package com.android.settings.wifi.slice;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
import android.content.Context;
-import android.content.Intent;
import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
+import android.net.NetworkScoreManager;
import android.net.Uri;
-import android.net.wifi.WifiInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
+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 android.util.Log;
import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
-import com.android.internal.util.Preconditions;
import com.android.settings.slices.SliceBackgroundWorker;
-import com.android.settingslib.wifi.AccessPoint;
-import com.android.settingslib.wifi.WifiTracker;
+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 implements
- WifiTracker.WifiListener {
+public class WifiScanWorker extends SliceBackgroundWorker 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
- WifiNetworkCallback mNetworkCallback;
-
- private final Context mContext;
- private final ConnectivityManager mConnectivityManager;
- private final WifiTracker mWifiTracker;
-
- private static String sClickedWifiSsid;
+ 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);
- mContext = context;
- mConnectivityManager = context.getSystemService(ConnectivityManager.class);
- mWifiTracker = new WifiTracker(mContext, this /* wifiListener */,
- true /* includeSaved */, true /* includeScans */);
+
+ 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() {
- mWifiTracker.onStart();
- onAccessPointsChanged();
+ mLifecycleRegistry.markState(Lifecycle.State.STARTED);
+ mLifecycleRegistry.markState(Lifecycle.State.RESUMED);
+ updateResults();
}
@Override
protected void onSliceUnpinned() {
- mWifiTracker.onStop();
- unregisterNetworkCallback();
- clearClickedWifiOnSliceUnpinned();
+ mLifecycleRegistry.markState(Lifecycle.State.STARTED);
+ mLifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void close() {
- mWifiTracker.onDestroy();
+ mLifecycleRegistry.markState(Lifecycle.State.DESTROYED);
+ mWorkerThread.quit();
}
@Override
- public void onWifiStateChanged(int state) {
+ 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();
}
- @Override
- public void onConnectedChanged() {
- }
-
- @Override
- public void onAccessPointsChanged() {
- // in case state has changed
- if (!mWifiTracker.getManager().isWifiEnabled()) {
- updateResults(null);
- return;
- }
- // AccessPoints are sorted by the WifiTracker
- final List accessPoints = mWifiTracker.getAccessPoints();
- final List resultList = new ArrayList<>();
- final int apRowCount = getApRowCount();
- for (AccessPoint ap : accessPoints) {
- if (ap.isReachable()) {
- resultList.add(clone(ap));
- if (resultList.size() >= apRowCount) {
- break;
- }
- }
- }
- updateResults(resultList);
- }
-
protected int getApRowCount() {
return DEFAULT_EXPANDED_ROW_COUNT;
}
- private AccessPoint clone(AccessPoint accessPoint) {
- final Bundle savedState = new Bundle();
- accessPoint.saveWifiState(savedState);
- return new AccessPoint(mContext, savedState);
+ @Override
+ public void onNumSavedSubscriptionsChanged() {
+ // Do nothing.
}
@Override
- protected boolean areListsTheSame(List a, List b) {
- if (!a.equals(b)) {
- return false;
- }
+ public void onNumSavedNetworksChanged() {
+ // Do nothing.
+ }
- // compare access point states one by one
- final int listSize = a.size();
- for (int i = 0; i < listSize; i++) {
- if (a.get(i).getDetailedState() != b.get(i).getDetailedState()) {
- return false;
+ /**
+ * 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 true;
+ return keyWifiEntry;
}
- static void saveClickedWifi(AccessPoint accessPoint) {
- sClickedWifiSsid = accessPoint.getSsidStr();
- }
-
- static void clearClickedWifi() {
- sClickedWifiSsid = null;
- }
-
- static boolean isWifiClicked(WifiInfo info) {
- final String ssid = WifiInfo.sanitizeSsid(info.getSSID());
- return !TextUtils.isEmpty(ssid) && TextUtils.equals(ssid, sClickedWifiSsid);
- }
-
- protected void clearClickedWifiOnSliceUnpinned() {
- clearClickedWifi();
- }
-
- protected boolean isSessionValid() {
- return true;
- }
-
- public void registerNetworkCallback(Network wifiNetwork) {
- if (wifiNetwork == null) {
+ @VisibleForTesting
+ void updateResults() {
+ if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED
+ || mLifecycleRegistry.getCurrentState() != Lifecycle.State.RESUMED) {
+ super.updateResults(null);
return;
}
- if (mNetworkCallback != null && mNetworkCallback.isSameNetwork(wifiNetwork)) {
- return;
+ final List resultList = new ArrayList<>();
+ final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
+ if (connectedWifiEntry != null) {
+ connectedWifiEntry.setListener(this);
+ resultList.add(new WifiSliceItem(getContext(), connectedWifiEntry));
}
-
- unregisterNetworkCallback();
-
- mNetworkCallback = new WifiNetworkCallback(wifiNetwork);
- mConnectivityManager.registerNetworkCallback(
- new NetworkRequest.Builder()
- .clearCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .build(),
- mNetworkCallback,
- new Handler(Looper.getMainLooper()));
- }
-
- public void unregisterNetworkCallback() {
- if (mNetworkCallback != null) {
- try {
- mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
- } catch (RuntimeException e) {
- Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e);
+ for (WifiEntry wifiEntry : mWifiPickerTracker.getWifiEntries()) {
+ if (resultList.size() >= getApRowCount()) {
+ break;
}
- mNetworkCallback = null;
- }
- }
-
- class WifiNetworkCallback extends NetworkCallback {
-
- private final Network mNetwork;
- private boolean mIsCaptivePortal;
- private boolean mHasPartialConnectivity;
- private boolean mIsValidated;
-
- WifiNetworkCallback(Network network) {
- mNetwork = Preconditions.checkNotNull(network);
- }
-
- @Override
- public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
- if (!isSameNetwork(network)) {
- return;
- }
-
- final boolean prevIsCaptivePortal = mIsCaptivePortal;
- final boolean prevHasPartialConnectivity = mHasPartialConnectivity;
- final boolean prevIsValidated = mIsValidated;
-
- mIsCaptivePortal = nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
- mHasPartialConnectivity = nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
- mIsValidated = nc.hasCapability(NET_CAPABILITY_VALIDATED);
-
- if (prevIsCaptivePortal == mIsCaptivePortal
- && prevHasPartialConnectivity == mHasPartialConnectivity
- && prevIsValidated == mIsValidated) {
- return;
- }
-
- notifySliceChange();
-
- // Automatically start captive portal
- if (!prevIsCaptivePortal && mIsCaptivePortal
- && isWifiClicked(mWifiTracker.getManager().getConnectionInfo())
- && isSessionValid()) {
- final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
- .putExtra(ConnectivityManager.EXTRA_NETWORK, network)
- .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- // Sending a broadcast in the system process needs to specify a user
- mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+ if (wifiEntry.getLevel() != WifiEntry.WIFI_LEVEL_UNREACHABLE) {
+ wifiEntry.setListener(this);
+ resultList.add(new WifiSliceItem(getContext(), wifiEntry));
}
}
-
- /**
- * Returns true if the supplied network is not null and is the same as the originally
- * supplied value.
- */
- public boolean isSameNetwork(Network network) {
- return mNetwork.equals(network);
- }
+ super.updateResults(resultList);
}
}
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index a489b05e2e4..324d68c870e 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -29,9 +29,6 @@ import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -52,9 +49,8 @@ import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBuilderUtils;
import com.android.settings.wifi.WifiDialogActivity;
import com.android.settings.wifi.WifiSettings;
-import com.android.settings.wifi.WifiUtils;
-import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
+import com.android.wifitrackerlib.WifiEntry;
import java.util.Arrays;
import java.util.List;
@@ -71,12 +67,10 @@ public class WifiSlice implements CustomSliceable {
protected final Context mContext;
protected final WifiManager mWifiManager;
- protected final ConnectivityManager mConnectivityManager;
public WifiSlice(Context context) {
mContext = context;
mWifiManager = mContext.getSystemService(WifiManager.class);
- mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
}
@Override
@@ -87,17 +81,16 @@ public class WifiSlice implements CustomSliceable {
@Override
public Slice getSlice() {
final boolean isWifiEnabled = isWifiEnabled();
- ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* accessPoint */);
+ ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* wifiSliceItem */);
if (!isWifiEnabled) {
- WifiScanWorker.clearClickedWifi();
return listBuilder.build();
}
final WifiScanWorker worker = SliceBackgroundWorker.getInstance(getUri());
- final List apList = worker != null ? worker.getResults() : null;
+ final List apList = worker != null ? worker.getResults() : null;
final int apCount = apList == null ? 0 : apList.size();
- final boolean isFirstApActive = apCount > 0 && apList.get(0).isActive();
- handleNetworkCallback(worker, isFirstApActive);
+ final boolean isFirstApActive = apCount > 0
+ && apList.get(0).getConnectedState() != WifiEntry.CONNECTED_STATE_DISCONNECTED;
if (isFirstApActive) {
// refresh header subtext
@@ -112,7 +105,7 @@ public class WifiSlice implements CustomSliceable {
final CharSequence placeholder = mContext.getText(R.string.summary_placeholder);
for (int i = 0; i < DEFAULT_EXPANDED_ROW_COUNT; i++) {
if (i < apCount) {
- listBuilder.addRow(getAccessPointRow(apList.get(i)));
+ listBuilder.addRow(getWifiSliceItemRow(apList.get(i)));
} else if (i == apCount) {
listBuilder.addRow(getLoadingRow(placeholder));
} else {
@@ -124,22 +117,12 @@ public class WifiSlice implements CustomSliceable {
return listBuilder.build();
}
- private void handleNetworkCallback(WifiScanWorker worker, boolean isFirstApActive) {
- if (worker == null) {
- return;
- }
- if (isFirstApActive) {
- worker.registerNetworkCallback(mWifiManager.getCurrentNetwork());
- } else {
- worker.unregisterNetworkCallback();
- }
- }
-
protected boolean isApRowCollapsed() {
return false;
}
- protected ListBuilder.RowBuilder getHeaderRow(boolean isWifiEnabled, AccessPoint accessPoint) {
+ protected ListBuilder.RowBuilder getHeaderRow(boolean isWifiEnabled,
+ WifiSliceItem wifiSliceItem) {
final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_wireless);
final String title = mContext.getString(R.string.wifi_settings);
@@ -152,115 +135,90 @@ public class WifiSlice implements CustomSliceable {
.setPrimaryAction(primarySliceAction);
}
- private ListBuilder getListBuilder(boolean isWifiEnabled, AccessPoint accessPoint) {
+ private ListBuilder getListBuilder(boolean isWifiEnabled, WifiSliceItem wifiSliceItem) {
final PendingIntent toggleAction = getBroadcastIntent(mContext);
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
null /* actionTitle */, isWifiEnabled);
final ListBuilder builder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
.setAccentColor(COLOR_NOT_TINTED)
.setKeywords(getKeywords())
- .addRow(getHeaderRow(isWifiEnabled, accessPoint))
+ .addRow(getHeaderRow(isWifiEnabled, wifiSliceItem))
.addAction(toggleSliceAction);
return builder;
}
- private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) {
- final boolean isCaptivePortal = accessPoint.isActive() && isCaptivePortal();
- final CharSequence title = accessPoint.getTitle();
- final CharSequence summary = getAccessPointSummary(accessPoint, isCaptivePortal);
- final IconCompat levelIcon = getAccessPointLevelIcon(accessPoint);
+ private ListBuilder.RowBuilder getWifiSliceItemRow(WifiSliceItem wifiSliceItem) {
+ final CharSequence title = wifiSliceItem.getTitle();
+ final IconCompat levelIcon = getWifiSliceItemLevelIcon(wifiSliceItem);
final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
.setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
.setTitle(title)
- .setSubtitle(summary)
- .setPrimaryAction(getAccessPointAction(accessPoint, isCaptivePortal, levelIcon,
- title));
+ .setSubtitle(wifiSliceItem.getSummary())
+ .setContentDescription(wifiSliceItem.getContentDescription())
+ .setPrimaryAction(getWifiEntryAction(wifiSliceItem, levelIcon, title));
- if (isCaptivePortal) {
- rowBuilder.addEndItem(getCaptivePortalEndAction(accessPoint, title));
- } else {
- final IconCompat endIcon = getEndIcon(accessPoint);
- if (endIcon != null) {
- rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE);
- }
+ final IconCompat endIcon = getEndIcon(wifiSliceItem);
+ if (endIcon != null) {
+ rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE);
}
return rowBuilder;
}
- private CharSequence getAccessPointSummary(AccessPoint accessPoint, boolean isCaptivePortal) {
- if (isCaptivePortal) {
- return mContext.getText(R.string.wifi_tap_to_sign_in);
- }
-
- final CharSequence summary = accessPoint.getSettingsSummary();
- return TextUtils.isEmpty(summary) ? mContext.getText(R.string.disconnected) : summary;
- }
-
- private IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) {
+ private IconCompat getWifiSliceItemLevelIcon(WifiSliceItem wifiSliceItem) {
final @ColorInt int tint;
- if (accessPoint.isActive()) {
- final NetworkInfo.State state = accessPoint.getNetworkInfo().getState();
- if (state == NetworkInfo.State.CONNECTED) {
- tint = Utils.getColorAccentDefaultColor(mContext);
- } else { // connecting
- tint = Utils.getDisabled(mContext, Utils.getColorAttrDefaultColor(mContext,
- android.R.attr.colorControlNormal));
- }
- } else {
+ if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
+ tint = Utils.getColorAccentDefaultColor(mContext);
+ } else if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_DISCONNECTED) {
tint = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal);
+ } else {
+ tint = Utils.getDisabled(mContext, Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.colorControlNormal));
}
final Drawable drawable = mContext.getDrawable(
- com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel()));
+ com.android.settingslib.Utils.getWifiIconResource(wifiSliceItem.getLevel()));
drawable.setTint(tint);
return Utils.createIconWithDrawable(drawable);
}
- private IconCompat getEndIcon(AccessPoint accessPoint) {
- if (accessPoint.isActive()) {
+ private IconCompat getEndIcon(WifiSliceItem wifiSliceItem) {
+ if (wifiSliceItem.getConnectedState() != WifiEntry.CONNECTED_STATE_DISCONNECTED) {
return null;
- } else if (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
+ }
+
+ if (wifiSliceItem.getSecurity() != WifiEntry.SECURITY_NONE) {
return IconCompat.createWithResource(mContext, R.drawable.ic_friction_lock_closed);
- } else if (accessPoint.isMetered()) {
- return IconCompat.createWithResource(mContext, R.drawable.ic_friction_money);
}
return null;
}
- private SliceAction getCaptivePortalEndAction(AccessPoint accessPoint, CharSequence title) {
- return getAccessPointAction(accessPoint, false /* isCaptivePortal */,
- IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent), title);
- }
+ private SliceAction getWifiEntryAction(WifiSliceItem wifiSliceItem, IconCompat icon,
+ CharSequence title) {
+ final int requestCode = wifiSliceItem.getKey().hashCode();
- private SliceAction getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal,
- IconCompat icon, CharSequence title) {
- final int requestCode = accessPoint.hashCode();
- if (isCaptivePortal) {
- final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
- .putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork());
- return getBroadcastAction(requestCode, intent, icon, title);
- }
-
- final Bundle extras = new Bundle();
- accessPoint.saveWifiState(extras);
-
- if (accessPoint.isActive()) {
+ if (wifiSliceItem.getConnectedState() != WifiEntry.CONNECTED_STATE_DISCONNECTED) {
+ final Bundle bundle = new Bundle();
+ bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY,
+ wifiSliceItem.getKey());
final Intent intent = new SubSettingLauncher(mContext)
.setTitleRes(R.string.pref_title_network_details)
- .setDestination(WifiNetworkDetailsFragment.class.getName())
- .setArguments(extras)
+ .setDestination(WifiNetworkDetailsFragment2.class.getName())
+ .setArguments(bundle)
.setSourceMetricsCategory(SettingsEnums.WIFI)
.toIntent();
return getActivityAction(requestCode, intent, icon, title);
- } else if (WifiUtils.getConnectingType(accessPoint) != WifiUtils.CONNECT_TYPE_OTHERS) {
- final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
- .putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
- return getBroadcastAction(requestCode, intent, icon, title);
- } else {
+ }
+
+ if (wifiSliceItem.shouldEditBeforeConnect()) {
final Intent intent = new Intent(mContext, WifiDialogActivity.class)
- .putExtra(WifiDialogActivity.KEY_ACCESS_POINT_STATE, extras);
+ .putExtra(WifiDialogActivity.KEY_CHOSEN_WIFIENTRY_KEY, wifiSliceItem.getKey());
return getActivityAction(requestCode, intent, icon, title);
}
+
+ final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
+ .putExtra(ConnectToWifiHandler.KEY_CHOSEN_WIFIENTRY_KEY, wifiSliceItem.getKey())
+ .putExtra(ConnectToWifiHandler.KEY_WIFI_SLICE_URI, getUri());
+ return getBroadcastAction(requestCode, intent, icon, title);
}
private SliceAction getActivityAction(int requestCode, Intent intent, IconCompat icon,
@@ -291,12 +249,6 @@ public class WifiSlice implements CustomSliceable {
.setSubtitle(title);
}
- protected boolean isCaptivePortal() {
- final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities(
- mWifiManager.getCurrentNetwork());
- return WifiUtils.canSignIntoNetwork(nc);
- }
-
/**
* Update the current wifi status to the boolean value keyed by
* {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
diff --git a/src/com/android/settings/wifi/slice/WifiSliceItem.java b/src/com/android/settings/wifi/slice/WifiSliceItem.java
new file mode 100644
index 00000000000..7a0f0d73a20
--- /dev/null
+++ b/src/com/android/settings/wifi/slice/WifiSliceItem.java
@@ -0,0 +1,135 @@
+/*
+ * 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.settings.wifi.slice;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.android.settingslib.R;
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * The data set which is needed by a Wi-Fi Slice, it collects necessary data from {@link WifiEntry}
+ * and provides similar getter methods for corresponding data.
+ */
+public class WifiSliceItem {
+
+ private final Context mContext;
+ private final String mKey;
+ private final String mTitle;
+ private final int mSecurity;
+ private final int mConnectedState;
+ private final int mLevel;
+ private final boolean mShouldEditBeforeConnect;
+ private final String mSummary;
+
+ // These values must be kept within [WifiEntry.WIFI_LEVEL_MIN, WifiEntry.WIFI_LEVEL_MAX]
+ private static final int[] WIFI_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wifi,
+ R.string.accessibility_wifi_one_bar,
+ R.string.accessibility_wifi_two_bars,
+ R.string.accessibility_wifi_three_bars,
+ R.string.accessibility_wifi_signal_full
+ };
+
+ public WifiSliceItem(Context context, WifiEntry wifiEntry) {
+ mContext = context;
+ mKey = wifiEntry.getKey();
+ mTitle = wifiEntry.getTitle();
+ mSecurity = wifiEntry.getSecurity();
+ mConnectedState = wifiEntry.getConnectedState();
+ mLevel = wifiEntry.getLevel();
+ mShouldEditBeforeConnect = wifiEntry.shouldEditBeforeConnect();
+ mSummary = wifiEntry.getSummary(false /* concise */);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof WifiSliceItem)) {
+ return false;
+ }
+
+ final WifiSliceItem otherItem = (WifiSliceItem) other;
+ if (!TextUtils.equals(getKey(), otherItem.getKey())) {
+ return false;
+ }
+ if (getConnectedState() != otherItem.getConnectedState()) {
+ return false;
+ }
+ if (getLevel() != otherItem.getLevel()) {
+ return false;
+ }
+ if (!TextUtils.equals(getSummary(), otherItem.getSummary())) {
+ return false;
+ }
+ return true;
+ }
+
+ public String getKey() {
+ return mKey;
+ }
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public int getSecurity() {
+ return mSecurity;
+ }
+
+ public int getConnectedState() {
+ return mConnectedState;
+ }
+
+ public int getLevel() {
+ return mLevel;
+ }
+
+ /**
+ * In Wi-Fi picker, when users click a saved network, it will connect to the Wi-Fi network.
+ * However, for some special cases, Wi-Fi picker should show Wi-Fi editor UI for users to edit
+ * security or password before connecting. Or users will always get connection fail results.
+ */
+ public boolean shouldEditBeforeConnect() {
+ return mShouldEditBeforeConnect;
+ }
+
+ /**
+ * Returns a 'NOT' concise summary, this is different from WifiEntry#getSummary().
+ */
+ public String getSummary() {
+ return mSummary;
+ }
+
+ /**
+ * This method has similar code as WifiEntryPreference#buildContentDescription().
+ * TODO(b/154191825): Adds WifiEntry#getContentDescription() to replace the duplicate code.
+ */
+ public CharSequence getContentDescription() {
+ CharSequence contentDescription = mTitle;
+ if (!TextUtils.isEmpty(mSummary)) {
+ contentDescription = TextUtils.concat(contentDescription, ",", mSummary);
+ }
+ if (mLevel >= 0 && mLevel < WIFI_CONNECTION_STRENGTH.length) {
+ contentDescription = TextUtils.concat(contentDescription, ",",
+ mContext.getString(WIFI_CONNECTION_STRENGTH[mLevel]));
+ }
+ return TextUtils.concat(contentDescription, ",", mSecurity == WifiEntry.SECURITY_NONE
+ ? mContext.getString(R.string.accessibility_wifi_security_type_none)
+ : mContext.getString(R.string.accessibility_wifi_security_type_secured));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java
index 80db53e7be1..ea57bf7e89d 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java
@@ -18,6 +18,7 @@ package com.android.settings.testutils.shadow;
import static org.robolectric.RuntimeEnvironment.application;
+import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -81,6 +82,11 @@ public class ShadowWifiManager extends org.robolectric.shadows.ShadowWifiManager
return false;
}
+ @Implementation
+ protected List getScanResults() {
+ return new ArrayList();
+ }
+
public static ShadowWifiManager get() {
return Shadow.extract(application.getSystemService(WifiManager.class));
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
index 41d1bbe4f38..12f7c67b4bb 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
@@ -50,7 +50,7 @@ public class WifiDialogActivityTest {
private static final String AP1_SSID = "\"ap1\"";
@Mock
- private WifiConfigController mController;
+ private WifiConfigController2 mController;
@Before
public void setUp() {
@@ -63,8 +63,12 @@ public class WifiDialogActivityTest {
@Test
public void onSubmit_shouldConnectToNetwork() {
- WifiDialogActivity activity = Robolectric.setupActivity(WifiDialogActivity.class);
- WifiDialog dialog = (WifiDialog) ShadowAlertDialogCompat.getLatestAlertDialog();
+ WifiDialogActivity activity =
+ Robolectric.buildActivity(WifiDialogActivity.class,
+ new Intent().putExtra(WifiDialogActivity.KEY_CHOSEN_WIFIENTRY_KEY,
+ "StandardWifiEntry:OpenNetwork,0"))
+ .setup().get();
+ WifiDialog2 dialog = (WifiDialog2) ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
ReflectionHelpers.setField(dialog, "mController", mController);
@@ -74,35 +78,18 @@ public class WifiDialogActivityTest {
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
}
- @Test
- public void onSubmit_whenConnectForCallerIsFalse_shouldNotConnectToNetwork() {
- WifiDialogActivity activity =
- Robolectric.buildActivity(
- WifiDialogActivity.class,
- new Intent().putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false))
- .setup().get();
- WifiDialog dialog = (WifiDialog) ShadowAlertDialogCompat.getLatestAlertDialog();
-
- assertThat(dialog).isNotNull();
-
- ReflectionHelpers.setField(dialog, "mController", mController);
-
- activity.onSubmit(dialog);
-
- assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
- }
-
@Test
public void onSubmit_whenLaunchInSetupFlow_shouldBeLightThemeForWifiDialog() {
WifiDialogActivity activity =
Robolectric.buildActivity(
WifiDialogActivity.class,
new Intent()
- .putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false)
.putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true)
- .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true))
+ .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
+ .putExtra(WifiDialogActivity.KEY_CHOSEN_WIFIENTRY_KEY,
+ "StandardWifiEntry:OpenNetwork,0"))
.setup().get();
- WifiDialog dialog = (WifiDialog) ShadowAlertDialogCompat.getLatestAlertDialog();
+ WifiDialog2 dialog = (WifiDialog2) ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
index ac1384f8756..829ec8fc4dd 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
@@ -26,95 +26,69 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
-import android.net.wifi.WifiManager;
+import android.content.Intent;
-import com.android.settings.testutils.shadow.ShadowWifiManager;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.settings.wifi.WifiDialogActivity;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowWifiManager.class)
public class ConnectToWifiHandlerTest {
private static final String AP_SSID = "\"ap\"";
private Context mContext;
private ConnectToWifiHandler mHandler;
- private WifiConfiguration mWifiConfig;
@Mock
- private AccessPoint mAccessPoint;
+ private WifiScanWorker mWifiScanWorker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mHandler = new ConnectToWifiHandler();
- mWifiConfig = spy(new WifiConfiguration());
- mWifiConfig.SSID = AP_SSID;
- doReturn(mWifiConfig).when(mAccessPoint).getConfig();
+ mContext = spy(RuntimeEnvironment.application);
+ mHandler = spy(new ConnectToWifiHandler());
+ doReturn(mWifiScanWorker).when(mHandler).getWifiScanWorker(any());
}
@Test
- public void connect_shouldConnectToUnsavedOpenNetwork() {
- when(mAccessPoint.isSaved()).thenReturn(false);
- when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_NONE);
+ public void onReceive_nonNullKeyAndUri_shouldConnectWifintry() {
+ final Intent intent = new Intent();
+ final String key = "key";
+ intent.putExtra(ConnectToWifiHandler.KEY_CHOSEN_WIFIENTRY_KEY, key);
+ intent.putExtra(ConnectToWifiHandler.KEY_WIFI_SLICE_URI,
+ com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI);
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(mWifiScanWorker.getWifiEntry(key)).thenReturn(wifiEntry);
- mHandler.connect(mContext, mAccessPoint);
+ mHandler.onReceive(mContext, intent);
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
+ verify(wifiEntry).connect(any());
}
@Test
- public void connect_shouldStartOsuProvisioning() {
- when(mAccessPoint.isSaved()).thenReturn(false);
- when(mAccessPoint.isOsuProvider()).thenReturn(true);
+ public void onConnectResult_failNoConfig_shouldStartActivity() {
+ final String key = "key";
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(wifiEntry.getKey()).thenReturn(key);
+ final ConnectToWifiHandler.WifiEntryConnectCallback callback =
+ spy(new ConnectToWifiHandler.WifiEntryConnectCallback(mContext, wifiEntry));
- mHandler.connect(mContext, mAccessPoint);
+ callback.onConnectResult(ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG);
- verify(mAccessPoint).startOsuProvisioning(any(WifiManager.ActionListener.class));
- }
-
-
- @Test
- public void connect_shouldConnectWithPasspointProvider() {
- when(mAccessPoint.isSaved()).thenReturn(false);
- when(mAccessPoint.isPasspoint()).thenReturn(true);
-
- mHandler.connect(mContext, mAccessPoint);
-
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
- }
-
- @Test
- public void connect_shouldConnectToSavedSecuredNetwork() {
- when(mAccessPoint.isSaved()).thenReturn(true);
- when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_PSK);
- final NetworkSelectionStatus status = mock(NetworkSelectionStatus.class);
- when(status.hasEverConnected()).thenReturn(true);
- when(mWifiConfig.getNetworkSelectionStatus()).thenReturn(status);
-
- mHandler.connect(mContext, mAccessPoint);
-
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
- }
-
- @Test
- public void connect_shouldNotConnectToUnsavedSecuredNetwork() {
- when(mAccessPoint.isSaved()).thenReturn(false);
- when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_PSK);
-
- mHandler.connect(mContext, mAccessPoint);
-
- assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
+ final ArgumentCaptor argument = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext).startActivity(argument.capture());
+ assertThat(argument.getValue().getStringExtra(WifiDialogActivity.KEY_CHOSEN_WIFIENTRY_KEY))
+ .isEqualTo(key);
+ assertThat(argument.getValue().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK)
+ .isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiScanWorkerTest.java
deleted file mode 100644
index 0e525207caa..00000000000
--- a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiScanWorkerTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.wifi.WifiManager;
-import android.os.UserHandle;
-
-import com.android.settings.testutils.shadow.ShadowWifiManager;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {
- ShadowWifiManager.class,
- WifiScanWorkerTest.ShadowWifiTracker.class,
-})
-public class ContextualWifiScanWorkerTest {
-
- private Context mContext;
- private WifiManager mWifiManager;
- private ConnectivityManager mConnectivityManager;
- private ContextualWifiScanWorker mWifiScanWorker;
- private ConnectToWifiHandler mConnectToWifiHandler;
-
- @Before
- public void setUp() {
- mContext = spy(RuntimeEnvironment.application);
- mWifiManager = mContext.getSystemService(WifiManager.class);
- mWifiManager.setWifiEnabled(true);
-
- mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
- mWifiScanWorker = new ContextualWifiScanWorker(mContext, CONTEXTUAL_WIFI_SLICE_URI);
- mConnectToWifiHandler = new ConnectToWifiHandler();
- }
-
- @After
- public void tearDown() {
- mWifiScanWorker.clearClickedWifi();
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldSendBroadcast() {
- final Intent intent = WifiScanWorkerTest.getIntentWithAccessPoint("ap1");
- WifiScanWorkerTest.setConnectionInfoSSID("ap1");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
- final NetworkCallback callback = mWifiScanWorker.mNetworkCallback;
-
- mWifiScanWorker.onSlicePinned();
- mConnectToWifiHandler.onReceive(mContext, intent);
- mWifiScanWorker.onSliceUnpinned();
- callback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_newSession_shouldNotSendBroadcast() {
- final Intent intent = WifiScanWorkerTest.getIntentWithAccessPoint("ap1");
- WifiScanWorkerTest.setConnectionInfoSSID("ap1");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
-
- mConnectToWifiHandler.onReceive(mContext, intent);
- ContextualWifiScanWorker.newVisibleUiSession();
- mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
index 33195438fe0..395048c3c64 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
@@ -17,216 +17,89 @@
package com.android.settings.wifi.slice;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
-import static com.android.settings.wifi.WifiDialogActivity.KEY_ACCESS_POINT_STATE;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.UserHandle;
+import androidx.lifecycle.Lifecycle;
-import com.android.settings.slices.ShadowSliceBackgroundWorker;
-import com.android.settings.testutils.shadow.ShadowWifiManager;
-import com.android.settingslib.wifi.AccessPoint;
-import com.android.settingslib.wifi.WifiTracker;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowNetworkInfo;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowSliceBackgroundWorker.class, ShadowWifiManager.class,
- WifiScanWorkerTest.ShadowWifiTracker.class})
public class WifiScanWorkerTest {
- private Context mContext;
- private ContentResolver mResolver;
- private WifiManager mWifiManager;
- private ConnectivityManager mConnectivityManager;
private WifiScanWorker mWifiScanWorker;
- private ConnectToWifiHandler mConnectToWifiHandler;
+ @Mock
+ WifiPickerTracker mWifiPickerTracker;
@Before
public void setUp() {
- mContext = spy(RuntimeEnvironment.application);
- mResolver = mock(ContentResolver.class);
- doReturn(mResolver).when(mContext).getContentResolver();
- mWifiManager = mContext.getSystemService(WifiManager.class);
- mWifiManager.setWifiEnabled(true);
+ MockitoAnnotations.initMocks(this);
- mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
- mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
- mConnectToWifiHandler = new ConnectToWifiHandler();
- }
-
- @After
- public void tearDown() {
- mWifiScanWorker.clearClickedWifi();
+ mWifiScanWorker = new WifiScanWorker(RuntimeEnvironment.application, WIFI_SLICE_URI);
+ mWifiScanWorker.mWifiPickerTracker = mWifiPickerTracker;
}
@Test
- public void onWifiStateChanged_shouldNotifyChange() {
- mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED);
-
- verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
+ public void onConstructor_shouldBeInCreatedState() {
+ assertThat(mWifiScanWorker.getLifecycle().getCurrentState())
+ .isEqualTo(Lifecycle.State.CREATED);
}
@Test
- public void AccessPointList_sameState_shouldBeTheSame() {
- final AccessPoint ap1 = createAccessPoint(DetailedState.CONNECTED);
- final AccessPoint ap2 = createAccessPoint(DetailedState.CONNECTED);
-
- assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2)))
- .isTrue();
- }
-
- @Test
- public void AccessPointList_differentState_shouldBeDifferent() {
- final AccessPoint ap1 = createAccessPoint(DetailedState.CONNECTING);
- final AccessPoint ap2 = createAccessPoint(DetailedState.CONNECTED);
-
- assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2)))
- .isFalse();
- }
-
- @Test
- public void AccessPointList_differentListLength_shouldBeDifferent() {
- final AccessPoint ap1 = createAccessPoint(DetailedState.CONNECTED);
- final AccessPoint ap2 = createAccessPoint(DetailedState.CONNECTED);
- final List list = new ArrayList<>();
- list.add(ap1);
- list.add(ap2);
-
- assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse();
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_shouldNotifyChange() {
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
-
- mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldSendBroadcast() {
- final Intent intent = getIntentWithAccessPoint("ap1");
- setConnectionInfoSSID("ap1");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
-
- mConnectToWifiHandler.onReceive(mContext, intent);
- mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotSendBroadcast() {
- final Intent intent = getIntentWithAccessPoint("ap1");
- setConnectionInfoSSID("ap2");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
-
- mConnectToWifiHandler.onReceive(mContext, intent);
- mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotSendBroadcast() {
- setConnectionInfoSSID("ap1");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
-
- mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
-
- verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
- }
-
- @Test
- public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotSendBroadcast() {
- final Intent intent = getIntentWithAccessPoint("ap1");
- setConnectionInfoSSID("ap1");
- final Network network = mConnectivityManager.getActiveNetwork();
- mWifiScanWorker.registerNetworkCallback(network);
- final NetworkCallback callback = mWifiScanWorker.mNetworkCallback;
-
+ public void onSlicePinned_shouldBeInResumedState() {
mWifiScanWorker.onSlicePinned();
- mConnectToWifiHandler.onReceive(mContext, intent);
+
+ assertThat(mWifiScanWorker.getLifecycle().getCurrentState())
+ .isEqualTo(Lifecycle.State.RESUMED);
+ }
+
+ @Test
+ public void onSliceUnpinned_shouldBeInCreatedState() {
mWifiScanWorker.onSliceUnpinned();
- callback.onCapabilitiesChanged(network,
- WifiSliceTest.makeCaptivePortalNetworkCapabilities());
- verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+ assertThat(mWifiScanWorker.getLifecycle().getCurrentState())
+ .isEqualTo(Lifecycle.State.CREATED);
}
- static Intent getIntentWithAccessPoint(String ssid) {
- final Bundle savedState = new Bundle();
- savedState.putString("key_ssid", ssid);
- return new Intent().putExtra(KEY_ACCESS_POINT_STATE, savedState);
+ @Test
+ public void close_shouldBeInDestroyedState() {
+ mWifiScanWorker.close();
+
+ assertThat(mWifiScanWorker.getLifecycle().getCurrentState())
+ .isEqualTo(Lifecycle.State.DESTROYED);
}
- static void setConnectionInfoSSID(String ssid) {
- final WifiInfo wifiInfo = mock(WifiInfo.class);
- when(wifiInfo.getSSID()).thenReturn(ssid);
- ShadowWifiManager.get().setConnectionInfo(wifiInfo);
+ @Test
+ public void getWifiEntry_connectedWifiKey_shouldGetConnectedWifi() {
+ final String key = "key";
+ final WifiEntry connectedWifiEntry = mock(WifiEntry.class);
+ when(connectedWifiEntry.getKey()).thenReturn(key);
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(connectedWifiEntry);
+
+ assertThat(mWifiScanWorker.getWifiEntry(key)).isEqualTo(connectedWifiEntry);
}
- private AccessPoint createAccessPoint(String ssid, DetailedState detailedState) {
- final NetworkInfo info = ShadowNetworkInfo.newInstance(detailedState, 1 /* type */,
- 0 /*subType */, true /* isAvailable */, true /* isConnected */);
- final Bundle savedState = new Bundle();
- savedState.putString("key_ssid", ssid);
- savedState.putParcelable("key_networkinfo", info);
- return new AccessPoint(mContext, savedState);
- }
+ @Test
+ public void getWifiEntry_reachableWifiKey_shouldGetReachableWifi() {
+ final String key = "key";
+ final WifiEntry reachableWifiEntry = mock(WifiEntry.class);
+ when(reachableWifiEntry.getKey()).thenReturn(key);
+ when(mWifiPickerTracker.getWifiEntries()).thenReturn(Arrays.asList(reachableWifiEntry));
- private AccessPoint createAccessPoint(DetailedState detailedState) {
- return createAccessPoint("ap", detailedState);
- }
-
- @Implements(WifiTracker.class)
- public static class ShadowWifiTracker {
- @Implementation
- public void onStart() {
- // do nothing
- }
+ assertThat(mWifiScanWorker.getWifiEntry(key)).isEqualTo(reachableWifiEntry);
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
index ad74a326c83..5431540028d 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
@@ -23,17 +23,14 @@ import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COU
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
@@ -49,7 +46,8 @@ import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.testutils.SliceTester;
-import com.android.settingslib.wifi.AccessPoint;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectedState;
import org.junit.Before;
import org.junit.Test;
@@ -74,7 +72,6 @@ public class WifiSliceTest {
private Context mContext;
private ContentResolver mResolver;
private WifiManager mWifiManager;
- private ConnectivityManager mConnectivityManager;
private WifiSlice mWifiSlice;
@Before
@@ -88,9 +85,6 @@ public class WifiSliceTest {
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mWifiManager.setWifiEnabled(true);
- mConnectivityManager = spy(mContext.getSystemService(ConnectivityManager.class));
- doReturn(mConnectivityManager).when(mContext).getSystemService(ConnectivityManager.class);
-
mWifiSlice = new WifiSlice(mContext);
}
@@ -138,33 +132,42 @@ public class WifiSliceTest {
mContext.getString(R.string.wifi_empty_list_wifi_on));
}
- private AccessPoint createAccessPoint(String name, boolean active, boolean reachable) {
- final AccessPoint accessPoint = mock(AccessPoint.class);
- doReturn(name).when(accessPoint).getTitle();
- doReturn(active).when(accessPoint).isActive();
- doReturn(reachable).when(accessPoint).isReachable();
- if (active) {
- final NetworkInfo networkInfo = mock(NetworkInfo.class);
- doReturn(networkInfo).when(accessPoint).getNetworkInfo();
- doReturn(NetworkInfo.State.CONNECTED).when(networkInfo).getState();
- }
- return accessPoint;
+ private WifiSliceItem createWifiSliceItem(String title, @ConnectedState int connectedState) {
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(wifiEntry.getTitle()).thenReturn(title);
+ when(wifiEntry.getKey()).thenReturn("key");
+ when(wifiEntry.getConnectedState()).thenReturn(connectedState);
+ when(wifiEntry.getLevel()).thenReturn(WifiEntry.WIFI_LEVEL_MAX);
+ return new WifiSliceItem(mContext, wifiEntry);
}
- private void setWorkerResults(AccessPoint... accessPoints) {
- final ArrayList results = new ArrayList<>();
- for (AccessPoint ap : accessPoints) {
- results.add(ap);
+ private void setWorkerResults(WifiSliceItem... wifiSliceItems) {
+ final ArrayList results = new ArrayList<>();
+ for (WifiSliceItem wifiSliceItem : wifiSliceItems) {
+ results.add(wifiSliceItem);
}
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(mWifiSlice.getUri());
doReturn(results).when(worker).getResults();
}
@Test
- public void getWifiSlice_noReachableAp_shouldReturnLoadingRow() {
+ public void getWifiSlice_oneConnectedAp_shouldReturnLoadingRow() {
+ setWorkerResults(createWifiSliceItem(AP1_NAME, WifiEntry.CONNECTED_STATE_CONNECTED));
+
+ final Slice wifiSlice = mWifiSlice.getSlice();
+ final List sliceItems = wifiSlice.getItems();
+
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
+ // Has scanning text
+ SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
+ }
+
+ @Test
+ public void getWifiSlice_oneConnectedApAndOneDisconnectedAp_shouldReturnLoadingRow() {
setWorkerResults(
- createAccessPoint(AP1_NAME, false, false),
- createAccessPoint(AP2_NAME, false, false));
+ createWifiSliceItem(AP1_NAME, WifiEntry.CONNECTED_STATE_CONNECTED),
+ createWifiSliceItem(AP2_NAME, WifiEntry.CONNECTED_STATE_DISCONNECTED));
final Slice wifiSlice = mWifiSlice.getSlice();
final List sliceItems = wifiSlice.getItems();
@@ -177,8 +180,8 @@ public class WifiSliceTest {
}
@Test
- public void getWifiSlice_oneActiveAp_shouldReturnLoadingRow() {
- setWorkerResults(createAccessPoint(AP1_NAME, true, true));
+ public void getWifiSlice_oneDisconnectedAp_shouldReturnLoadingRow() {
+ setWorkerResults(createWifiSliceItem(AP1_NAME, WifiEntry.CONNECTED_STATE_DISCONNECTED));
final Slice wifiSlice = mWifiSlice.getSlice();
final List sliceItems = wifiSlice.getItems();
@@ -190,40 +193,11 @@ public class WifiSliceTest {
}
@Test
- public void getWifiSlice_oneActiveApAndOneUnreachableAp_shouldReturnLoadingRow() {
+ public void getWifiSlice_apReachExpandedCount_shouldNotReturnLoadingRow() {
setWorkerResults(
- createAccessPoint(AP1_NAME, true, true),
- createAccessPoint(AP2_NAME, false, false));
-
- final Slice wifiSlice = mWifiSlice.getSlice();
- final List sliceItems = wifiSlice.getItems();
-
- SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
- SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP2_NAME);
- // Has scanning text
- SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
- mContext.getString(R.string.wifi_empty_list_wifi_on));
- }
-
- @Test
- public void getWifiSlice_oneReachableAp_shouldReturnLoadingRow() {
- setWorkerResults(createAccessPoint(AP1_NAME, false, true));
-
- final Slice wifiSlice = mWifiSlice.getSlice();
- final List sliceItems = wifiSlice.getItems();
-
- SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
- // Has scanning text
- SliceTester.assertAnySliceItemContainsSubtitle(sliceItems,
- mContext.getString(R.string.wifi_empty_list_wifi_on));
- }
-
- @Test
- public void getWifiSlice_allReachableAps_shouldNotReturnLoadingRow() {
- setWorkerResults(
- createAccessPoint(AP1_NAME, false, true),
- createAccessPoint(AP2_NAME, false, true),
- createAccessPoint(AP3_NAME, false, true));
+ createWifiSliceItem(AP1_NAME, WifiEntry.CONNECTED_STATE_DISCONNECTED),
+ createWifiSliceItem(AP2_NAME, WifiEntry.CONNECTED_STATE_DISCONNECTED),
+ createWifiSliceItem(AP3_NAME, WifiEntry.CONNECTED_STATE_DISCONNECTED));
final Slice wifiSlice = mWifiSlice.getSlice();
final List sliceItems = wifiSlice.getItems();
@@ -236,29 +210,6 @@ public class WifiSliceTest {
mContext.getString(R.string.wifi_empty_list_wifi_on));
}
- @Test
- public void getWifiSlice_isCaptivePortal_shouldHaveCaptivePortalItems() {
- setWorkerResults(createAccessPoint(AP1_NAME, true, true));
- doReturn(makeCaptivePortalNetworkCapabilities()).when(mConnectivityManager)
- .getNetworkCapabilities(any());
- final IconCompat expectedIcon = IconCompat.createWithResource(mContext,
- R.drawable.ic_settings_accent);
-
- final Slice wifiSlice = mWifiSlice.getSlice();
- final List sliceItems = wifiSlice.getItems();
-
- SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
- SliceTester.assertAnySliceItemContainsIcon(sliceItems, expectedIcon);
- }
-
- static NetworkCapabilities makeCaptivePortalNetworkCapabilities() {
- final NetworkCapabilities nc = new NetworkCapabilities();
- nc.clearAll();
- nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
- return nc;
- }
-
@Test
public void handleUriChange_updatesWifi() {
final Intent intent = mWifiSlice.getIntent();