Loading res/values/strings.xml +2 −2 Original line number Diff line number Diff line Loading @@ -1886,11 +1886,11 @@ <!-- Wifi Network Details --> <!-- Wifi details preference title to display router IP subnet mask --> <string name="wifi_details_subnet_mask">Subnet Mask</string> <string name="wifi_details_subnet_mask">Subnet mask</string> <!-- Wifi details preference title to display router DNS info --> <string name="wifi_details_dns">DNS</string> <!-- Wifi details preference category title for IPv6 information --> <string name="wifi_details_ipv6_address_header">IPv6 Addresses</string> <string name="wifi_details_ipv6_address_header">IPv6 addresses</string> <!-- Wifi saved access points. Used as a label under the shortcut icon that goes to Wifi saved access points. [CHAR LIMIT=20] --> <string name="wifi_saved_access_points_label">Saved networks</string> Loading res/xml/wifi_network_details_fragment.xml +5 −1 Original line number Diff line number Diff line Loading @@ -54,12 +54,16 @@ <PreferenceCategory android:key="ip_details_category" android:title="@string/wifi_setup_detail"> <com.android.settings.wifi.WifiDetailPreference android:key="mac_address" android:title="@string/wifi_advanced_mac_address_title" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference android:key="ip_address" android:title="@string/wifi_ip_address" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference android:key="router" android:key="gateway" android:title="@string/wifi_gateway" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference Loading src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +72 −37 Original line number Diff line number Diff line Loading @@ -18,18 +18,20 @@ package com.android.settings.wifi.details; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkBadging; import android.net.NetworkInfo; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; Loading @@ -44,7 +46,9 @@ import com.android.settingslib.wifi.AccessPoint; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import java.util.StringJoiner; /** * Controller for logic pertaining to displaying Wifi information for the Loading @@ -65,9 +69,11 @@ public class WifiDetailPreferenceController extends PreferenceController impleme @VisibleForTesting static final String KEY_SECURITY_PREF = "security"; @VisibleForTesting static final String KEY_MAC_ADDRESS_PREF = "mac_address"; @VisibleForTesting static final String KEY_IP_ADDRESS_PREF = "ip_address"; @VisibleForTesting static final String KEY_ROUTER_PREF = "router"; static final String KEY_GATEWAY_PREF = "gateway"; @VisibleForTesting static final String KEY_SUBNET_MASK_PREF = "subnet_mask"; @VisibleForTesting Loading @@ -83,6 +89,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; private final ConnectivityManager mConnectivityManager; // Preferences - in order of appearance private Preference mConnectionDetailPref; Loading @@ -90,14 +97,15 @@ public class WifiDetailPreferenceController extends PreferenceController impleme private WifiDetailPreference mLinkSpeedPref; private WifiDetailPreference mFrequencyPref; private WifiDetailPreference mSecurityPref; private WifiDetailPreference mMacAddressPref; private WifiDetailPreference mIpAddressPref; private WifiDetailPreference mRouterPref; private WifiDetailPreference mGatewayPref; private WifiDetailPreference mSubnetPref; private WifiDetailPreference mDnsPref; private PreferenceCategory mIpv6AddressCategory; public WifiDetailPreferenceController(AccessPoint accessPoint, Context context, Lifecycle lifecycle, WifiManager wifiManager) { Lifecycle lifecycle, WifiManager wifiManager, ConnectivityManager connectivityManager) { super(context); mAccessPoint = accessPoint; Loading @@ -106,6 +114,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mSignalStr = context.getResources().getStringArray(R.array.wifi_signal); mWifiConfig = accessPoint.getConfig(); mWifiManager = wifiManager; mConnectivityManager = connectivityManager; mWifiInfo = wifiManager.getConnectionInfo(); lifecycle.addObserver(this); Loading Loading @@ -136,8 +145,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mFrequencyPref = (WifiDetailPreference) screen.findPreference(KEY_FREQUENCY_PREF); mSecurityPref = (WifiDetailPreference) screen.findPreference(KEY_SECURITY_PREF); mMacAddressPref = (WifiDetailPreference) screen.findPreference(KEY_MAC_ADDRESS_PREF); mIpAddressPref = (WifiDetailPreference) screen.findPreference(KEY_IP_ADDRESS_PREF); mRouterPref = (WifiDetailPreference) screen.findPreference(KEY_ROUTER_PREF); mGatewayPref = (WifiDetailPreference) screen.findPreference(KEY_GATEWAY_PREF); mSubnetPref = (WifiDetailPreference) screen.findPreference(KEY_SUBNET_MASK_PREF); mDnsPref = (WifiDetailPreference) screen.findPreference(KEY_DNS_PREF); Loading Loading @@ -174,6 +184,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mConnectionDetailPref.setIcon(wifiIcon); mConnectionDetailPref.setTitle(mAccessPoint.getSettingsSummary()); // MAC Address Pref mMacAddressPref.setDetailText(mWifiInfo.getMacAddress()); // Signal Strength Pref Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); wifiIconDark.setTint(mContext.getResources().getColor( Loading @@ -184,6 +197,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]); // Link Speed Pref int linkSpeedMbps = mWifiInfo.getLinkSpeed(); mLinkSpeedPref.setVisible(linkSpeedMbps >= 0); mLinkSpeedPref.setDetailText(mContext.getString( R.string.link_speed, mWifiInfo.getLinkSpeed())); Loading @@ -203,67 +218,87 @@ public class WifiDetailPreferenceController extends PreferenceController impleme } private void setIpText() { // Reset all fields mIpv6AddressCategory.removeAll(); mIpv6AddressCategory.setVisible(false); mIpAddressPref.setVisible(false); mSubnetPref.setVisible(false); mGatewayPref.setVisible(false); mDnsPref.setVisible(false); Network currentNetwork = mWifiManager.getCurrentNetwork(); if (currentNetwork == null) { return; } ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); LinkProperties prop = cm.getLinkProperties(currentNetwork); List<InetAddress> addresses = prop.getAllAddresses(); LinkProperties linkProperties = mConnectivityManager.getLinkProperties(currentNetwork); if (linkProperties == null) { return; } List<InetAddress> addresses = linkProperties.getAddresses(); // Set ip addresses // Set IPv4 and Ipv6 addresses for (int i = 0; i < addresses.size(); i++) { InetAddress addr = addresses.get(i); if (addr instanceof Inet4Address) { mIpAddressPref.setDetailText(addr.getHostAddress()); mIpAddressPref.setVisible(true); } else if (addr instanceof Inet6Address) { String ip = addr.getHostAddress(); Preference pref = new Preference(mPrefContext); pref.setKey(ip); pref.setTitle(ip); mIpv6AddressCategory.addPreference(pref); mIpv6AddressCategory.setVisible(true); // TODO(sghuman): Make sure to mIpv6AddressCategory.setVisible(true); } } String subnetMask = null; String router; DhcpInfo dhcp = mWifiManager.getDhcpInfo(); if (dhcp != null) { if (dhcp.netmask == 0) { Log.e(TAG, "invalid netmask value of 0 for DhcpInfo: " + dhcp); mSubnetPref.setVisible(false); } else { subnetMask = NetworkUtils.intToInetAddress(dhcp.netmask).getHostAddress(); mSubnetPref.setVisible(true); // Set up IPv4 gateway and subnet mask String gateway = null; String subnet = null; for (RouteInfo routeInfo : linkProperties.getRoutes()) { if (routeInfo.hasGateway() && routeInfo.getGateway() instanceof Inet4Address) { gateway = routeInfo.getGateway().getHostAddress(); } IpPrefix ipPrefix = routeInfo.getDestination(); if (ipPrefix != null && ipPrefix.getAddress() instanceof Inet4Address && ipPrefix.getPrefixLength() > 0) { subnet = ipv4PrefixLengthToSubnetMask(ipPrefix.getPrefixLength()); } } router = NetworkUtils.intToInetAddress(dhcp.gateway).getHostAddress(); } else { // Statically configured IP // TODO(sghuman): How do we get subnet mask for static ips? mSubnetPref.setVisible(false); if (!TextUtils.isEmpty(subnet)) { mSubnetPref.setDetailText(subnet); mSubnetPref.setVisible(true); } router = mWifiManager.getWifiApConfiguration().getStaticIpConfiguration().gateway .getHostAddress(); if (!TextUtils.isEmpty(gateway)) { mGatewayPref.setDetailText(gateway); mGatewayPref.setVisible(true); } mRouterPref.setDetailText(router); mSubnetPref.setDetailText(subnetMask); // Set DNS addresses = prop.getDnsServers(); StringBuilder builder = new StringBuilder(); // Set IPv4 DNS addresses StringJoiner stringJoiner = new StringJoiner(","); for (InetAddress dnsServer : linkProperties.getDnsServers()) { if (dnsServer instanceof Inet4Address) { stringJoiner.add(dnsServer.getHostAddress()); } } String dnsText = stringJoiner.toString(); if (!dnsText.isEmpty()) { mDnsPref.setDetailText(dnsText); mDnsPref.setVisible(true); } } // addresses is backed by an ArrayList, so use a hand-written iterator for performance gains for (int i = 0; i < addresses.size(); i++) { if (i > 0) builder.append(", "); builder.append(addresses.get(i).getHostAddress()); private static String ipv4PrefixLengthToSubnetMask(int prefixLength) { try { InetAddress all = InetAddress.getByAddress( new byte[]{(byte) 255, (byte) 255, (byte) 255, (byte) 255}); return NetworkUtils.getNetworkPart(all, prefixLength).getHostAddress(); } catch (UnknownHostException e) { return null; } mDnsPref.setDetailText(builder.toString()); } /** Loading src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +3 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.wifi.details; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.os.Bundle; import android.widget.Button; Loading Loading @@ -45,13 +46,10 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private AccessPoint mAccessPoint; private Button mForgetButton; private WifiDetailPreferenceController mWifiDetailPreferenceController; private WifiManager mWifiManager; @Override public void onAttach(Context context) { mAccessPoint = new AccessPoint(context, getArguments()); mWifiManager = context.getSystemService(WifiManager.class); super.onAttach(context); } Loading Loading @@ -95,7 +93,8 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { mAccessPoint, context, getLifecycle(), mWifiManager); context.getSystemService(WifiManager.class), context.getSystemService(ConnectivityManager.class)); ArrayList<PreferenceController> controllers = new ArrayList(1); controllers.add(mWifiDetailPreferenceController); Loading tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +131 −7 Original line number Diff line number Diff line Loading @@ -18,14 +18,22 @@ package com.android.settings.wifi.details; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkBadging; import android.net.NetworkInfo; import android.net.RouteInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; Loading @@ -46,8 +54,14 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import java.net.InetAddress; import java.net.UnknownHostException; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) Loading @@ -56,28 +70,35 @@ public class WifiDetailPreferenceControllerTest { private static final int LEVEL = 1; private static final int RSSI = -55; private static final int LINK_SPEED = 123; private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS; private static final String SECURITY = "None"; private InetAddress mIpv4Address; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PreferenceScreen mockScreen; @Mock private AccessPoint mockAccessPoint; @Mock private WifiManager mockWifiManager; @Mock private ConnectivityManager mockConnectivityManager; @Mock private NetworkInfo mockNetworkInfo; @Mock private WifiConfiguration mockWifiConfig; @Mock private WifiInfo mockWifiInfo; @Mock private Network mockNetwork; @Mock private Preference mockConnectionDetailPref; @Mock private WifiDetailPreference mockSignalStrengthPref; @Mock private WifiDetailPreference mockLinkSpeedPref; @Mock private WifiDetailPreference mockFrequencyPref; @Mock private WifiDetailPreference mockSecurityPref; @Mock private WifiDetailPreference mockMacAddressPref; @Mock private WifiDetailPreference mockIpAddressPref; @Mock private WifiDetailPreference mockRouterPref; @Mock private WifiDetailPreference mockGatewayPref; @Mock private WifiDetailPreference mockSubnetPref; @Mock private WifiDetailPreference mockDnsPref; @Mock private PreferenceCategory mockIpv6AddressCategory; private LinkProperties mLinkProperties; private Context mContext = RuntimeEnvironment.application; private Lifecycle mLifecycle; private WifiDetailPreferenceController mController; Loading @@ -88,6 +109,13 @@ public class WifiDetailPreferenceControllerTest { mLifecycle = new Lifecycle(); try { mIpv4Address = InetAddress.getByAddress( new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255 }); } catch (UnknownHostException e) { throw new RuntimeException(e); } when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig); when(mockAccessPoint.getLevel()).thenReturn(LEVEL); when(mockAccessPoint.getNetworkInfo()).thenReturn(mockNetworkInfo); Loading @@ -96,16 +124,20 @@ public class WifiDetailPreferenceControllerTest { when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED); when(mockWifiInfo.getRssi()).thenReturn(RSSI); when(mockWifiInfo.getMacAddress()).thenReturn(MAC_ADDRESS); when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo); when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork); mLinkProperties = new LinkProperties(); when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(mLinkProperties); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); setupMockedPreferenceScreen(); } private void setupMockedPreferenceScreen() { when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF)) .thenReturn(mockConnectionDetailPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF)) Loading @@ -116,10 +148,12 @@ public class WifiDetailPreferenceControllerTest { .thenReturn(mockFrequencyPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF)) .thenReturn(mockSecurityPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF)) .thenReturn(mockMacAddressPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF)) .thenReturn(mockIpAddressPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_ROUTER_PREF)) .thenReturn(mockRouterPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_GATEWAY_PREF)) .thenReturn(mockGatewayPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SUBNET_MASK_PREF)) .thenReturn(mockSubnetPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_DNS_PREF)) Loading Loading @@ -194,12 +228,102 @@ public class WifiDetailPreferenceControllerTest { verify(mockLinkSpeedPref).setDetailText(expectedLinkSpeed); } @Test public void linkSpeedPref_shouldNotShowIfNotSet() { when(mockWifiInfo.getLinkSpeed()).thenReturn(-1); mController.onResume(); verify(mockLinkSpeedPref).setVisible(false); } @Test public void macAddressPref_shouldHaveDetailTextSet() { mController.onResume(); verify(mockMacAddressPref).setDetailText(MAC_ADDRESS); } @Test public void ipAddressPref_shouldHaveDetailTextSet() { LinkAddress ipv4Address = new LinkAddress(mIpv4Address, 32); mLinkProperties.addLinkAddress(ipv4Address); mController.onResume(); verify(mockIpAddressPref).setDetailText(mIpv4Address.getHostAddress()); } @Test public void gatewayAndSubnet_shouldHaveDetailTextSet() { int prefixLength = 24; IpPrefix subnet = new IpPrefix(mIpv4Address, prefixLength); InetAddress gateway = mIpv4Address; mLinkProperties.addRoute(new RouteInfo(subnet, gateway)); mController.onResume(); verify(mockSubnetPref).setDetailText("255.255.255.0"); verify(mockGatewayPref).setDetailText(mIpv4Address.getHostAddress()); } @Test public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException { mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4})); mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8})); mController.onResume(); verify(mockDnsPref).setDetailText("8.8.4.4,8.8.8.8"); } @Test public void noCurrentNetwork_allIpDetailsHidden() { when(mockWifiManager.getCurrentNetwork()).thenReturn(null); reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref); mController.onResume(); verify(mockIpv6AddressCategory).setVisible(false); 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 public void noLinkProperties_allIpDetailsHidden() { when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null); reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref); mController.onResume(); verify(mockIpv6AddressCategory).setVisible(false); 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 public void canForgetNetwork_noNetwork() { when(mockAccessPoint.getConfig()).thenReturn(null); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); assertThat(mController.canForgetNetwork()).isFalse(); } Loading @@ -210,7 +334,7 @@ public class WifiDetailPreferenceControllerTest { when(mockAccessPoint.getConfig()).thenReturn(null); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); assertThat(mController.canForgetNetwork()).isTrue(); } Loading Loading
res/values/strings.xml +2 −2 Original line number Diff line number Diff line Loading @@ -1886,11 +1886,11 @@ <!-- Wifi Network Details --> <!-- Wifi details preference title to display router IP subnet mask --> <string name="wifi_details_subnet_mask">Subnet Mask</string> <string name="wifi_details_subnet_mask">Subnet mask</string> <!-- Wifi details preference title to display router DNS info --> <string name="wifi_details_dns">DNS</string> <!-- Wifi details preference category title for IPv6 information --> <string name="wifi_details_ipv6_address_header">IPv6 Addresses</string> <string name="wifi_details_ipv6_address_header">IPv6 addresses</string> <!-- Wifi saved access points. Used as a label under the shortcut icon that goes to Wifi saved access points. [CHAR LIMIT=20] --> <string name="wifi_saved_access_points_label">Saved networks</string> Loading
res/xml/wifi_network_details_fragment.xml +5 −1 Original line number Diff line number Diff line Loading @@ -54,12 +54,16 @@ <PreferenceCategory android:key="ip_details_category" android:title="@string/wifi_setup_detail"> <com.android.settings.wifi.WifiDetailPreference android:key="mac_address" android:title="@string/wifi_advanced_mac_address_title" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference android:key="ip_address" android:title="@string/wifi_ip_address" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference android:key="router" android:key="gateway" android:title="@string/wifi_gateway" android:selectable="false"/> <com.android.settings.wifi.WifiDetailPreference Loading
src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +72 −37 Original line number Diff line number Diff line Loading @@ -18,18 +18,20 @@ package com.android.settings.wifi.details; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkBadging; import android.net.NetworkInfo; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; Loading @@ -44,7 +46,9 @@ import com.android.settingslib.wifi.AccessPoint; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import java.util.StringJoiner; /** * Controller for logic pertaining to displaying Wifi information for the Loading @@ -65,9 +69,11 @@ public class WifiDetailPreferenceController extends PreferenceController impleme @VisibleForTesting static final String KEY_SECURITY_PREF = "security"; @VisibleForTesting static final String KEY_MAC_ADDRESS_PREF = "mac_address"; @VisibleForTesting static final String KEY_IP_ADDRESS_PREF = "ip_address"; @VisibleForTesting static final String KEY_ROUTER_PREF = "router"; static final String KEY_GATEWAY_PREF = "gateway"; @VisibleForTesting static final String KEY_SUBNET_MASK_PREF = "subnet_mask"; @VisibleForTesting Loading @@ -83,6 +89,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; private final ConnectivityManager mConnectivityManager; // Preferences - in order of appearance private Preference mConnectionDetailPref; Loading @@ -90,14 +97,15 @@ public class WifiDetailPreferenceController extends PreferenceController impleme private WifiDetailPreference mLinkSpeedPref; private WifiDetailPreference mFrequencyPref; private WifiDetailPreference mSecurityPref; private WifiDetailPreference mMacAddressPref; private WifiDetailPreference mIpAddressPref; private WifiDetailPreference mRouterPref; private WifiDetailPreference mGatewayPref; private WifiDetailPreference mSubnetPref; private WifiDetailPreference mDnsPref; private PreferenceCategory mIpv6AddressCategory; public WifiDetailPreferenceController(AccessPoint accessPoint, Context context, Lifecycle lifecycle, WifiManager wifiManager) { Lifecycle lifecycle, WifiManager wifiManager, ConnectivityManager connectivityManager) { super(context); mAccessPoint = accessPoint; Loading @@ -106,6 +114,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mSignalStr = context.getResources().getStringArray(R.array.wifi_signal); mWifiConfig = accessPoint.getConfig(); mWifiManager = wifiManager; mConnectivityManager = connectivityManager; mWifiInfo = wifiManager.getConnectionInfo(); lifecycle.addObserver(this); Loading Loading @@ -136,8 +145,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mFrequencyPref = (WifiDetailPreference) screen.findPreference(KEY_FREQUENCY_PREF); mSecurityPref = (WifiDetailPreference) screen.findPreference(KEY_SECURITY_PREF); mMacAddressPref = (WifiDetailPreference) screen.findPreference(KEY_MAC_ADDRESS_PREF); mIpAddressPref = (WifiDetailPreference) screen.findPreference(KEY_IP_ADDRESS_PREF); mRouterPref = (WifiDetailPreference) screen.findPreference(KEY_ROUTER_PREF); mGatewayPref = (WifiDetailPreference) screen.findPreference(KEY_GATEWAY_PREF); mSubnetPref = (WifiDetailPreference) screen.findPreference(KEY_SUBNET_MASK_PREF); mDnsPref = (WifiDetailPreference) screen.findPreference(KEY_DNS_PREF); Loading Loading @@ -174,6 +184,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mConnectionDetailPref.setIcon(wifiIcon); mConnectionDetailPref.setTitle(mAccessPoint.getSettingsSummary()); // MAC Address Pref mMacAddressPref.setDetailText(mWifiInfo.getMacAddress()); // Signal Strength Pref Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); wifiIconDark.setTint(mContext.getResources().getColor( Loading @@ -184,6 +197,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]); // Link Speed Pref int linkSpeedMbps = mWifiInfo.getLinkSpeed(); mLinkSpeedPref.setVisible(linkSpeedMbps >= 0); mLinkSpeedPref.setDetailText(mContext.getString( R.string.link_speed, mWifiInfo.getLinkSpeed())); Loading @@ -203,67 +218,87 @@ public class WifiDetailPreferenceController extends PreferenceController impleme } private void setIpText() { // Reset all fields mIpv6AddressCategory.removeAll(); mIpv6AddressCategory.setVisible(false); mIpAddressPref.setVisible(false); mSubnetPref.setVisible(false); mGatewayPref.setVisible(false); mDnsPref.setVisible(false); Network currentNetwork = mWifiManager.getCurrentNetwork(); if (currentNetwork == null) { return; } ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); LinkProperties prop = cm.getLinkProperties(currentNetwork); List<InetAddress> addresses = prop.getAllAddresses(); LinkProperties linkProperties = mConnectivityManager.getLinkProperties(currentNetwork); if (linkProperties == null) { return; } List<InetAddress> addresses = linkProperties.getAddresses(); // Set ip addresses // Set IPv4 and Ipv6 addresses for (int i = 0; i < addresses.size(); i++) { InetAddress addr = addresses.get(i); if (addr instanceof Inet4Address) { mIpAddressPref.setDetailText(addr.getHostAddress()); mIpAddressPref.setVisible(true); } else if (addr instanceof Inet6Address) { String ip = addr.getHostAddress(); Preference pref = new Preference(mPrefContext); pref.setKey(ip); pref.setTitle(ip); mIpv6AddressCategory.addPreference(pref); mIpv6AddressCategory.setVisible(true); // TODO(sghuman): Make sure to mIpv6AddressCategory.setVisible(true); } } String subnetMask = null; String router; DhcpInfo dhcp = mWifiManager.getDhcpInfo(); if (dhcp != null) { if (dhcp.netmask == 0) { Log.e(TAG, "invalid netmask value of 0 for DhcpInfo: " + dhcp); mSubnetPref.setVisible(false); } else { subnetMask = NetworkUtils.intToInetAddress(dhcp.netmask).getHostAddress(); mSubnetPref.setVisible(true); // Set up IPv4 gateway and subnet mask String gateway = null; String subnet = null; for (RouteInfo routeInfo : linkProperties.getRoutes()) { if (routeInfo.hasGateway() && routeInfo.getGateway() instanceof Inet4Address) { gateway = routeInfo.getGateway().getHostAddress(); } IpPrefix ipPrefix = routeInfo.getDestination(); if (ipPrefix != null && ipPrefix.getAddress() instanceof Inet4Address && ipPrefix.getPrefixLength() > 0) { subnet = ipv4PrefixLengthToSubnetMask(ipPrefix.getPrefixLength()); } } router = NetworkUtils.intToInetAddress(dhcp.gateway).getHostAddress(); } else { // Statically configured IP // TODO(sghuman): How do we get subnet mask for static ips? mSubnetPref.setVisible(false); if (!TextUtils.isEmpty(subnet)) { mSubnetPref.setDetailText(subnet); mSubnetPref.setVisible(true); } router = mWifiManager.getWifiApConfiguration().getStaticIpConfiguration().gateway .getHostAddress(); if (!TextUtils.isEmpty(gateway)) { mGatewayPref.setDetailText(gateway); mGatewayPref.setVisible(true); } mRouterPref.setDetailText(router); mSubnetPref.setDetailText(subnetMask); // Set DNS addresses = prop.getDnsServers(); StringBuilder builder = new StringBuilder(); // Set IPv4 DNS addresses StringJoiner stringJoiner = new StringJoiner(","); for (InetAddress dnsServer : linkProperties.getDnsServers()) { if (dnsServer instanceof Inet4Address) { stringJoiner.add(dnsServer.getHostAddress()); } } String dnsText = stringJoiner.toString(); if (!dnsText.isEmpty()) { mDnsPref.setDetailText(dnsText); mDnsPref.setVisible(true); } } // addresses is backed by an ArrayList, so use a hand-written iterator for performance gains for (int i = 0; i < addresses.size(); i++) { if (i > 0) builder.append(", "); builder.append(addresses.get(i).getHostAddress()); private static String ipv4PrefixLengthToSubnetMask(int prefixLength) { try { InetAddress all = InetAddress.getByAddress( new byte[]{(byte) 255, (byte) 255, (byte) 255, (byte) 255}); return NetworkUtils.getNetworkPart(all, prefixLength).getHostAddress(); } catch (UnknownHostException e) { return null; } mDnsPref.setDetailText(builder.toString()); } /** Loading
src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +3 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.wifi.details; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.os.Bundle; import android.widget.Button; Loading Loading @@ -45,13 +46,10 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private AccessPoint mAccessPoint; private Button mForgetButton; private WifiDetailPreferenceController mWifiDetailPreferenceController; private WifiManager mWifiManager; @Override public void onAttach(Context context) { mAccessPoint = new AccessPoint(context, getArguments()); mWifiManager = context.getSystemService(WifiManager.class); super.onAttach(context); } Loading Loading @@ -95,7 +93,8 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { mAccessPoint, context, getLifecycle(), mWifiManager); context.getSystemService(WifiManager.class), context.getSystemService(ConnectivityManager.class)); ArrayList<PreferenceController> controllers = new ArrayList(1); controllers.add(mWifiDetailPreferenceController); Loading
tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +131 −7 Original line number Diff line number Diff line Loading @@ -18,14 +18,22 @@ package com.android.settings.wifi.details; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkBadging; import android.net.NetworkInfo; import android.net.RouteInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; Loading @@ -46,8 +54,14 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import java.net.InetAddress; import java.net.UnknownHostException; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) Loading @@ -56,28 +70,35 @@ public class WifiDetailPreferenceControllerTest { private static final int LEVEL = 1; private static final int RSSI = -55; private static final int LINK_SPEED = 123; private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS; private static final String SECURITY = "None"; private InetAddress mIpv4Address; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PreferenceScreen mockScreen; @Mock private AccessPoint mockAccessPoint; @Mock private WifiManager mockWifiManager; @Mock private ConnectivityManager mockConnectivityManager; @Mock private NetworkInfo mockNetworkInfo; @Mock private WifiConfiguration mockWifiConfig; @Mock private WifiInfo mockWifiInfo; @Mock private Network mockNetwork; @Mock private Preference mockConnectionDetailPref; @Mock private WifiDetailPreference mockSignalStrengthPref; @Mock private WifiDetailPreference mockLinkSpeedPref; @Mock private WifiDetailPreference mockFrequencyPref; @Mock private WifiDetailPreference mockSecurityPref; @Mock private WifiDetailPreference mockMacAddressPref; @Mock private WifiDetailPreference mockIpAddressPref; @Mock private WifiDetailPreference mockRouterPref; @Mock private WifiDetailPreference mockGatewayPref; @Mock private WifiDetailPreference mockSubnetPref; @Mock private WifiDetailPreference mockDnsPref; @Mock private PreferenceCategory mockIpv6AddressCategory; private LinkProperties mLinkProperties; private Context mContext = RuntimeEnvironment.application; private Lifecycle mLifecycle; private WifiDetailPreferenceController mController; Loading @@ -88,6 +109,13 @@ public class WifiDetailPreferenceControllerTest { mLifecycle = new Lifecycle(); try { mIpv4Address = InetAddress.getByAddress( new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255 }); } catch (UnknownHostException e) { throw new RuntimeException(e); } when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig); when(mockAccessPoint.getLevel()).thenReturn(LEVEL); when(mockAccessPoint.getNetworkInfo()).thenReturn(mockNetworkInfo); Loading @@ -96,16 +124,20 @@ public class WifiDetailPreferenceControllerTest { when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED); when(mockWifiInfo.getRssi()).thenReturn(RSSI); when(mockWifiInfo.getMacAddress()).thenReturn(MAC_ADDRESS); when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo); when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork); mLinkProperties = new LinkProperties(); when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(mLinkProperties); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); setupMockedPreferenceScreen(); } private void setupMockedPreferenceScreen() { when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF)) .thenReturn(mockConnectionDetailPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF)) Loading @@ -116,10 +148,12 @@ public class WifiDetailPreferenceControllerTest { .thenReturn(mockFrequencyPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF)) .thenReturn(mockSecurityPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF)) .thenReturn(mockMacAddressPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF)) .thenReturn(mockIpAddressPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_ROUTER_PREF)) .thenReturn(mockRouterPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_GATEWAY_PREF)) .thenReturn(mockGatewayPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SUBNET_MASK_PREF)) .thenReturn(mockSubnetPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_DNS_PREF)) Loading Loading @@ -194,12 +228,102 @@ public class WifiDetailPreferenceControllerTest { verify(mockLinkSpeedPref).setDetailText(expectedLinkSpeed); } @Test public void linkSpeedPref_shouldNotShowIfNotSet() { when(mockWifiInfo.getLinkSpeed()).thenReturn(-1); mController.onResume(); verify(mockLinkSpeedPref).setVisible(false); } @Test public void macAddressPref_shouldHaveDetailTextSet() { mController.onResume(); verify(mockMacAddressPref).setDetailText(MAC_ADDRESS); } @Test public void ipAddressPref_shouldHaveDetailTextSet() { LinkAddress ipv4Address = new LinkAddress(mIpv4Address, 32); mLinkProperties.addLinkAddress(ipv4Address); mController.onResume(); verify(mockIpAddressPref).setDetailText(mIpv4Address.getHostAddress()); } @Test public void gatewayAndSubnet_shouldHaveDetailTextSet() { int prefixLength = 24; IpPrefix subnet = new IpPrefix(mIpv4Address, prefixLength); InetAddress gateway = mIpv4Address; mLinkProperties.addRoute(new RouteInfo(subnet, gateway)); mController.onResume(); verify(mockSubnetPref).setDetailText("255.255.255.0"); verify(mockGatewayPref).setDetailText(mIpv4Address.getHostAddress()); } @Test public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException { mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4})); mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8})); mController.onResume(); verify(mockDnsPref).setDetailText("8.8.4.4,8.8.8.8"); } @Test public void noCurrentNetwork_allIpDetailsHidden() { when(mockWifiManager.getCurrentNetwork()).thenReturn(null); reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref); mController.onResume(); verify(mockIpv6AddressCategory).setVisible(false); 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 public void noLinkProperties_allIpDetailsHidden() { when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null); reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref); mController.onResume(); verify(mockIpv6AddressCategory).setVisible(false); 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 public void canForgetNetwork_noNetwork() { when(mockAccessPoint.getConfig()).thenReturn(null); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); assertThat(mController.canForgetNetwork()).isFalse(); } Loading @@ -210,7 +334,7 @@ public class WifiDetailPreferenceControllerTest { when(mockAccessPoint.getConfig()).thenReturn(null); mController = new WifiDetailPreferenceController( mockAccessPoint, mContext, mLifecycle, mockWifiManager); mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); assertThat(mController.canForgetNetwork()).isTrue(); } Loading