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