• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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