Refactor WifiScanWorker

Extracted WifiScanWorker from WifiSlice

Bug: 128056349
Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.wifi
Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.slices
Change-Id: I9b3c809ee6c2b7466c959631840b257b91b49d88
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 0000000..cf45d08
--- /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<AccessPoint>
+        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<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
+        final List<AccessPoint> 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<AccessPoint> a, List<AccessPoint> 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 f2c919b..d3df5fc 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.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 getBackgroundWorkerClass() {
         return WifiScanWorker.class;
     }
-
-    public static class WifiScanWorker extends SliceBackgroundWorker<AccessPoint>
-            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<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
-            final List<AccessPoint> 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<AccessPoint> a, List<AccessPoint> 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 005ffbe..9f12130 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.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 @@
         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 0000000..7ddbce4
--- /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<AccessPoint> 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 e9f35d8..b2718fc 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 @@
 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.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.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 @@
     private ContentResolver mResolver;
     private WifiManager mWifiManager;
     private WifiSlice mWifiSlice;
-    private WifiScanWorker mWifiScanWorker;
 
     @Before
     public void setUp() {
@@ -90,7 +84,6 @@
         mWifiManager.setWifiEnabled(true);
 
         mWifiSlice = new WifiSlice(mContext);
-        mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
     }
 
     @Test
@@ -160,13 +153,12 @@
     }
 
     @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<SliceItem> sliceItems = wifiSlice.getItems();
 
         SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
@@ -177,11 +169,10 @@
     }
 
     @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<SliceItem> sliceItems = wifiSlice.getItems();
 
         SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
@@ -191,13 +182,12 @@
     }
 
     @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<SliceItem> sliceItems = wifiSlice.getItems();
 
         SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
@@ -208,11 +198,10 @@
     }
 
     @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<SliceItem> sliceItems = wifiSlice.getItems();
 
         SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
@@ -222,13 +211,12 @@
     }
 
     @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<SliceItem> sliceItems = wifiSlice.getItems();
 
         SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME);
@@ -249,51 +237,6 @@
         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<AccessPoint> 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);