diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java new file mode 100644 index 00000000000..cf45d082f35 --- /dev/null +++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.slice; + +import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; + +import android.content.Context; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Bundle; + +import com.android.settings.slices.SliceBackgroundWorker; +import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.WifiTracker; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice. + */ +public class WifiScanWorker extends SliceBackgroundWorker + implements WifiTracker.WifiListener { + + private final Context mContext; + + private WifiTracker mWifiTracker; + + public WifiScanWorker(Context context, Uri uri) { + super(context, uri); + mContext = context; + } + + @Override + protected void onSlicePinned() { + if (mWifiTracker == null) { + mWifiTracker = new WifiTracker(mContext, this /* wifiListener */, + true /* includeSaved */, true /* includeScans */); + } + mWifiTracker.onStart(); + onAccessPointsChanged(); + } + + @Override + protected void onSliceUnpinned() { + mWifiTracker.onStop(); + } + + @Override + public void close() { + mWifiTracker.onDestroy(); + } + + @Override + public void onWifiStateChanged(int state) { + notifySliceChange(); + } + + @Override + public void onConnectedChanged() { + } + + @Override + public void onAccessPointsChanged() { + // in case state has changed + if (!mWifiTracker.getManager().isWifiEnabled()) { + updateResults(null); + return; + } + // AccessPoints are sorted by the WifiTracker + final List accessPoints = mWifiTracker.getAccessPoints(); + final List resultList = new ArrayList<>(); + for (AccessPoint ap : accessPoints) { + if (ap.isReachable()) { + resultList.add(clone(ap)); + if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { + break; + } + } + } + updateResults(resultList); + } + + private AccessPoint clone(AccessPoint accessPoint) { + final Bundle savedState = new Bundle(); + accessPoint.saveWifiState(savedState); + return new AccessPoint(mContext, savedState); + } + + @Override + protected boolean areListsTheSame(List a, List b) { + if (!a.equals(b)) { + return false; + } + + // compare access point states one by one + final int listSize = a.size(); + for (int i = 0; i < listSize; i++) { + if (getState(a.get(i)) != getState(b.get(i))) { + return false; + } + } + return true; + } + + private NetworkInfo.State getState(AccessPoint accessPoint) { + final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); + if (networkInfo != null) { + return networkInfo.getState(); + } + return null; + } +} \ No newline at end of file diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index f2c919b1733..d3df5fccb53 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -62,9 +62,7 @@ import com.android.settings.wifi.WifiSettings; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details.WifiNetworkDetailsFragment; import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.WifiTracker; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -362,97 +360,4 @@ public class WifiSlice implements CustomSliceable { public Class getBackgroundWorkerClass() { return WifiScanWorker.class; } - - public static class WifiScanWorker extends SliceBackgroundWorker - implements WifiTracker.WifiListener { - - private final Context mContext; - - private WifiTracker mWifiTracker; - - public WifiScanWorker(Context context, Uri uri) { - super(context, uri); - mContext = context; - } - - @Override - protected void onSlicePinned() { - if (mWifiTracker == null) { - mWifiTracker = new WifiTracker(mContext, this /* wifiListener */, - true /* includeSaved */, true /* includeScans */); - } - mWifiTracker.onStart(); - onAccessPointsChanged(); - } - - @Override - protected void onSliceUnpinned() { - mWifiTracker.onStop(); - } - - @Override - public void close() { - mWifiTracker.onDestroy(); - } - - @Override - public void onWifiStateChanged(int state) { - notifySliceChange(); - } - - @Override - public void onConnectedChanged() { - } - - @Override - public void onAccessPointsChanged() { - // in case state has changed - if (!mWifiTracker.getManager().isWifiEnabled()) { - updateResults(null); - return; - } - // AccessPoints are sorted by the WifiTracker - final List accessPoints = mWifiTracker.getAccessPoints(); - final List resultList = new ArrayList<>(); - for (AccessPoint ap : accessPoints) { - if (ap.isReachable()) { - resultList.add(clone(ap)); - if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { - break; - } - } - } - updateResults(resultList); - } - - private AccessPoint clone(AccessPoint accessPoint) { - final Bundle savedState = new Bundle(); - accessPoint.saveWifiState(savedState); - return new AccessPoint(mContext, savedState); - } - - @Override - protected boolean areListsTheSame(List a, List b) { - if (!a.equals(b)) { - return false; - } - - // compare access point states one by one - final int listSize = a.size(); - for (int i = 0; i < listSize; i++) { - if (getState(a.get(i)) != getState(b.get(i))) { - return false; - } - } - return true; - } - - private State getState(AccessPoint accessPoint) { - final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); - if (networkInfo != null) { - return networkInfo.getState(); - } - return null; - } - } } diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 005ffbebc08..9f121306b8c 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -55,7 +55,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; -import com.android.settings.wifi.slice.WifiSlice; +import com.android.settings.wifi.slice.WifiScanWorker; import com.android.settingslib.wifi.WifiTracker; import org.junit.After; @@ -474,7 +474,7 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } - @Implements(WifiSlice.WifiScanWorker.class) + @Implements(WifiScanWorker.class) public static class ShadowWifiScanWorker { private static WifiTracker mWifiTracker; diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java new file mode 100644 index 00000000000..7ddbce48a9f --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.slice; + +import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.wifi.WifiManager; +import android.os.Bundle; + +import androidx.slice.SliceProvider; +import androidx.slice.widget.SliceLiveData; + +import com.android.settingslib.wifi.AccessPoint; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class WifiScanWorkerTest { + + private static final String AP_NAME = "ap"; + + private Context mContext; + private ContentResolver mResolver; + private WifiManager mWifiManager; + private WifiScanWorker mWifiScanWorker; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mResolver = mock(ContentResolver.class); + doReturn(mResolver).when(mContext).getContentResolver(); + mWifiManager = mContext.getSystemService(WifiManager.class); + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + mWifiManager.setWifiEnabled(true); + + mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); + } + + @Test + public void onWifiStateChanged_shouldNotifyChange() { + mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); + + verify(mResolver).notifyChange(WIFI_SLICE_URI, null); + } + + private AccessPoint createAccessPoint(String name, State state) { + final NetworkInfo info = mock(NetworkInfo.class); + doReturn(state).when(info).getState(); + + final Bundle savedState = new Bundle(); + savedState.putString("key_ssid", name); + savedState.putParcelable("key_networkinfo", info); + return new AccessPoint(mContext, savedState); + } + + @Test + public void SliceAccessPoint_sameState_shouldBeTheSame() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isTrue(); + } + + @Test + public void SliceAccessPoint_differentState_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTING); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isFalse(); + } + + @Test + public void SliceAccessPoint_differentLength_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + final List list = new ArrayList<>(); + list.add(ap1); + list.add(ap2); + + assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java index e9f35d8a31a..b2718fc0631 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java @@ -19,25 +19,20 @@ package com.android.settings.wifi.slice; import static android.app.slice.Slice.HINT_LIST_ITEM; import static android.app.slice.SliceItem.FORMAT_SLICE; -import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; -import static com.android.settings.wifi.slice.WifiSlice.WifiScanWorker; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.NetworkInfo; -import android.net.NetworkInfo.State; import android.net.Uri; import android.net.wifi.WifiManager; -import android.os.Bundle; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; @@ -53,6 +48,9 @@ import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.SliceTester; import com.android.settingslib.wifi.AccessPoint; +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -62,11 +60,8 @@ import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - @RunWith(RobolectricTestRunner.class) +@Config(shadows = WifiSliceTest.ShadowSliceBackgroundWorker.class) public class WifiSliceTest { private static final String AP1_NAME = "ap1"; @@ -76,7 +71,6 @@ public class WifiSliceTest { private ContentResolver mResolver; private WifiManager mWifiManager; private WifiSlice mWifiSlice; - private WifiScanWorker mWifiScanWorker; @Before public void setUp() { @@ -90,7 +84,6 @@ public class WifiSliceTest { mWifiManager.setWifiEnabled(true); mWifiSlice = new WifiSlice(mContext); - mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); } @Test @@ -160,13 +153,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_noReachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, false), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -177,11 +169,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveAp_shouldReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, true, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -191,13 +182,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveApAndOneUnreachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, true, true), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -208,11 +198,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneReachableAp_shouldNotReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -222,13 +211,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_allReachableAps_shouldNotReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, true), createAccessPoint(AP2_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -249,51 +237,6 @@ public class WifiSliceTest { assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED); } - @Test - public void onWifiStateChanged_shouldNotifyChange() { - mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); - - verify(mResolver).notifyChange(WIFI_SLICE_URI, null); - } - - private AccessPoint createAccessPoint(String name, State state) { - final NetworkInfo info = mock(NetworkInfo.class); - doReturn(state).when(info).getState(); - - final Bundle savedState = new Bundle(); - savedState.putString("key_ssid", name); - savedState.putParcelable("key_networkinfo", info); - return new AccessPoint(mContext, savedState); - } - - @Test - public void SliceAccessPoint_sameState_shouldBeTheSame() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isTrue(); - } - - @Test - public void SliceAccessPoint_differentState_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTING); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isFalse(); - } - @Test - public void SliceAccessPoint_differentLength_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - final List list = new ArrayList<>(); - list.add(ap1); - list.add(ap2); - - assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); - } - @Implements(SliceBackgroundWorker.class) public static class ShadowSliceBackgroundWorker { private static WifiScanWorker mWifiScanWorker = mock(WifiScanWorker.class);