Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53d147dd authored by Jason Chiu's avatar Jason Chiu
Browse files

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
parent 4eb82951
Loading
Loading
Loading
Loading
+127 −0
Original line number Diff line number Diff line
/*
 * 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
+0 −95
Original line number Diff line number Diff line
@@ -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<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;
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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;

+119 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}
+9 −66
Original line number Diff line number Diff line
@@ -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<SliceItem> 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<SliceItem> 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<SliceItem> 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<SliceItem> 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<SliceItem> 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<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);