From 8474a9c877deac8760e4dd663f8fbd2ceb65cc5e Mon Sep 17 00:00:00 2001 From: Sundeep Ghuman Date: Thu, 6 Apr 2017 17:56:09 -0700 Subject: [PATCH] Add a broadcast receiver to WifiDetailsPreferenceController. This allows the WifiNetworkDetailsFragment to update dynamically based on network and connection changes. Bug: b/36278407 Test: make RunSettingsRoboTests Change-Id: I388cf9842a144e45b68f2d173c7b29f347226b78 --- .../WifiDetailPreferenceController.java | 112 +++++++++++++----- .../details/WifiNetworkDetailsFragment.java | 6 +- .../WifiDetailPreferenceControllerTest.java | 90 +++++++++++--- 3 files changed, 159 insertions(+), 49 deletions(-) diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index faa2a77a184..e8bca376c93 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -15,7 +15,11 @@ */ package com.android.settings.wifi.details; +import android.app.Fragment; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.IpPrefix; @@ -39,6 +43,7 @@ import com.android.settings.R; import com.android.settings.core.PreferenceController; import com.android.settings.core.lifecycle.Lifecycle; import com.android.settings.core.lifecycle.LifecycleObserver; +import com.android.settings.core.lifecycle.events.OnPause; import com.android.settings.core.lifecycle.events.OnResume; import com.android.settings.wifi.WifiDetailPreference; import com.android.settingslib.wifi.AccessPoint; @@ -55,8 +60,9 @@ import java.util.StringJoiner; * {@link WifiNetworkDetailsFragment}. */ public class WifiDetailPreferenceController extends PreferenceController implements - LifecycleObserver, OnResume { + LifecycleObserver, OnPause, OnResume { private static final String TAG = "WifiDetailsPrefCtrl"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTION_DETAIL_PREF = "connection_detail"; @@ -82,14 +88,15 @@ public class WifiDetailPreferenceController extends PreferenceController impleme static final String KEY_IPV6_ADDRESS_CATEGORY = "ipv6_details_category"; private AccessPoint mAccessPoint; + private final ConnectivityManager mConnectivityManager; + private final Fragment mFragment; private NetworkInfo mNetworkInfo; private Context mPrefContext; private int mRssi; private String[] mSignalStr; - private WifiConfiguration mWifiConfig; + private final WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; - private final ConnectivityManager mConnectivityManager; // Preferences - in order of appearance private Preference mConnectionDetailPref; @@ -104,18 +111,39 @@ public class WifiDetailPreferenceController extends PreferenceController impleme private WifiDetailPreference mDnsPref; private PreferenceCategory mIpv6AddressCategory; - public WifiDetailPreferenceController(AccessPoint accessPoint, Context context, - Lifecycle lifecycle, WifiManager wifiManager, ConnectivityManager connectivityManager) { + private final IntentFilter mFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case WifiManager.NETWORK_STATE_CHANGED_ACTION: + case WifiManager.RSSI_CHANGED_ACTION: + updateInfo(); + } + } + }; + + public WifiDetailPreferenceController( + AccessPoint accessPoint, + ConnectivityManager connectivityManager, + Context context, + Fragment fragment, + Lifecycle lifecycle, + WifiManager wifiManager) { super(context); mAccessPoint = accessPoint; + mConnectivityManager = connectivityManager; + mFragment = fragment; mNetworkInfo = accessPoint.getNetworkInfo(); mRssi = accessPoint.getRssi(); mSignalStr = context.getResources().getStringArray(R.array.wifi_signal); mWifiConfig = accessPoint.getConfig(); mWifiManager = wifiManager; - mConnectivityManager = connectivityManager; - mWifiInfo = wifiManager.getConnectionInfo(); + + mFilter = new IntentFilter(); + mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); lifecycle.addObserver(this); } @@ -163,39 +191,33 @@ public class WifiDetailPreferenceController extends PreferenceController impleme @Override public void onResume() { - mWifiInfo = mWifiManager.getConnectionInfo(); + updateInfo(); - refreshFromWifiInfo(); - setIpText(); + mContext.registerReceiver(mReceiver, mFilter); } - private void refreshFromWifiInfo() { - if (mWifiInfo == null) { + @Override + public void onPause() { + mContext.unregisterReceiver(mReceiver); + } + + private void updateInfo() { + mNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork()); + mWifiInfo = mWifiManager.getConnectionInfo(); + if (mNetworkInfo == null || mWifiInfo == null) { + exitActivity(); return; } - mAccessPoint.update(mWifiConfig, mWifiInfo, mNetworkInfo); - int iconSignalLevel = WifiManager.calculateSignalLevel( - mWifiInfo.getRssi(), WifiManager.RSSI_LEVELS); - Drawable wifiIcon = NetworkBadging.getWifiIcon( - iconSignalLevel, NetworkBadging.BADGING_NONE, mContext.getTheme()).mutate(); + refreshNetworkState(); - // Connected Header Pref - mConnectionDetailPref.setIcon(wifiIcon); - mConnectionDetailPref.setTitle(mAccessPoint.getSettingsSummary()); + // Update Connection Header icon and Signal Strength Preference + mRssi = mWifiInfo.getRssi(); + refreshRssiViews(); // MAC Address Pref mMacAddressPref.setDetailText(mWifiInfo.getMacAddress()); - // Signal Strength Pref - Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); - wifiIconDark.setTint(mContext.getResources().getColor( - R.color.wifi_details_icon_color, mContext.getTheme())); - mSignalStrengthPref.setIcon(wifiIconDark); - - int summarySignalLevel = mAccessPoint.getLevel(); - mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]); - // Link Speed Pref int linkSpeedMbps = mWifiInfo.getLinkSpeed(); mLinkSpeedPref.setVisible(linkSpeedMbps >= 0); @@ -215,6 +237,37 @@ public class WifiDetailPreferenceController extends PreferenceController impleme Log.e(TAG, "Unexpected frequency " + frequency); } mFrequencyPref.setDetailText(band); + + setIpText(); + } + + private void exitActivity() { + if (DEBUG) { + Log.d(TAG, "Exiting the WifiNetworkDetailsPage"); + } + mFragment.getActivity().finish(); + } + + private void refreshNetworkState() { + mAccessPoint.update(mWifiConfig, mWifiInfo, mNetworkInfo); + mConnectionDetailPref.setTitle(mAccessPoint.getSettingsSummary()); + } + + private void refreshRssiViews() { + int iconSignalLevel = WifiManager.calculateSignalLevel( + mRssi, WifiManager.RSSI_LEVELS); + Drawable wifiIcon = NetworkBadging.getWifiIcon( + iconSignalLevel, NetworkBadging.BADGING_NONE, mContext.getTheme()).mutate(); + + mConnectionDetailPref.setIcon(wifiIcon); + + Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); + wifiIconDark.setTint(mContext.getResources().getColor( + R.color.wifi_details_icon_color, mContext.getTheme())); + mSignalStrengthPref.setIcon(wifiIconDark); + + int summarySignalLevel = mAccessPoint.getLevel(); + mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]); } private void setIpText() { @@ -321,5 +374,6 @@ public class WifiDetailPreferenceController extends PreferenceController impleme mWifiManager.forget(mWifiConfig.networkId, null /* action listener */); } } + mFragment.getActivity().finish(); } } diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index ebd11434ce4..adcfcc0b3ab 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -69,7 +69,6 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private void forgetNetwork() { mMetricsFeatureProvider.action(getActivity(), MetricsProto.MetricsEvent.ACTION_WIFI_FORGET); mWifiDetailPreferenceController.forgetNetwork(); - getActivity().finish(); } @Override @@ -91,10 +90,11 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { protected List getPreferenceControllers(Context context) { mWifiDetailPreferenceController = new WifiDetailPreferenceController( mAccessPoint, + context.getSystemService(ConnectivityManager.class), context, + this, getLifecycle(), - context.getSystemService(WifiManager.class), - context.getSystemService(ConnectivityManager.class)); + context.getSystemService(WifiManager.class)); ArrayList controllers = new ArrayList(1); controllers.add(mWifiDetailPreferenceController); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 7cb69ea02dd..efe0c1c5408 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -24,7 +24,9 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.IpPrefix; @@ -56,9 +58,6 @@ 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; @@ -79,12 +78,14 @@ public class WifiDetailPreferenceControllerTest { private PreferenceScreen mockScreen; @Mock private AccessPoint mockAccessPoint; - @Mock private WifiManager mockWifiManager; + @Mock private Activity mockActivity; @Mock private ConnectivityManager mockConnectivityManager; + @Mock private Network mockNetwork; @Mock private NetworkInfo mockNetworkInfo; @Mock private WifiConfiguration mockWifiConfig; @Mock private WifiInfo mockWifiInfo; - @Mock private Network mockNetwork; + @Mock private WifiNetworkDetailsFragment mockFragment; + @Mock private WifiManager mockWifiManager; @Mock private Preference mockConnectionDetailPref; @Mock private WifiDetailPreference mockSignalStrengthPref; @@ -122,6 +123,9 @@ public class WifiDetailPreferenceControllerTest { when(mockAccessPoint.getRssi()).thenReturn(RSSI); when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY); + when(mockConnectivityManager.getNetworkInfo(any(Network.class))) + .thenReturn(mockNetworkInfo); + when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED); when(mockWifiInfo.getRssi()).thenReturn(RSSI); when(mockWifiInfo.getMacAddress()).thenReturn(MAC_ADDRESS); @@ -131,12 +135,23 @@ public class WifiDetailPreferenceControllerTest { mLinkProperties = new LinkProperties(); when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(mLinkProperties); - mController = new WifiDetailPreferenceController( - mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); + when(mockFragment.getActivity()).thenReturn(mockActivity); + + mController = newWifiDetailPreferenceController(); setupMockedPreferenceScreen(); } + private WifiDetailPreferenceController newWifiDetailPreferenceController() { + return new WifiDetailPreferenceController( + mockAccessPoint, + mockConnectivityManager, + mContext, + mockFragment, + mLifecycle, + mockWifiManager); + } + private void setupMockedPreferenceScreen() { when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF)) .thenReturn(mockConnectionDetailPref); @@ -175,11 +190,17 @@ public class WifiDetailPreferenceControllerTest { } @Test - public void latestWifiInfoAndConfig_shouldBeFetchedOnResume() { + public void latestWifiInfo_shouldBeFetchedOnResume() { mController.onResume(); - // Once in construction, once in onResume - verify(mockWifiManager, times(2)).getConnectionInfo(); + verify(mockWifiManager, times(1)).getConnectionInfo(); + } + + @Test + public void latestNetworkInfo_shouldBeFetchedOnResume() { + mController.onResume(); + + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); } @Test @@ -321,9 +342,9 @@ public class WifiDetailPreferenceControllerTest { @Test public void canForgetNetwork_noNetwork() { when(mockAccessPoint.getConfig()).thenReturn(null); - - mController = new WifiDetailPreferenceController( - mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); + mController = newWifiDetailPreferenceController(); + mController.displayPreference(mockScreen); + mController.onResume(); assertThat(mController.canForgetNetwork()).isFalse(); } @@ -332,9 +353,9 @@ public class WifiDetailPreferenceControllerTest { public void canForgetNetwork_ephemeral() { when(mockWifiInfo.isEphemeral()).thenReturn(true); when(mockAccessPoint.getConfig()).thenReturn(null); - - mController = new WifiDetailPreferenceController( - mockAccessPoint, mContext, mLifecycle, mockWifiManager, mockConnectivityManager); + mController = newWifiDetailPreferenceController(); + mController.displayPreference(mockScreen); + mController.onResume(); assertThat(mController.canForgetNetwork()).isTrue(); } @@ -347,10 +368,11 @@ public class WifiDetailPreferenceControllerTest { @Test public void forgetNetwork_ephemeral() { String ssid = "ssid"; - when(mockWifiInfo.isEphemeral()).thenReturn(true); when(mockWifiInfo.getSSID()).thenReturn(ssid); + mController.onResume(); + mController.forgetNetwork(); verify(mockWifiManager).disableEphemeralNetwork(ssid); @@ -364,4 +386,38 @@ public class WifiDetailPreferenceControllerTest { verify(mockWifiManager).forget(mockWifiConfig.networkId, null); } + + @Test + public void networkStateChangedIntent_shouldRefetchInfo() { + mController.onResume(); + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(1)).getConnectionInfo(); + + mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); + + verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(2)).getConnectionInfo(); + } + + @Test + public void rssiChangedIntent_shouldRefetchInfo() { + mController.onResume(); + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(1)).getConnectionInfo(); + + mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION)); + + verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(2)).getConnectionInfo(); + } + + @Test + public void networkDisconnectdState_shouldFinishActivity() { + mController.onResume(); + + when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(null); + mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); + + verify(mockActivity).finish(); + } }