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

Commit 77d8cff0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor WifiScanWorker"

parents 16ff496f 53d147dd
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);