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