Fix automatically directing the user to the captive portal in Wi-Fi Slice
The feature failed after the CL "Force the adapter to rebind cards with a toggle". Because toggle slices have been forced to rebind after starting another activity and when any slice is updating. This unpins Wi-Fi slice and stops WifiScanWorker and then clears the saved clicked network. Solution: 1. Change ConnectToWifiHandler from activity to receiver and send broadcasts to it with FLAG_RECEIVER_FOREGROUND, so Wi-Fi slice won't be forced to rebind. 2. Seperate Wi-Fi scan worker and contextual Wi-Fi scan worker. Keep the original logic for the generic one, and then add the logic below to the contextual one. 3. Do not clear the saved clicked network when slice is unppined because it happens frequently in contextual homepage. 4. Introduce a static long in ContextualWifiScanWorker that updates once in every visible UI session. A session is when the screen is visible to user. 5. Use session token to determine whether auto-starting captive portal is needed. Fixes: 128056349 Test: robotest, visual in homepage and network panel Change-Id: I9e03c379806e124fa7253b2a635574b2433f6afc
This commit is contained in:
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.doReturn;
|
||||
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;
|
||||
@@ -35,8 +36,8 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -44,6 +45,7 @@ import org.robolectric.annotation.Config;
|
||||
public class ConnectToWifiHandlerTest {
|
||||
|
||||
private static final String AP_SSID = "\"ap\"";
|
||||
private Context mContext;
|
||||
private ConnectToWifiHandler mHandler;
|
||||
private WifiConfiguration mWifiConfig;
|
||||
@Mock
|
||||
@@ -53,7 +55,8 @@ public class ConnectToWifiHandlerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mHandler = new ConnectToWifiHandler();
|
||||
mWifiConfig = new WifiConfiguration();
|
||||
mWifiConfig.SSID = AP_SSID;
|
||||
doReturn(mWifiConfig).when(mAccessPoint).getConfig();
|
||||
@@ -64,7 +67,7 @@ public class ConnectToWifiHandlerTest {
|
||||
when(mAccessPoint.isSaved()).thenReturn(false);
|
||||
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_NONE);
|
||||
|
||||
mHandler.connect(mAccessPoint);
|
||||
mHandler.connect(mContext, mAccessPoint);
|
||||
|
||||
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
|
||||
}
|
||||
@@ -74,7 +77,7 @@ public class ConnectToWifiHandlerTest {
|
||||
when(mAccessPoint.isSaved()).thenReturn(false);
|
||||
when(mAccessPoint.isOsuProvider()).thenReturn(true);
|
||||
|
||||
mHandler.connect(mAccessPoint);
|
||||
mHandler.connect(mContext, mAccessPoint);
|
||||
|
||||
verify(mAccessPoint).startOsuProvisioning(any(WifiManager.ActionListener.class));
|
||||
}
|
||||
@@ -85,7 +88,7 @@ public class ConnectToWifiHandlerTest {
|
||||
when(mAccessPoint.isSaved()).thenReturn(false);
|
||||
when(mAccessPoint.isPasspoint()).thenReturn(true);
|
||||
|
||||
mHandler.connect(mAccessPoint);
|
||||
mHandler.connect(mContext, mAccessPoint);
|
||||
|
||||
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
|
||||
}
|
||||
@@ -98,7 +101,7 @@ public class ConnectToWifiHandlerTest {
|
||||
status.setHasEverConnected(true);
|
||||
mWifiConfig.setNetworkSelectionStatus(status);
|
||||
|
||||
mHandler.connect(mAccessPoint);
|
||||
mHandler.connect(mContext, mAccessPoint);
|
||||
|
||||
assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
|
||||
}
|
||||
@@ -108,7 +111,7 @@ public class ConnectToWifiHandlerTest {
|
||||
when(mAccessPoint.isSaved()).thenReturn(false);
|
||||
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_PSK);
|
||||
|
||||
mHandler.connect(mAccessPoint);
|
||||
mHandler.connect(mContext, mAccessPoint);
|
||||
|
||||
assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
|
||||
}
|
||||
|
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
}
|
@@ -17,6 +17,7 @@
|
||||
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;
|
||||
|
||||
@@ -42,9 +43,6 @@ import android.net.wifi.WifiSsid;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowWifiManager;
|
||||
import com.android.settingslib.wifi.AccessPoint;
|
||||
import com.android.settingslib.wifi.WifiTracker;
|
||||
@@ -57,7 +55,6 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
@@ -85,14 +82,11 @@ public class WifiScanWorkerTest {
|
||||
mResolver = mock(ContentResolver.class);
|
||||
doReturn(mResolver).when(mContext).getContentResolver();
|
||||
mWifiManager = mContext.getSystemService(WifiManager.class);
|
||||
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
mWifiManager.setWifiEnabled(true);
|
||||
|
||||
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
|
||||
mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
|
||||
mConnectToWifiHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
|
||||
mConnectToWifiHandler = new ConnectToWifiHandler();
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -147,42 +141,36 @@ public class WifiScanWorkerTest {
|
||||
verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
|
||||
}
|
||||
|
||||
private void setConnectionInfoSSID(String ssid) {
|
||||
final WifiInfo wifiInfo = new WifiInfo();
|
||||
wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
|
||||
ShadowWifiManager.get().setConnectionInfo(wifiInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldStartActivity() {
|
||||
final AccessPoint accessPoint = createAccessPoint("ap1");
|
||||
public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldSendBroadcast() {
|
||||
final Intent intent = getIntentWithAccessPoint("ap1");
|
||||
setConnectionInfoSSID("ap1");
|
||||
final Network network = mConnectivityManager.getActiveNetwork();
|
||||
mWifiScanWorker.registerNetworkCallback(network);
|
||||
|
||||
mConnectToWifiHandler.connect(accessPoint);
|
||||
mConnectToWifiHandler.onReceive(mContext, intent);
|
||||
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
|
||||
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
|
||||
|
||||
verify(mContext).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotStartActivity() {
|
||||
final AccessPoint accessPoint = createAccessPoint("ap1");
|
||||
public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotSendBroadcast() {
|
||||
final Intent intent = getIntentWithAccessPoint("ap1");
|
||||
setConnectionInfoSSID("ap2");
|
||||
final Network network = mConnectivityManager.getActiveNetwork();
|
||||
mWifiScanWorker.registerNetworkCallback(network);
|
||||
|
||||
mConnectToWifiHandler.connect(accessPoint);
|
||||
mConnectToWifiHandler.onReceive(mContext, intent);
|
||||
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
|
||||
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
|
||||
|
||||
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotStartActivity() {
|
||||
public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotSendBroadcast() {
|
||||
setConnectionInfoSSID("ap1");
|
||||
final Network network = mConnectivityManager.getActiveNetwork();
|
||||
mWifiScanWorker.registerNetworkCallback(network);
|
||||
@@ -190,24 +178,36 @@ public class WifiScanWorkerTest {
|
||||
mWifiScanWorker.mNetworkCallback.onCapabilitiesChanged(network,
|
||||
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
|
||||
|
||||
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotStartActivity() {
|
||||
final AccessPoint accessPoint = createAccessPoint("ap1");
|
||||
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;
|
||||
|
||||
mWifiScanWorker.onSlicePinned();
|
||||
mConnectToWifiHandler.connect(accessPoint);
|
||||
mConnectToWifiHandler.onReceive(mContext, intent);
|
||||
mWifiScanWorker.onSliceUnpinned();
|
||||
callback.onCapabilitiesChanged(network,
|
||||
WifiSliceTest.makeCaptivePortalNetworkCapabilities());
|
||||
|
||||
verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.CURRENT));
|
||||
}
|
||||
|
||||
static Intent getIntentWithAccessPoint(String ssid) {
|
||||
final Bundle savedState = new Bundle();
|
||||
savedState.putString("key_ssid", ssid);
|
||||
return new Intent().putExtra(KEY_ACCESS_POINT_STATE, savedState);
|
||||
}
|
||||
|
||||
static void setConnectionInfoSSID(String ssid) {
|
||||
final WifiInfo wifiInfo = new WifiInfo();
|
||||
wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
|
||||
ShadowWifiManager.get().setConnectionInfo(wifiInfo);
|
||||
}
|
||||
|
||||
private AccessPoint createAccessPoint(String ssid, DetailedState detailedState) {
|
||||
@@ -223,10 +223,6 @@ public class WifiScanWorkerTest {
|
||||
return createAccessPoint("ap", detailedState);
|
||||
}
|
||||
|
||||
private AccessPoint createAccessPoint(String ssid) {
|
||||
return createAccessPoint(ssid, DetailedState.DISCONNECTED);
|
||||
}
|
||||
|
||||
@Implements(WifiTracker.class)
|
||||
public static class ShadowWifiTracker {
|
||||
@Implementation
|
||||
|
Reference in New Issue
Block a user