Add a "sign into network" button to the wifi details page.
Bug: 36203355 Test: manually signed into captive portal Test: make -j64 RunSettingsRoboTests Change-Id: I3242ef30125ddfdaaac9b80ead4f8ac14ea6d364
This commit is contained in:
@@ -28,9 +28,9 @@
|
|||||||
android:key="general_details_category" >
|
android:key="general_details_category" >
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<com.android.settings.applications.LayoutPreference
|
<com.android.settings.applications.LayoutPreference
|
||||||
android:key="forget_button"
|
android:key="buttons"
|
||||||
android:selectable="false"
|
android:layout="@layout/two_buttons_panel"
|
||||||
android:layout="@layout/single_button_panel" />
|
android:selectable="false" />
|
||||||
|
|
||||||
<com.android.settings.wifi.WifiDetailPreference
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
android:key="signal_strength"
|
android:key="signal_strength"
|
||||||
|
@@ -16,6 +16,11 @@
|
|||||||
|
|
||||||
package com.android.settings.vpn2;
|
package com.android.settings.vpn2;
|
||||||
|
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
|
import android.os.Handler;
|
||||||
import android.net.ProxyInfo;
|
import android.net.ProxyInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,6 +31,11 @@ import android.net.ProxyInfo;
|
|||||||
*/
|
*/
|
||||||
public interface ConnectivityManagerWrapper {
|
public interface ConnectivityManagerWrapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the real ConnectivityManager object wrapped by this wrapper.
|
||||||
|
*/
|
||||||
|
public ConnectivityManager getConnectivityManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@code ConnectivityManager.getAlwaysOnVpnPackageForUser()}.
|
* Calls {@code ConnectivityManager.getAlwaysOnVpnPackageForUser()}.
|
||||||
*
|
*
|
||||||
@@ -39,4 +49,27 @@ public interface ConnectivityManagerWrapper {
|
|||||||
* @see android.net.ConnectivityManager#getGlobalProxy
|
* @see android.net.ConnectivityManager#getGlobalProxy
|
||||||
*/
|
*/
|
||||||
ProxyInfo getGlobalProxy();
|
ProxyInfo getGlobalProxy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@code ConnectivityManager.registerNetworkCallback()}.
|
||||||
|
*
|
||||||
|
* This is part of the ConnectivityManager public API in SDK 26 or above, but is not yet visible
|
||||||
|
* to the robolectric tests, which currently build with SDK 23.
|
||||||
|
* TODO: delete this once the robolectric tests build with SDK 26 or above.
|
||||||
|
*
|
||||||
|
* @see android.net.ConnectivityManager#registerNetworkCallback(NetworkRequest,NetworkCallback,Handler)
|
||||||
|
*/
|
||||||
|
public void registerNetworkCallback(NetworkRequest request, NetworkCallback callback,
|
||||||
|
Handler handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@code ConnectivityManager.startCaptivePortalApp()}.
|
||||||
|
*
|
||||||
|
* This is part of the ConnectivityManager public API in SDK 26 or above, but is not yet visible
|
||||||
|
* to the robolectric tests, which currently build with SDK 23.
|
||||||
|
* TODO: delete this once the robolectric tests build with SDK 26 or above.
|
||||||
|
*
|
||||||
|
* @see android.net.ConnectivityManager#startCaptivePortalApp(Network)
|
||||||
|
*/
|
||||||
|
public void startCaptivePortalApp(Network network);
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,10 @@
|
|||||||
package com.android.settings.vpn2;
|
package com.android.settings.vpn2;
|
||||||
|
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
|
import android.os.Handler;
|
||||||
import android.net.ProxyInfo;
|
import android.net.ProxyInfo;
|
||||||
|
|
||||||
public class ConnectivityManagerWrapperImpl implements ConnectivityManagerWrapper {
|
public class ConnectivityManagerWrapperImpl implements ConnectivityManagerWrapper {
|
||||||
@@ -27,6 +31,11 @@ public class ConnectivityManagerWrapperImpl implements ConnectivityManagerWrappe
|
|||||||
mCm = cm;
|
mCm = cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectivityManager getConnectivityManager() {
|
||||||
|
return mCm;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAlwaysOnVpnPackageForUser(int userId) {
|
public String getAlwaysOnVpnPackageForUser(int userId) {
|
||||||
return mCm.getAlwaysOnVpnPackageForUser(userId);
|
return mCm.getAlwaysOnVpnPackageForUser(userId);
|
||||||
@@ -36,4 +45,15 @@ public class ConnectivityManagerWrapperImpl implements ConnectivityManagerWrappe
|
|||||||
public ProxyInfo getGlobalProxy() {
|
public ProxyInfo getGlobalProxy() {
|
||||||
return mCm.getGlobalProxy();
|
return mCm.getGlobalProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerNetworkCallback(NetworkRequest request, NetworkCallback callback,
|
||||||
|
Handler handler) {
|
||||||
|
mCm.registerNetworkCallback(request, callback, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startCaptivePortalApp(Network network) {
|
||||||
|
mCm.startCaptivePortalApp(network);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,30 +22,38 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkBadging;
|
import android.net.NetworkBadging;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkUtils;
|
import android.net.NetworkUtils;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.wifi.WifiConfiguration;
|
import android.net.wifi.WifiConfiguration;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Handler;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.core.PreferenceController;
|
import com.android.settings.core.PreferenceController;
|
||||||
import com.android.settings.core.lifecycle.Lifecycle;
|
import com.android.settings.core.lifecycle.Lifecycle;
|
||||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||||
import com.android.settings.core.lifecycle.events.OnPause;
|
import com.android.settings.core.lifecycle.events.OnPause;
|
||||||
import com.android.settings.core.lifecycle.events.OnResume;
|
import com.android.settings.core.lifecycle.events.OnResume;
|
||||||
import com.android.settings.wifi.WifiDetailPreference;
|
import com.android.settings.wifi.WifiDetailPreference;
|
||||||
|
import com.android.settings.vpn2.ConnectivityManagerWrapper;
|
||||||
import com.android.settingslib.wifi.AccessPoint;
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
@@ -55,6 +63,9 @@ import java.net.UnknownHostException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for logic pertaining to displaying Wifi information for the
|
* Controller for logic pertaining to displaying Wifi information for the
|
||||||
* {@link WifiNetworkDetailsFragment}.
|
* {@link WifiNetworkDetailsFragment}.
|
||||||
@@ -67,6 +78,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String KEY_CONNECTION_DETAIL_PREF = "connection_detail";
|
static final String KEY_CONNECTION_DETAIL_PREF = "connection_detail";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
static final String KEY_BUTTONS_PREF = "buttons";
|
||||||
|
@VisibleForTesting
|
||||||
static final String KEY_SIGNAL_STRENGTH_PREF = "signal_strength";
|
static final String KEY_SIGNAL_STRENGTH_PREF = "signal_strength";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String KEY_LINK_SPEED = "link_speed";
|
static final String KEY_LINK_SPEED = "link_speed";
|
||||||
@@ -88,9 +101,14 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
static final String KEY_IPV6_ADDRESS_CATEGORY = "ipv6_details_category";
|
static final String KEY_IPV6_ADDRESS_CATEGORY = "ipv6_details_category";
|
||||||
|
|
||||||
private AccessPoint mAccessPoint;
|
private AccessPoint mAccessPoint;
|
||||||
|
private final ConnectivityManagerWrapper mConnectivityManagerWrapper;
|
||||||
private final ConnectivityManager mConnectivityManager;
|
private final ConnectivityManager mConnectivityManager;
|
||||||
private final Fragment mFragment;
|
private final Fragment mFragment;
|
||||||
|
private final Handler mHandler;
|
||||||
|
private LinkProperties mLinkProperties;
|
||||||
|
private Network mNetwork;
|
||||||
private NetworkInfo mNetworkInfo;
|
private NetworkInfo mNetworkInfo;
|
||||||
|
private NetworkCapabilities mNetworkCapabilities;
|
||||||
private Context mPrefContext;
|
private Context mPrefContext;
|
||||||
private int mRssi;
|
private int mRssi;
|
||||||
private String[] mSignalStr;
|
private String[] mSignalStr;
|
||||||
@@ -98,8 +116,10 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
private WifiInfo mWifiInfo;
|
private WifiInfo mWifiInfo;
|
||||||
private final WifiManager mWifiManager;
|
private final WifiManager mWifiManager;
|
||||||
|
|
||||||
// Preferences - in order of appearance
|
// UI elements - in order of appearance
|
||||||
private Preference mConnectionDetailPref;
|
private Preference mConnectionDetailPref;
|
||||||
|
private LayoutPreference mButtonsPref;
|
||||||
|
private Button mSignInButton;
|
||||||
private WifiDetailPreference mSignalStrengthPref;
|
private WifiDetailPreference mSignalStrengthPref;
|
||||||
private WifiDetailPreference mLinkSpeedPref;
|
private WifiDetailPreference mLinkSpeedPref;
|
||||||
private WifiDetailPreference mFrequencyPref;
|
private WifiDetailPreference mFrequencyPref;
|
||||||
@@ -123,18 +143,50 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
|
||||||
|
.clearCapabilities().addTransportType(TRANSPORT_WIFI).build();
|
||||||
|
|
||||||
|
// Must be run on the UI thread since it directly manipulates UI state.
|
||||||
|
private final NetworkCallback mNetworkCallback = new NetworkCallback() {
|
||||||
|
@Override
|
||||||
|
public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
|
||||||
|
if (network.equals(mNetwork) && !lp.equals(mLinkProperties)) {
|
||||||
|
mLinkProperties = lp;
|
||||||
|
updateIpLayerInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
|
||||||
|
if (network.equals(mNetwork) && !nc.equals(mNetworkCapabilities)) {
|
||||||
|
mNetworkCapabilities = nc;
|
||||||
|
updateIpLayerInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLost(Network network) {
|
||||||
|
if (network.equals(mNetwork)) {
|
||||||
|
exitActivity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public WifiDetailPreferenceController(
|
public WifiDetailPreferenceController(
|
||||||
AccessPoint accessPoint,
|
AccessPoint accessPoint,
|
||||||
ConnectivityManager connectivityManager,
|
ConnectivityManagerWrapper connectivityManagerWrapper,
|
||||||
Context context,
|
Context context,
|
||||||
Fragment fragment,
|
Fragment fragment,
|
||||||
|
Handler handler,
|
||||||
Lifecycle lifecycle,
|
Lifecycle lifecycle,
|
||||||
WifiManager wifiManager) {
|
WifiManager wifiManager) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mAccessPoint = accessPoint;
|
mAccessPoint = accessPoint;
|
||||||
mConnectivityManager = connectivityManager;
|
mConnectivityManager = connectivityManagerWrapper.getConnectivityManager();
|
||||||
|
mConnectivityManagerWrapper = connectivityManagerWrapper;
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
|
mHandler = handler;
|
||||||
mNetworkInfo = accessPoint.getNetworkInfo();
|
mNetworkInfo = accessPoint.getNetworkInfo();
|
||||||
mRssi = accessPoint.getRssi();
|
mRssi = accessPoint.getRssi();
|
||||||
mSignalStr = context.getResources().getStringArray(R.array.wifi_signal);
|
mSignalStr = context.getResources().getStringArray(R.array.wifi_signal);
|
||||||
@@ -167,6 +219,12 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
|
|
||||||
mConnectionDetailPref = screen.findPreference(KEY_CONNECTION_DETAIL_PREF);
|
mConnectionDetailPref = screen.findPreference(KEY_CONNECTION_DETAIL_PREF);
|
||||||
|
|
||||||
|
mButtonsPref = (LayoutPreference) screen.findPreference(KEY_BUTTONS_PREF);
|
||||||
|
mSignInButton = (Button) mButtonsPref.findViewById(R.id.right_button);
|
||||||
|
mSignInButton.setText(com.android.internal.R.string.network_available_sign_in);
|
||||||
|
mSignInButton.setOnClickListener(
|
||||||
|
view -> mConnectivityManagerWrapper.startCaptivePortalApp(mNetwork));
|
||||||
|
|
||||||
mSignalStrengthPref =
|
mSignalStrengthPref =
|
||||||
(WifiDetailPreference) screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
|
(WifiDetailPreference) screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
|
||||||
mLinkSpeedPref = (WifiDetailPreference) screen.findPreference(KEY_LINK_SPEED);
|
mLinkSpeedPref = (WifiDetailPreference) screen.findPreference(KEY_LINK_SPEED);
|
||||||
@@ -191,6 +249,12 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
|
mConnectivityManagerWrapper.registerNetworkCallback(mNetworkRequest, mNetworkCallback,
|
||||||
|
mHandler);
|
||||||
|
mNetwork = mWifiManager.getCurrentNetwork();
|
||||||
|
mLinkProperties = mConnectivityManager.getLinkProperties(mNetwork);
|
||||||
|
mNetworkCapabilities = mConnectivityManager.getNetworkCapabilities(mNetwork);
|
||||||
|
|
||||||
updateInfo();
|
updateInfo();
|
||||||
|
|
||||||
mContext.registerReceiver(mReceiver, mFilter);
|
mContext.registerReceiver(mReceiver, mFilter);
|
||||||
@@ -198,13 +262,17 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
|
mNetwork = null;
|
||||||
|
mLinkProperties = null;
|
||||||
|
mNetworkCapabilities = null;
|
||||||
mContext.unregisterReceiver(mReceiver);
|
mContext.unregisterReceiver(mReceiver);
|
||||||
|
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInfo() {
|
private void updateInfo() {
|
||||||
mNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
|
mNetworkInfo = mConnectivityManager.getNetworkInfo(mNetwork);
|
||||||
mWifiInfo = mWifiManager.getConnectionInfo();
|
mWifiInfo = mWifiManager.getConnectionInfo();
|
||||||
if (mNetworkInfo == null || mWifiInfo == null) {
|
if (mNetwork == null || mNetworkInfo == null || mWifiInfo == null) {
|
||||||
exitActivity();
|
exitActivity();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -238,7 +306,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
}
|
}
|
||||||
mFrequencyPref.setDetailText(band);
|
mFrequencyPref.setDetailText(band);
|
||||||
|
|
||||||
setIpText();
|
updateIpLayerInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exitActivity() {
|
private void exitActivity() {
|
||||||
@@ -270,7 +338,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]);
|
mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setIpText() {
|
private void updateIpLayerInfo() {
|
||||||
|
mSignInButton.setVisibility(canSignIntoNetwork() ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
|
||||||
// Reset all fields
|
// Reset all fields
|
||||||
mIpv6AddressCategory.removeAll();
|
mIpv6AddressCategory.removeAll();
|
||||||
mIpv6AddressCategory.setVisible(false);
|
mIpv6AddressCategory.setVisible(false);
|
||||||
@@ -279,18 +349,12 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
mGatewayPref.setVisible(false);
|
mGatewayPref.setVisible(false);
|
||||||
mDnsPref.setVisible(false);
|
mDnsPref.setVisible(false);
|
||||||
|
|
||||||
Network currentNetwork = mWifiManager.getCurrentNetwork();
|
if (mNetwork == null || mLinkProperties == null) {
|
||||||
if (currentNetwork == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
List<InetAddress> addresses = mLinkProperties.getAddresses();
|
||||||
|
|
||||||
LinkProperties linkProperties = mConnectivityManager.getLinkProperties(currentNetwork);
|
// Set IPv4 and IPv6 addresses
|
||||||
if (linkProperties == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<InetAddress> addresses = linkProperties.getAddresses();
|
|
||||||
|
|
||||||
// Set IPv4 and Ipv6 addresses
|
|
||||||
for (int i = 0; i < addresses.size(); i++) {
|
for (int i = 0; i < addresses.size(); i++) {
|
||||||
InetAddress addr = addresses.get(i);
|
InetAddress addr = addresses.get(i);
|
||||||
if (addr instanceof Inet4Address) {
|
if (addr instanceof Inet4Address) {
|
||||||
@@ -310,7 +374,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
// Set up IPv4 gateway and subnet mask
|
// Set up IPv4 gateway and subnet mask
|
||||||
String gateway = null;
|
String gateway = null;
|
||||||
String subnet = null;
|
String subnet = null;
|
||||||
for (RouteInfo routeInfo : linkProperties.getRoutes()) {
|
for (RouteInfo routeInfo : mLinkProperties.getRoutes()) {
|
||||||
if (routeInfo.hasGateway() && routeInfo.getGateway() instanceof Inet4Address) {
|
if (routeInfo.hasGateway() && routeInfo.getGateway() instanceof Inet4Address) {
|
||||||
gateway = routeInfo.getGateway().getHostAddress();
|
gateway = routeInfo.getGateway().getHostAddress();
|
||||||
}
|
}
|
||||||
@@ -333,7 +397,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
|
|
||||||
// Set IPv4 DNS addresses
|
// Set IPv4 DNS addresses
|
||||||
StringJoiner stringJoiner = new StringJoiner(",");
|
StringJoiner stringJoiner = new StringJoiner(",");
|
||||||
for (InetAddress dnsServer : linkProperties.getDnsServers()) {
|
for (InetAddress dnsServer : mLinkProperties.getDnsServers()) {
|
||||||
if (dnsServer instanceof Inet4Address) {
|
if (dnsServer instanceof Inet4Address) {
|
||||||
stringJoiner.add(dnsServer.getHostAddress());
|
stringJoiner.add(dnsServer.getHostAddress());
|
||||||
}
|
}
|
||||||
@@ -362,6 +426,14 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
|
|||||||
return mWifiInfo != null && mWifiInfo.isEphemeral() || mWifiConfig != null;
|
return mWifiInfo != null && mWifiInfo.isEphemeral() || mWifiConfig != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the user can sign into the network represented by this preference.
|
||||||
|
*/
|
||||||
|
private boolean canSignIntoNetwork() {
|
||||||
|
return mNetworkCapabilities != null && mNetworkCapabilities.hasCapability(
|
||||||
|
NET_CAPABILITY_CAPTIVE_PORTAL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forgets the wifi network associated with this preference.
|
* Forgets the wifi network associated with this preference.
|
||||||
*/
|
*/
|
||||||
|
@@ -17,8 +17,12 @@ package com.android.settings.wifi.details;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
@@ -26,6 +30,7 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.core.PreferenceController;
|
import com.android.settings.core.PreferenceController;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settings.vpn2.ConnectivityManagerWrapperImpl;
|
||||||
import com.android.settingslib.wifi.AccessPoint;
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -40,9 +45,6 @@ import java.util.List;
|
|||||||
public class WifiNetworkDetailsFragment extends DashboardFragment {
|
public class WifiNetworkDetailsFragment extends DashboardFragment {
|
||||||
private static final String TAG = "WifiNetworkDetailsFrg";
|
private static final String TAG = "WifiNetworkDetailsFrg";
|
||||||
|
|
||||||
// XML KEYS
|
|
||||||
private static final String KEY_FORGET_BUTTON = "forget_button";
|
|
||||||
|
|
||||||
private AccessPoint mAccessPoint;
|
private AccessPoint mAccessPoint;
|
||||||
private Button mForgetButton;
|
private Button mForgetButton;
|
||||||
private WifiDetailPreferenceController mWifiDetailPreferenceController;
|
private WifiDetailPreferenceController mWifiDetailPreferenceController;
|
||||||
@@ -59,9 +61,11 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
|
|||||||
|
|
||||||
// Header Title set automatically from launching Preference
|
// Header Title set automatically from launching Preference
|
||||||
|
|
||||||
LayoutPreference forgetPreference = ((LayoutPreference) findPreference(KEY_FORGET_BUTTON));
|
LayoutPreference buttonsPreference = ((LayoutPreference) findPreference(
|
||||||
forgetPreference.setVisible(mWifiDetailPreferenceController.canForgetNetwork());
|
WifiDetailPreferenceController.KEY_BUTTONS_PREF));
|
||||||
mForgetButton = (Button) forgetPreference.findViewById(R.id.button);
|
buttonsPreference.setVisible(mWifiDetailPreferenceController.canForgetNetwork());
|
||||||
|
|
||||||
|
mForgetButton = (Button) buttonsPreference.findViewById(R.id.left_button);
|
||||||
mForgetButton.setText(R.string.forget);
|
mForgetButton.setText(R.string.forget);
|
||||||
mForgetButton.setOnClickListener(view -> forgetNetwork());
|
mForgetButton.setOnClickListener(view -> forgetNetwork());
|
||||||
}
|
}
|
||||||
@@ -88,11 +92,13 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||||
|
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
|
||||||
mWifiDetailPreferenceController = new WifiDetailPreferenceController(
|
mWifiDetailPreferenceController = new WifiDetailPreferenceController(
|
||||||
mAccessPoint,
|
mAccessPoint,
|
||||||
context.getSystemService(ConnectivityManager.class),
|
new ConnectivityManagerWrapperImpl(cm),
|
||||||
context,
|
context,
|
||||||
this,
|
this,
|
||||||
|
new Handler(Looper.getMainLooper()), // UI thread.
|
||||||
getLifecycle(),
|
getLifecycle(),
|
||||||
context.getSystemService(WifiManager.class));
|
context.getSystemService(WifiManager.class));
|
||||||
|
|
||||||
|
@@ -18,6 +18,8 @@ package com.android.settings.wifi.details;
|
|||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
@@ -29,25 +31,35 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkBadging;
|
import android.net.NetworkBadging;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
import android.net.NetworkRequest;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.wifi.WifiConfiguration;
|
import android.net.wifi.WifiConfiguration;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Handler;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsRobolectricTestRunner;
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.core.lifecycle.Lifecycle;
|
import com.android.settings.core.lifecycle.Lifecycle;
|
||||||
import com.android.settings.wifi.WifiDetailPreference;
|
import com.android.settings.wifi.WifiDetailPreference;
|
||||||
|
import com.android.settings.vpn2.ConnectivityManagerWrapper;
|
||||||
|
import com.android.settings.vpn2.ConnectivityManagerWrapperImpl;
|
||||||
import com.android.settingslib.wifi.AccessPoint;
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -55,6 +67,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
@@ -83,6 +96,7 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
@Mock private AccessPoint mockAccessPoint;
|
@Mock private AccessPoint mockAccessPoint;
|
||||||
@Mock private Activity mockActivity;
|
@Mock private Activity mockActivity;
|
||||||
@Mock private ConnectivityManager mockConnectivityManager;
|
@Mock private ConnectivityManager mockConnectivityManager;
|
||||||
|
@Mock private ConnectivityManagerWrapperImpl mockConnectivityManagerWrapper;
|
||||||
@Mock private Network mockNetwork;
|
@Mock private Network mockNetwork;
|
||||||
@Mock private NetworkInfo mockNetworkInfo;
|
@Mock private NetworkInfo mockNetworkInfo;
|
||||||
@Mock private WifiConfiguration mockWifiConfig;
|
@Mock private WifiConfiguration mockWifiConfig;
|
||||||
@@ -91,6 +105,8 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
@Mock private WifiManager mockWifiManager;
|
@Mock private WifiManager mockWifiManager;
|
||||||
|
|
||||||
@Mock private Preference mockConnectionDetailPref;
|
@Mock private Preference mockConnectionDetailPref;
|
||||||
|
@Mock private LayoutPreference mockButtonsPref;
|
||||||
|
@Mock private Button mockSignInButton;
|
||||||
@Mock private WifiDetailPreference mockSignalStrengthPref;
|
@Mock private WifiDetailPreference mockSignalStrengthPref;
|
||||||
@Mock private WifiDetailPreference mockLinkSpeedPref;
|
@Mock private WifiDetailPreference mockLinkSpeedPref;
|
||||||
@Mock private WifiDetailPreference mockFrequencyPref;
|
@Mock private WifiDetailPreference mockFrequencyPref;
|
||||||
@@ -102,9 +118,10 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
@Mock private WifiDetailPreference mockDnsPref;
|
@Mock private WifiDetailPreference mockDnsPref;
|
||||||
@Mock private PreferenceCategory mockIpv6AddressCategory;
|
@Mock private PreferenceCategory mockIpv6AddressCategory;
|
||||||
|
|
||||||
private LinkProperties mLinkProperties;
|
private ArgumentCaptor<NetworkCallback> mCallbackCaptor;
|
||||||
private Context mContext = RuntimeEnvironment.application;
|
private Context mContext = RuntimeEnvironment.application;
|
||||||
private Lifecycle mLifecycle;
|
private Lifecycle mLifecycle;
|
||||||
|
private LinkProperties mLinkProperties;
|
||||||
private WifiDetailPreferenceController mController;
|
private WifiDetailPreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -126,14 +143,20 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);
|
||||||
|
|
||||||
when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
|
when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
|
||||||
when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
|
when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
|
||||||
when(mockAccessPoint.getNetworkInfo()).thenReturn(mockNetworkInfo);
|
when(mockAccessPoint.getNetworkInfo()).thenReturn(mockNetworkInfo);
|
||||||
when(mockAccessPoint.getRssi()).thenReturn(RSSI);
|
when(mockAccessPoint.getRssi()).thenReturn(RSSI);
|
||||||
when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);
|
when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);
|
||||||
|
|
||||||
|
when(mockConnectivityManagerWrapper.getConnectivityManager())
|
||||||
|
.thenReturn(mockConnectivityManager);
|
||||||
when(mockConnectivityManager.getNetworkInfo(any(Network.class)))
|
when(mockConnectivityManager.getNetworkInfo(any(Network.class)))
|
||||||
.thenReturn(mockNetworkInfo);
|
.thenReturn(mockNetworkInfo);
|
||||||
|
doNothing().when(mockConnectivityManagerWrapper).registerNetworkCallback(
|
||||||
|
any(NetworkRequest.class), mCallbackCaptor.capture(), any(Handler.class));
|
||||||
|
|
||||||
when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED);
|
when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED);
|
||||||
when(mockWifiInfo.getRssi()).thenReturn(RSSI);
|
when(mockWifiInfo.getRssi()).thenReturn(RSSI);
|
||||||
@@ -154,9 +177,10 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
private WifiDetailPreferenceController newWifiDetailPreferenceController() {
|
private WifiDetailPreferenceController newWifiDetailPreferenceController() {
|
||||||
return new WifiDetailPreferenceController(
|
return new WifiDetailPreferenceController(
|
||||||
mockAccessPoint,
|
mockAccessPoint,
|
||||||
mockConnectivityManager,
|
mockConnectivityManagerWrapper,
|
||||||
mContext,
|
mContext,
|
||||||
mockFragment,
|
mockFragment,
|
||||||
|
null, // Handler
|
||||||
mLifecycle,
|
mLifecycle,
|
||||||
mockWifiManager);
|
mockWifiManager);
|
||||||
}
|
}
|
||||||
@@ -166,6 +190,10 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
|
|
||||||
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF))
|
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF))
|
||||||
.thenReturn(mockConnectionDetailPref);
|
.thenReturn(mockConnectionDetailPref);
|
||||||
|
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_BUTTONS_PREF))
|
||||||
|
.thenReturn(mockButtonsPref);
|
||||||
|
when(mockButtonsPref.findViewById(R.id.right_button))
|
||||||
|
.thenReturn(mockSignInButton);
|
||||||
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
|
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
|
||||||
.thenReturn(mockSignalStrengthPref);
|
.thenReturn(mockSignalStrengthPref);
|
||||||
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_LINK_SPEED))
|
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_LINK_SPEED))
|
||||||
@@ -214,6 +242,23 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
|
verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void networkCallback_shouldBeRegisteredOnResume() {
|
||||||
|
mController.onResume();
|
||||||
|
|
||||||
|
verify(mockConnectivityManagerWrapper, times(1)).registerNetworkCallback(
|
||||||
|
any(NetworkRequest.class), mCallbackCaptor.capture(), any(Handler.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void networkCallback_shouldBeUnregisteredOnPause() {
|
||||||
|
mController.onResume();
|
||||||
|
mController.onPause();
|
||||||
|
|
||||||
|
verify(mockConnectivityManager, times(1)).unregisterNetworkCallback(
|
||||||
|
mCallbackCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void connectionDetailPref_shouldHaveIconSet() {
|
public void connectionDetailPref_shouldHaveIconSet() {
|
||||||
Drawable expectedIcon =
|
Drawable expectedIcon =
|
||||||
@@ -311,23 +356,14 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noCurrentNetwork_allIpDetailsHidden() {
|
public void noCurrentNetwork_shouldFinishActivity() {
|
||||||
|
// If WifiManager#getCurrentNetwork() returns null, then the network is neither connected
|
||||||
|
// nor connecting and WifiStateMachine has not reached L2ConnectedState.
|
||||||
when(mockWifiManager.getCurrentNetwork()).thenReturn(null);
|
when(mockWifiManager.getCurrentNetwork()).thenReturn(null);
|
||||||
reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref,
|
|
||||||
mockDnsPref);
|
|
||||||
|
|
||||||
mController.onResume();
|
mController.onResume();
|
||||||
|
|
||||||
verify(mockIpv6AddressCategory).setVisible(false);
|
verify(mockActivity).finish();
|
||||||
verify(mockIpAddressPref).setVisible(false);
|
|
||||||
verify(mockSubnetPref).setVisible(false);
|
|
||||||
verify(mockGatewayPref).setVisible(false);
|
|
||||||
verify(mockDnsPref).setVisible(false);
|
|
||||||
verify(mockIpv6AddressCategory, never()).setVisible(true);
|
|
||||||
verify(mockIpAddressPref, never()).setVisible(true);
|
|
||||||
verify(mockSubnetPref, never()).setVisible(true);
|
|
||||||
verify(mockGatewayPref, never()).setVisible(true);
|
|
||||||
verify(mockDnsPref, never()).setVisible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -432,6 +468,15 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
verify(mockActivity).finish();
|
verify(mockActivity).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void networkOnLost_shouldFinishActivity() {
|
||||||
|
mController.onResume();
|
||||||
|
|
||||||
|
mCallbackCaptor.getValue().onLost(mockNetwork);
|
||||||
|
|
||||||
|
verify(mockActivity).finish();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ipv6AddressPref_shouldHaveHostAddressTextSet() {
|
public void ipv6AddressPref_shouldHaveHostAddressTextSet() {
|
||||||
LinkAddress ipv6Address = new LinkAddress(mIpv6Address, 128);
|
LinkAddress ipv6Address = new LinkAddress(mIpv6Address, 128);
|
||||||
@@ -457,4 +502,40 @@ public class WifiDetailPreferenceControllerTest {
|
|||||||
verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
|
verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
|
||||||
assertThat(preferenceCaptor.getValue().isSelectable()).isFalse();
|
assertThat(preferenceCaptor.getValue().isSelectable()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void captivePortal_shouldShowSignInButton() {
|
||||||
|
reset(mockSignInButton);
|
||||||
|
InOrder inOrder = inOrder(mockSignInButton);
|
||||||
|
mController.onResume();
|
||||||
|
inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
NetworkCapabilities nc = new NetworkCapabilities();
|
||||||
|
nc.clearAll();
|
||||||
|
nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
|
||||||
|
|
||||||
|
NetworkCallback callback = mCallbackCaptor.getValue();
|
||||||
|
callback.onCapabilitiesChanged(mockNetwork, nc);
|
||||||
|
inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
nc = new NetworkCapabilities(nc);
|
||||||
|
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
|
||||||
|
callback.onCapabilitiesChanged(mockNetwork, nc);
|
||||||
|
inOrder.verify(mockSignInButton).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
nc = new NetworkCapabilities(nc);
|
||||||
|
nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
|
||||||
|
callback.onCapabilitiesChanged(mockNetwork, nc);
|
||||||
|
inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignInButton_shouldStartCaptivePortalApp() {
|
||||||
|
mController.onResume();
|
||||||
|
|
||||||
|
ArgumentCaptor<OnClickListener> captor = ArgumentCaptor.forClass(OnClickListener.class);
|
||||||
|
verify(mockSignInButton).setOnClickListener(captor.capture());
|
||||||
|
captor.getValue().onClick(mockSignInButton);
|
||||||
|
verify(mockConnectivityManagerWrapper).startCaptivePortalApp(mockNetwork);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user