Loading packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +40 −16 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.support.annotation.NonNull; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.style.TtsSpan; import android.util.Log; Loading Loading @@ -130,11 +131,14 @@ public class AccessPoint implements Comparable<AccessPoint> { * <p>This cache should not be evicted with scan results, as the values here are used to * generate a fallback in the absence of scores for the visible APs. */ // TODO(b/63073866): change this to have score eviction logic private final Map<String, ScoredNetwork> mScoredNetworkCache = new HashMap<>(); private final Map<String, TimestampedScoredNetwork> mScoredNetworkCache = new HashMap<>(); /** Maximum age in millis of cached scored networks in {@link #mScoredNetworkCache}. */ @VisibleForTesting static final long MAX_CACHED_SCORE_AGE_MILLIS = 24 * DateUtils.DAY_IN_MILLIS; /** Maximum age of scan results to hold onto while actively scanning. **/ private static final long MAX_SCAN_RESULT_AGE_MS = 15000; private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; static final String KEY_NETWORKINFO = "key_networkinfo"; static final String KEY_WIFIINFO = "key_wifiinfo"; Loading Loading @@ -246,10 +250,10 @@ public class AccessPoint implements Comparable<AccessPoint> { } } if (savedState.containsKey(KEY_SCOREDNETWORKCACHE)) { ArrayList<ScoredNetwork> scoredNetworkArrayList = ArrayList<TimestampedScoredNetwork> scoredNetworkArrayList = savedState.getParcelableArrayList(KEY_SCOREDNETWORKCACHE); for (ScoredNetwork score : scoredNetworkArrayList) { mScoredNetworkCache.put(score.networkKey.wifiKey.bssid, score); for (TimestampedScoredNetwork timedScore : scoredNetworkArrayList) { mScoredNetworkCache.put(timedScore.getScore().networkKey.wifiKey.bssid, timedScore); } } if (savedState.containsKey(KEY_FQDN)) { Loading Loading @@ -448,20 +452,40 @@ public class AccessPoint implements Comparable<AccessPoint> { /** * Updates the AccessPoint rankingScore and speed, returning true if the data has changed. * * <p>Any cached {@link TimestampedScoredNetwork} objects older than * {@link #MAX_CACHED_SCORE_AGE_MILLIS} will be removed when this method is invoked. * * <p>Precondition: {@link #mRssi} is up to date before invoking this method. * * @param scoreCache The score cache to use to retrieve scores. * @return true if the set speed has changed */ private boolean updateScores(WifiNetworkScoreCache scoreCache) { long nowMillis = SystemClock.elapsedRealtime(); for (ScanResult result : mScanResultCache.values()) { ScoredNetwork score = scoreCache.getScoredNetwork(result); if (score == null) { continue; } mScoredNetworkCache.put(result.BSSID, score); TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID); if (timedScore == null) { mScoredNetworkCache.put( result.BSSID, new TimestampedScoredNetwork(score, nowMillis)); } else { // Update data since the has been seen in the score cache timedScore.update(score, nowMillis); } } // Remove old cached networks long evictionCutoff = nowMillis - MAX_CACHED_SCORE_AGE_MILLIS; Iterator<TimestampedScoredNetwork> iterator = mScoredNetworkCache.values().iterator(); iterator.forEachRemaining(timestampedScoredNetwork -> { if (timestampedScoredNetwork.getUpdatedTimestampMillis() < evictionCutoff) { iterator.remove(); } }); return updateSpeed(); } Loading @@ -474,15 +498,15 @@ public class AccessPoint implements Comparable<AccessPoint> { // set speed to the connected ScanResult if the AccessPoint is the active network if (isActive() && mInfo != null) { ScoredNetwork score = mScoredNetworkCache.get(mInfo.getBSSID()); if (score != null) { TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(mInfo.getBSSID()); if (timedScore != null) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Set score using specific access point curve for connected AP: " + getSsidStr()); } // TODO(b/63073866): Map using getLevel rather than specific rssi value so score // doesn't change without a visible wifi bar change. int speed = score.calculateBadge(mInfo.getRssi()); int speed = timedScore.getScore().calculateBadge(mInfo.getRssi()); if (speed != Speed.NONE) { mSpeed = speed; } Loading @@ -509,8 +533,8 @@ public class AccessPoint implements Comparable<AccessPoint> { int count = 0; int totalSpeed = 0; for (ScoredNetwork score : mScoredNetworkCache.values()) { int speed = score.calculateBadge(mRssi); for (TimestampedScoredNetwork timedScore : mScoredNetworkCache.values()) { int speed = timedScore.getScore().calculateBadge(mRssi); if (speed != Speed.NONE) { count++; totalSpeed += speed; Loading Loading @@ -555,7 +579,7 @@ public class AccessPoint implements Comparable<AccessPoint> { for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) { ScanResult result = iter.next(); // result timestamp is in microseconds if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MS) { if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) { iter.remove(); } } Loading Loading @@ -1004,13 +1028,13 @@ public class AccessPoint implements Comparable<AccessPoint> { } @Speed private int getSpecificApSpeed(ScanResult result) { ScoredNetwork score = mScoredNetworkCache.get(result.BSSID); if (score == null) { TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID); if (timedScore == null) { return Speed.NONE; } // For debugging purposes we may want to use mRssi rather than result.level as the average // speed wil be determined by mRssi return score.calculateBadge(result.level); return timedScore.getScore().calculateBadge(result.level); } /** Loading packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java +11 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.os.Bundle; import android.support.annotation.Keep; import com.android.settingslib.wifi.AccessPoint.Speed; import java.util.ArrayList; Loading Loading @@ -58,6 +59,7 @@ public class TestAccessPointBuilder { Context mContext; private ArrayList<ScanResult> mScanResultCache; private ArrayList<TimestampedScoredNetwork> mScoredNetworkCache; @Keep public TestAccessPointBuilder(Context context) { Loading Loading @@ -85,6 +87,9 @@ public class TestAccessPointBuilder { if (mScanResultCache != null) { bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, mScanResultCache); } if (mScoredNetworkCache != null) { bundle.putParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE, mScoredNetworkCache); } bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity); bundle.putInt(AccessPoint.KEY_SPEED, mSpeed); bundle.putBoolean(AccessPoint.KEY_IS_CARRIER_AP, mIsCarrierAp); Loading Loading @@ -238,4 +243,10 @@ public class TestAccessPointBuilder { mCarrierName = carrierName; return this; } public TestAccessPointBuilder setScoredNetworkCache( ArrayList<TimestampedScoredNetwork> scoredNetworkCache) { mScoredNetworkCache = scoredNetworkCache; return this; } } packages/SettingsLib/src/com/android/settingslib/wifi/TimestampedScoredNetwork.java 0 → 100644 +76 −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.net.ScoredNetwork; import android.os.Parcel; import android.os.Parcelable; /** * Data encapsulation object to associate a time with a {@link ScoredNetwork} */ class TimestampedScoredNetwork implements Parcelable { private ScoredNetwork mScore; private long mUpdatedTimestampMillis; TimestampedScoredNetwork(ScoredNetwork score, long updatedTimestampMillis) { mScore = score; mUpdatedTimestampMillis = updatedTimestampMillis; } protected TimestampedScoredNetwork(Parcel in) { mScore = ScoredNetwork.CREATOR.createFromParcel(in); mUpdatedTimestampMillis = in.readLong(); } public void update(ScoredNetwork score, long updatedTimestampMillis) { mScore = score; mUpdatedTimestampMillis = updatedTimestampMillis; } public ScoredNetwork getScore() { return mScore; } public long getUpdatedTimestampMillis() { return mUpdatedTimestampMillis; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(mScore, flags); dest.writeLong(mUpdatedTimestampMillis); } public static final Creator<TimestampedScoredNetwork> CREATOR = new Creator<TimestampedScoredNetwork>() { @Override public TimestampedScoredNetwork createFromParcel(Parcel in) { return new TimestampedScoredNetwork(in); } @Override public TimestampedScoredNetwork[] newArray(int size) { return new TimestampedScoredNetwork[size]; } }; } packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +128 −6 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -50,8 +48,8 @@ import android.text.SpannableString; import android.text.style.TtsSpan; import com.android.settingslib.R; import com.android.settingslib.wifi.AccessPoint.Speed; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -59,17 +57,22 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @SmallTest @RunWith(AndroidJUnit4.class) public class AccessPointTest { private static final String TEST_SSID = "test_ssid"; private static final String TEST_SSID = "\"test_ssid\""; private static final int NUM_SCAN_RESULTS = 5; private static final ArrayList<ScanResult> SCAN_RESULTS = buildScanResultCache(); private static final RssiCurve FAST_BADGE_CURVE = new RssiCurve(-150, 10, new byte[]{Speed.FAST}); public static final String TEST_BSSID = "00:00:00:00:00:00"; private Context mContext; @Mock private RssiCurve mockBadgeCurve; @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache; Loading Loading @@ -602,8 +605,8 @@ public class AccessPointTest { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve); return new ScoredNetwork( new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")), mockBadgeCurve, new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)), badgeCurve, false /* meteredHint */, attr1); Loading Loading @@ -632,6 +635,18 @@ public class AccessPointTest { return configuration; } private AccessPoint createApWithFastTimestampedScoredNetworkCache( long elapsedTimeMillis) { TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE), elapsedTimeMillis); return new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setScoredNetworkCache( new ArrayList<>(Arrays.asList(recentScore))) .build(); } /** * Assert that the first AccessPoint appears before the second AccessPoint * once sorting has been completed. Loading Loading @@ -964,4 +979,111 @@ public class AccessPointTest { assertThat(ap.getSpeed()).isEqualTo(fallbackSpeed); } @Test public void testScoredNetworkCacheBundling() { long timeMillis = SystemClock.elapsedRealtime(); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(timeMillis); Bundle bundle = new Bundle(); ap.saveWifiState(bundle); ArrayList<TimestampedScoredNetwork> list = bundle.getParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE); assertThat(list).hasSize(1); assertThat(list.get(0).getUpdatedTimestampMillis()).isEqualTo(timeMillis); RssiCurve curve = list.get(0).getScore().attributes.getParcelable( ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE); assertThat(curve).isEqualTo(FAST_BADGE_CURVE); } @Test public void testRecentNetworkScoresAreUsedForSpeedLabelGeneration() { AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(SystemClock.elapsedRealtime()); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testNetworkScoresAreUsedForSpeedLabelGenerationWhenWithinAgeRange() { long withinRangeTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS - 10000); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(withinRangeTimeMillis); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testOldNetworkScoresAreNotUsedForSpeedLabelGeneration() { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(tooOldTimeMillis); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.NONE); } @Test public void testUpdateScoresRefreshesScoredNetworkCacheTimestamps () { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( scoredNetwork, tooOldTimeMillis); AccessPoint ap = new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setBssid(TEST_BSSID) .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) .setScanResultCache(SCAN_RESULTS) .build(); when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(scoredNetwork); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); // Fast should still be returned since cache was updated with recent time assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testUpdateScoresRefreshesScoredNetworkCacheWithNewSpeed () { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( scoredNetwork, tooOldTimeMillis); AccessPoint ap = new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setBssid(TEST_BSSID) .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) .setScanResultCache(SCAN_RESULTS) .build(); int newSpeed = Speed.MODERATE; when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) newSpeed); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); // Fast should still be returned since cache was updated with recent time assertThat(ap.getSpeed()).isEqualTo(newSpeed); } } Loading
packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +40 −16 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.support.annotation.NonNull; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.style.TtsSpan; import android.util.Log; Loading Loading @@ -130,11 +131,14 @@ public class AccessPoint implements Comparable<AccessPoint> { * <p>This cache should not be evicted with scan results, as the values here are used to * generate a fallback in the absence of scores for the visible APs. */ // TODO(b/63073866): change this to have score eviction logic private final Map<String, ScoredNetwork> mScoredNetworkCache = new HashMap<>(); private final Map<String, TimestampedScoredNetwork> mScoredNetworkCache = new HashMap<>(); /** Maximum age in millis of cached scored networks in {@link #mScoredNetworkCache}. */ @VisibleForTesting static final long MAX_CACHED_SCORE_AGE_MILLIS = 24 * DateUtils.DAY_IN_MILLIS; /** Maximum age of scan results to hold onto while actively scanning. **/ private static final long MAX_SCAN_RESULT_AGE_MS = 15000; private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; static final String KEY_NETWORKINFO = "key_networkinfo"; static final String KEY_WIFIINFO = "key_wifiinfo"; Loading Loading @@ -246,10 +250,10 @@ public class AccessPoint implements Comparable<AccessPoint> { } } if (savedState.containsKey(KEY_SCOREDNETWORKCACHE)) { ArrayList<ScoredNetwork> scoredNetworkArrayList = ArrayList<TimestampedScoredNetwork> scoredNetworkArrayList = savedState.getParcelableArrayList(KEY_SCOREDNETWORKCACHE); for (ScoredNetwork score : scoredNetworkArrayList) { mScoredNetworkCache.put(score.networkKey.wifiKey.bssid, score); for (TimestampedScoredNetwork timedScore : scoredNetworkArrayList) { mScoredNetworkCache.put(timedScore.getScore().networkKey.wifiKey.bssid, timedScore); } } if (savedState.containsKey(KEY_FQDN)) { Loading Loading @@ -448,20 +452,40 @@ public class AccessPoint implements Comparable<AccessPoint> { /** * Updates the AccessPoint rankingScore and speed, returning true if the data has changed. * * <p>Any cached {@link TimestampedScoredNetwork} objects older than * {@link #MAX_CACHED_SCORE_AGE_MILLIS} will be removed when this method is invoked. * * <p>Precondition: {@link #mRssi} is up to date before invoking this method. * * @param scoreCache The score cache to use to retrieve scores. * @return true if the set speed has changed */ private boolean updateScores(WifiNetworkScoreCache scoreCache) { long nowMillis = SystemClock.elapsedRealtime(); for (ScanResult result : mScanResultCache.values()) { ScoredNetwork score = scoreCache.getScoredNetwork(result); if (score == null) { continue; } mScoredNetworkCache.put(result.BSSID, score); TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID); if (timedScore == null) { mScoredNetworkCache.put( result.BSSID, new TimestampedScoredNetwork(score, nowMillis)); } else { // Update data since the has been seen in the score cache timedScore.update(score, nowMillis); } } // Remove old cached networks long evictionCutoff = nowMillis - MAX_CACHED_SCORE_AGE_MILLIS; Iterator<TimestampedScoredNetwork> iterator = mScoredNetworkCache.values().iterator(); iterator.forEachRemaining(timestampedScoredNetwork -> { if (timestampedScoredNetwork.getUpdatedTimestampMillis() < evictionCutoff) { iterator.remove(); } }); return updateSpeed(); } Loading @@ -474,15 +498,15 @@ public class AccessPoint implements Comparable<AccessPoint> { // set speed to the connected ScanResult if the AccessPoint is the active network if (isActive() && mInfo != null) { ScoredNetwork score = mScoredNetworkCache.get(mInfo.getBSSID()); if (score != null) { TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(mInfo.getBSSID()); if (timedScore != null) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Set score using specific access point curve for connected AP: " + getSsidStr()); } // TODO(b/63073866): Map using getLevel rather than specific rssi value so score // doesn't change without a visible wifi bar change. int speed = score.calculateBadge(mInfo.getRssi()); int speed = timedScore.getScore().calculateBadge(mInfo.getRssi()); if (speed != Speed.NONE) { mSpeed = speed; } Loading @@ -509,8 +533,8 @@ public class AccessPoint implements Comparable<AccessPoint> { int count = 0; int totalSpeed = 0; for (ScoredNetwork score : mScoredNetworkCache.values()) { int speed = score.calculateBadge(mRssi); for (TimestampedScoredNetwork timedScore : mScoredNetworkCache.values()) { int speed = timedScore.getScore().calculateBadge(mRssi); if (speed != Speed.NONE) { count++; totalSpeed += speed; Loading Loading @@ -555,7 +579,7 @@ public class AccessPoint implements Comparable<AccessPoint> { for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) { ScanResult result = iter.next(); // result timestamp is in microseconds if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MS) { if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) { iter.remove(); } } Loading Loading @@ -1004,13 +1028,13 @@ public class AccessPoint implements Comparable<AccessPoint> { } @Speed private int getSpecificApSpeed(ScanResult result) { ScoredNetwork score = mScoredNetworkCache.get(result.BSSID); if (score == null) { TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID); if (timedScore == null) { return Speed.NONE; } // For debugging purposes we may want to use mRssi rather than result.level as the average // speed wil be determined by mRssi return score.calculateBadge(result.level); return timedScore.getScore().calculateBadge(result.level); } /** Loading
packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java +11 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.os.Bundle; import android.support.annotation.Keep; import com.android.settingslib.wifi.AccessPoint.Speed; import java.util.ArrayList; Loading Loading @@ -58,6 +59,7 @@ public class TestAccessPointBuilder { Context mContext; private ArrayList<ScanResult> mScanResultCache; private ArrayList<TimestampedScoredNetwork> mScoredNetworkCache; @Keep public TestAccessPointBuilder(Context context) { Loading Loading @@ -85,6 +87,9 @@ public class TestAccessPointBuilder { if (mScanResultCache != null) { bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, mScanResultCache); } if (mScoredNetworkCache != null) { bundle.putParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE, mScoredNetworkCache); } bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity); bundle.putInt(AccessPoint.KEY_SPEED, mSpeed); bundle.putBoolean(AccessPoint.KEY_IS_CARRIER_AP, mIsCarrierAp); Loading Loading @@ -238,4 +243,10 @@ public class TestAccessPointBuilder { mCarrierName = carrierName; return this; } public TestAccessPointBuilder setScoredNetworkCache( ArrayList<TimestampedScoredNetwork> scoredNetworkCache) { mScoredNetworkCache = scoredNetworkCache; return this; } }
packages/SettingsLib/src/com/android/settingslib/wifi/TimestampedScoredNetwork.java 0 → 100644 +76 −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.net.ScoredNetwork; import android.os.Parcel; import android.os.Parcelable; /** * Data encapsulation object to associate a time with a {@link ScoredNetwork} */ class TimestampedScoredNetwork implements Parcelable { private ScoredNetwork mScore; private long mUpdatedTimestampMillis; TimestampedScoredNetwork(ScoredNetwork score, long updatedTimestampMillis) { mScore = score; mUpdatedTimestampMillis = updatedTimestampMillis; } protected TimestampedScoredNetwork(Parcel in) { mScore = ScoredNetwork.CREATOR.createFromParcel(in); mUpdatedTimestampMillis = in.readLong(); } public void update(ScoredNetwork score, long updatedTimestampMillis) { mScore = score; mUpdatedTimestampMillis = updatedTimestampMillis; } public ScoredNetwork getScore() { return mScore; } public long getUpdatedTimestampMillis() { return mUpdatedTimestampMillis; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(mScore, flags); dest.writeLong(mUpdatedTimestampMillis); } public static final Creator<TimestampedScoredNetwork> CREATOR = new Creator<TimestampedScoredNetwork>() { @Override public TimestampedScoredNetwork createFromParcel(Parcel in) { return new TimestampedScoredNetwork(in); } @Override public TimestampedScoredNetwork[] newArray(int size) { return new TimestampedScoredNetwork[size]; } }; }
packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +128 −6 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -50,8 +48,8 @@ import android.text.SpannableString; import android.text.style.TtsSpan; import com.android.settingslib.R; import com.android.settingslib.wifi.AccessPoint.Speed; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -59,17 +57,22 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @SmallTest @RunWith(AndroidJUnit4.class) public class AccessPointTest { private static final String TEST_SSID = "test_ssid"; private static final String TEST_SSID = "\"test_ssid\""; private static final int NUM_SCAN_RESULTS = 5; private static final ArrayList<ScanResult> SCAN_RESULTS = buildScanResultCache(); private static final RssiCurve FAST_BADGE_CURVE = new RssiCurve(-150, 10, new byte[]{Speed.FAST}); public static final String TEST_BSSID = "00:00:00:00:00:00"; private Context mContext; @Mock private RssiCurve mockBadgeCurve; @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache; Loading Loading @@ -602,8 +605,8 @@ public class AccessPointTest { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve); return new ScoredNetwork( new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")), mockBadgeCurve, new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)), badgeCurve, false /* meteredHint */, attr1); Loading Loading @@ -632,6 +635,18 @@ public class AccessPointTest { return configuration; } private AccessPoint createApWithFastTimestampedScoredNetworkCache( long elapsedTimeMillis) { TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE), elapsedTimeMillis); return new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setScoredNetworkCache( new ArrayList<>(Arrays.asList(recentScore))) .build(); } /** * Assert that the first AccessPoint appears before the second AccessPoint * once sorting has been completed. Loading Loading @@ -964,4 +979,111 @@ public class AccessPointTest { assertThat(ap.getSpeed()).isEqualTo(fallbackSpeed); } @Test public void testScoredNetworkCacheBundling() { long timeMillis = SystemClock.elapsedRealtime(); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(timeMillis); Bundle bundle = new Bundle(); ap.saveWifiState(bundle); ArrayList<TimestampedScoredNetwork> list = bundle.getParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE); assertThat(list).hasSize(1); assertThat(list.get(0).getUpdatedTimestampMillis()).isEqualTo(timeMillis); RssiCurve curve = list.get(0).getScore().attributes.getParcelable( ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE); assertThat(curve).isEqualTo(FAST_BADGE_CURVE); } @Test public void testRecentNetworkScoresAreUsedForSpeedLabelGeneration() { AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(SystemClock.elapsedRealtime()); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testNetworkScoresAreUsedForSpeedLabelGenerationWhenWithinAgeRange() { long withinRangeTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS - 10000); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(withinRangeTimeMillis); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testOldNetworkScoresAreNotUsedForSpeedLabelGeneration() { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(tooOldTimeMillis); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); assertThat(ap.getSpeed()).isEqualTo(Speed.NONE); } @Test public void testUpdateScoresRefreshesScoredNetworkCacheTimestamps () { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( scoredNetwork, tooOldTimeMillis); AccessPoint ap = new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setBssid(TEST_BSSID) .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) .setScanResultCache(SCAN_RESULTS) .build(); when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(scoredNetwork); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); // Fast should still be returned since cache was updated with recent time assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); } @Test public void testUpdateScoresRefreshesScoredNetworkCacheWithNewSpeed () { long tooOldTimeMillis = SystemClock.elapsedRealtime() - (AccessPoint.MAX_CACHED_SCORE_AGE_MILLIS + 1); ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( scoredNetwork, tooOldTimeMillis); AccessPoint ap = new TestAccessPointBuilder(mContext) .setSsid(TEST_SSID) .setBssid(TEST_BSSID) .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) .setScanResultCache(SCAN_RESULTS) .build(); int newSpeed = Speed.MODERATE; when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) newSpeed); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); // Fast should still be returned since cache was updated with recent time assertThat(ap.getSpeed()).isEqualTo(newSpeed); } }