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

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

Merge "AccessPoint - Add Builder; Add unit tests for compareTo()"

parents ffffb475 98537437
Loading
Loading
Loading
Loading
+41 −21
Original line number Diff line number Diff line
@@ -89,15 +89,15 @@ public class AccessPoint implements Comparable<AccessPoint> {
            new ConcurrentHashMap<String, ScanResult>(32);
    private static final long MAX_SCAN_RESULT_AGE_MS = 15000;

    private static final String KEY_NETWORKINFO = "key_networkinfo";
    private static final String KEY_WIFIINFO = "key_wifiinfo";
    private static final String KEY_SCANRESULT = "key_scanresult";
    private static final String KEY_SSID = "key_ssid";
    private static final String KEY_SECURITY = "key_security";
    private static final String KEY_PSKTYPE = "key_psktype";
    private static final String KEY_SCANRESULTCACHE = "key_scanresultcache";
    private static final String KEY_CONFIG = "key_config";
    private static final AtomicInteger sLastId = new AtomicInteger(0);
    static final String KEY_NETWORKINFO = "key_networkinfo";
    static final String KEY_WIFIINFO = "key_wifiinfo";
    static final String KEY_SCANRESULT = "key_scanresult";
    static final String KEY_SSID = "key_ssid";
    static final String KEY_SECURITY = "key_security";
    static final String KEY_PSKTYPE = "key_psktype";
    static final String KEY_SCANRESULTCACHE = "key_scanresultcache";
    static final String KEY_CONFIG = "key_config";
    static final AtomicInteger sLastId = new AtomicInteger(0);

    /**
     * These values are matched in string arrays -- changes must be kept in sync
@@ -114,6 +114,8 @@ public class AccessPoint implements Comparable<AccessPoint> {

    public static final int SIGNAL_LEVELS = 4;

    static final int UNREACHABLE_RSSI = Integer.MAX_VALUE;

    private final Context mContext;

    private String ssid;
@@ -125,7 +127,7 @@ public class AccessPoint implements Comparable<AccessPoint> {

    private WifiConfiguration mConfig;

    private int mRssi = Integer.MAX_VALUE;
    private int mRssi = UNREACHABLE_RSSI;
    private long mSeen = 0;

    private WifiInfo mInfo;
@@ -214,6 +216,21 @@ public class AccessPoint implements Comparable<AccessPoint> {
        this.mRankingScore = that.mRankingScore;
    }

    /**
    * Returns a negative integer, zero, or a positive integer if this AccessPoint is less than,
    * equal to, or greater than the other AccessPoint.
    *
    * Sort order rules for AccessPoints:
    *   1. Active before inactive
    *   2. Reachable before unreachable
    *   3. Saved before unsaved
    *   4. (Internal only) Network ranking score
    *   5. Stronger signal before weaker signal
    *   6. SSID alphabetically
    *
    * Note that AccessPoints with a signal are usually also Reachable,
    * and will thus appear before unreachable saved AccessPoints.
    */
    @Override
    public int compareTo(@NonNull AccessPoint other) {
        // Active one goes first.
@@ -221,18 +238,16 @@ public class AccessPoint implements Comparable<AccessPoint> {
        if (!isActive() && other.isActive()) return 1;

        // Reachable one goes before unreachable one.
        if (mRssi != Integer.MAX_VALUE && other.mRssi == Integer.MAX_VALUE) return -1;
        if (mRssi == Integer.MAX_VALUE && other.mRssi != Integer.MAX_VALUE) return 1;
        if (isReachable() && !other.isReachable()) return -1;
        if (!isReachable() && other.isReachable()) return 1;

        // Configured (saved) one goes before unconfigured one.
        if (networkId != WifiConfiguration.INVALID_NETWORK_ID
                && other.networkId == WifiConfiguration.INVALID_NETWORK_ID) return -1;
        if (networkId == WifiConfiguration.INVALID_NETWORK_ID
                && other.networkId != WifiConfiguration.INVALID_NETWORK_ID) return 1;
        if (isSaved() && !other.isSaved()) return -1;
        if (!isSaved() && other.isSaved()) return 1;

        // Higher scores go before lower scores
        if (mRankingScore != other.mRankingScore) {
            return (mRankingScore > other.mRankingScore) ? -1 : 1;
        if (getRankingScore() != other.getRankingScore()) {
            return (getRankingScore() > other.getRankingScore()) ? -1 : 1;
        }

        // Sort by signal strength, bucketed by level
@@ -242,7 +257,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
            return difference;
        }
        // Sort by ssid.
        return ssid.compareToIgnoreCase(other.ssid);
        return getSsidStr().compareToIgnoreCase(other.getSsidStr());
    }

    @Override
@@ -355,7 +370,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
    }

    public int getLevel() {
        if (mRssi == Integer.MAX_VALUE) {
        if (!isReachable()) {
            return -1;
        }
        return WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS);
@@ -531,7 +546,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
            }
        } else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) {
            summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider));
        } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range
        } else if (!isReachable()) { // Wifi out of range
            summary.append(mContext.getString(R.string.wifi_not_in_range));
        } else { // In range, not disabled.
            if (config != null) { // Is saved network
@@ -874,6 +889,11 @@ public class AccessPoint implements Comparable<AccessPoint> {
        return mBadge;
    }

    /** Return true if the current RSSI is reachable, and false otherwise. */
    boolean isReachable() {
        return mRssi != UNREACHABLE_RSSI;
    }

    public static String getSummary(Context context, String ssid, DetailedState state,
            boolean isEphemeral, String passpointProvider) {
        if (state == DetailedState.CONNECTED && ssid == null) {
+177 −14
Original line number Diff line number Diff line
@@ -15,9 +15,8 @@
 */
package com.android.settingslib.wifi;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import android.content.Context;
import android.net.ConnectivityManager;
@@ -39,6 +38,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.Collections;

@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -59,12 +59,12 @@ public class AccessPointTest {
        final AccessPoint ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle);
        final CharSequence ssid = ap.getSsid();

        assertTrue(ssid instanceof SpannableString);
        assertThat(ssid instanceof SpannableString).isTrue();

        TtsSpan[] spans = ((SpannableString) ssid).getSpans(0, TEST_SSID.length(), TtsSpan.class);

        assertEquals(1, spans.length);
        assertEquals(TtsSpan.TYPE_TELEPHONE, spans[0].getType());
        assertThat(spans.length).isEqualTo(1);
        assertThat(spans[0].getType()).isEqualTo(TtsSpan.TYPE_TELEPHONE);
    }

    @Test
@@ -80,11 +80,11 @@ public class AccessPointTest {
        originalAccessPoint.update(configuration, wifiInfo, networkInfo);
        AccessPoint copy = new AccessPoint(mContext, originalAccessPoint);

        assertEquals(originalAccessPoint.getSsid().toString(), copy.getSsid().toString());
        assertEquals(originalAccessPoint.getBssid(), copy.getBssid());
        assertSame(originalAccessPoint.getConfig(), copy.getConfig());
        assertEquals(originalAccessPoint.getSecurity(), copy.getSecurity());
        assertTrue(originalAccessPoint.compareTo(copy) == 0);
        assertThat(originalAccessPoint.getSsid().toString()).isEqualTo(copy.getSsid().toString());
        assertThat(originalAccessPoint.getBssid()).isEqualTo(copy.getBssid());
        assertThat(originalAccessPoint.getConfig()).isEqualTo(copy.getConfig());
        assertThat(originalAccessPoint.getSecurity()).isEqualTo(copy.getSecurity());
        assertThat(originalAccessPoint.compareTo(copy) == 0).isTrue();
    }

    @Test
@@ -101,11 +101,93 @@ public class AccessPointTest {

        bundle.putParcelableArrayList("key_scanresultcache", scanResults);
        AccessPoint original = new AccessPoint(mContext, bundle);
        assertEquals(4, original.getRssi());
        assertThat(original.getRssi()).isEqualTo(4);
        AccessPoint copy = new AccessPoint(mContext, createWifiConfiguration());
        assertEquals(Integer.MIN_VALUE, copy.getRssi());
        assertThat(copy.getRssi()).isEqualTo(Integer.MIN_VALUE);
        copy.copyFrom(original);
        assertEquals(original.getRssi(), copy.getRssi());
        assertThat(original.getRssi()).isEqualTo(copy.getRssi());
    }

    @Test
    public void testCompareTo_GivesActiveBeforeInactive() {
        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();

        assertSortingWorks(activeAp, inactiveAp);
    }

    @Test
    public void testCompareTo_GivesReachableBeforeUnreachable() {
        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();

        assertSortingWorks(nearAp, farAp);
    }

    @Test
    public void testCompareTo_GivesSavedBeforeUnsaved() {
        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
        AccessPoint notSavedAp = new TestAccessPointBuilder(mContext).setSaved(false).build();

        assertSortingWorks(savedAp, notSavedAp);
    }

    //TODO: add tests for mRankingScore sort order if ranking is exposed

    @Test
    public void testCompareTo_GivesHighLevelBeforeLowLevel() {
        final int highLevel = AccessPoint.SIGNAL_LEVELS - 1;
        final int lowLevel = 1;
        assertThat(highLevel).isGreaterThan(lowLevel);

        AccessPoint strongAp = new TestAccessPointBuilder(mContext).setLevel(highLevel).build();
        AccessPoint weakAp = new TestAccessPointBuilder(mContext).setLevel(lowLevel).build();

        assertSortingWorks(strongAp, weakAp);
    }

    @Test
    public void testCompareTo_GivesSsidAlphabetically() {

        final String firstName = "AAAAAA";
        final String secondName = "zzzzzz";

        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();

        assertThat(firstAp.getSsidStr().compareToIgnoreCase(secondAp.getSsidStr()) < 0).isTrue();
        assertSortingWorks(firstAp, secondAp);
    }

    @Test
    public void testCompareTo_AllSortingRulesCombined() {

        AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
        AccessPoint reachableAndMinLevel = new TestAccessPointBuilder(mContext)
                .setReachable(true).build();
        AccessPoint saved = new TestAccessPointBuilder(mContext).setSaved(true).build();
        AccessPoint highLevelAndReachable = new TestAccessPointBuilder(mContext)
                .setLevel(AccessPoint.SIGNAL_LEVELS - 1).build();
        AccessPoint firstName = new TestAccessPointBuilder(mContext).setSsid("a").build();
        AccessPoint lastname = new TestAccessPointBuilder(mContext).setSsid("z").build();

        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();
        points.add(lastname);
        points.add(firstName);
        points.add(highLevelAndReachable);
        points.add(saved);
        points.add(reachableAndMinLevel);
        points.add(active);

        Collections.sort(points);
        assertThat(points.indexOf(active)).isLessThan(points.indexOf(reachableAndMinLevel));
        assertThat(points.indexOf(reachableAndMinLevel)).isLessThan(points.indexOf(saved));
        // note: the saved AP will not appear before highLevelAndReachable,
        // because all APs with a signal level are reachable,
        // and isReachable() takes higher sorting precedence than isSaved().
        assertThat(points.indexOf(saved)).isLessThan(points.indexOf(firstName));
        assertThat(points.indexOf(highLevelAndReachable)).isLessThan(points.indexOf(firstName));
        assertThat(points.indexOf(firstName)).isLessThan(points.indexOf(lastname));
    }

    private WifiConfiguration createWifiConfiguration() {
@@ -115,4 +197,85 @@ public class AccessPointTest {
        configuration.networkId = 123;
        return configuration;
    }

    /**
    * Assert that the first AccessPoint appears after the second AccessPoint
    * once sorting has been completed.
    */
    private void assertSortingWorks(AccessPoint first, AccessPoint second) {

        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();

        // add in reverse order so we can tell that sorting actually changed something
        points.add(second);
        points.add(first);
        Collections.sort(points);
        assertWithMessage(
                String.format("After sorting: second AccessPoint should have higher array index "
                    + "than the first, but found indicies second '%s' and first '%s'.",
                    points.indexOf(second), points.indexOf(first)))
            .that(points.indexOf(second)).isGreaterThan(points.indexOf(first));
    }

    @Test
    public void testBuilder_setActive() {
        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
        assertThat(activeAp.isActive()).isTrue();

        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
        assertThat(inactiveAp.isActive()).isFalse();
    }

    @Test
    public void testBuilder_setReachable() {
        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
        assertThat(nearAp.isReachable()).isTrue();

        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();
        assertThat(farAp.isReachable()).isFalse();
    }

    @Test
    public void testBuilder_setSaved() {
        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
        assertThat(savedAp.isSaved()).isTrue();

        AccessPoint newAp = new TestAccessPointBuilder(mContext).setSaved(false).build();
        assertThat(newAp.isSaved()).isFalse();
    }

    @Test
    public void testBuilder_setLevel() {
        AccessPoint testAp;

        for (int i = 0; i < AccessPoint.SIGNAL_LEVELS; i++) {
            testAp = new TestAccessPointBuilder(mContext).setLevel(i).build();
            assertThat(testAp.getLevel()).isEqualTo(i);
        }

        // numbers larger than the max level should be set to max
        testAp = new TestAccessPointBuilder(mContext).setLevel(AccessPoint.SIGNAL_LEVELS).build();
        assertThat(testAp.getLevel()).isEqualTo(AccessPoint.SIGNAL_LEVELS - 1);

        // numbers less than 0 should give level 0
        testAp = new TestAccessPointBuilder(mContext).setLevel(-100).build();
        assertThat(testAp.getLevel()).isEqualTo(0);
    }

    @Test
    public void testBuilder_settingReachableAfterLevelDoesNotAffectLevel() {
        int level = 1;
        assertThat(level).isLessThan(AccessPoint.SIGNAL_LEVELS - 1);

        AccessPoint testAp =
                new TestAccessPointBuilder(mContext).setLevel(level).setReachable(true).build();
        assertThat(testAp.getLevel()).isEqualTo(level);
    }

    @Test
    public void testBuilder_setSsid() {
        String name = "AmazingSsid!";
        AccessPoint namedAp = new TestAccessPointBuilder(mContext).setSsid(name).build();
        assertThat(namedAp.getSsidStr()).isEqualTo(name);
    }
}
+128 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settingslib.wifi;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.os.Bundle;

/**
* Build and return a valid AccessPoint.
*
* Only intended for testing the AccessPoint class;
* AccessPoints were designed to only be populated
* by the mechanisms of scan results and wifi configurations.
*/
public class TestAccessPointBuilder {
    // match the private values in WifiManager
    private static final int MIN_RSSI = -100;
    private static final int MAX_RSSI = -55;

    // set some sensible defaults
    private int mRssi = AccessPoint.UNREACHABLE_RSSI;
    private int networkId = WifiConfiguration.INVALID_NETWORK_ID;
    private String ssid = "TestSsid";
    private NetworkInfo mNetworkInfo = null;

    Context mContext;

    public TestAccessPointBuilder(Context context) {
        mContext = context;
    }

    public AccessPoint build() {
        Bundle bundle = new Bundle();

        WifiConfiguration wifiConig = new WifiConfiguration();
        wifiConig.networkId = networkId;

        bundle.putString(AccessPoint.KEY_SSID, ssid);
        bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConig);
        bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
        AccessPoint ap = new AccessPoint(mContext, bundle);
        ap.setRssi(mRssi);
        return ap;
    }

    public TestAccessPointBuilder setActive(boolean active) {
        if (active) {
            mNetworkInfo = new NetworkInfo(
                ConnectivityManager.TYPE_DUMMY,
                ConnectivityManager.TYPE_DUMMY,
                "TestNetwork",
                "TestNetwork");
        } else {
            mNetworkInfo = null;
        }
        return this;
    }

    /**
    * Set the signal level.
    * Side effect: if this AccessPoint was previously unreachable,
    * setting the level will also make it reachable.
    */
    public TestAccessPointBuilder setLevel(int level) {
        int outputRange = AccessPoint.SIGNAL_LEVELS - 1;

        if (level > outputRange) {
            level = outputRange;
        } else if (level < 0) {
            level = 0;
        }

        int inputRange = MAX_RSSI - MIN_RSSI;

        // calculate the rssi required to get the level we want.
        // this is a rearrangement of the formula from WifiManager.calculateSignalLevel()
        mRssi = (int)((float)(level * inputRange) / (float)outputRange) + MIN_RSSI;
        return this;
    }

    /**
    * Set whether the AccessPoint is reachable.
    * Side effect: if the signal level was not previously set,
    * making an AccessPoint reachable will set the signal to the minimum level.
    */
    public TestAccessPointBuilder setReachable(boolean reachable) {
        if (reachable) {
            // only override the mRssi if it hasn't been set yet
            if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
                mRssi = MIN_RSSI;
            }
        } else {
            mRssi = AccessPoint.UNREACHABLE_RSSI;
        }
        return this;
    }

    public TestAccessPointBuilder setSaved(boolean saved){
        if (saved) {
             networkId = 1;
        } else {
             networkId = WifiConfiguration.INVALID_NETWORK_ID;
        }
        return this;
    }

    public TestAccessPointBuilder setSsid(String newSsid) {
        ssid = newSsid;
        return this;
    }
}