• 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.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