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.metrics; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotEquals; 22 import static org.junit.Assert.assertTrue; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.never; 25 import static org.mockito.Mockito.times; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.verifyNoMoreInteractions; 28 29 import android.telephony.TelephonyProtoEnums; 30 import android.telephony.ims.DelegateRegistrationState; 31 import android.telephony.ims.FeatureTagState; 32 import android.telephony.ims.SipDelegateManager; 33 import android.util.ArraySet; 34 import android.util.Log; 35 36 import androidx.test.filters.SmallTest; 37 38 import com.android.ims.rcs.uce.util.FeatureTags; 39 import com.android.internal.telephony.TelephonyStatsLog; 40 import com.android.internal.telephony.TelephonyTest; 41 import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent; 42 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent; 43 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent; 44 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats; 45 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats; 46 import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; 47 import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; 48 import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; 49 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats; 50 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse; 51 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats; 52 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession; 53 import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats; 54 55 import org.junit.After; 56 import org.junit.Before; 57 import org.junit.Test; 58 import org.mockito.ArgumentCaptor; 59 60 import java.util.ArrayList; 61 import java.util.Arrays; 62 import java.util.List; 63 import java.util.Set; 64 65 public class RcsStatsTest extends TelephonyTest { 66 private static final String TAG = RcsStatsTest.class.getSimpleName(); 67 68 private static final long START_TIME_MILLIS = 2000L; 69 private static final int SLOT_ID = 0; 70 private static final int SLOT2_ID = 1; 71 private static final int INVALID_SLOT_ID = -1; 72 private static final int CARRIER_ID = 100; 73 private static final int CARRIER2_ID = 200; 74 private static final int INVALID_CARRIER_ID = -1; 75 private static final int INVALID_SUB_ID = Integer.MIN_VALUE; 76 77 private class TestResult { 78 public String tagName; 79 public int tagValue; 80 public long duration; 81 public int deniedReason; 82 public int deregiReason; TestResult(String tagName, int tagValue, long duration, int deniedReason, int deregiReason)83 TestResult(String tagName, int tagValue, long duration, 84 int deniedReason, int deregiReason) { 85 this.tagName = tagName; 86 this.tagValue = tagValue; 87 this.duration = duration; 88 this.deniedReason = deniedReason; 89 this.deregiReason = deregiReason; 90 } 91 } 92 93 private final int mSubId = 10; 94 private final int mSubId2 = 20; 95 96 private TestableRcsStats mRcsStats; 97 98 private class TestableRcsStats extends RcsStats { 99 private long mTimeMillis = START_TIME_MILLIS; 100 private boolean mEnabledInvalidSubId = false; 101 TestableRcsStats()102 TestableRcsStats() { 103 super(); 104 } 105 106 @Override getSlotId(int subId)107 protected int getSlotId(int subId) { 108 if (mEnabledInvalidSubId) { 109 return INVALID_SLOT_ID; 110 } 111 112 if (subId == mSubId) { 113 return SLOT_ID; 114 } else if (subId == mSubId2) { 115 return SLOT2_ID; 116 } 117 return SLOT2_ID; 118 } 119 120 @Override getCarrierId(int subId)121 protected int getCarrierId(int subId) { 122 if (mEnabledInvalidSubId) { 123 return INVALID_CARRIER_ID; 124 } 125 126 if (subId == mSubId) { 127 return CARRIER_ID; 128 } else if (subId == mSubId2) { 129 return CARRIER2_ID; 130 } 131 return INVALID_CARRIER_ID; 132 } 133 134 @Override isValidCarrierId(int carrierId)135 protected boolean isValidCarrierId(int carrierId) { 136 if (carrierId == INVALID_CARRIER_ID) { 137 return false; 138 } 139 return true; 140 } 141 142 @Override getWallTimeMillis()143 protected long getWallTimeMillis() { 144 // NOTE: super class constructor will be executed before private field is set, which 145 // gives the wrong start time (mTimeMillis will have its default value of 0L) 146 Log.d(TAG, "getWallTimeMillis return value : " + mTimeMillis); 147 return mTimeMillis == 0L ? START_TIME_MILLIS : mTimeMillis; 148 } 149 150 @Override logd(String msg)151 protected void logd(String msg) { 152 Log.w(TAG, msg); 153 } 154 155 @Override getSubId(int slotId)156 protected int getSubId(int slotId) { 157 if (mEnabledInvalidSubId) { 158 return INVALID_SUB_ID; 159 } 160 161 if (slotId == SLOT_ID) { 162 return mSubId; 163 } else if (slotId == SLOT2_ID) { 164 return mSubId2; 165 } 166 return INVALID_SUB_ID; 167 } 168 setEnableInvalidSubId()169 public void setEnableInvalidSubId() { 170 mEnabledInvalidSubId = true; 171 } setTimeMillis(long timeMillis)172 private void setTimeMillis(long timeMillis) { 173 mTimeMillis = timeMillis; 174 } 175 incTimeMillis(long timeMillis)176 private void incTimeMillis(long timeMillis) { 177 mTimeMillis += timeMillis; 178 Log.d(TAG, "incTimeMillis mTimeMillis : " + mTimeMillis); 179 } 180 getRcsAcsProvisioningCachedSize()181 public int getRcsAcsProvisioningCachedSize() { 182 return mRcsAcsProvisioningStatsList.size(); 183 } 184 getImsRegistrationServiceDescCachedSize()185 public int getImsRegistrationServiceDescCachedSize() { 186 return mImsRegistrationServiceDescStatsList.size(); 187 } 188 getRcsAcsProvisioningCachedTime(int carreirId, int slotId)189 public long getRcsAcsProvisioningCachedTime(int carreirId, int slotId) { 190 for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) { 191 if (stats.carrierId == carreirId && stats.slotId == slotId) { 192 return stats.stateTimerMillis; 193 } 194 } 195 return 0L; 196 } 197 getRcsProvisioningCallbackMapSize()198 public int getRcsProvisioningCallbackMapSize() { 199 return mRcsProvisioningCallbackMap.size(); 200 } 201 dedicatedBearerListenerEventMap_get( final int listenerId)202 public ImsDedicatedBearerListenerEvent dedicatedBearerListenerEventMap_get( 203 final int listenerId) { 204 return mDedicatedBearerListenerEventMap.get(listenerId); 205 } 206 dedicatedBearerListenerEventMap_containsKey(final int listenerId)207 public boolean dedicatedBearerListenerEventMap_containsKey(final int listenerId) { 208 return mDedicatedBearerListenerEventMap.containsKey(listenerId); 209 } 210 dedicatedBearerListenerEventMap_remove(final int listenerId)211 public void dedicatedBearerListenerEventMap_remove(final int listenerId) { 212 mDedicatedBearerListenerEventMap.remove(listenerId); 213 } 214 } 215 216 @Before setUp()217 public void setUp() throws Exception { 218 super.setUp(getClass().getSimpleName()); 219 220 mRcsStats = new TestableRcsStats(); 221 } 222 223 @After tearDown()224 public void tearDown() throws Exception { 225 mRcsStats = null; 226 super.tearDown(); 227 } 228 229 @Test 230 @SmallTest onImsRegistrationFeatureTagStats_withAtoms()231 public void onImsRegistrationFeatureTagStats_withAtoms() throws Exception { 232 int slotId = SLOT_ID; 233 int carrierId = CARRIER_ID; 234 List<String> featureTagList = Arrays.asList( 235 "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.im\"", 236 "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"", 237 "+g.3gpp.icsi-ref=\"hh%3Ashin%3A-b.a.b.o\"", 238 "+g.gsma.rcs.isbot" 239 ); 240 241 int registrationTech = 0; 242 243 mRcsStats.onImsRegistrationFeatureTagStats( 244 mSubId, featureTagList, registrationTech); 245 246 mRcsStats.onStoreCompleteImsRegistrationFeatureTagStats(mSubId); 247 248 ArgumentCaptor<ImsRegistrationFeatureTagStats> captor = 249 ArgumentCaptor.forClass(ImsRegistrationFeatureTagStats.class); 250 verify(mPersistAtomsStorage, times(featureTagList.size())) 251 .addImsRegistrationFeatureTagStats(captor.capture()); 252 List<ImsRegistrationFeatureTagStats> captorValues = captor.getAllValues(); 253 254 assertEquals(captorValues.size(), featureTagList.size()); 255 for (int index = 0; index < captorValues.size(); index++) { 256 ImsRegistrationFeatureTagStats stats = captorValues.get(index); 257 assertEquals(CARRIER_ID, stats.carrierId); 258 assertEquals(SLOT_ID, stats.slotId); 259 assertEquals(mRcsStats.convertTagNameToValue(featureTagList.get(index)), 260 stats.featureTagName); 261 assertEquals(registrationTech, stats.registrationTech); 262 } 263 } 264 265 @Test 266 @SmallTest onRcsClientProvisioningStats_withAtoms()267 public void onRcsClientProvisioningStats_withAtoms() throws Exception { 268 /* 269 * RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT 270 * RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION 271 * RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED 272 */ 273 int event = 274 TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT; 275 276 mRcsStats.onRcsClientProvisioningStats(mSubId, event); 277 278 ArgumentCaptor<RcsClientProvisioningStats> captor = 279 ArgumentCaptor.forClass(RcsClientProvisioningStats.class); 280 verify(mPersistAtomsStorage).addRcsClientProvisioningStats(captor.capture()); 281 RcsClientProvisioningStats stats = captor.getValue(); 282 assertEquals(CARRIER_ID, stats.carrierId); 283 assertEquals(SLOT_ID, stats.slotId); 284 assertEquals(event, stats.event); 285 verifyNoMoreInteractions(mPersistAtomsStorage); 286 } 287 288 @Test 289 @SmallTest onRcsAcsProvisioningStats_withAtoms()290 public void onRcsAcsProvisioningStats_withAtoms() throws Exception { 291 boolean isSingleRegistrationEnabled = true; 292 int[] responseCode = {200, 401}; 293 /* 294 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR 295 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML 296 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML 297 */ 298 int[] responseType = { 299 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML, 300 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR}; 301 int[] slotIds = {SLOT_ID, SLOT_ID}; 302 int[] carrierIds = {CARRIER_ID, CARRIER_ID}; 303 304 // this will be cached 305 mRcsStats.onRcsAcsProvisioningStats( 306 mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); 307 308 long timeGap = 6000L; 309 mRcsStats.incTimeMillis(timeGap); 310 311 // this will be cached, previous will be stored 312 mRcsStats.onRcsAcsProvisioningStats( 313 mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled); 314 315 ArgumentCaptor<RcsAcsProvisioningStats> captor = 316 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 317 verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); 318 RcsAcsProvisioningStats stats = captor.getValue(); 319 assertEquals(carrierIds[0], stats.carrierId); 320 assertEquals(slotIds[0], stats.slotId); 321 assertEquals(responseCode[0], stats.responseCode); 322 assertEquals(responseType[0], stats.responseType); 323 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 324 assertEquals(timeGap, stats.stateTimerMillis); 325 326 // the last atoms will be cached 327 assertEquals(1, mRcsStats.getRcsAcsProvisioningCachedSize()); 328 verifyNoMoreInteractions(mPersistAtomsStorage); 329 } 330 331 @Test 332 @SmallTest onRcsAcsProvisioningStats_withAtomsInvalidSubId()333 public void onRcsAcsProvisioningStats_withAtomsInvalidSubId() throws Exception { 334 boolean isSingleRegistrationEnabled = true; 335 int[] responseCode = {200, 401}; 336 int[] responseType = { 337 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML, 338 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR}; 339 int[] slotIds = {SLOT_ID, SLOT_ID}; 340 int[] carrierIds = {CARRIER_ID, CARRIER_ID}; 341 342 // this will be cached 343 mRcsStats.onRcsAcsProvisioningStats( 344 mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); 345 346 long timeGap = 6000L; 347 mRcsStats.incTimeMillis(timeGap); 348 349 // slotId and carrierId are invalid based on subId 350 mRcsStats.setEnableInvalidSubId(); 351 352 // this will not be cached, previous will be stored 353 mRcsStats.onRcsAcsProvisioningStats( 354 mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled); 355 356 ArgumentCaptor<RcsAcsProvisioningStats> captor = 357 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 358 verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); 359 RcsAcsProvisioningStats stats = captor.getValue(); 360 assertEquals(carrierIds[0], stats.carrierId); 361 assertEquals(slotIds[0], stats.slotId); 362 assertEquals(responseCode[0], stats.responseCode); 363 assertEquals(responseType[0], stats.responseType); 364 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 365 assertEquals(timeGap, stats.stateTimerMillis); 366 // the last atoms will not be cached 367 assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize()); 368 369 verifyNoMoreInteractions(mPersistAtomsStorage); 370 } 371 372 @Test 373 @SmallTest onRcsAcsProvisioningStats_byCallBack()374 public void onRcsAcsProvisioningStats_byCallBack() throws Exception { 375 long timeGap = 6000L; 376 boolean isSingleRegistrationEnabled = true; 377 int responseCode = 200; 378 int responseType = 379 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML; 380 byte[] config = new byte[0]; 381 382 RcsStats.RcsProvisioningCallback rcsProvisioningCallback = 383 mRcsStats.getRcsProvisioningCallback(mSubId, isSingleRegistrationEnabled); 384 // has one callback obj 385 assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 1); 386 387 rcsProvisioningCallback.onPreProvisioningReceived(config); 388 mRcsStats.incTimeMillis(timeGap); 389 rcsProvisioningCallback.onRemoved(); 390 // callback will be removed, Map is empty. 391 assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 0); 392 393 ArgumentCaptor<RcsAcsProvisioningStats> captor = 394 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 395 verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); 396 RcsAcsProvisioningStats stats = captor.getValue(); 397 assertEquals(CARRIER_ID, stats.carrierId); 398 assertEquals(SLOT_ID, stats.slotId); 399 assertEquals(responseCode, stats.responseCode); 400 assertEquals(responseType, stats.responseType); 401 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 402 assertEquals(timeGap, stats.stateTimerMillis); 403 verifyNoMoreInteractions(mPersistAtomsStorage); 404 } 405 406 @Test 407 @SmallTest onRcsAcsProvisioningStats_byErrorCallBack()408 public void onRcsAcsProvisioningStats_byErrorCallBack() throws Exception { 409 long timeGap = 6000L; 410 boolean isSingleRegistrationEnabled = true; 411 int responseCode = 401; 412 int responseType = 413 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR; 414 415 RcsStats.RcsProvisioningCallback rcsProvisioningCallback = 416 mRcsStats.getRcsProvisioningCallback(mSubId, false); 417 rcsProvisioningCallback = 418 mRcsStats.getRcsProvisioningCallback(mSubId2, isSingleRegistrationEnabled); 419 // has two callback obj, subId, subId2 420 assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 2); 421 422 rcsProvisioningCallback.onAutoConfigurationErrorReceived(responseCode, "responseCode"); 423 mRcsStats.incTimeMillis(timeGap); 424 mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId2); 425 rcsProvisioningCallback.onRemoved(); 426 // subId2's callback will be removed, Map has only one callback for subId. 427 assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 1); 428 429 // addRcsAcsProvisioningStats is called once. 430 ArgumentCaptor<RcsAcsProvisioningStats> captor = 431 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 432 verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture()); 433 RcsAcsProvisioningStats stats = captor.getValue(); 434 assertEquals(CARRIER2_ID, stats.carrierId); 435 assertEquals(SLOT2_ID, stats.slotId); 436 assertEquals(responseCode, stats.responseCode); 437 assertEquals(responseType, stats.responseType); 438 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 439 assertEquals(timeGap, stats.stateTimerMillis); 440 verifyNoMoreInteractions(mPersistAtomsStorage); 441 } 442 443 @Test 444 @SmallTest onStoreCompleteRcsAcsProvisioningStats_withSubId()445 public void onStoreCompleteRcsAcsProvisioningStats_withSubId() throws Exception { 446 boolean isSingleRegistrationEnabled = true; 447 int[] responseCode = {401, 200}; 448 /* 449 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR 450 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML 451 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML 452 */ 453 int[] responseType = {TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR, 454 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML}; 455 int[] slotIds = {SLOT_ID, SLOT2_ID}; 456 int[] carrierIds = {CARRIER_ID, CARRIER2_ID}; 457 458 // this will be cached 459 mRcsStats.onRcsAcsProvisioningStats( 460 mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); 461 // this will be cached 462 mRcsStats.onRcsAcsProvisioningStats( 463 mSubId2, responseCode[1], responseType[1], isSingleRegistrationEnabled); 464 465 long timeGap = 6000L; 466 mRcsStats.incTimeMillis(timeGap); 467 468 // cached atoms will be stored and removed 469 mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId); 470 mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId2); 471 472 ArgumentCaptor<RcsAcsProvisioningStats> captor = 473 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 474 verify(mPersistAtomsStorage, times(slotIds.length)) 475 .addRcsAcsProvisioningStats(captor.capture()); 476 List<RcsAcsProvisioningStats> statsList = captor.getAllValues(); 477 assertEquals(slotIds.length, statsList.size()); 478 for (int i = 0; i < statsList.size(); i++) { 479 RcsAcsProvisioningStats stats = statsList.get(i); 480 assertEquals(carrierIds[i], stats.carrierId); 481 assertEquals(slotIds[i], stats.slotId); 482 assertEquals(responseCode[i], stats.responseCode); 483 assertEquals(responseType[i], stats.responseType); 484 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 485 assertEquals(timeGap, stats.stateTimerMillis); 486 } 487 // cached data should be empty 488 assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize()); 489 verifyNoMoreInteractions(mPersistAtomsStorage); 490 } 491 492 @Test 493 @SmallTest onFlushIncompleteRcsAcsProvisioningStats_withoutSubId()494 public void onFlushIncompleteRcsAcsProvisioningStats_withoutSubId() throws Exception { 495 boolean isSingleRegistrationEnabled = true; 496 int[] responseCode = {401, 200}; 497 /* 498 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR 499 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML 500 * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML 501 */ 502 int[] responseType = {TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR, 503 TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML}; 504 int[] slotIds = {SLOT_ID, SLOT2_ID}; 505 int[] carrierIds = {CARRIER_ID, CARRIER2_ID}; 506 507 // this will be cached 508 mRcsStats.onRcsAcsProvisioningStats( 509 mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled); 510 // this will be cached 511 mRcsStats.onRcsAcsProvisioningStats( 512 mSubId2, responseCode[1], responseType[1], isSingleRegistrationEnabled); 513 514 long timeGap = 6000L; 515 mRcsStats.incTimeMillis(timeGap); 516 517 // cached atoms will be stored, but atoms are keeped 518 mRcsStats.onFlushIncompleteRcsAcsProvisioningStats(); 519 520 ArgumentCaptor<RcsAcsProvisioningStats> captor = 521 ArgumentCaptor.forClass(RcsAcsProvisioningStats.class); 522 verify(mPersistAtomsStorage, times(slotIds.length)) 523 .addRcsAcsProvisioningStats(captor.capture()); 524 List<RcsAcsProvisioningStats> statsList = captor.getAllValues(); 525 assertEquals(slotIds.length, statsList.size()); 526 for (int i = 0; i < statsList.size(); i++) { 527 RcsAcsProvisioningStats stats = statsList.get(i); 528 assertEquals(carrierIds[i], stats.carrierId); 529 assertEquals(slotIds[i], stats.slotId); 530 assertEquals(responseCode[i], stats.responseCode); 531 assertEquals(responseType[i], stats.responseType); 532 assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled); 533 assertEquals(timeGap, stats.stateTimerMillis); 534 535 // check cached atom's time should be updated 536 assertEquals(mRcsStats.getWallTimeMillis(), 537 mRcsStats.getRcsAcsProvisioningCachedTime(carrierIds[i], slotIds[i])); 538 } 539 verifyNoMoreInteractions(mPersistAtomsStorage); 540 } 541 542 @Test 543 @SmallTest onSipDelegateStats_addStats()544 public void onSipDelegateStats_addStats() throws Exception { 545 final int destroyReason = SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD; 546 final long timeGap = 6000L; 547 List<Set<String>> supportedTagsList = getSupportedTagsList(); 548 Set<String> registeredTags = supportedTagsList.get(0); 549 // create and destroy a sipDelegate.. 550 mRcsStats.createSipDelegateStats(mSubId, registeredTags); 551 mRcsStats.incTimeMillis(timeGap); 552 mRcsStats.onSipDelegateStats(mSubId, registeredTags, 553 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD); 554 555 ArgumentCaptor<SipDelegateStats> captor = 556 ArgumentCaptor.forClass(SipDelegateStats.class); 557 verify(mPersistAtomsStorage).addSipDelegateStats(captor.capture()); 558 SipDelegateStats stats = captor.getValue(); 559 assertTrue(stats.dimension != 0); 560 assertEquals(CARRIER_ID, stats.carrierId); 561 assertEquals(SLOT_ID, stats.slotId); 562 assertEquals(timeGap, stats.uptimeMillis); 563 assertEquals(destroyReason, stats.destroyReason); 564 verifyNoMoreInteractions(mPersistAtomsStorage); 565 } 566 getSupportedTagsList()567 private List<Set<String>> getSupportedTagsList() { 568 List<Set<String>> registeredTagsList = new ArrayList<>(); 569 Set<String> supportedTags1 = new ArraySet<>(); 570 supportedTags1.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG); 571 supportedTags1.add(FeatureTags.FEATURE_TAG_CHAT_SESSION); 572 registeredTagsList.add(supportedTags1); 573 574 Set<String> supportedTags2 = new ArraySet<>(); 575 supportedTags2.add(FeatureTags.FEATURE_TAG_FILE_TRANSFER); 576 supportedTags2.add(FeatureTags.FEATURE_TAG_CHAT_IM); 577 supportedTags2.add(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING); 578 registeredTagsList.add(supportedTags2); 579 580 Set<String> supportedTags3 = new ArraySet<>(); 581 supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION); 582 supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG); 583 supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED); 584 registeredTagsList.add(supportedTags3); 585 586 return registeredTagsList; 587 } 588 589 @Test 590 @SmallTest onSipDelegateStats_addMultipleEntries()591 public void onSipDelegateStats_addMultipleEntries() throws Exception { 592 final long timeGap = 6000L; 593 List<Integer> destroyReasonList = new ArrayList<>(); 594 destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_UNKNOWN); 595 destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD); 596 destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP); 597 final int testSize = destroyReasonList.size(); 598 List<Set<String>> supportedTagsList = getSupportedTagsList(); 599 600 // create and destroy a sipDelegate multiple times 601 for (int i = 0; i < testSize; i++) { 602 mRcsStats.createSipDelegateStats(mSubId, supportedTagsList.get(i)); 603 } 604 605 for (int i = 0; i < testSize; i++) { 606 mRcsStats.incTimeMillis(timeGap); 607 mRcsStats.onSipDelegateStats(mSubId, supportedTagsList.get(i), 608 destroyReasonList.get(i)); 609 } 610 611 List<ExpectedSipDelegateResult> expectedSipDelegateResults = 612 getExpectedResult(destroyReasonList); 613 final int expectedResultSize = expectedSipDelegateResults.size(); 614 ArgumentCaptor<SipDelegateStats> captor = 615 ArgumentCaptor.forClass(SipDelegateStats.class); 616 verify(mPersistAtomsStorage, times(expectedResultSize)) 617 .addSipDelegateStats(captor.capture()); 618 619 List<SipDelegateStats> captorValues = captor.getAllValues(); 620 assertEquals(captorValues.size(), expectedResultSize); 621 for (int i = 0; i < expectedResultSize; i++) { 622 SipDelegateStats stats = captorValues.get(i); 623 ExpectedSipDelegateResult expectedResult = expectedSipDelegateResults.get(i); 624 assertTrue(stats.dimension != 0); 625 assertEquals(CARRIER_ID, stats.carrierId); 626 assertEquals(SLOT_ID, stats.slotId); 627 assertEquals(timeGap * (i + 1), stats.uptimeMillis); 628 assertEquals(expectedResult.destroyReason, stats.destroyReason); 629 } 630 verifyNoMoreInteractions(mPersistAtomsStorage); 631 } 632 633 private class ExpectedSipDelegateResult { 634 public int id; 635 public int destroyReason; ExpectedSipDelegateResult(int id, int destroyReason)636 ExpectedSipDelegateResult(int id, int destroyReason) { 637 this.id = id; 638 this.destroyReason = destroyReason; 639 } 640 } 641 getExpectedResult(List<Integer> destroyReasonList)642 private List<ExpectedSipDelegateResult> getExpectedResult(List<Integer> destroyReasonList) { 643 List<ExpectedSipDelegateResult> results = new ArrayList<>(); 644 int size = destroyReasonList.size(); 645 646 for (int i = 0; i < size; i++) { 647 results.add(new ExpectedSipDelegateResult(i, destroyReasonList.get(i))); 648 } 649 650 return results; 651 } 652 653 @Test 654 @SmallTest onSipTransportFeatureTagStats_addMultipleEntries()655 public void onSipTransportFeatureTagStats_addMultipleEntries() throws Exception { 656 final long timeGap = 6000L; 657 Set<FeatureTagState> deniedTags = new ArraySet<>(); 658 Set<FeatureTagState> deRegiTags = new ArraySet<>(); 659 Set<String> regiTags = new ArraySet<>(); 660 661 // create new featureTags 662 regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG); 663 deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 664 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE)); 665 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 666 667 mRcsStats.incTimeMillis(timeGap); 668 669 // change status of featureTags 670 regiTags.clear(); 671 deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 672 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED)); 673 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 674 675 mRcsStats.incTimeMillis(timeGap); 676 677 List<TestResult> expectedResults = getTestResult(timeGap, false); 678 679 int expectedResultSize = expectedResults.size(); 680 ArgumentCaptor<SipTransportFeatureTagStats> captor = 681 ArgumentCaptor.forClass(SipTransportFeatureTagStats.class); 682 verify(mPersistAtomsStorage, times(expectedResultSize)) 683 .addSipTransportFeatureTagStats(captor.capture()); 684 685 List<SipTransportFeatureTagStats> captorValues = captor.getAllValues(); 686 687 assertEquals(captorValues.size(), expectedResultSize); 688 for (int i = 0; i < captorValues.size(); i++) { 689 SipTransportFeatureTagStats stats = captorValues.get(i); 690 TestResult expectedResult = expectedResults.get(i); 691 assertEquals(CARRIER_ID, stats.carrierId); 692 assertEquals(SLOT_ID, stats.slotId); 693 assertEquals(expectedResult.tagValue, stats.featureTagName); 694 assertEquals(expectedResult.duration, stats.associatedMillis); 695 assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason); 696 assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason); 697 } 698 verifyNoMoreInteractions(mPersistAtomsStorage); 699 } 700 701 @Test 702 @SmallTest onSipTransportFeatureTagStats_addInvalidEntries()703 public void onSipTransportFeatureTagStats_addInvalidEntries() throws Exception { 704 final long timeGap = 6000L; 705 Set<FeatureTagState> deniedTags = new ArraySet<>(); 706 Set<FeatureTagState> deRegiTags = new ArraySet<>(); 707 Set<String> regiTags = new ArraySet<>(); 708 709 final int invalidSubId = INVALID_SUB_ID; 710 711 // create new featureTags with an invalidId 712 regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG); 713 deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 714 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE)); 715 mRcsStats.onSipTransportFeatureTagStats(invalidSubId, deniedTags, deRegiTags, regiTags); 716 mRcsStats.incTimeMillis(timeGap); 717 718 // change status of featureTags with an invalidId 719 regiTags.clear(); 720 deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 721 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED)); 722 mRcsStats.onSipTransportFeatureTagStats(invalidSubId, deniedTags, deRegiTags, regiTags); 723 mRcsStats.incTimeMillis(timeGap); 724 725 verify(mPersistAtomsStorage, never()).addSipTransportFeatureTagStats(any()); 726 } 727 728 729 @Test 730 @SmallTest onSipTransportFeatureTagStats_addCustomTag()731 public void onSipTransportFeatureTagStats_addCustomTag() throws Exception { 732 final long timeGap = 6000L; 733 Set<FeatureTagState> deniedTags = new ArraySet<>(); 734 Set<FeatureTagState> deRegiTags = new ArraySet<>(); 735 Set<String> regiTags = new ArraySet<>(); 736 737 // create new featureTags 738 String customTag = "custom@tag"; 739 regiTags.add(customTag); 740 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 741 742 mRcsStats.incTimeMillis(timeGap); 743 744 // change status of featureTags 745 regiTags.clear(); 746 deRegiTags.add(new FeatureTagState(customTag, 747 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED)); 748 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 749 750 mRcsStats.incTimeMillis(timeGap); 751 752 TestResult expectedResult = new TestResult(customTag, 753 TelephonyProtoEnums.IMS_FEATURE_TAG_CUSTOM, timeGap, RcsStats.NONE, RcsStats.NONE); 754 755 ArgumentCaptor<SipTransportFeatureTagStats> captor = 756 ArgumentCaptor.forClass(SipTransportFeatureTagStats.class); 757 758 verify(mPersistAtomsStorage).addSipTransportFeatureTagStats(captor.capture()); 759 SipTransportFeatureTagStats stats = captor.getValue(); 760 761 assertEquals(CARRIER_ID, stats.carrierId); 762 assertEquals(SLOT_ID, stats.slotId); 763 assertEquals(expectedResult.tagValue, stats.featureTagName); 764 assertEquals(expectedResult.duration, stats.associatedMillis); 765 assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason); 766 assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason); 767 768 verifyNoMoreInteractions(mPersistAtomsStorage); 769 } 770 771 @Test 772 @SmallTest concludeSipTransportFeatureTagsStat_addMultipleEntries()773 public void concludeSipTransportFeatureTagsStat_addMultipleEntries() throws Exception { 774 final long timeGap = 6000L; 775 Set<FeatureTagState> deniedTags = new ArraySet<>(); 776 Set<FeatureTagState> deRegiTags = new ArraySet<>(); 777 Set<String> regiTags = new ArraySet<>(); 778 // create new featureTags 779 regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG); 780 deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 781 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE)); 782 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 783 784 mRcsStats.incTimeMillis(timeGap); 785 786 // change status of featureTags 787 regiTags.clear(); 788 deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 789 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED)); 790 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 791 792 793 mRcsStats.incTimeMillis(timeGap); 794 795 // change status of featureTags and metrics are pulled. 796 deRegiTags.clear(); 797 regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG); 798 mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags); 799 800 mRcsStats.incTimeMillis(timeGap); 801 mRcsStats.concludeSipTransportFeatureTagsStat(); 802 803 List<TestResult> expectedResults = getTestResult(timeGap, true); 804 805 int expectedResultSize = expectedResults.size(); 806 ArgumentCaptor<SipTransportFeatureTagStats> captor = 807 ArgumentCaptor.forClass(SipTransportFeatureTagStats.class); 808 verify(mPersistAtomsStorage, times(expectedResultSize)) 809 .addSipTransportFeatureTagStats(captor.capture()); 810 811 List<SipTransportFeatureTagStats> captorValues = captor.getAllValues(); 812 813 assertEquals(captorValues.size(), expectedResultSize); 814 for (int i = 0; i < captorValues.size(); i++) { 815 SipTransportFeatureTagStats stats = captorValues.get(i); 816 TestResult expectedResult = expectedResults.get(i); 817 assertEquals(CARRIER_ID, stats.carrierId); 818 assertEquals(SLOT_ID, stats.slotId); 819 assertEquals(expectedResult.tagValue, stats.featureTagName); 820 assertEquals(expectedResult.duration, stats.associatedMillis); 821 assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason); 822 assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason); 823 } 824 verifyNoMoreInteractions(mPersistAtomsStorage); 825 826 } 827 getTestResult(long timeGap, boolean concludeTest)828 private List<TestResult> getTestResult(long timeGap, boolean concludeTest) { 829 List<TestResult> results = new ArrayList<>(); 830 results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 831 TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER, 832 timeGap, 833 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE)); 834 results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 835 TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG, 836 timeGap, RcsStats.NONE, RcsStats.NONE)); 837 if (concludeTest) { 838 results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 839 TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG, 840 timeGap, RcsStats.NONE, 841 DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED)); 842 results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 843 TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER, 844 timeGap, 845 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE)); 846 results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER, 847 TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER, 848 timeGap, 849 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE)); 850 results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG, 851 TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG, 852 timeGap, RcsStats.NONE, RcsStats.NONE)); 853 854 } 855 return results; 856 } 857 858 @Test 859 @SmallTest onSipMessageResponse_withAtoms()860 public void onSipMessageResponse_withAtoms() throws Exception { 861 String testSipMessageMethod = "MESSAGE"; 862 int testSipRequestMessageDirection = 1; //INCOMING: 0, OUTGOING: 1 863 int testSipMessageResponse = 200; 864 int testMessageError = 0; 865 String testCallId = "testId"; 866 // Request message 867 mRcsStats.onSipMessageRequest(testCallId, testSipMessageMethod, 868 testSipRequestMessageDirection); 869 // Response message 870 mRcsStats.onSipMessageResponse(mSubId, testCallId, testSipMessageResponse, 871 testMessageError); 872 ArgumentCaptor<SipMessageResponse> captor = 873 ArgumentCaptor.forClass(SipMessageResponse.class); 874 verify(mPersistAtomsStorage).addSipMessageResponse(captor.capture()); 875 SipMessageResponse stats = captor.getValue(); 876 assertEquals(CARRIER_ID, stats.carrierId); 877 assertEquals(SLOT_ID, stats.slotId); 878 assertEquals(TelephonyProtoEnums.SIP_REQUEST_MESSAGE, stats.sipMessageMethod); 879 assertEquals(testSipRequestMessageDirection, stats.sipMessageDirection); 880 assertEquals(testSipMessageResponse, stats.sipMessageResponse); 881 assertEquals(testMessageError, stats.messageError); 882 verifyNoMoreInteractions(mPersistAtomsStorage); 883 } 884 885 @Test 886 @SmallTest onSipTransportSession_withAtoms()887 public void onSipTransportSession_withAtoms() throws Exception { 888 String testInviteSipMethod = "INVITE"; 889 String testCallId = "testId"; 890 int testSipResponse = 0; 891 int testSipRequestMessageDirection = 1; //INCOMING: 0, OUTGOING: 1 892 // Request Message 893 mRcsStats.earlySipTransportSession( 894 testInviteSipMethod, testCallId, testSipRequestMessageDirection); 895 // gracefully close 896 mRcsStats.onSipTransportSessionClosed(mSubId, testCallId, testSipResponse, true); 897 ArgumentCaptor<SipTransportSession> captor = 898 ArgumentCaptor.forClass(SipTransportSession.class); 899 verify(mPersistAtomsStorage).addCompleteSipTransportSession(captor.capture()); 900 SipTransportSession stats = captor.getValue(); 901 assertEquals(CARRIER_ID, stats.carrierId); 902 assertEquals(SLOT_ID, stats.slotId); 903 assertEquals(TelephonyProtoEnums.SIP_REQUEST_INVITE, stats.sessionMethod); 904 assertEquals(testSipRequestMessageDirection, stats.sipMessageDirection); 905 assertEquals(testSipResponse, stats.sipResponse); 906 assertEquals(true/*isEndedGracefully*/, stats.isEndedGracefully); 907 verifyNoMoreInteractions(mPersistAtomsStorage); 908 } 909 910 @Test 911 @SmallTest onImsDedicatedBearerListenerEvent_Added()912 public void onImsDedicatedBearerListenerEvent_Added() throws Exception { 913 final int listenerId = 1; 914 int ratAtEnd = TelephonyProtoEnums.NETWORK_TYPE_LTE; 915 final int qci = 5; 916 917 mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId); 918 mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, ratAtEnd, qci); 919 assertTrue(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId)); 920 ImsDedicatedBearerListenerEvent testProto = 921 mRcsStats.dedicatedBearerListenerEventMap_get(listenerId); 922 assertEquals(SLOT_ID, testProto.slotId); 923 assertEquals(ratAtEnd, testProto.ratAtEnd); 924 assertEquals(qci, testProto.qci); 925 assertFalse(testProto.dedicatedBearerEstablished); 926 verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any()); 927 928 // same listenerId, different contents. should be ignored 929 ratAtEnd = TelephonyProtoEnums.NETWORK_TYPE_NR; 930 mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID + 1, ratAtEnd + 1, qci + 1); 931 testProto = mRcsStats.dedicatedBearerListenerEventMap_get(listenerId); 932 assertEquals(SLOT_ID, testProto.slotId); 933 assertNotEquals(ratAtEnd, testProto.ratAtEnd); 934 assertEquals(qci, testProto.qci); 935 verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any()); 936 937 mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId); 938 } 939 940 @Test 941 @SmallTest onImsDedicatedBearerListenerEvent_bearerEstablished()942 public void onImsDedicatedBearerListenerEvent_bearerEstablished() throws Exception { 943 final int listenerId = 2; 944 final int rat = TelephonyProtoEnums.NETWORK_TYPE_LTE; 945 final int qci = 6; 946 947 mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId); 948 mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true); 949 verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any()); 950 951 mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId); 952 mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, rat, qci); 953 assertTrue(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId)); 954 mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true); 955 ImsDedicatedBearerListenerEvent testProto = 956 mRcsStats.dedicatedBearerListenerEventMap_get(listenerId); 957 assertEquals(qci, testProto.qci); 958 assertTrue(testProto.dedicatedBearerEstablished); 959 960 verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any()); 961 } 962 963 @Test 964 @SmallTest onImsDedicatedBearerListenerEvent_Removed()965 public void onImsDedicatedBearerListenerEvent_Removed() throws Exception { 966 final int listenerId = 3; 967 final int rat = TelephonyProtoEnums.NETWORK_TYPE_LTE; 968 final int qci = 7; 969 970 mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId); 971 mRcsStats.onImsDedicatedBearerListenerRemoved(listenerId); 972 verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any()); 973 974 mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, rat, qci); 975 mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true); 976 mRcsStats.onImsDedicatedBearerListenerRemoved(listenerId); 977 verify(mPersistAtomsStorage, times(1)).addImsDedicatedBearerListenerEvent(any()); 978 979 // and values should be same 980 ArgumentCaptor<ImsDedicatedBearerListenerEvent> captor = 981 ArgumentCaptor.forClass(ImsDedicatedBearerListenerEvent.class); 982 verify(mPersistAtomsStorage).addImsDedicatedBearerListenerEvent(captor.capture()); 983 ImsDedicatedBearerListenerEvent stats = captor.getValue(); 984 assertEquals(CARRIER_ID, stats.carrierId); 985 assertEquals(SLOT_ID, stats.slotId); 986 assertEquals(rat, stats.ratAtEnd); 987 assertEquals(qci, stats.qci); 988 assertEquals(true, stats.dedicatedBearerEstablished); 989 verifyNoMoreInteractions(mPersistAtomsStorage); 990 991 assertFalse(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId)); 992 } 993 994 @Test 995 @SmallTest onImsDedicatedBearerEvent_withAtoms()996 public void onImsDedicatedBearerEvent_withAtoms() throws Exception { 997 // reference comments in test_imsDedicatedBearerListenerEvent for canditate value 998 int ratAtEnd = TelephonyStatsLog 999 .IMS_DEDICATED_BEARER_LISTENER_EVENT__RAT_AT_END__NETWORK_TYPE_LTE_CA; 1000 int qci = 6; 1001 /* 1002 * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED = 1; 1003 * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_MODIFIED = 2; 1004 * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_DELETED = 3; 1005 */ 1006 int bearerState = TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED; 1007 boolean localConnectionInfoReceived = false; 1008 boolean remoteConnectionInfoReceived = true; 1009 boolean hasListeners = true; 1010 1011 mRcsStats.onImsDedicatedBearerEvent(SLOT_ID, ratAtEnd, qci, bearerState, 1012 localConnectionInfoReceived, remoteConnectionInfoReceived, hasListeners); 1013 1014 ArgumentCaptor<ImsDedicatedBearerEvent> captor = 1015 ArgumentCaptor.forClass(ImsDedicatedBearerEvent.class); 1016 verify(mPersistAtomsStorage).addImsDedicatedBearerEvent(captor.capture()); 1017 ImsDedicatedBearerEvent stats = captor.getValue(); 1018 assertEquals(CARRIER_ID, stats.carrierId); 1019 assertEquals(SLOT_ID, stats.slotId); 1020 assertEquals(ratAtEnd, stats.ratAtEnd); 1021 assertEquals(qci, stats.qci); 1022 assertEquals(bearerState, stats.bearerState); 1023 assertEquals(localConnectionInfoReceived, stats.localConnectionInfoReceived); 1024 assertEquals(remoteConnectionInfoReceived, stats.remoteConnectionInfoReceived); 1025 assertEquals(hasListeners, stats.hasListeners); 1026 verifyNoMoreInteractions(mPersistAtomsStorage); 1027 } 1028 1029 @Test 1030 @SmallTest onImsRegistrationServiceDescStats_withAtoms()1031 public void onImsRegistrationServiceDescStats_withAtoms() throws Exception { 1032 int registrationTech = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE 1033 ArrayList<String> serviceIdList = new ArrayList<>(); 1034 serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP"); 1035 serviceIdList.add("org.openmobilealliance:IM-session"); 1036 serviceIdList.add("Unknown1"); 1037 ArrayList<String> serviceIdVersionList = new ArrayList<>(); 1038 serviceIdVersionList.add("1.0"); 1039 serviceIdVersionList.add("1.0"); 1040 serviceIdVersionList.add("3.0"); 1041 1042 mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList, 1043 registrationTech); 1044 1045 // getWallTimeMillis 1046 /* 1047 * UCE_EVENT__TYPE__PUBLISH = 0; 1048 * UCE_EVENT__TYPE__SUBSCRIBE = 1; 1049 * UCE_EVENT__TYPE__INCOMING_OPTION = 2; 1050 * UCE_EVENT__TYPE__OUTGOING_OPTION = 3; 1051 */ 1052 int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH; 1053 boolean successful = true; 1054 /* 1055 * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0; 1056 * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1; 1057 * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2; 1058 * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3; 1059 * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4; 1060 * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5; 1061 * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6; 1062 * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7; 1063 * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8; 1064 * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9; 1065 * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10; 1066 */ 1067 int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE; 1068 int networkResponse = 200; 1069 1070 mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); 1071 1072 { 1073 ArgumentCaptor<UceEventStats> captor = ArgumentCaptor.forClass(UceEventStats.class); 1074 verify(mPersistAtomsStorage).addUceEventStats(captor.capture()); 1075 UceEventStats stats = captor.getValue(); 1076 assertEquals(CARRIER_ID, stats.carrierId); 1077 assertEquals(SLOT_ID, stats.slotId); 1078 assertEquals(successful, stats.successful); 1079 assertEquals(commandCode, stats.commandCode); 1080 assertEquals(networkResponse, stats.networkResponse); 1081 verifyNoMoreInteractions(mPersistAtomsStorage); 1082 } 1083 1084 long timeGap = 6000L; 1085 mRcsStats.incTimeMillis(timeGap); 1086 1087 mRcsStats.onStoreCompleteImsRegistrationServiceDescStats(mSubId); 1088 1089 ArgumentCaptor<ImsRegistrationServiceDescStats> captor = 1090 ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class); 1091 verify(mPersistAtomsStorage, times(3)) 1092 .addImsRegistrationServiceDescStats(captor.capture()); 1093 List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues(); 1094 1095 assertEquals(captorValues.size(), serviceIdList.size()); 1096 1097 for (int index = 0; index < captorValues.size(); index++) { 1098 ImsRegistrationServiceDescStats stats = captorValues.get(index); 1099 assertEquals(CARRIER_ID, stats.carrierId); 1100 assertEquals(SLOT_ID, stats.slotId); 1101 int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index)); 1102 assertEquals(serviceId, stats.serviceIdName); 1103 float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index)); 1104 assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f); 1105 assertEquals(registrationTech, stats.registrationTech); 1106 assertEquals(timeGap, stats.publishedMillis); 1107 } 1108 verifyNoMoreInteractions(mPersistAtomsStorage); 1109 } 1110 1111 @Test 1112 @SmallTest onImsRegistrationServiceDescStats_withAtomsInvalidSubId()1113 public void onImsRegistrationServiceDescStats_withAtomsInvalidSubId() throws Exception { 1114 int registrationTech = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE 1115 ArrayList<String> serviceIdList = new ArrayList<>(); 1116 serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP"); 1117 serviceIdList.add("org.openmobilealliance:IM-session"); 1118 serviceIdList.add("Unknown1"); 1119 ArrayList<String> serviceIdVersionList = new ArrayList<>(); 1120 serviceIdVersionList.add("1.0"); 1121 serviceIdVersionList.add("1.0"); 1122 serviceIdVersionList.add("3.0"); 1123 1124 mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList, 1125 registrationTech); 1126 1127 // getWallTimeMillis 1128 /* 1129 * UCE_EVENT__TYPE__PUBLISH = 0; 1130 * UCE_EVENT__TYPE__SUBSCRIBE = 1; 1131 * UCE_EVENT__TYPE__INCOMING_OPTION = 2; 1132 * UCE_EVENT__TYPE__OUTGOING_OPTION = 3; 1133 */ 1134 int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH; 1135 boolean successful = true; 1136 /* 1137 * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0; 1138 * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1; 1139 * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2; 1140 * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3; 1141 * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4; 1142 * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5; 1143 * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6; 1144 * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7; 1145 * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8; 1146 * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9; 1147 * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10; 1148 */ 1149 int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE; 1150 int networkResponse = 200; 1151 mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); 1152 1153 // slotId and carrierId are invalid based on subId 1154 mRcsStats.setEnableInvalidSubId(); 1155 long timeGap = 6000L; 1156 mRcsStats.incTimeMillis(timeGap); 1157 mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse); 1158 1159 ArgumentCaptor<ImsRegistrationServiceDescStats> captor = 1160 ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class); 1161 verify(mPersistAtomsStorage, times(3)) 1162 .addImsRegistrationServiceDescStats(captor.capture()); 1163 List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues(); 1164 1165 assertEquals(captorValues.size(), serviceIdList.size()); 1166 1167 for (int index = 0; index < captorValues.size(); index++) { 1168 ImsRegistrationServiceDescStats stats = captorValues.get(index); 1169 assertEquals(CARRIER_ID, stats.carrierId); 1170 assertEquals(SLOT_ID, stats.slotId); 1171 int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index)); 1172 assertEquals(serviceId, stats.serviceIdName); 1173 float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index)); 1174 assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f); 1175 assertEquals(registrationTech, stats.registrationTech); 1176 assertEquals(timeGap, stats.publishedMillis); 1177 } 1178 assertEquals(0, mRcsStats.getImsRegistrationServiceDescCachedSize()); 1179 } 1180 1181 @Test 1182 @SmallTest onUceEventStats_withAtoms()1183 public void onUceEventStats_withAtoms() throws Exception { 1184 int messageType = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH; 1185 boolean successful = true; 1186 int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__REQUEST_TIMEOUT; 1187 int networkResponse = 408; 1188 1189 mRcsStats.onUceEventStats(mSubId, messageType, successful, commandCode, networkResponse); 1190 1191 ArgumentCaptor<UceEventStats> captor = ArgumentCaptor.forClass(UceEventStats.class); 1192 verify(mPersistAtomsStorage).addUceEventStats(captor.capture()); 1193 UceEventStats stats = captor.getValue(); 1194 assertEquals(CARRIER_ID, stats.carrierId); 1195 assertEquals(SLOT_ID, stats.slotId); 1196 assertEquals(successful, stats.successful); 1197 assertEquals(commandCode, stats.commandCode); 1198 assertEquals(networkResponse, stats.networkResponse); 1199 verifyNoMoreInteractions(mPersistAtomsStorage); 1200 } 1201 1202 @Test 1203 @SmallTest onPresenceNotifyEvent_withAtoms()1204 public void onPresenceNotifyEvent_withAtoms() throws Exception { 1205 String reason = "deactivated"; 1206 boolean contentBodyReceived = true; 1207 boolean rcsCaps = true; 1208 boolean mmtelCaps = false; 1209 boolean noCaps = false; 1210 1211 mRcsStats.onPresenceNotifyEvent(mSubId, reason, contentBodyReceived, 1212 rcsCaps, mmtelCaps, noCaps); 1213 1214 ArgumentCaptor<PresenceNotifyEvent> captor = 1215 ArgumentCaptor.forClass(PresenceNotifyEvent.class); 1216 verify(mPersistAtomsStorage).addPresenceNotifyEvent(captor.capture()); 1217 PresenceNotifyEvent stats = captor.getValue(); 1218 assertEquals(CARRIER_ID, stats.carrierId); 1219 assertEquals(SLOT_ID, stats.slotId); 1220 int reasonInt = mRcsStats.convertPresenceNotifyReason(reason); 1221 assertEquals(reasonInt, stats.reason); 1222 assertEquals(contentBodyReceived, stats.contentBodyReceived); 1223 assertEquals(1, stats.rcsCapsCount); 1224 assertEquals(0, stats.mmtelCapsCount); 1225 assertEquals(0, stats.noCapsCount); 1226 assertEquals(1, stats.rcsCapsCount); 1227 verifyNoMoreInteractions(mPersistAtomsStorage); 1228 } 1229 1230 @Test 1231 @SmallTest onGbaEvent_withAtoms()1232 public void onGbaEvent_withAtoms() throws Exception { 1233 boolean successful = false; 1234 /* 1235 * GBA_EVENT__FAILED_REASON__UNKNOWN 1236 * GBA_EVENT__FAILED_REASON__FEATURE_NOT_SUPPORTED 1237 * GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY 1238 * GBA_EVENT__FAILED_REASON__NETWORK_FAILURE 1239 * GBA_EVENT__FAILED_REASON__INCORRECT_NAF_ID 1240 * GBA_EVENT__FAILED_REASON__SECURITY_PROTOCOL_NOT_SUPPORTED 1241 */ 1242 int failedReason = TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY; 1243 1244 mRcsStats.onGbaFailureEvent(mSubId, failedReason); 1245 1246 ArgumentCaptor<GbaEvent> captor = ArgumentCaptor.forClass(GbaEvent.class); 1247 verify(mPersistAtomsStorage).addGbaEvent(captor.capture()); 1248 GbaEvent stats = captor.getValue(); 1249 assertEquals(CARRIER_ID, stats.carrierId); 1250 assertEquals(SLOT_ID, stats.slotId); 1251 assertEquals(successful, stats.successful); 1252 assertEquals(failedReason, stats.failedReason); 1253 verifyNoMoreInteractions(mPersistAtomsStorage); 1254 } 1255 } 1256