| /* |
| * 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)) |
| } |
| } |