blob: 4408958734404cd307e9d027afdfbc0c71a5f2ac [file] [log] [blame]
/*
* Copyright (C) 2021 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.server.connectivity
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkScore.KEEP_CONNECTED_NONE
import android.net.NetworkScore.POLICY_EXITING
import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY
import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI
import android.os.Build
import androidx.test.filters.SmallTest
import com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD
import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
private fun score(vararg policies: Int) = FullScore(0,
policies.fold(0L) { acc, e -> acc or (1L shl e) }, KEEP_CONNECTED_NONE)
private fun caps(transport: Int) = NetworkCapabilities.Builder().addTransportType(transport).build()
@SmallTest
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class NetworkRankerTest {
private val mRanker = NetworkRanker()
private class TestScore(private val sc: FullScore, private val nc: NetworkCapabilities)
: NetworkRanker.Scoreable {
override fun getScore() = sc
override fun getCapsNoCopy(): NetworkCapabilities = nc
}
@Test
fun testYieldToBadWiFiOneCell() {
// Only cell, it wins
val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
val scores = listOf(winner)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneCellOneBadWiFi() {
// Bad wifi wins against yielding validated cell
val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
caps(TRANSPORT_WIFI))
val scores = listOf(
winner,
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneCellTwoBadWiFi() {
// Bad wifi wins against yielding validated cell. Prefer the one that's primary.
val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI))
val scores = listOf(
winner,
TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
caps(TRANSPORT_WIFI)),
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneCellTwoBadWiFiOneNotAvoided() {
// Bad wifi ever validated wins against bad wifi that never was validated (or was
// avoided when bad).
val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
caps(TRANSPORT_WIFI))
val scores = listOf(
winner,
TestScore(score(), caps(TRANSPORT_WIFI)),
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneCellOneBadWiFiOneGoodWiFi() {
// Good wifi wins
val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
val scores = listOf(
winner,
TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiTwoCellsOneBadWiFi() {
// Cell that doesn't yield wins over cell that yields and bad wifi
val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR))
val scores = listOf(
winner,
TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiTwoCellsOneBadWiFiOneGoodWiFi() {
// Good wifi wins over cell that doesn't yield and cell that yields
val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
val scores = listOf(
winner,
TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR)),
TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneExitingGoodWiFi() {
// Yielding cell wins over good exiting wifi
val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
val scores = listOf(
winner,
TestScore(score(POLICY_IS_VALIDATED, POLICY_EXITING), caps(TRANSPORT_WIFI))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
@Test
fun testYieldToBadWiFiOneExitingBadWiFi() {
// Yielding cell wins over bad exiting wifi
val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
caps(TRANSPORT_CELLULAR))
val scores = listOf(
winner,
TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
POLICY_EXITING), caps(TRANSPORT_WIFI))
)
assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
}
}