1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.util 18 19 import android.content.Context 20 import android.content.res.Resources 21 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER 22 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE 23 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY 24 import android.net.ConnectivityResources 25 import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI 26 import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE 27 import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener 28 import android.os.Build 29 import android.provider.Settings 30 import android.telephony.SubscriptionInfo 31 import android.telephony.SubscriptionManager 32 import android.telephony.TelephonyManager 33 import android.test.mock.MockContentResolver 34 import androidx.test.filters.SmallTest 35 import com.android.connectivity.resources.R 36 import com.android.internal.util.test.FakeSettingsProvider 37 import com.android.testutils.DevSdkIgnoreRule 38 import com.android.testutils.DevSdkIgnoreRunner 39 import org.junit.After 40 import org.junit.Assert.assertEquals 41 import org.junit.Assert.assertFalse 42 import org.junit.Assert.assertTrue 43 import org.junit.Test 44 import org.junit.runner.RunWith 45 import org.mockito.ArgumentCaptor 46 import org.mockito.ArgumentMatchers.anyInt 47 import org.mockito.ArgumentMatchers.argThat 48 import org.mockito.ArgumentMatchers.eq 49 import org.mockito.Mockito.any 50 import org.mockito.Mockito.doCallRealMethod 51 import org.mockito.Mockito.doReturn 52 import org.mockito.Mockito.mock 53 import org.mockito.Mockito.times 54 import org.mockito.Mockito.verify 55 56 /** 57 * Tests for [MultinetworkPolicyTracker]. 58 * 59 * Build, install and run with: 60 * atest android.net.util.MultinetworkPolicyTrackerTest 61 */ 62 @RunWith(DevSdkIgnoreRunner::class) 63 @SmallTest 64 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 65 class MultinetworkPolicyTrackerTest { 66 private val resources = mock(Resources::class.java).also { 67 doReturn(R.integer.config_networkAvoidBadWifi).`when`(it).getIdentifier( 68 eq("config_networkAvoidBadWifi"), eq("integer"), any()) 69 doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi) 70 } 71 private val telephonyManager = mock(TelephonyManager::class.java) 72 private val subscriptionManager = mock(SubscriptionManager::class.java).also { 73 doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt()) 74 } 75 private val resolver = MockContentResolver().apply { 76 addProvider(Settings.AUTHORITY, FakeSettingsProvider()) } 77 private val context = mock(Context::class.java).also { 78 doReturn(Context.TELEPHONY_SERVICE).`when`(it) 79 .getSystemServiceName(TelephonyManager::class.java) 80 doReturn(telephonyManager).`when`(it).getSystemService(Context.TELEPHONY_SERVICE) 81 if (it.getSystemService(TelephonyManager::class.java) == null) { 82 // Test is using mockito extended 83 doCallRealMethod().`when`(it).getSystemService(TelephonyManager::class.java) 84 } 85 doReturn(subscriptionManager).`when`(it) 86 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) 87 doReturn(resolver).`when`(it).contentResolver 88 doReturn(resources).`when`(it).resources 89 doReturn(it).`when`(it).createConfigurationContext(any()) 90 Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1") 91 ConnectivityResources.setResourcesContextForTest(it) 92 } 93 private val tracker = MultinetworkPolicyTracker(context, null /* handler */) 94 95 private fun assertMultipathPreference(preference: Int) { 96 Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, 97 preference.toString()) 98 tracker.updateMeteredMultipathPreference() 99 assertEquals(preference, tracker.meteredMultipathPreference) 100 } 101 102 @After 103 fun tearDown() { 104 ConnectivityResources.setResourcesContextForTest(null) 105 } 106 107 @Test 108 fun testUpdateMeteredMultipathPreference() { 109 assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER) 110 assertMultipathPreference(MULTIPATH_PREFERENCE_RELIABILITY) 111 assertMultipathPreference(MULTIPATH_PREFERENCE_PERFORMANCE) 112 } 113 114 @Test 115 fun testUpdateAvoidBadWifi() { 116 Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") 117 assertTrue(tracker.updateAvoidBadWifi()) 118 assertFalse(tracker.avoidBadWifi) 119 120 doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi) 121 assertTrue(tracker.updateAvoidBadWifi()) 122 assertTrue(tracker.avoidBadWifi) 123 } 124 125 @Test 126 fun testOnActiveDataSubscriptionIdChanged() { 127 val testSubId = 1000 128 val subscriptionInfo = SubscriptionInfo(testSubId, ""/* iccId */, 1/* iccId */, 129 "TMO"/* displayName */, "TMO"/* carrierName */, 1/* nameSource */, 1/* iconTint */, 130 "123"/* number */, 1/* roaming */, null/* icon */, "310"/* mcc */, "210"/* mnc */, 131 ""/* countryIso */, false/* isEmbedded */, null/* nativeAccessRules */, 132 "1"/* cardString */) 133 doReturn(subscriptionInfo).`when`(subscriptionManager).getActiveSubscriptionInfo(testSubId) 134 135 // Modify avoidBadWifi and meteredMultipathPreference settings value and local variables in 136 // MultinetworkPolicyTracker should be also updated after subId changed. 137 Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") 138 Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, 139 MULTIPATH_PREFERENCE_PERFORMANCE.toString()) 140 141 val listenerCaptor = ArgumentCaptor.forClass( 142 ActiveDataSubscriptionIdListener::class.java) 143 verify(telephonyManager, times(1)) 144 .registerTelephonyCallback(any(), listenerCaptor.capture()) 145 val listener = listenerCaptor.value 146 listener.onActiveDataSubscriptionIdChanged(testSubId) 147 148 // Check it get resource value with test sub id. 149 verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId) 150 verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 }) 151 152 // Check if avoidBadWifi and meteredMultipathPreference values have been updated. 153 assertFalse(tracker.avoidBadWifi) 154 assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference) 155 } 156 } 157