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 com.android.server.net; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.fail; 22 import static org.mockito.Mockito.any; 23 import static org.mockito.Mockito.anyInt; 24 import static org.mockito.Mockito.clearInvocations; 25 import static org.mockito.Mockito.eq; 26 import static org.mockito.Mockito.mock; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.reset; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.annotation.NonNull; 34 import android.annotation.Nullable; 35 import android.content.Context; 36 import android.net.NetworkTemplate; 37 import android.os.Build; 38 import android.os.test.TestLooper; 39 import android.telephony.NetworkRegistrationInfo; 40 import android.telephony.PhoneStateListener; 41 import android.telephony.ServiceState; 42 import android.telephony.SubscriptionManager; 43 import android.telephony.TelephonyManager; 44 45 import com.android.internal.util.CollectionUtils; 46 import com.android.server.net.NetworkStatsSubscriptionsMonitor.RatTypeListener; 47 import com.android.testutils.DevSdkIgnoreRule; 48 import com.android.testutils.DevSdkIgnoreRunner; 49 50 import org.junit.Before; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.mockito.ArgumentCaptor; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 57 import java.util.ArrayList; 58 import java.util.List; 59 import java.util.concurrent.Executor; 60 import java.util.concurrent.Executors; 61 62 @RunWith(DevSdkIgnoreRunner.class) 63 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 64 public final class NetworkStatsSubscriptionsMonitorTest { 65 private static final int TEST_SUBID1 = 3; 66 private static final int TEST_SUBID2 = 5; 67 private static final String TEST_IMSI1 = "466921234567890"; 68 private static final String TEST_IMSI2 = "466920987654321"; 69 private static final String TEST_IMSI3 = "466929999999999"; 70 71 @Mock private Context mContext; 72 @Mock private SubscriptionManager mSubscriptionManager; 73 @Mock private TelephonyManager mTelephonyManager; 74 @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate; 75 private final List<Integer> mTestSubList = new ArrayList<>(); 76 77 private final Executor mExecutor = Executors.newSingleThreadExecutor(); 78 private NetworkStatsSubscriptionsMonitor mMonitor; 79 private TestLooper mTestLooper = new TestLooper(); 80 81 @Before setUp()82 public void setUp() { 83 MockitoAnnotations.initMocks(this); 84 85 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); 86 87 when(mContext.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE))) 88 .thenReturn(mSubscriptionManager); 89 when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) 90 .thenReturn(mTelephonyManager); 91 92 mMonitor = new NetworkStatsSubscriptionsMonitor(mContext, mTestLooper.getLooper(), 93 mExecutor, mDelegate); 94 } 95 96 @Test testStartStop()97 public void testStartStop() { 98 // Verify that addOnSubscriptionsChangedListener() is never called before start(). 99 verify(mSubscriptionManager, never()) 100 .addOnSubscriptionsChangedListener(mExecutor, mMonitor); 101 mMonitor.start(); 102 verify(mSubscriptionManager).addOnSubscriptionsChangedListener(mExecutor, mMonitor); 103 104 // Verify that removeOnSubscriptionsChangedListener() is never called before stop() 105 verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(mMonitor); 106 mMonitor.stop(); 107 verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(mMonitor); 108 } 109 110 @NonNull convertArrayListToIntArray(@onNull List<Integer> arrayList)111 private static int[] convertArrayListToIntArray(@NonNull List<Integer> arrayList) { 112 final int[] list = new int[arrayList.size()]; 113 for (int i = 0; i < arrayList.size(); i++) { 114 list[i] = arrayList.get(i); 115 } 116 return list; 117 } 118 setRatTypeForSub(List<RatTypeListener> listeners, int subId, int type)119 private void setRatTypeForSub(List<RatTypeListener> listeners, 120 int subId, int type) { 121 final ServiceState serviceState = mock(ServiceState.class); 122 when(serviceState.getDataNetworkType()).thenReturn(type); 123 final RatTypeListener match = CollectionUtils 124 .find(listeners, it -> it.getSubId() == subId); 125 if (match == null) { 126 fail("Could not find listener with subId: " + subId); 127 } 128 match.onServiceStateChanged(serviceState); 129 } 130 addTestSub(int subId, String subscriberId)131 private void addTestSub(int subId, String subscriberId) { 132 // add SubId to TestSubList. 133 if (mTestSubList.contains(subId)) fail("The subscriber list already contains this ID"); 134 135 mTestSubList.add(subId); 136 137 final int[] subList = convertArrayListToIntArray(mTestSubList); 138 when(mSubscriptionManager.getCompleteActiveSubscriptionIdList()).thenReturn(subList); 139 when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); 140 mMonitor.onSubscriptionsChanged(); 141 } 142 updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId)143 private void updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId) { 144 when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); 145 mMonitor.onSubscriptionsChanged(); 146 } 147 removeTestSub(int subId)148 private void removeTestSub(int subId) { 149 // Remove subId from TestSubList. 150 mTestSubList.removeIf(it -> it == subId); 151 final int[] subList = convertArrayListToIntArray(mTestSubList); 152 when(mSubscriptionManager.getCompleteActiveSubscriptionIdList()).thenReturn(subList); 153 mMonitor.onSubscriptionsChanged(); 154 } 155 assertRatTypeChangedForSub(String subscriberId, int ratType)156 private void assertRatTypeChangedForSub(String subscriberId, int ratType) { 157 assertEquals(ratType, mMonitor.getRatTypeForSubscriberId(subscriberId)); 158 final ArgumentCaptor<Integer> typeCaptor = ArgumentCaptor.forClass(Integer.class); 159 // Verify callback with the subscriberId and the RAT type should be as expected. 160 // It will fail if get a callback with an unexpected RAT type. 161 verify(mDelegate).onCollapsedRatTypeChanged(eq(subscriberId), typeCaptor.capture()); 162 final int type = typeCaptor.getValue(); 163 assertEquals(ratType, type); 164 } 165 assertRatTypeNotChangedForSub(String subscriberId, int ratType)166 private void assertRatTypeNotChangedForSub(String subscriberId, int ratType) { 167 assertEquals(mMonitor.getRatTypeForSubscriberId(subscriberId), ratType); 168 // Should never get callback with any RAT type. 169 verify(mDelegate, never()).onCollapsedRatTypeChanged(eq(subscriberId), anyInt()); 170 } 171 172 @Test testSubChangedAndRatTypeChanged()173 public void testSubChangedAndRatTypeChanged() { 174 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = 175 ArgumentCaptor.forClass(RatTypeListener.class); 176 177 mMonitor.start(); 178 // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback 179 // before changing RAT type. 180 addTestSub(TEST_SUBID1, TEST_IMSI1); 181 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 182 183 // Insert sim2. 184 addTestSub(TEST_SUBID2, TEST_IMSI2); 185 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 186 verify(mTelephonyManager, times(2)).listen(ratTypeListenerCaptor.capture(), 187 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 188 reset(mDelegate); 189 190 // Set RAT type of sim1 to UMTS. 191 // Verify RAT type of sim1 after subscription gets onCollapsedRatTypeChanged() callback 192 // and others remain untouched. 193 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, 194 TelephonyManager.NETWORK_TYPE_UMTS); 195 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 196 assertRatTypeNotChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); 197 assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); 198 reset(mDelegate); 199 200 // Set RAT type of sim2 to LTE. 201 // Verify RAT type of sim2 after subscription gets onCollapsedRatTypeChanged() callback 202 // and others remain untouched. 203 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID2, 204 TelephonyManager.NETWORK_TYPE_LTE); 205 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 206 assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_LTE); 207 assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); 208 reset(mDelegate); 209 210 // Remove sim2 and verify that callbacks are fired and RAT type is correct for sim2. 211 // while the other two remain untouched. 212 removeTestSub(TEST_SUBID2); 213 verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); 214 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 215 assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); 216 assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); 217 reset(mDelegate); 218 219 // Set RAT type of sim1 to UNKNOWN. Then stop monitoring subscription changes 220 // and verify that the listener for sim1 is removed. 221 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, 222 TelephonyManager.NETWORK_TYPE_UNKNOWN); 223 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 224 reset(mDelegate); 225 226 mMonitor.stop(); 227 verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); 228 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 229 } 230 231 232 @Test test5g()233 public void test5g() { 234 mMonitor.start(); 235 // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback 236 // before changing RAT type. Also capture listener for later use. 237 addTestSub(TEST_SUBID1, TEST_IMSI1); 238 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 239 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = 240 ArgumentCaptor.forClass(RatTypeListener.class); 241 verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), 242 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 243 final RatTypeListener listener = CollectionUtils 244 .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1); 245 assertNotNull(listener); 246 247 // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs 248 // NETWORK_TYPE_5G_NSA. 249 final ServiceState serviceState = mock(ServiceState.class); 250 when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); 251 when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); 252 listener.onServiceStateChanged(serviceState); 253 assertRatTypeChangedForSub(TEST_IMSI1, NetworkTemplate.NETWORK_TYPE_5G_NSA); 254 reset(mDelegate); 255 256 // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE. 257 when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); 258 listener.onServiceStateChanged(serviceState); 259 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); 260 reset(mDelegate); 261 262 // Verify NR connected with other RAT type does not take effect. 263 when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS); 264 when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); 265 listener.onServiceStateChanged(serviceState); 266 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 267 reset(mDelegate); 268 269 // Set RAT type to 5G standalone mode, the RAT type should be NR. 270 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, 271 TelephonyManager.NETWORK_TYPE_NR); 272 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); 273 reset(mDelegate); 274 275 // Set NR state to none in standalone mode does not change anything. 276 when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR); 277 when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); 278 listener.onServiceStateChanged(serviceState); 279 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); 280 } 281 282 @Test testSubscriberIdUnavailable()283 public void testSubscriberIdUnavailable() { 284 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = 285 ArgumentCaptor.forClass(RatTypeListener.class); 286 287 mMonitor.start(); 288 // Insert sim1, set subscriberId to null which is normal in SIM PIN locked case. 289 // Verify RAT type is NETWORK_TYPE_UNKNOWN and service will not perform listener 290 // registration. 291 addTestSub(TEST_SUBID1, null); 292 verify(mTelephonyManager, never()).listen(any(), anyInt()); 293 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 294 295 // Set IMSI for sim1, verify the listener will be registered. 296 updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1); 297 verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), 298 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 299 reset(mTelephonyManager); 300 when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); 301 302 // Set RAT type of sim1 to UMTS. Verify RAT type of sim1 is changed. 303 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, 304 TelephonyManager.NETWORK_TYPE_UMTS); 305 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 306 reset(mDelegate); 307 308 // Set IMSI to null again to simulate somehow IMSI is not available, such as 309 // modem crash. Verify service should unregister listener. 310 updateSubscriberIdForTestSub(TEST_SUBID1, null); 311 verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()), 312 eq(PhoneStateListener.LISTEN_NONE)); 313 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 314 reset(mDelegate); 315 clearInvocations(mTelephonyManager); 316 317 // Simulate somehow IMSI is back. Verify service will register with 318 // another listener and fire callback accordingly. 319 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor2 = 320 ArgumentCaptor.forClass(RatTypeListener.class); 321 updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1); 322 verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor2.capture(), 323 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 324 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 325 reset(mDelegate); 326 clearInvocations(mTelephonyManager); 327 328 // Set RAT type of sim1 to LTE. Verify RAT type of sim1 still works. 329 setRatTypeForSub(ratTypeListenerCaptor2.getAllValues(), TEST_SUBID1, 330 TelephonyManager.NETWORK_TYPE_LTE); 331 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); 332 reset(mDelegate); 333 334 mMonitor.stop(); 335 verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor2.getValue()), 336 eq(PhoneStateListener.LISTEN_NONE)); 337 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 338 } 339 340 /** 341 * Verify that when IMSI suddenly changed for a given subId, the service will register a new 342 * listener and unregister the old one, and report changes on updated IMSI. This is for modem 343 * feature that may be enabled for certain carrier, which changes to use a different IMSI while 344 * roaming on certain networks for multi-IMSI SIM cards, but the subId stays the same. 345 */ 346 @Test testSubscriberIdChanged()347 public void testSubscriberIdChanged() { 348 mMonitor.start(); 349 // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback 350 // before changing RAT type. 351 addTestSub(TEST_SUBID1, TEST_IMSI1); 352 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = 353 ArgumentCaptor.forClass(RatTypeListener.class); 354 verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), 355 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 356 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 357 358 // Set RAT type of sim1 to UMTS. 359 // Verify RAT type of sim1 changes accordingly. 360 setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, 361 TelephonyManager.NETWORK_TYPE_UMTS); 362 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); 363 reset(mDelegate); 364 clearInvocations(mTelephonyManager); 365 366 // Simulate IMSI of sim1 changed to IMSI2. Verify the service will register with 367 // another listener and remove the old one. The RAT type of new IMSI stays at 368 // NETWORK_TYPE_UNKNOWN until received initial callback from telephony. 369 final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor2 = 370 ArgumentCaptor.forClass(RatTypeListener.class); 371 updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI2); 372 verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor2.capture(), 373 eq(PhoneStateListener.LISTEN_SERVICE_STATE)); 374 verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()), 375 eq(PhoneStateListener.LISTEN_NONE)); 376 assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 377 assertRatTypeNotChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); 378 reset(mDelegate); 379 380 // Set RAT type of sim1 to UMTS for new listener to simulate the initial callback received 381 // from telephony after registration. Verify RAT type of sim1 changes with IMSI2 382 // accordingly. 383 setRatTypeForSub(ratTypeListenerCaptor2.getAllValues(), TEST_SUBID1, 384 TelephonyManager.NETWORK_TYPE_UMTS); 385 assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); 386 assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UMTS); 387 reset(mDelegate); 388 } 389 } 390