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.internal.telephony.metrics; 18 19 import static com.android.internal.telephony.TelephonyStatsLog.CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS; 20 import static com.android.internal.telephony.TelephonyStatsLog.CARRIER_ROAMING_SATELLITE_SESSION; 21 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_DATA_SERVICE_SWITCH; 22 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE; 23 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SHORT_CODE_SMS; 24 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_CONFIG_UPDATER; 25 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_ENTITLEMENT; 26 import static com.android.internal.telephony.TelephonyStatsLog.SIM_SLOT_STATE; 27 import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY; 28 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE; 29 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION; 30 import static com.android.internal.telephony.util.TelephonyUtils.IS_DEBUGGABLE; 31 32 import static com.google.common.truth.Truth.assertThat; 33 34 import static org.mockito.Mockito.anyLong; 35 import static org.mockito.Mockito.doReturn; 36 import static org.mockito.Mockito.eq; 37 import static org.mockito.Mockito.mock; 38 import static org.mockito.Mockito.times; 39 import static org.mockito.Mockito.verify; 40 import static org.mockito.Mockito.verifyNoMoreInteractions; 41 42 import android.app.StatsManager; 43 import android.telephony.TelephonyManager; 44 import android.util.StatsEvent; 45 46 import androidx.test.filters.SmallTest; 47 48 import com.android.internal.telephony.Phone; 49 import com.android.internal.telephony.PhoneFactory; 50 import com.android.internal.telephony.TelephonyTest; 51 import com.android.internal.telephony.flags.FeatureFlags; 52 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteControllerStats; 53 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteSession; 54 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch; 55 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState; 56 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; 57 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; 58 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; 59 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage; 60 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession; 61 import com.android.internal.telephony.uicc.IccCardStatus.CardState; 62 import com.android.internal.telephony.uicc.UiccCard; 63 import com.android.internal.telephony.uicc.UiccController; 64 import com.android.internal.telephony.uicc.UiccPort; 65 import com.android.internal.telephony.uicc.UiccProfile; 66 import com.android.internal.telephony.uicc.UiccSlot; 67 68 import org.junit.After; 69 import org.junit.Before; 70 import org.junit.Test; 71 72 import java.util.ArrayList; 73 import java.util.List; 74 75 public class MetricsCollectorTest extends TelephonyTest { 76 private static final StatsManager.PullAtomMetadata POLICY_PULL_DAILY = 77 new StatsManager.PullAtomMetadata.Builder() 78 .setCoolDownMillis(24L * 3600L * 1000L) 79 .build(); 80 private static final long MIN_COOLDOWN_MILLIS = 23L * 3600L * 1000L; 81 private static final long POWER_CORRELATED_MIN_COOLDOWN_MILLIS = 82 IS_DEBUGGABLE ? 4L * 60L * 1000L : 5L * 3600L * 1000L; 83 private static final long MIN_CALLS_PER_BUCKET = 5L; 84 85 // NOTE: these fields are currently 32-bit internally and padded to 64-bit by TelephonyManager 86 private static final int SUPPORTED_RAF_1 = 87 (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM 88 | (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE 89 | (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR; 90 private static final int SUPPORTED_RAF_2 = 91 (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM 92 | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT 93 | (int) TelephonyManager.NETWORK_TYPE_BITMASK_UMTS; 94 private static final int SUPPORTED_RAF_BOTH = SUPPORTED_RAF_1 | SUPPORTED_RAF_2; 95 96 // TODO: if we want to check puller registration by mocking StatsManager, we will have to enable 97 // inline mocking since the StatsManager class is final 98 99 // b/153195691: we cannot verify the contents of StatsEvent as its getters are marked with @hide 100 101 // Mocked classes 102 private Phone mSecondPhone; 103 private UiccSlot mPhysicalSlot; 104 private UiccSlot mEsimSlot; 105 private UiccCard mActiveCard; 106 private UiccPort mActivePort; 107 private ServiceStateStats mServiceStateStats; 108 private VonrHelper mVonrHelper; 109 private FeatureFlags mFeatureFlags; 110 111 private MetricsCollector mMetricsCollector; 112 113 @Before setUp()114 public void setUp() throws Exception { 115 super.setUp(getClass().getSimpleName()); 116 mSecondPhone = mock(Phone.class); 117 mPhysicalSlot = mock(UiccSlot.class); 118 mEsimSlot = mock(UiccSlot.class); 119 mActiveCard = mock(UiccCard.class); 120 mActivePort = mock(UiccPort.class); 121 mServiceStateStats = mock(ServiceStateStats.class); 122 mVonrHelper = mock(VonrHelper.class); 123 mFeatureFlags = mock(FeatureFlags.class); 124 mMetricsCollector = 125 new MetricsCollector(mContext, mPersistAtomsStorage, 126 mDeviceStateHelper, mVonrHelper, mDefaultNetworkMonitor, mFeatureFlags); 127 doReturn(mSST).when(mSecondPhone).getServiceStateTracker(); 128 doReturn(mServiceStateStats).when(mSST).getServiceStateStats(); 129 } 130 131 @After tearDown()132 public void tearDown() throws Exception { 133 mMetricsCollector = null; 134 super.tearDown(); 135 } 136 137 @Test 138 @SmallTest onPullAtom_simSlotState_bothSimPresent()139 public void onPullAtom_simSlotState_bothSimPresent() { 140 // these have been tested extensively in SimSlotStateTest, here we verify atom generation 141 UiccProfile activeProfile = mock(UiccProfile.class); 142 doReturn(4).when(activeProfile).getNumApplications(); 143 doReturn(activeProfile).when(mActivePort).getUiccProfile(); 144 doReturn(true).when(mPhysicalSlot).isActive(); 145 doReturn(CardState.CARDSTATE_PRESENT).when(mPhysicalSlot).getCardState(); 146 doReturn(false).when(mPhysicalSlot).isEuicc(); 147 doReturn(true).when(mEsimSlot).isActive(); 148 doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState(); 149 doReturn(true).when(mEsimSlot).isEuicc(); 150 doReturn(mActiveCard).when(mEsimSlot).getUiccCard(); 151 doReturn(new UiccPort[] {mActivePort}).when(mActiveCard).getUiccPortList(); 152 doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots(); 153 doReturn(mPhysicalSlot).when(mUiccController).getUiccSlot(eq(0)); 154 doReturn(mEsimSlot).when(mUiccController).getUiccSlot(eq(1)); 155 StatsEvent expectedAtom = 156 StatsEvent.newBuilder() 157 .setAtomId(SIM_SLOT_STATE) 158 .writeInt(2) 159 .writeInt(2) 160 .writeInt(1) 161 .build(); 162 List<StatsEvent> actualAtoms = new ArrayList<>(); 163 164 int result = mMetricsCollector.onPullAtom(SIM_SLOT_STATE, actualAtoms); 165 166 assertThat(actualAtoms).hasSize(1); 167 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 168 // TODO(b/153196254): verify atom contents 169 } 170 171 @Test 172 @SmallTest onPullAtom_simSlotState_beforeUiccControllerReady()173 public void onPullAtom_simSlotState_beforeUiccControllerReady() throws Exception { 174 // there is a slight chance that MetricsCollector gets pulled after registration while 175 // PhoneFactory havne't made UiccController yet, RuntimeException will be thrown 176 replaceInstance(UiccController.class, "mInstance", mUiccController, null); 177 List<StatsEvent> actualAtoms = new ArrayList<>(); 178 179 int result = mMetricsCollector.onPullAtom(SIM_SLOT_STATE, actualAtoms); 180 181 assertThat(actualAtoms).hasSize(0); 182 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 183 } 184 185 @Test 186 @SmallTest onPullAtom_supportedRadioAccessFamily_singlePhone()187 public void onPullAtom_supportedRadioAccessFamily_singlePhone() { 188 doReturn(SUPPORTED_RAF_1).when(mPhone).getRadioAccessFamily(); 189 StatsEvent expectedAtom = 190 StatsEvent.newBuilder() 191 .setAtomId(SUPPORTED_RADIO_ACCESS_FAMILY) 192 .writeLong(SUPPORTED_RAF_1) 193 .build(); 194 List<StatsEvent> actualAtoms = new ArrayList<>(); 195 196 int result = mMetricsCollector.onPullAtom(SUPPORTED_RADIO_ACCESS_FAMILY, actualAtoms); 197 198 assertThat(actualAtoms).hasSize(1); 199 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 200 // TODO(b/153196254): verify atom contents 201 } 202 203 @Test 204 @SmallTest onPullAtom_supportedRadioAccessFamily_dualPhones()205 public void onPullAtom_supportedRadioAccessFamily_dualPhones() { 206 doReturn(SUPPORTED_RAF_1).when(mPhone).getRadioAccessFamily(); 207 doReturn(SUPPORTED_RAF_2).when(mSecondPhone).getRadioAccessFamily(); 208 mPhones = new Phone[] {mPhone, mSecondPhone}; 209 StatsEvent expectedAtom = 210 StatsEvent.newBuilder() 211 .setAtomId(SUPPORTED_RADIO_ACCESS_FAMILY) 212 .writeLong(SUPPORTED_RAF_BOTH) 213 .build(); 214 List<StatsEvent> actualAtoms = new ArrayList<>(); 215 216 int result = mMetricsCollector.onPullAtom(SUPPORTED_RADIO_ACCESS_FAMILY, actualAtoms); 217 218 assertThat(actualAtoms).hasSize(1); 219 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 220 // TODO(b/153196254): verify atom contents 221 } 222 223 @Test 224 @SmallTest onPullAtom_supportedRadioAccessFamily_dualPhonesWithUnknownRaf()225 public void onPullAtom_supportedRadioAccessFamily_dualPhonesWithUnknownRaf() { 226 doReturn(SUPPORTED_RAF_1).when(mPhone).getRadioAccessFamily(); 227 doReturn((int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN) 228 .when(mSecondPhone) 229 .getRadioAccessFamily(); 230 mPhones = new Phone[] {mPhone, mSecondPhone}; 231 StatsEvent expectedAtom = 232 StatsEvent.newBuilder() 233 .setAtomId(SUPPORTED_RADIO_ACCESS_FAMILY) 234 .writeLong(SUPPORTED_RAF_1) 235 .build(); 236 List<StatsEvent> actualAtoms = new ArrayList<>(); 237 238 int result = mMetricsCollector.onPullAtom(SUPPORTED_RADIO_ACCESS_FAMILY, actualAtoms); 239 240 assertThat(actualAtoms).hasSize(1); 241 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 242 // TODO(b/153196254): verify atom contents 243 } 244 245 @Test 246 @SmallTest onPullAtom_supportedRadioAccessFamily_beforePhoneReady()247 public void onPullAtom_supportedRadioAccessFamily_beforePhoneReady() throws Exception { 248 replaceInstance(PhoneFactory.class, "sMadeDefaults", true, false); 249 List<StatsEvent> actualAtoms = new ArrayList<>(); 250 251 int result = mMetricsCollector.onPullAtom(SUPPORTED_RADIO_ACCESS_FAMILY, actualAtoms); 252 253 assertThat(actualAtoms).hasSize(0); 254 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 255 } 256 257 @Test 258 @SmallTest onPullAtom_voiceCallRatUsage_empty()259 public void onPullAtom_voiceCallRatUsage_empty() throws Exception { 260 doReturn(new VoiceCallRatUsage[0]) 261 .when(mPersistAtomsStorage) 262 .getVoiceCallRatUsages(anyLong()); 263 List<StatsEvent> actualAtoms = new ArrayList<>(); 264 265 int result = mMetricsCollector.onPullAtom(VOICE_CALL_RAT_USAGE, actualAtoms); 266 267 assertThat(actualAtoms).hasSize(0); 268 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 269 } 270 271 @Test 272 @SmallTest onPullAtom_voiceCallRatUsage_tooFrequent()273 public void onPullAtom_voiceCallRatUsage_tooFrequent() throws Exception { 274 doReturn(null).when(mPersistAtomsStorage).getVoiceCallRatUsages(anyLong()); 275 List<StatsEvent> actualAtoms = new ArrayList<>(); 276 277 int result = mMetricsCollector.onPullAtom(VOICE_CALL_RAT_USAGE, actualAtoms); 278 279 assertThat(actualAtoms).hasSize(0); 280 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 281 verify(mPersistAtomsStorage, times(1)).getVoiceCallRatUsages(eq(MIN_COOLDOWN_MILLIS)); 282 verifyNoMoreInteractions(mPersistAtomsStorage); 283 } 284 285 @Test 286 @SmallTest onPullAtom_voiceCallRatUsage_bucketWithTooFewCalls()287 public void onPullAtom_voiceCallRatUsage_bucketWithTooFewCalls() throws Exception { 288 VoiceCallRatUsage usage1 = new VoiceCallRatUsage(); 289 usage1.callCount = MIN_CALLS_PER_BUCKET; 290 VoiceCallRatUsage usage2 = new VoiceCallRatUsage(); 291 usage2.callCount = MIN_CALLS_PER_BUCKET - 1L; 292 doReturn(new VoiceCallRatUsage[] {usage1, usage1, usage1, usage2}) 293 .when(mPersistAtomsStorage) 294 .getVoiceCallRatUsages(anyLong()); 295 List<StatsEvent> actualAtoms = new ArrayList<>(); 296 297 int result = mMetricsCollector.onPullAtom(VOICE_CALL_RAT_USAGE, actualAtoms); 298 299 assertThat(actualAtoms).hasSize(3); // usage 2 should be dropped 300 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 301 // TODO(b/153196254): verify atom contents 302 } 303 304 @Test 305 @SmallTest onPullAtom_voiceCallSession_empty()306 public void onPullAtom_voiceCallSession_empty() throws Exception { 307 doReturn(new VoiceCallSession[0]) 308 .when(mPersistAtomsStorage) 309 .getVoiceCallSessions(anyLong()); 310 List<StatsEvent> actualAtoms = new ArrayList<>(); 311 312 int result = mMetricsCollector.onPullAtom(VOICE_CALL_SESSION, actualAtoms); 313 314 assertThat(actualAtoms).hasSize(0); 315 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 316 } 317 318 @Test 319 @SmallTest onPullAtom_voiceCallSession_tooFrequent()320 public void onPullAtom_voiceCallSession_tooFrequent() throws Exception { 321 doReturn(null).when(mPersistAtomsStorage).getVoiceCallSessions(anyLong()); 322 List<StatsEvent> actualAtoms = new ArrayList<>(); 323 324 int result = mMetricsCollector.onPullAtom(VOICE_CALL_SESSION, actualAtoms); 325 326 assertThat(actualAtoms).hasSize(0); 327 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 328 verify(mPersistAtomsStorage, times(1)).getVoiceCallSessions(eq(MIN_COOLDOWN_MILLIS)); 329 verifyNoMoreInteractions(mPersistAtomsStorage); 330 } 331 332 @Test 333 @SmallTest onPullAtom_voiceCallSession_multipleCalls()334 public void onPullAtom_voiceCallSession_multipleCalls() throws Exception { 335 VoiceCallSession call = new VoiceCallSession(); 336 doReturn(new VoiceCallSession[] {call, call, call, call}) 337 .when(mPersistAtomsStorage) 338 .getVoiceCallSessions(anyLong()); 339 List<StatsEvent> actualAtoms = new ArrayList<>(); 340 341 int result = mMetricsCollector.onPullAtom(VOICE_CALL_SESSION, actualAtoms); 342 343 assertThat(actualAtoms).hasSize(4); 344 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 345 // TODO(b/153196254): verify atom contents 346 } 347 348 @Test 349 @SmallTest onPullAtom_cellularDataServiceSwitch_empty()350 public void onPullAtom_cellularDataServiceSwitch_empty() throws Exception { 351 doReturn(new CellularDataServiceSwitch[0]) 352 .when(mPersistAtomsStorage) 353 .getCellularDataServiceSwitches(anyLong()); 354 List<StatsEvent> actualAtoms = new ArrayList<>(); 355 356 int result = mMetricsCollector.onPullAtom(CELLULAR_DATA_SERVICE_SWITCH, actualAtoms); 357 358 assertThat(actualAtoms).hasSize(0); 359 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 360 // TODO(b/153196254): verify atom contents 361 } 362 363 @Test 364 @SmallTest onPullAtom_cellularDataServiceSwitch_tooFrequent()365 public void onPullAtom_cellularDataServiceSwitch_tooFrequent() throws Exception { 366 doReturn(null).when(mPersistAtomsStorage).getCellularDataServiceSwitches(anyLong()); 367 List<StatsEvent> actualAtoms = new ArrayList<>(); 368 369 int result = mMetricsCollector.onPullAtom(CELLULAR_DATA_SERVICE_SWITCH, actualAtoms); 370 371 assertThat(actualAtoms).hasSize(0); 372 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 373 verify(mPersistAtomsStorage, times(1)) 374 .getCellularDataServiceSwitches(eq(MIN_COOLDOWN_MILLIS)); 375 verifyNoMoreInteractions(mPersistAtomsStorage); 376 } 377 378 @Test 379 @SmallTest onPullAtom_cellularDataServiceSwitch_multipleSwitches()380 public void onPullAtom_cellularDataServiceSwitch_multipleSwitches() throws Exception { 381 CellularDataServiceSwitch serviceSwitch = new CellularDataServiceSwitch(); 382 doReturn(new CellularDataServiceSwitch[] {serviceSwitch, serviceSwitch, serviceSwitch}) 383 .when(mPersistAtomsStorage) 384 .getCellularDataServiceSwitches(anyLong()); 385 List<StatsEvent> actualAtoms = new ArrayList<>(); 386 387 int result = mMetricsCollector.onPullAtom(CELLULAR_DATA_SERVICE_SWITCH, actualAtoms); 388 389 assertThat(actualAtoms).hasSize(3); 390 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 391 // TODO(b/153196254): verify atom contents 392 } 393 394 @Test 395 @SmallTest onPullAtom_cellularServiceState_empty()396 public void onPullAtom_cellularServiceState_empty() throws Exception { 397 doReturn(new CellularServiceState[0]) 398 .when(mPersistAtomsStorage) 399 .getCellularServiceStates(anyLong()); 400 List<StatsEvent> actualAtoms = new ArrayList<>(); 401 402 int result = mMetricsCollector.onPullAtom(CELLULAR_SERVICE_STATE, actualAtoms); 403 404 assertThat(actualAtoms).hasSize(0); 405 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 406 // TODO(b/153196254): verify atom contents 407 } 408 409 @Test 410 @SmallTest onPullAtom_cellularServiceState_tooFrequent()411 public void onPullAtom_cellularServiceState_tooFrequent() throws Exception { 412 doReturn(null).when(mPersistAtomsStorage).getCellularServiceStates(anyLong()); 413 mContextFixture.putIntResource( 414 com.android.internal.R.integer.config_metrics_pull_cooldown_millis, 415 (int) POWER_CORRELATED_MIN_COOLDOWN_MILLIS); 416 List<StatsEvent> actualAtoms = new ArrayList<>(); 417 418 int result = mMetricsCollector.onPullAtom(CELLULAR_SERVICE_STATE, actualAtoms); 419 420 assertThat(actualAtoms).hasSize(0); 421 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 422 verify(mPersistAtomsStorage, times(1)).getCellularServiceStates( 423 eq(POWER_CORRELATED_MIN_COOLDOWN_MILLIS)); 424 verifyNoMoreInteractions(mPersistAtomsStorage); 425 } 426 427 @Test 428 @SmallTest onPullAtom_cellularServiceState_multipleStates()429 public void onPullAtom_cellularServiceState_multipleStates() throws Exception { 430 CellularServiceState state = new CellularServiceState(); 431 doReturn(new CellularServiceState[] {state, state, state}) 432 .when(mPersistAtomsStorage) 433 .getCellularServiceStates(anyLong()); 434 List<StatsEvent> actualAtoms = new ArrayList<>(); 435 436 int result = mMetricsCollector.onPullAtom(CELLULAR_SERVICE_STATE, actualAtoms); 437 438 assertThat(actualAtoms).hasSize(3); 439 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 440 // TODO(b/153196254): verify atom contents 441 } 442 443 @Test onPullAtom_outgoingShortCodeSms_empty()444 public void onPullAtom_outgoingShortCodeSms_empty() { 445 doReturn(new OutgoingShortCodeSms[0]).when(mPersistAtomsStorage) 446 .getOutgoingShortCodeSms(anyLong()); 447 List<StatsEvent> actualAtoms = new ArrayList<>(); 448 449 int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms); 450 451 assertThat(actualAtoms).hasSize(0); 452 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 453 } 454 455 @Test onPullAtom_outgoingShortCodeSms_tooFrequent()456 public void onPullAtom_outgoingShortCodeSms_tooFrequent() { 457 doReturn(null).when(mPersistAtomsStorage).getOutgoingShortCodeSms(anyLong()); 458 List<StatsEvent> actualAtoms = new ArrayList<>(); 459 460 int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms); 461 462 assertThat(actualAtoms).hasSize(0); 463 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 464 verify(mPersistAtomsStorage, times(1)) 465 .getOutgoingShortCodeSms(eq(MIN_COOLDOWN_MILLIS)); 466 verifyNoMoreInteractions(mPersistAtomsStorage); 467 } 468 469 @Test onPullAtom_outgoingShortCodeSms_multipleSms()470 public void onPullAtom_outgoingShortCodeSms_multipleSms() { 471 OutgoingShortCodeSms outgoingShortCodeSms = new OutgoingShortCodeSms(); 472 doReturn(new OutgoingShortCodeSms[] {outgoingShortCodeSms, outgoingShortCodeSms, 473 outgoingShortCodeSms, outgoingShortCodeSms}) 474 .when(mPersistAtomsStorage) 475 .getOutgoingShortCodeSms(anyLong()); 476 List<StatsEvent> actualAtoms = new ArrayList<>(); 477 478 int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms); 479 480 assertThat(actualAtoms).hasSize(4); 481 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 482 } 483 484 @Test onPullAtom_carrierRoamingSatelliteSession_empty()485 public void onPullAtom_carrierRoamingSatelliteSession_empty() { 486 doReturn(new CarrierRoamingSatelliteSession[0]).when(mPersistAtomsStorage) 487 .getCarrierRoamingSatelliteSessionStats(anyLong()); 488 List<StatsEvent> actualAtoms = new ArrayList<>(); 489 490 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_SESSION, actualAtoms); 491 492 assertThat(actualAtoms).hasSize(0); 493 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 494 } 495 496 @Test onPullAtom_carrierRoamingSatelliteSession_tooFrequent()497 public void onPullAtom_carrierRoamingSatelliteSession_tooFrequent() { 498 doReturn(null).when(mPersistAtomsStorage) 499 .getCarrierRoamingSatelliteSessionStats(anyLong()); 500 List<StatsEvent> actualAtoms = new ArrayList<>(); 501 502 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_SESSION, actualAtoms); 503 504 assertThat(actualAtoms).hasSize(0); 505 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 506 verify(mPersistAtomsStorage, times(1)) 507 .getCarrierRoamingSatelliteSessionStats(eq(MIN_COOLDOWN_MILLIS)); 508 verifyNoMoreInteractions(mPersistAtomsStorage); 509 } 510 511 @Test onPullAtom_carrierRoamingSatelliteSession_multipleAtoms()512 public void onPullAtom_carrierRoamingSatelliteSession_multipleAtoms() { 513 CarrierRoamingSatelliteSession carrierRoamingSatelliteSession = 514 new CarrierRoamingSatelliteSession(); 515 doReturn(new CarrierRoamingSatelliteSession[] {carrierRoamingSatelliteSession, 516 carrierRoamingSatelliteSession, carrierRoamingSatelliteSession, 517 carrierRoamingSatelliteSession}) 518 .when(mPersistAtomsStorage) 519 .getCarrierRoamingSatelliteSessionStats(anyLong()); 520 List<StatsEvent> actualAtoms = new ArrayList<>(); 521 522 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_SESSION, actualAtoms); 523 524 assertThat(actualAtoms).hasSize(4); 525 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 526 } 527 528 @Test onPullAtom_carrierRoamingSatelliteControllerStats_empty()529 public void onPullAtom_carrierRoamingSatelliteControllerStats_empty() { 530 doReturn(new CarrierRoamingSatelliteControllerStats[0]).when(mPersistAtomsStorage) 531 .getCarrierRoamingSatelliteControllerStats(anyLong()); 532 List<StatsEvent> actualAtoms = new ArrayList<>(); 533 534 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS, 535 actualAtoms); 536 537 assertThat(actualAtoms).hasSize(0); 538 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 539 } 540 541 @Test onPullAtom_carrierRoamingSatelliteControllerStats_multipleAtoms()542 public void onPullAtom_carrierRoamingSatelliteControllerStats_multipleAtoms() { 543 CarrierRoamingSatelliteControllerStats carrierRoamingSatelliteControllerStats = 544 new CarrierRoamingSatelliteControllerStats(); 545 doReturn(new CarrierRoamingSatelliteControllerStats[] { 546 carrierRoamingSatelliteControllerStats}) 547 .when(mPersistAtomsStorage) 548 .getCarrierRoamingSatelliteControllerStats(anyLong()); 549 List<StatsEvent> actualAtoms = new ArrayList<>(); 550 551 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS, 552 actualAtoms); 553 554 assertThat(actualAtoms).hasSize(1); 555 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 556 } 557 558 @Test onPullAtom_carrierRoamingSatelliteControllerStats_tooFrequent()559 public void onPullAtom_carrierRoamingSatelliteControllerStats_tooFrequent() { 560 doReturn(null).when(mPersistAtomsStorage) 561 .getCarrierRoamingSatelliteControllerStats(anyLong()); 562 List<StatsEvent> actualAtoms = new ArrayList<>(); 563 564 int result = mMetricsCollector.onPullAtom(CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS, 565 actualAtoms); 566 567 assertThat(actualAtoms).hasSize(0); 568 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 569 verify(mPersistAtomsStorage, times(1)) 570 .getCarrierRoamingSatelliteControllerStats(eq(MIN_COOLDOWN_MILLIS)); 571 verifyNoMoreInteractions(mPersistAtomsStorage); 572 } 573 574 @Test onPullAtom_satelliteEntitlement_empty()575 public void onPullAtom_satelliteEntitlement_empty() { 576 doReturn(new SatelliteEntitlement[0]).when(mPersistAtomsStorage) 577 .getSatelliteEntitlementStats(anyLong()); 578 List<StatsEvent> actualAtoms = new ArrayList<>(); 579 580 int result = mMetricsCollector.onPullAtom(SATELLITE_ENTITLEMENT, actualAtoms); 581 582 assertThat(actualAtoms).hasSize(0); 583 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 584 } 585 586 @Test onPullAtom_satelliteEntitlement_tooFrequent()587 public void onPullAtom_satelliteEntitlement_tooFrequent() { 588 doReturn(null).when(mPersistAtomsStorage).getSatelliteEntitlementStats( 589 anyLong()); 590 List<StatsEvent> actualAtoms = new ArrayList<>(); 591 592 int result = mMetricsCollector.onPullAtom(SATELLITE_ENTITLEMENT, actualAtoms); 593 594 assertThat(actualAtoms).hasSize(0); 595 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 596 verify(mPersistAtomsStorage, times(1)) 597 .getSatelliteEntitlementStats(eq(MIN_COOLDOWN_MILLIS)); 598 verifyNoMoreInteractions(mPersistAtomsStorage); 599 } 600 601 @Test onPullAtom_satelliteEntitlement_multipleAtoms()602 public void onPullAtom_satelliteEntitlement_multipleAtoms() { 603 SatelliteEntitlement satelliteEntitlement = new SatelliteEntitlement(); 604 doReturn(new SatelliteEntitlement[] {satelliteEntitlement, satelliteEntitlement, 605 satelliteEntitlement, satelliteEntitlement}) 606 .when(mPersistAtomsStorage) 607 .getSatelliteEntitlementStats(anyLong()); 608 List<StatsEvent> actualAtoms = new ArrayList<>(); 609 610 int result = mMetricsCollector.onPullAtom(SATELLITE_ENTITLEMENT, actualAtoms); 611 612 assertThat(actualAtoms).hasSize(4); 613 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 614 } 615 616 @Test onPullAtom_satelliteConfigUpdater_empty()617 public void onPullAtom_satelliteConfigUpdater_empty() { 618 doReturn(new SatelliteConfigUpdater[0]).when(mPersistAtomsStorage) 619 .getSatelliteConfigUpdaterStats(anyLong()); 620 List<StatsEvent> actualAtoms = new ArrayList<>(); 621 622 int result = mMetricsCollector.onPullAtom(SATELLITE_CONFIG_UPDATER, actualAtoms); 623 624 assertThat(actualAtoms).hasSize(0); 625 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 626 } 627 628 @Test onPullAtom_satelliteConfigUpdater_tooFrequent()629 public void onPullAtom_satelliteConfigUpdater_tooFrequent() { 630 doReturn(null).when(mPersistAtomsStorage).getSatelliteConfigUpdaterStats( 631 anyLong()); 632 List<StatsEvent> actualAtoms = new ArrayList<>(); 633 634 int result = mMetricsCollector.onPullAtom(SATELLITE_CONFIG_UPDATER, actualAtoms); 635 636 assertThat(actualAtoms).hasSize(0); 637 assertThat(result).isEqualTo(StatsManager.PULL_SKIP); 638 verify(mPersistAtomsStorage, times(1)) 639 .getSatelliteConfigUpdaterStats(eq(MIN_COOLDOWN_MILLIS)); 640 verifyNoMoreInteractions(mPersistAtomsStorage); 641 } 642 643 @Test onPullAtom_satelliteConfigUpdater_multipleAtoms()644 public void onPullAtom_satelliteConfigUpdater_multipleAtoms() { 645 SatelliteConfigUpdater satelliteConfigUpdater = new SatelliteConfigUpdater(); 646 doReturn(new SatelliteConfigUpdater[] {satelliteConfigUpdater, satelliteConfigUpdater, 647 satelliteConfigUpdater, satelliteConfigUpdater}) 648 .when(mPersistAtomsStorage) 649 .getSatelliteConfigUpdaterStats(anyLong()); 650 List<StatsEvent> actualAtoms = new ArrayList<>(); 651 652 int result = mMetricsCollector.onPullAtom(SATELLITE_CONFIG_UPDATER, actualAtoms); 653 654 assertThat(actualAtoms).hasSize(4); 655 assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS); 656 } 657 } 658