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 com.android.internal.telephony.data; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.ArgumentMatchers.anyString; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.content.ComponentName; 32 import android.content.IntentFilter; 33 import android.content.pm.ServiceInfo; 34 import android.net.NetworkCapabilities; 35 import android.os.AsyncResult; 36 import android.os.IBinder; 37 import android.os.Looper; 38 import android.os.Message; 39 import android.os.PersistableBundle; 40 import android.telephony.AccessNetworkConstants; 41 import android.telephony.AccessNetworkConstants.AccessNetworkType; 42 import android.telephony.NetworkService; 43 import android.telephony.data.ApnSetting; 44 import android.telephony.data.IQualifiedNetworksService; 45 import android.telephony.data.IQualifiedNetworksServiceCallback; 46 import android.testing.AndroidTestingRunner; 47 import android.testing.TestableLooper; 48 49 import com.android.internal.telephony.TelephonyTest; 50 import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback; 51 52 import org.junit.After; 53 import org.junit.Before; 54 import org.junit.Test; 55 import org.junit.runner.RunWith; 56 import org.mockito.Mockito; 57 58 @RunWith(AndroidTestingRunner.class) 59 @TestableLooper.RunWithLooper 60 public class AccessNetworksManagerTest extends TelephonyTest { 61 private AccessNetworksManager mAccessNetworksManager; 62 63 // Mocked classes 64 private IQualifiedNetworksService mMockedQns; 65 private IBinder mMockedIBinder; 66 private AccessNetworksManagerCallback mMockedCallback; 67 private DataConfigManager mMockedDataConfigManager; 68 69 // The real callback passed created by AccessNetworksManager. 70 private IQualifiedNetworksServiceCallback.Stub mQnsCallback; 71 72 private PersistableBundle mBundle; 73 addQnsService()74 private void addQnsService() throws Exception { 75 ServiceInfo QnsInfo = new ServiceInfo(); 76 QnsInfo.packageName = "fake.qns"; 77 QnsInfo.name = "QualifiedNetworksService"; 78 QnsInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE"; 79 IntentFilter qnsIntentfilter = new IntentFilter(); 80 doReturn(mMockedIBinder).when(mMockedQns).asBinder(); 81 doReturn(mMockedQns).when(mMockedIBinder).queryLocalInterface(anyString()); 82 83 doAnswer(invocation -> { 84 mQnsCallback = (IQualifiedNetworksServiceCallback.Stub) invocation.getArguments()[1]; 85 return null; 86 }).when(mMockedQns).createNetworkAvailabilityProvider(anyInt(), 87 any(IQualifiedNetworksServiceCallback.Stub.class)); 88 mContextFixture.addService( 89 NetworkService.SERVICE_INTERFACE, 90 new ComponentName("fake.qns", 91 "fake.qns"), 92 "fake.qns", 93 mMockedQns, 94 QnsInfo, 95 qnsIntentfilter); 96 } 97 98 @Before setUp()99 public void setUp() throws Exception { 100 super.setUp(getClass().getSimpleName()); 101 mMockedQns = mock(IQualifiedNetworksService.class); 102 mMockedIBinder = mock(IBinder.class); 103 104 mBundle = mContextFixture.getCarrierConfigBundle(); 105 when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle); 106 107 addQnsService(); 108 mContextFixture.putResource( 109 com.android.internal.R.string.config_qualified_networks_service_package, 110 "fake.qns"); 111 112 mMockedCallback = Mockito.mock(AccessNetworksManagerCallback.class); 113 doAnswer(invocation -> { 114 ((Runnable) invocation.getArguments()[0]).run(); 115 return null; 116 }).when(mMockedCallback).invokeFromExecutor(any(Runnable.class)); 117 118 mMockedDataConfigManager = Mockito.mock(DataConfigManager.class); 119 mAccessNetworksManager = new AccessNetworksManager(mPhone, Looper.myLooper()); 120 121 processAllMessages(); 122 replaceInstance(AccessNetworksManager.class, "mDataConfigManager", 123 mAccessNetworksManager, mMockedDataConfigManager); 124 125 logd("-setUp"); 126 } 127 128 @After tearDown()129 public void tearDown() throws Exception { 130 mAccessNetworksManager = null; 131 mBundle = null; 132 super.tearDown(); 133 } 134 135 @Test testBindService()136 public void testBindService() { 137 assertThat(mQnsCallback).isNotNull(); 138 } 139 140 @Test testQualifiedNetworkTypesChanged()141 public void testQualifiedNetworkTypesChanged() throws Exception { 142 assertThat(mQnsCallback).isNotNull(); 143 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse(); 144 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS)) 145 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 146 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS)) 147 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 148 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse(); 149 150 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 151 new int[]{AccessNetworkType.IWLAN}); 152 processAllMessages(); 153 154 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS)) 155 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 156 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS)) 157 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 158 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isTrue(); 159 } 160 161 @Test testGuideTransportTypeForEmergencyDataNetwork()162 public void testGuideTransportTypeForEmergencyDataNetwork() throws Exception { 163 doAnswer(invocation -> { 164 int accessNetwork = AccessNetworkType.UNKNOWN; 165 if (invocation.getArguments()[1].equals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)) { 166 accessNetwork = AccessNetworkType.IWLAN; 167 } else if (invocation.getArguments()[1] 168 .equals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)) { 169 accessNetwork = AccessNetworkType.EUTRAN; 170 } 171 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_EMERGENCY, 172 new int[]{accessNetwork}); 173 return null; 174 }).when(mMockedQns).reportEmergencyDataNetworkPreferredTransportChanged(anyInt(), anyInt()); 175 176 AsyncResult asyncResult = 177 new AsyncResult(null, AccessNetworkConstants.TRANSPORT_TYPE_WLAN, null); 178 Message msg = this.mAccessNetworksManager 179 .obtainMessage(1 /* EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY */, asyncResult); 180 mAccessNetworksManager.sendMessage(msg); 181 processAllMessages(); 182 183 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_EMERGENCY)) 184 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 185 } 186 187 @Test testEmptyNetworkTypes()188 public void testEmptyNetworkTypes() throws Exception { 189 testQualifiedNetworkTypesChanged(); 190 191 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 192 new int[0]); 193 processAllMessages(); 194 195 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS)) 196 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 197 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS)) 198 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 199 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse(); 200 } 201 202 @Test testInvalidNetworkTypes()203 public void testInvalidNetworkTypes() throws Exception { 204 testQualifiedNetworkTypesChanged(); 205 206 // Input unknown would become a no-op 207 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 208 new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UNKNOWN}); 209 processAllMessages(); 210 211 // There shouldn't be any changes. 212 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS)) 213 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 214 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS)) 215 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 216 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isTrue(); 217 } 218 219 @Test testEmptyList()220 public void testEmptyList() throws Exception { 221 testQualifiedNetworkTypesChanged(); 222 223 // Empty list input 224 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 225 new int[0]); 226 processAllMessages(); 227 228 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS)) 229 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 230 assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS)) 231 .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 232 assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse(); 233 } 234 235 @Test testCallback()236 public void testCallback() throws Exception { 237 mAccessNetworksManager.registerCallback(mMockedCallback); 238 239 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 240 new int[]{AccessNetworkType.IWLAN}); 241 processAllMessages(); 242 243 verify(mMockedCallback).onPreferredTransportChanged( 244 eq(NetworkCapabilities.NET_CAPABILITY_MMS)); 245 verify(mMockedCallback).onPreferredTransportChanged( 246 eq(NetworkCapabilities.NET_CAPABILITY_IMS)); 247 Mockito.clearInvocations(mMockedCallback); 248 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 249 NetworkCapabilities.NET_CAPABILITY_MMS)).isEqualTo( 250 AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 251 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 252 NetworkCapabilities.NET_CAPABILITY_IMS)).isEqualTo( 253 AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 254 255 mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_XCAP, 256 new int[]{AccessNetworkType.IWLAN}); 257 processAllMessages(); 258 259 verify(mMockedCallback).onPreferredTransportChanged( 260 eq(NetworkCapabilities.NET_CAPABILITY_XCAP)); 261 Mockito.clearInvocations(mMockedCallback); 262 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 263 NetworkCapabilities.NET_CAPABILITY_XCAP)).isEqualTo( 264 AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 265 266 mQnsCallback.onQualifiedNetworkTypesChanged( 267 ApnSetting.TYPE_XCAP | ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS, 268 new int[]{}); 269 verify(mMockedCallback).onPreferredTransportChanged( 270 eq(NetworkCapabilities.NET_CAPABILITY_IMS)); 271 verify(mMockedCallback).onPreferredTransportChanged( 272 eq(NetworkCapabilities.NET_CAPABILITY_MMS)); 273 verify(mMockedCallback).onPreferredTransportChanged( 274 eq(NetworkCapabilities.NET_CAPABILITY_XCAP)); 275 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 276 NetworkCapabilities.NET_CAPABILITY_IMS)).isEqualTo( 277 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 278 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 279 NetworkCapabilities.NET_CAPABILITY_MMS)).isEqualTo( 280 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 281 assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability( 282 NetworkCapabilities.NET_CAPABILITY_XCAP)).isEqualTo( 283 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 284 285 } 286 } 287