diff --git a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java index 742edd196dd..12a6d143656 100644 --- a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java +++ b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java @@ -17,32 +17,22 @@ package com.android.settings.wifi; import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkScoreManager; -import android.net.wifi.WifiManager; import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Process; -import android.os.SimpleClock; -import android.os.SystemClock; +import android.util.FeatureFlagUtils; -import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.wifi.details.WifiNetworkDetailsFragment; import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.wifi.WifiEntryPreference; -import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiPickerTracker; - -import java.time.Clock; -import java.time.ZoneOffset; +import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.AccessPointPreference; +import com.android.settingslib.wifi.WifiTracker; +import com.android.settingslib.wifi.WifiTrackerFactory; // TODO(b/151133650): Replace AbstractPreferenceController with BasePreferenceController. /** @@ -50,28 +40,21 @@ import java.time.ZoneOffset; * controller class when there is a wifi connection present. */ public class WifiConnectionPreferenceController extends AbstractPreferenceController implements - WifiPickerTracker.WifiPickerTrackerCallback { + WifiTracker.WifiListener { private static final String TAG = "WifiConnPrefCtrl"; private static final String KEY = "active_wifi_connection"; - // Max age of tracked WifiEntries. - private static final long MAX_SCAN_AGE_MILLIS = 15_000; - // Interval between initiating WifiPickerTracker scans. - private static final long SCAN_INTERVAL_MILLIS = 10_000; - private UpdateListener mUpdateListener; private Context mPrefContext; private String mPreferenceGroupKey; private PreferenceGroup mPreferenceGroup; - @VisibleForTesting - public WifiPickerTracker mWifiPickerTracker; - private WifiEntryPreference mPreference; + private WifiTracker mWifiTracker; + private AccessPointPreference mPreference; + private AccessPointPreference.UserBadgeCache mBadgeCache; private int order; private int mMetricsCategory; - // Worker thread used for WifiPickerTracker work. - private HandlerThread mWorkerThread; /** * Used to notify a parent controller that this controller has changed in availability, or has @@ -99,34 +82,16 @@ public class WifiConnectionPreferenceController extends AbstractPreferenceContro super(context); mUpdateListener = updateListener; mPreferenceGroupKey = preferenceGroupKey; + mWifiTracker = WifiTrackerFactory.create(context, this, lifecycle, true /* includeSaved */, + true /* includeScans */); this.order = order; mMetricsCategory = metricsCategory; - - mWorkerThread = new HandlerThread( - TAG + "{" + Integer.toHexString(System.identityHashCode(this)) + "}", - Process.THREAD_PRIORITY_BACKGROUND); - mWorkerThread.start(); - final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) { - @Override - public long millis() { - return SystemClock.elapsedRealtime(); - } - }; - mWifiPickerTracker = new WifiPickerTracker(lifecycle, context, - context.getSystemService(WifiManager.class), - context.getSystemService(ConnectivityManager.class), - context.getSystemService(NetworkScoreManager.class), - new Handler(Looper.getMainLooper()), - mWorkerThread.getThreadHandler(), - elapsedRealtimeClock, - MAX_SCAN_AGE_MILLIS, - SCAN_INTERVAL_MILLIS, - this); + mBadgeCache = new AccessPointPreference.UserBadgeCache(context.getPackageManager()); } @Override public boolean isAvailable() { - return mWifiPickerTracker.getConnectedWifiEntry() != null; + return mWifiTracker.isConnected() && getCurrentAccessPoint() != null; } @Override @@ -142,69 +107,88 @@ public class WifiConnectionPreferenceController extends AbstractPreferenceContro update(); } - private void updatePreference(WifiEntry wifiEntry) { + private AccessPoint getCurrentAccessPoint() { + for (AccessPoint accessPoint : mWifiTracker.getAccessPoints()) { + if (accessPoint.isActive()) { + return accessPoint; + } + } + return null; + } + + private void updatePreference(AccessPoint accessPoint) { if (mPreference != null) { mPreferenceGroup.removePreference(mPreference); mPreference = null; } - if (wifiEntry == null || mPrefContext == null) { + if (accessPoint == null) { return; } + if (mPrefContext != null) { + mPreference = new AccessPointPreference(accessPoint, mPrefContext, mBadgeCache, + R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */); + mPreference.setKey(KEY); + mPreference.refresh(); + mPreference.setOrder(order); - mPreference = new WifiEntryPreference(mPrefContext, wifiEntry); - mPreference.setKey(KEY); - mPreference.refresh(); - mPreference.setOrder(order); - mPreference.setOnPreferenceClickListener(pref -> { - final Bundle args = new Bundle(); - args.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, - wifiEntry.getKey()); - new SubSettingLauncher(mPrefContext) - .setTitleRes(R.string.pref_title_network_details) - .setDestination(WifiNetworkDetailsFragment2.class.getName()) - .setArguments(args) - .setSourceMetricsCategory(mMetricsCategory) - .launch(); - return true; - }); - mPreferenceGroup.addPreference(mPreference); + if (FeatureFlagUtils.isEnabled(mPrefContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { + mPreference.setOnPreferenceClickListener(pref -> { + Bundle args = new Bundle(); + mPreference.getAccessPoint().saveWifiState(args); + new SubSettingLauncher(mPrefContext) + .setTitleRes(R.string.pref_title_network_details) + .setDestination(WifiNetworkDetailsFragment2.class.getName()) + .setArguments(args) + .setSourceMetricsCategory(mMetricsCategory) + .launch(); + return true; + }); + } else { + mPreference.setOnPreferenceClickListener(pref -> { + Bundle args = new Bundle(); + mPreference.getAccessPoint().saveWifiState(args); + new SubSettingLauncher(mPrefContext) + .setTitleRes(R.string.pref_title_network_details) + .setDestination(WifiNetworkDetailsFragment.class.getName()) + .setArguments(args) + .setSourceMetricsCategory(mMetricsCategory) + .launch(); + return true; + }); + } + mPreferenceGroup.addPreference(mPreference); + } } private void update() { - final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry(); - if (connectedWifiEntry == null) { + AccessPoint connectedAccessPoint = null; + if (mWifiTracker.isConnected()) { + connectedAccessPoint = getCurrentAccessPoint(); + } + if (connectedAccessPoint == null) { updatePreference(null); } else { - if (mPreference == null || !mPreference.getWifiEntry().equals(connectedWifiEntry)) { - updatePreference(connectedWifiEntry); - } else if (mPreference != null) { - mPreference.refresh(); - } + if (mPreference == null || !mPreference.getAccessPoint().equals(connectedAccessPoint)) { + updatePreference(connectedAccessPoint); + } else if (mPreference != null) { + mPreference.refresh(); + } } mUpdateListener.onChildrenUpdated(); } - /** Called when the state of Wifi has changed. */ @Override - public void onWifiStateChanged() { - update(); - } - - /** - * Update the results when data changes. - */ - @Override - public void onWifiEntriesChanged() { + public void onWifiStateChanged(int state) { update(); } @Override - public void onNumSavedSubscriptionsChanged() { - // Do nothing. + public void onConnectedChanged() { + update(); } @Override - public void onNumSavedNetworksChanged() { - // Do nothing. + public void onAccessPointsChanged() { + update(); } } diff --git a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java index ea957c3e762..703731858c3 100644 --- a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java @@ -29,15 +29,12 @@ import static org.mockito.Mockito.when; import android.content.Context; -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - import com.android.settings.wifi.WifiConnectionPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.wifi.WifiEntryPreference; -import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiPickerTracker; +import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.AccessPointPreference; +import com.android.settingslib.wifi.WifiTracker; +import com.android.settingslib.wifi.WifiTrackerFactory; import org.junit.Before; import org.junit.Test; @@ -48,12 +45,19 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.ArrayList; +import java.util.Arrays; + +import androidx.lifecycle.LifecycleOwner; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; + @RunWith(RobolectricTestRunner.class) public class WifiConnectionPreferenceControllerTest { private static final String KEY = "wifi_connection"; @Mock - WifiPickerTracker mWifiPickerTracker; + WifiTracker mWifiTracker; @Mock PreferenceScreen mScreen; @Mock @@ -70,6 +74,7 @@ public class WifiConnectionPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + WifiTrackerFactory.setTestingWifiTracker(mWifiTracker); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); when(mScreen.findPreference(eq(KEY))).thenReturn(mPreferenceCategory); @@ -78,51 +83,49 @@ public class WifiConnectionPreferenceControllerTest { mController = new WifiConnectionPreferenceController(mContext, mLifecycle, mUpdateListener, KEY, 0, 0); - mController.mWifiPickerTracker = mWifiPickerTracker; } @Test - public void isAvailable_noConnectedWifiEntry_availableIsFalse() { - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null); - + public void isAvailable_noWiFiConnection_availableIsFalse() { + when(mWifiTracker.isConnected()).thenReturn(false); assertThat(mController.isAvailable()).isFalse(); } @Test - public void displayPreference_noConnectedWifiEntry_noPreferenceAdded() { - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null); - + public void displayPreference_noWiFiConnection_noPreferenceAdded() { + when(mWifiTracker.isConnected()).thenReturn(false); + when(mWifiTracker.getAccessPoints()).thenReturn(new ArrayList<>()); mController.displayPreference(mScreen); - verify(mPreferenceCategory, never()).addPreference(any()); } @Test - public void displayPreference_hasConnectedWifiEntry_preferenceAdded() { - final WifiEntry wifiEntry = mock(WifiEntry.class); - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry); - + public void displayPreference_hasWiFiConnection_preferenceAdded() { + when(mWifiTracker.isConnected()).thenReturn(true); + final AccessPoint accessPoint = mock(AccessPoint.class); + when(accessPoint.isActive()).thenReturn(true); + when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint)); mController.displayPreference(mScreen); - verify(mPreferenceCategory).addPreference(any(WifiEntryPreference.class)); + verify(mPreferenceCategory).addPreference(any(AccessPointPreference.class)); } @Test public void onConnectedChanged_wifiBecameDisconnected_preferenceRemoved() { - final WifiEntry wifiEntry = mock(WifiEntry.class); - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry); + when(mWifiTracker.isConnected()).thenReturn(true); + final AccessPoint accessPoint = mock(AccessPoint.class); + when(accessPoint.isActive()).thenReturn(true); + when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint)); mController.displayPreference(mScreen); - final ArgumentCaptor captor = ArgumentCaptor.forClass( - WifiEntryPreference.class); + final ArgumentCaptor captor = ArgumentCaptor.forClass( + AccessPointPreference.class); verify(mPreferenceCategory).addPreference(captor.capture()); - final WifiEntryPreference pref = captor.getValue(); + final AccessPointPreference pref = captor.getValue(); - // Become disconnected. - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null); + when(mWifiTracker.isConnected()).thenReturn(false); + when(mWifiTracker.getAccessPoints()).thenReturn(new ArrayList<>()); final int onUpdatedCountBefore = mOnChildUpdatedCount; - - mController.onWifiStateChanged(); - + mController.onConnectedChanged(); verify(mPreferenceCategory).removePreference(pref); assertThat(mOnChildUpdatedCount).isEqualTo(onUpdatedCountBefore + 1); } @@ -130,24 +133,28 @@ public class WifiConnectionPreferenceControllerTest { @Test public void onAccessPointsChanged_wifiBecameConnectedToDifferentAP_preferenceReplaced() { - final WifiEntry wifiEntry1 = mock(WifiEntry.class); - when(wifiEntry1.getKey()).thenReturn("KEY_1"); - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry1); - mController.displayPreference(mScreen); - final ArgumentCaptor captor = ArgumentCaptor.forClass( - WifiEntryPreference.class); + when(mWifiTracker.isConnected()).thenReturn(true); + final AccessPoint accessPoint1 = mock(AccessPoint.class); - final WifiEntry wifiEntry2 = mock(WifiEntry.class); - when(wifiEntry1.getKey()).thenReturn("KEY_2"); - when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry2); + when(accessPoint1.isActive()).thenReturn(true); + when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint1)); + mController.displayPreference(mScreen); + final ArgumentCaptor captor = ArgumentCaptor.forClass( + AccessPointPreference.class); + + + final AccessPoint accessPoint2 = mock(AccessPoint.class); + when(accessPoint1.isActive()).thenReturn(false); + when(accessPoint2.isActive()).thenReturn(true); + when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint1, accessPoint2)); final int onUpdatedCountBefore = mOnChildUpdatedCount; - mController.onWifiEntriesChanged(); + mController.onAccessPointsChanged(); verify(mPreferenceCategory, times(2)).addPreference(captor.capture()); - final WifiEntryPreference pref1 = captor.getAllValues().get(0); - final WifiEntryPreference pref2 = captor.getAllValues().get(1); - assertThat(pref1.getWifiEntry()).isEqualTo(wifiEntry1); - assertThat(pref2.getWifiEntry()).isEqualTo(wifiEntry2); + final AccessPointPreference pref1 = captor.getAllValues().get(0); + final AccessPointPreference pref2 = captor.getAllValues().get(1); + assertThat(pref1.getAccessPoint()).isEqualTo(accessPoint1); + assertThat(pref2.getAccessPoint()).isEqualTo(accessPoint2); verify(mPreferenceCategory).removePreference(eq(pref1)); assertThat(mOnChildUpdatedCount).isEqualTo(onUpdatedCountBefore + 1); }