1 /* 2 * Copyright (C) 2020 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.cts 18 19 import android.content.Context 20 import android.net.ConnectivityManager 21 import android.net.NetworkInfo 22 import android.net.NetworkInfo.DetailedState 23 import android.net.NetworkInfo.State 24 import android.os.Build 25 import android.telephony.TelephonyManager 26 import androidx.test.filters.SmallTest 27 import androidx.test.platform.app.InstrumentationRegistry 28 import androidx.test.runner.AndroidJUnit4 29 import com.android.modules.utils.build.SdkLevel 30 import com.android.testutils.DevSdkIgnoreRule 31 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 32 import com.android.testutils.NonNullTestUtils 33 import kotlin.reflect.jvm.isAccessible 34 import kotlin.test.assertFails 35 import kotlin.test.assertFailsWith 36 import org.junit.Assert.assertEquals 37 import org.junit.Assert.assertNotNull 38 import org.junit.Assert.assertNull 39 import org.junit.Assert.assertTrue 40 import org.junit.Rule 41 import org.junit.Test 42 import org.junit.runner.RunWith 43 44 const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE 45 const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI 46 const val MOBILE_TYPE_NAME = "mobile" 47 const val WIFI_TYPE_NAME = "WIFI" 48 const val LTE_SUBTYPE_NAME = "LTE" 49 50 @SmallTest 51 @RunWith(AndroidJUnit4::class) 52 class NetworkInfoTest { 53 @Rule @JvmField 54 val ignoreRule = DevSdkIgnoreRule() 55 56 @Test testAccessNetworkInfoPropertiesnull57 fun testAccessNetworkInfoProperties() { 58 val cm = InstrumentationRegistry.getInstrumentation().context 59 .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 60 val ni = cm.getAllNetworkInfo() 61 assertTrue(ni.isNotEmpty()) 62 63 for (netInfo in ni) { 64 when (netInfo.getType()) { 65 TYPE_MOBILE -> assertNetworkInfo(netInfo, MOBILE_TYPE_NAME) 66 TYPE_WIFI -> assertNetworkInfo(netInfo, WIFI_TYPE_NAME) 67 // TODO: Add BLUETOOTH_TETHER testing 68 } 69 } 70 } 71 assertNetworkInfonull72 private fun assertNetworkInfo(netInfo: NetworkInfo, expectedTypeName: String) { 73 assertTrue(expectedTypeName.equals(netInfo.getTypeName(), ignoreCase = true)) 74 assertNotNull(netInfo.toString()) 75 76 if (!netInfo.isConnectedOrConnecting()) return 77 78 assertTrue(netInfo.isAvailable()) 79 if (State.CONNECTED == netInfo.getState()) { 80 assertTrue(netInfo.isConnected()) 81 } 82 assertTrue(State.CONNECTING == netInfo.getState() || 83 State.CONNECTED == netInfo.getState()) 84 assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() || 85 DetailedState.CONNECTING == netInfo.getDetailedState() || 86 DetailedState.AUTHENTICATING == netInfo.getDetailedState() || 87 DetailedState.CONNECTED == netInfo.getDetailedState()) 88 } 89 90 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testConstructornull91 fun testConstructor() { 92 val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 93 MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) 94 95 assertEquals(TYPE_MOBILE, networkInfo.type) 96 assertEquals(TelephonyManager.NETWORK_TYPE_LTE, networkInfo.subtype) 97 assertEquals(MOBILE_TYPE_NAME, networkInfo.typeName) 98 assertEquals(LTE_SUBTYPE_NAME, networkInfo.subtypeName) 99 assertEquals(DetailedState.IDLE, networkInfo.detailedState) 100 assertEquals(State.UNKNOWN, networkInfo.state) 101 assertNull(networkInfo.reason) 102 assertNull(networkInfo.extraInfo) 103 104 assertFailsWith<IllegalArgumentException> { 105 NetworkInfo(ConnectivityManager.MAX_NETWORK_TYPE + 1, 106 TelephonyManager.NETWORK_TYPE_LTE, MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) 107 } 108 109 if (SdkLevel.isAtLeastT()) { 110 assertFailsWith<NullPointerException> { 111 NetworkInfo(NonNullTestUtils.nullUnsafe<NetworkInfo>(null)) 112 } 113 } else { 114 // Doesn't immediately crash on S- 115 NetworkInfo(NonNullTestUtils.nullUnsafe<NetworkInfo>(null)) 116 } 117 } 118 119 @Test testSetDetailedStatenull120 fun testSetDetailedState() { 121 val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, 122 MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) 123 val reason = "TestNetworkInfo" 124 val extraReason = "setDetailedState test" 125 126 networkInfo.setDetailedState(DetailedState.CONNECTED, reason, extraReason) 127 assertEquals(DetailedState.CONNECTED, networkInfo.detailedState) 128 assertEquals(State.CONNECTED, networkInfo.state) 129 assertEquals(reason, networkInfo.reason) 130 assertEquals(extraReason, networkInfo.extraInfo) 131 132 // Create an incorrect enum value by calling the default constructor of the enum 133 val constructor = DetailedState::class.java.declaredConstructors.first { 134 it.parameters.size == 2 135 } 136 constructor.isAccessible = true 137 val incorrectDetailedState = constructor.newInstance("any", 200) as DetailedState 138 if (SdkLevel.isAtLeastT()) { 139 assertFailsWith<NullPointerException> { 140 NetworkInfo(NonNullTestUtils.nullUnsafe<NetworkInfo>(null)) 141 } 142 assertFailsWith<NullPointerException> { 143 networkInfo.setDetailedState(NonNullTestUtils.nullUnsafe<DetailedState>(null), 144 "reason", "extraInfo") 145 } 146 // This actually throws ArrayOutOfBoundsException because of the implementation of 147 // EnumMap, but that's an implementation detail so accept any crash. 148 assertFails { 149 networkInfo.setDetailedState(incorrectDetailedState, "reason", "extraInfo") 150 } 151 } else { 152 // Doesn't immediately crash on S- 153 NetworkInfo(NonNullTestUtils.nullUnsafe<NetworkInfo>(null)) 154 networkInfo.setDetailedState(NonNullTestUtils.nullUnsafe<DetailedState>(null), 155 "reason", "extraInfo") 156 } 157 } 158 } 159