1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.metrics;
18 
19 import static android.telephony.SmsManager.RESULT_ERROR_NONE;
20 import static android.telephony.SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY;
21 import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
22 import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
23 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
24 import static android.text.format.DateUtils.DAY_IN_MILLIS;
25 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
26 
27 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
28 import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
29 import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__UNKNOWN;
30 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_ERROR_GENERIC;
31 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__ERROR__SMS_SUCCESS;
32 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP;
33 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2;
34 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP;
35 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2;
36 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_NORMAL;
37 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS__SMS_TYPE__SMS_TYPE_SMS_PP;
38 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR;
39 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS;
40 import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
41 import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
42 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
43 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
44 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
45 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
46 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
47 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
48 import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_CURRENT_LOCATION;
49 import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE;
50 import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_CONFIG_UPDATER;
51 import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_DEVICE_CONFIG;
52 
53 import static org.junit.Assert.assertArrayEquals;
54 import static org.junit.Assert.assertEquals;
55 import static org.junit.Assert.assertNotNull;
56 import static org.junit.Assert.assertNull;
57 import static org.junit.Assert.assertTrue;
58 import static org.mockito.Mockito.anyInt;
59 import static org.mockito.Mockito.anyString;
60 import static org.mockito.Mockito.doReturn;
61 import static org.mockito.Mockito.eq;
62 import static org.mockito.Mockito.inOrder;
63 import static org.mockito.Mockito.mock;
64 import static org.mockito.Mockito.times;
65 
66 import android.annotation.Nullable;
67 import android.content.Context;
68 import android.os.Build;
69 import android.telephony.DisconnectCause;
70 import android.telephony.PreciseDataConnectionState;
71 import android.telephony.SatelliteProtoEnums;
72 import android.telephony.ServiceState;
73 import android.telephony.SignalStrength;
74 import android.telephony.TelephonyManager;
75 import android.telephony.TelephonyProtoEnums;
76 import android.telephony.data.ApnSetting;
77 import android.telephony.ims.ImsReasonInfo;
78 import android.telephony.ims.SipDelegateManager;
79 
80 import androidx.test.filters.SmallTest;
81 
82 import com.android.internal.telephony.TelephonyStatsLog;
83 import com.android.internal.telephony.TelephonyTest;
84 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteControllerStats;
85 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteSession;
86 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
87 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
88 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
89 import com.android.internal.telephony.nano.PersistAtomsProto.DataNetworkValidation;
90 import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
91 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
92 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
93 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
94 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
95 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
96 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
97 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
98 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms;
99 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
100 import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms;
101 import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
102 import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
103 import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
104 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController;
105 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater;
106 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController;
107 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement;
108 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
109 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
110 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
111 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
112 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
113 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
114 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
115 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
116 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
117 import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
118 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
119 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
120 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.AudioCodec;
121 import com.android.internal.telephony.protobuf.nano.MessageNano;
122 
123 import org.junit.After;
124 import org.junit.Before;
125 import org.junit.Rule;
126 import org.junit.Test;
127 import org.junit.rules.TemporaryFolder;
128 import org.mockito.ArgumentCaptor;
129 import org.mockito.InOrder;
130 
131 import java.io.File;
132 import java.io.FileOutputStream;
133 import java.nio.charset.StandardCharsets;
134 import java.util.Arrays;
135 import java.util.Comparator;
136 import java.util.LinkedList;
137 import java.util.Queue;
138 import java.util.concurrent.TimeUnit;
139 
140 public class PersistAtomsStorageTest extends TelephonyTest {
141     private static final String TEST_FILE = "PersistAtomsStorageTest.pb";
142     private static final int MAX_NUM_CALL_SESSIONS = 50;
143     private static final long START_TIME_MILLIS = 2000L;
144     private static final int CARRIER1_ID = 1;
145     private static final int CARRIER2_ID = 1187;
146     private static final int CARRIER3_ID = 1435;
147     private static final int SLOT_ID1 = 1;
148     private static final int SLOT_ID2 = 2;
149     private static final int REGISTRATION1_TECH = 1;
150     private static final int REGISTRATION2_TECH = 2;
151 
152     // Mocked classes
153     private FileOutputStream mTestFileOutputStream;
154 
155     @Rule public TemporaryFolder mFolder = new TemporaryFolder();
156 
157     private File mTestFile;
158 
159     // call with SRVCC
160     private VoiceCallSession mCall1Proto;
161 
162     // call held after another incoming call, ended before the other call
163     private VoiceCallSession mCall2Proto;
164     private VoiceCallSession mCall3Proto;
165 
166     // failed call
167     private VoiceCallSession mCall4Proto;
168 
169     private VoiceCallRatUsage mCarrier1LteUsageProto;
170     private VoiceCallRatUsage mCarrier1UmtsUsageProto;
171     private VoiceCallRatUsage mCarrier2LteUsageProto;
172     private VoiceCallRatUsage mCarrier3LteUsageProto;
173     private VoiceCallRatUsage mCarrier3GsmUsageProto;
174 
175     private VoiceCallSession[] mVoiceCallSessions;
176     private VoiceCallRatUsage[] mVoiceCallRatUsages;
177 
178     // data service state switch for slot 0 and 1
179     private CellularDataServiceSwitch mServiceSwitch1Proto;
180     private CellularDataServiceSwitch mServiceSwitch2Proto;
181 
182     // Service states for slot 0 and 1
183     private CellularServiceState mServiceState1Proto;
184     private CellularServiceState mServiceState2Proto;
185     private CellularServiceState mServiceState3Proto;
186     private CellularServiceState mServiceState4Proto;
187     private CellularServiceState mServiceState5Proto;
188 
189     private CellularDataServiceSwitch[] mServiceSwitches;
190     private CellularServiceState[] mServiceStates;
191 
192     // IMS registrations for slot 0 and 1
193     private ImsRegistrationStats mImsRegStatsUnregisteredLte0;
194     private ImsRegistrationStats mImsRegStatsRegisteringLte0;
195     private ImsRegistrationStats mImsRegistrationStatsLte0;
196     private ImsRegistrationStats mImsRegistrationStatsWifi0;
197     private ImsRegistrationStats mImsRegistrationStatsLte1;
198 
199     // IMS registration terminations for slot 0 and 1
200     private ImsRegistrationTermination mImsRegistrationTerminationLte;
201     private ImsRegistrationTermination mImsRegistrationTerminationWifi;
202 
203     private ImsRegistrationStats[] mImsRegistrationStats;
204     private ImsRegistrationTermination[] mImsRegistrationTerminations;
205 
206     // Data call sessions
207     private DataCallSession mDataCallSession0;
208     private DataCallSession mDataCallSession1;
209 
210     // RCS registration feature tags for slot 0 and 1
211     private ImsRegistrationFeatureTagStats mImsRegistrationFeatureTagStats1Proto;
212     private ImsRegistrationFeatureTagStats mImsRegistrationFeatureTagStats2Proto;
213     private ImsRegistrationFeatureTagStats[] mImsRegistrationFeatureTagStatses;
214 
215     // RCS provisioning client stats for slot 0 and 1
216     private RcsClientProvisioningStats mRcsClientProvisioningStats1Proto;
217     private RcsClientProvisioningStats mRcsClientProvisioningStats2Proto;
218     private RcsClientProvisioningStats[] mRcsClientProvisioningStatses;
219 
220     // RCS provisioning ACS stats for slot 0 and 1
221     private RcsAcsProvisioningStats mRcsAcsProvisioningStats1Proto;
222     private RcsAcsProvisioningStats mRcsAcsProvisioningStats2Proto;
223     private RcsAcsProvisioningStats[] mRcsAcsProvisioningStatses;
224 
225     private ImsRegistrationServiceDescStats mImsRegistrationServiceIm;
226     private ImsRegistrationServiceDescStats mImsRegistrationServiceFt;
227     private ImsRegistrationServiceDescStats[] mImsRegistrationServiceDescStats;
228 
229     // IMS dedicated bearer listener event stats for slot 0 and 1
230     private ImsDedicatedBearerListenerEvent mImsDedicatedBearerListenerEvent1;
231     private ImsDedicatedBearerListenerEvent mImsDedicatedBearerListenerEvent2;
232     private ImsDedicatedBearerListenerEvent[] mImsDedicatedBearerListenerEvents;
233 
234     // IMS dedicated bearer event stats for slot 0 and 1
235     private ImsDedicatedBearerEvent mImsDedicatedBearerEvent1;
236     private ImsDedicatedBearerEvent mImsDedicatedBearerEvent2;
237     private ImsDedicatedBearerEvent[] mImsDedicatedBearerEvents;
238 
239     private UceEventStats mUceEventStats1;
240     private UceEventStats mUceEventStats2;
241     private UceEventStats[] mUceEventStatses;
242 
243     private PresenceNotifyEvent mPresenceNotifyEvent1;
244     private PresenceNotifyEvent mPresenceNotifyEvent2;
245     private PresenceNotifyEvent[] mPresenceNotifyEvents;
246 
247     private SipTransportFeatureTagStats mSipTransportFeatureTagStats1;
248     private SipTransportFeatureTagStats mSipTransportFeatureTagStats2;
249     private SipTransportFeatureTagStats[] mSipTransportFeatureTagStatsArray;
250 
251     private SipDelegateStats mSipDelegateStats1;
252     private SipDelegateStats mSipDelegateStats2;
253     private SipDelegateStats mSipDelegateStats3;
254     private SipDelegateStats[] mSipDelegateStatsArray;
255 
256     private GbaEvent mGbaEvent1;
257     private GbaEvent mGbaEvent2;
258     private GbaEvent[] mGbaEvent;
259 
260     private SipMessageResponse mSipMessageResponse1;
261     private SipMessageResponse mSipMessageResponse2;
262     private SipMessageResponse[] mSipMessageResponse;
263 
264     private SipTransportSession mSipTransportSession1;
265     private SipTransportSession mSipTransportSession2;
266     private SipTransportSession[] mSipTransportSession;
267 
268     private IncomingSms mIncomingSms1;
269     private IncomingSms mIncomingSms2;
270     private IncomingSms[] mIncomingSms;
271 
272     private OutgoingSms mOutgoingSms1;
273     private OutgoingSms mOutgoingSms2;
274     private OutgoingSms[] mOutgoingSms;
275 
276     private OutgoingShortCodeSms mOutgoingShortCodeSms1;
277     private OutgoingShortCodeSms mOutgoingShortCodeSms2;
278     private OutgoingShortCodeSms[] mOutgoingShortCodeSms;
279 
280     private SatelliteController mSatelliteController1;
281     private SatelliteController mSatelliteController2;
282     private SatelliteController[] mSatelliteControllers;
283 
284     private SatelliteSession mSatelliteSession1;
285     private SatelliteSession mSatelliteSession2;
286     private SatelliteSession[] mSatelliteSessions;
287 
288     private SatelliteIncomingDatagram mSatelliteIncomingDatagram1;
289     private SatelliteIncomingDatagram mSatelliteIncomingDatagram2;
290     private SatelliteIncomingDatagram[] mSatelliteIncomingDatagrams;
291 
292     private SatelliteOutgoingDatagram mSatelliteOutgoingDatagram1;
293     private SatelliteOutgoingDatagram mSatelliteOutgoingDatagram2;
294     private SatelliteOutgoingDatagram[] mSatelliteOutgoingDatagrams;
295 
296     private SatelliteProvision mSatelliteProvision1;
297     private SatelliteProvision mSatelliteProvision2;
298     private SatelliteProvision[] mSatelliteProvisions;
299 
300     private SatelliteSosMessageRecommender mSatelliteSosMessageRecommender1;
301     private SatelliteSosMessageRecommender mSatelliteSosMessageRecommender2;
302     private SatelliteSosMessageRecommender[] mSatelliteSosMessageRecommenders;
303 
304     private DataNetworkValidation mDataNetworkValidationLte1;
305     private DataNetworkValidation mDataNetworkValidationLte2;
306     private DataNetworkValidation mDataNetworkValidationIwlan1;
307     private DataNetworkValidation mDataNetworkValidationIwlan2;
308     private DataNetworkValidation[] mDataNetworkValidations;
309 
310     private CarrierRoamingSatelliteSession mCarrierRoamingSatelliteSession1;
311     private CarrierRoamingSatelliteSession mCarrierRoamingSatelliteSession2;
312     private CarrierRoamingSatelliteSession[] mCarrierRoamingSatelliteSessions;
313 
314     private CarrierRoamingSatelliteControllerStats mCarrierRoamingSatelliteControllerStats1;
315     private CarrierRoamingSatelliteControllerStats mCarrierRoamingSatelliteControllerStats2;
316     private CarrierRoamingSatelliteControllerStats[] mCarrierRoamingSatelliteControllerStats;
317 
318     private SatelliteEntitlement mSatelliteEntitlement1;
319     private SatelliteEntitlement mSatelliteEntitlement2;
320     private SatelliteEntitlement[] mSatelliteEntitlements;
321 
322     private SatelliteConfigUpdater mSatelliteConfigUpdater1;
323     private SatelliteConfigUpdater mSatelliteConfigUpdater2;
324     private SatelliteConfigUpdater[] mSatelliteConfigUpdaters;
325 
326     private SatelliteAccessController mSatelliteAccessController1;
327     private SatelliteAccessController mSatelliteAccessController2;
328     private SatelliteAccessController[] mSatelliteAccessControllers;
329 
makeTestData()330     private void makeTestData() {
331         // MO call with SRVCC (LTE to UMTS)
332         mCall1Proto = new VoiceCallSession();
333         mCall1Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
334         mCall1Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
335         mCall1Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
336         mCall1Proto.setupFailed = false;
337         mCall1Proto.disconnectReasonCode = DisconnectCause.LOCAL;
338         mCall1Proto.disconnectExtraCode = 0;
339         mCall1Proto.disconnectExtraMessage = "";
340         mCall1Proto.ratAtStart = TelephonyManager.NETWORK_TYPE_LTE;
341         mCall1Proto.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
342         mCall1Proto.ratSwitchCount = 1L;
343         mCall1Proto.codecBitmask =
344                 (1 << AudioCodec.AUDIO_CODEC_EVS_SWB) | (1 << AudioCodec.AUDIO_CODEC_AMR);
345         mCall1Proto.concurrentCallCountAtStart = 0;
346         mCall1Proto.concurrentCallCountAtEnd = 0;
347         mCall1Proto.simSlotIndex = 0;
348         mCall1Proto.isMultiSim = false;
349         mCall1Proto.isEsim = false;
350         mCall1Proto.carrierId = CARRIER1_ID;
351         mCall1Proto.srvccCompleted = true;
352         mCall1Proto.srvccFailureCount = 0L;
353         mCall1Proto.srvccCancellationCount = 0L;
354         mCall1Proto.rttEnabled = false;
355         mCall1Proto.isEmergency = false;
356         mCall1Proto.isRoaming = false;
357 
358         // VoLTE MT call on DSDS/eSIM, hanged up by remote
359         // concurrent with mCall3Proto, started first and ended first
360         mCall2Proto = new VoiceCallSession();
361         mCall2Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
362         mCall2Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
363         mCall2Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
364         mCall2Proto.setupFailed = false;
365         mCall2Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE;
366         mCall2Proto.disconnectExtraCode = 0;
367         mCall2Proto.disconnectExtraMessage = "normal call clearing";
368         mCall2Proto.ratAtStart = TelephonyManager.NETWORK_TYPE_LTE;
369         mCall2Proto.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
370         mCall2Proto.ratSwitchCount = 0L;
371         mCall2Proto.codecBitmask = (1 << AudioCodec.AUDIO_CODEC_EVS_SWB);
372         mCall2Proto.concurrentCallCountAtStart = 0;
373         mCall2Proto.concurrentCallCountAtEnd = 1;
374         mCall2Proto.simSlotIndex = 1;
375         mCall2Proto.isMultiSim = true;
376         mCall2Proto.isEsim = true;
377         mCall2Proto.carrierId = CARRIER2_ID;
378         mCall2Proto.srvccCompleted = false;
379         mCall2Proto.srvccFailureCount = 0L;
380         mCall2Proto.srvccCancellationCount = 0L;
381         mCall2Proto.rttEnabled = false;
382         mCall2Proto.isEmergency = false;
383         mCall2Proto.isRoaming = false;
384 
385         // VoLTE MT call on DSDS/eSIM, hanged up by local, with RTT
386         // concurrent with mCall2Proto, started last and ended last
387         mCall3Proto = new VoiceCallSession();
388         mCall3Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
389         mCall3Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
390         mCall3Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
391         mCall3Proto.setupFailed = false;
392         mCall3Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED;
393         mCall3Proto.disconnectExtraCode = 0;
394         mCall3Proto.disconnectExtraMessage = "normal call clearing";
395         mCall3Proto.ratAtStart = TelephonyManager.NETWORK_TYPE_LTE;
396         mCall3Proto.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
397         mCall3Proto.ratSwitchCount = 0L;
398         mCall3Proto.codecBitmask = (1 << AudioCodec.AUDIO_CODEC_EVS_SWB);
399         mCall3Proto.concurrentCallCountAtStart = 1;
400         mCall3Proto.concurrentCallCountAtEnd = 0;
401         mCall3Proto.simSlotIndex = 1;
402         mCall3Proto.isMultiSim = true;
403         mCall3Proto.isEsim = true;
404         mCall3Proto.carrierId = CARRIER2_ID;
405         mCall3Proto.srvccCompleted = false;
406         mCall3Proto.srvccFailureCount = 0L;
407         mCall3Proto.srvccCancellationCount = 0L;
408         mCall3Proto.rttEnabled = true;
409         mCall3Proto.isEmergency = false;
410         mCall3Proto.isRoaming = false;
411 
412         // CS MO emergency call while camped on LTE
413         mCall4Proto = new VoiceCallSession();
414         mCall4Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
415         mCall4Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
416         mCall4Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
417         mCall4Proto.setupFailed = true;
418         mCall4Proto.disconnectReasonCode = DisconnectCause.NORMAL;
419         mCall4Proto.disconnectExtraCode = 0;
420         mCall4Proto.disconnectExtraMessage = "";
421         mCall4Proto.ratAtStart = TelephonyManager.NETWORK_TYPE_LTE;
422         mCall4Proto.ratAtEnd = TelephonyManager.NETWORK_TYPE_GSM;
423         mCall4Proto.ratSwitchCount = 1L;
424         mCall4Proto.codecBitmask = (1 << AudioCodec.AUDIO_CODEC_AMR);
425         mCall4Proto.concurrentCallCountAtStart = 0;
426         mCall4Proto.concurrentCallCountAtEnd = 0;
427         mCall4Proto.simSlotIndex = 0;
428         mCall4Proto.isMultiSim = true;
429         mCall4Proto.isEsim = false;
430         mCall4Proto.carrierId = CARRIER3_ID;
431         mCall4Proto.srvccCompleted = false;
432         mCall4Proto.srvccFailureCount = 0L;
433         mCall4Proto.srvccCancellationCount = 0L;
434         mCall4Proto.rttEnabled = false;
435         mCall4Proto.isEmergency = true;
436         mCall4Proto.isRoaming = true;
437 
438         mCarrier1LteUsageProto = new VoiceCallRatUsage();
439         mCarrier1LteUsageProto.carrierId = CARRIER1_ID;
440         mCarrier1LteUsageProto.rat = TelephonyManager.NETWORK_TYPE_LTE;
441         mCarrier1LteUsageProto.callCount = 1L;
442         mCarrier1LteUsageProto.totalDurationMillis = 8000L;
443 
444         mCarrier1UmtsUsageProto = new VoiceCallRatUsage();
445         mCarrier1UmtsUsageProto.carrierId = CARRIER1_ID;
446         mCarrier1UmtsUsageProto.rat = TelephonyManager.NETWORK_TYPE_UMTS;
447         mCarrier1UmtsUsageProto.callCount = 1L;
448         mCarrier1UmtsUsageProto.totalDurationMillis = 6000L;
449 
450         mCarrier2LteUsageProto = new VoiceCallRatUsage();
451         mCarrier2LteUsageProto.carrierId = CARRIER2_ID;
452         mCarrier2LteUsageProto.rat = TelephonyManager.NETWORK_TYPE_LTE;
453         mCarrier2LteUsageProto.callCount = 2L;
454         mCarrier2LteUsageProto.totalDurationMillis = 20000L;
455 
456         mCarrier3LteUsageProto = new VoiceCallRatUsage();
457         mCarrier3LteUsageProto.carrierId = CARRIER3_ID;
458         mCarrier3LteUsageProto.rat = TelephonyManager.NETWORK_TYPE_LTE;
459         mCarrier3LteUsageProto.callCount = 1L;
460         mCarrier3LteUsageProto.totalDurationMillis = 1000L;
461 
462         mCarrier3GsmUsageProto = new VoiceCallRatUsage();
463         mCarrier3GsmUsageProto.carrierId = CARRIER3_ID;
464         mCarrier3GsmUsageProto.rat = TelephonyManager.NETWORK_TYPE_GSM;
465         mCarrier3GsmUsageProto.callCount = 1L;
466         mCarrier3GsmUsageProto.totalDurationMillis = 100000L;
467 
468         mVoiceCallRatUsages =
469                 new VoiceCallRatUsage[] {
470                     mCarrier1UmtsUsageProto,
471                     mCarrier1LteUsageProto,
472                     mCarrier2LteUsageProto,
473                     mCarrier3LteUsageProto,
474                     mCarrier3GsmUsageProto
475                 };
476         mVoiceCallSessions =
477                 new VoiceCallSession[] {mCall1Proto, mCall2Proto, mCall3Proto, mCall4Proto};
478 
479         // OOS to LTE on slot 0
480         mServiceSwitch1Proto = new CellularDataServiceSwitch();
481         mServiceSwitch1Proto.ratFrom = TelephonyManager.NETWORK_TYPE_UNKNOWN;
482         mServiceSwitch1Proto.ratTo = TelephonyManager.NETWORK_TYPE_LTE;
483         mServiceSwitch1Proto.simSlotIndex = 0;
484         mServiceSwitch1Proto.isMultiSim = true;
485         mServiceSwitch1Proto.carrierId = CARRIER1_ID;
486         mServiceSwitch1Proto.switchCount = 1;
487 
488         // LTE to UMTS on slot 1
489         mServiceSwitch2Proto = new CellularDataServiceSwitch();
490         mServiceSwitch2Proto.ratFrom = TelephonyManager.NETWORK_TYPE_LTE;
491         mServiceSwitch2Proto.ratTo = TelephonyManager.NETWORK_TYPE_UMTS;
492         mServiceSwitch2Proto.simSlotIndex = 0;
493         mServiceSwitch2Proto.isMultiSim = true;
494         mServiceSwitch2Proto.carrierId = CARRIER2_ID;
495         mServiceSwitch2Proto.switchCount = 2;
496 
497         // OOS on slot 0
498         mServiceState1Proto = new CellularServiceState();
499         mServiceState1Proto.voiceRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
500         mServiceState1Proto.dataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
501         mServiceState1Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
502         mServiceState1Proto.dataRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
503         mServiceState1Proto.isEndc = false;
504         mServiceState1Proto.simSlotIndex = 0;
505         mServiceState1Proto.isMultiSim = true;
506         mServiceState1Proto.carrierId = CARRIER1_ID;
507         mServiceState1Proto.totalTimeMillis = 5000L;
508         mServiceState1Proto.isEmergencyOnly = false;
509 
510         // LTE with ENDC on slot 0
511         mServiceState2Proto = new CellularServiceState();
512         mServiceState2Proto.voiceRat = TelephonyManager.NETWORK_TYPE_LTE;
513         mServiceState2Proto.dataRat = TelephonyManager.NETWORK_TYPE_LTE;
514         mServiceState2Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
515         mServiceState2Proto.dataRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
516         mServiceState2Proto.isEndc = true;
517         mServiceState2Proto.simSlotIndex = 0;
518         mServiceState2Proto.isMultiSim = true;
519         mServiceState2Proto.carrierId = CARRIER1_ID;
520         mServiceState2Proto.totalTimeMillis = 15000L;
521         mServiceState2Proto.isEmergencyOnly = false;
522 
523         // LTE with WFC and roaming on slot 1
524         mServiceState3Proto = new CellularServiceState();
525         mServiceState3Proto.voiceRat = TelephonyManager.NETWORK_TYPE_IWLAN;
526         mServiceState3Proto.dataRat = TelephonyManager.NETWORK_TYPE_LTE;
527         mServiceState3Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_INTERNATIONAL;
528         mServiceState3Proto.dataRoamingType = ServiceState.ROAMING_TYPE_INTERNATIONAL;
529         mServiceState3Proto.isEndc = false;
530         mServiceState3Proto.simSlotIndex = 1;
531         mServiceState3Proto.isMultiSim = true;
532         mServiceState3Proto.carrierId = CARRIER2_ID;
533         mServiceState3Proto.totalTimeMillis = 10000L;
534         mServiceState3Proto.isEmergencyOnly = false;
535 
536         // UMTS with roaming on slot 1
537         mServiceState4Proto = new CellularServiceState();
538         mServiceState4Proto.voiceRat = TelephonyManager.NETWORK_TYPE_UMTS;
539         mServiceState4Proto.dataRat = TelephonyManager.NETWORK_TYPE_UMTS;
540         mServiceState4Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_INTERNATIONAL;
541         mServiceState4Proto.dataRoamingType = ServiceState.ROAMING_TYPE_INTERNATIONAL;
542         mServiceState4Proto.isEndc = false;
543         mServiceState4Proto.simSlotIndex = 1;
544         mServiceState4Proto.isMultiSim = true;
545         mServiceState4Proto.carrierId = CARRIER2_ID;
546         mServiceState4Proto.totalTimeMillis = 10000L;
547         mServiceState4Proto.isEmergencyOnly = false;
548 
549         // Limited service on slot 0
550         mServiceState5Proto = new CellularServiceState();
551         mServiceState5Proto.voiceRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
552         mServiceState5Proto.dataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
553         mServiceState5Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
554         mServiceState5Proto.dataRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
555         mServiceState5Proto.isEndc = false;
556         mServiceState5Proto.simSlotIndex = 0;
557         mServiceState5Proto.isMultiSim = true;
558         mServiceState5Proto.carrierId = CARRIER1_ID;
559         mServiceState5Proto.totalTimeMillis = 15000L;
560         mServiceState5Proto.isEmergencyOnly = true;
561 
562         mServiceSwitches =
563                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto, mServiceSwitch2Proto};
564         mServiceStates =
565                 new CellularServiceState[] {
566                     mServiceState1Proto,
567                     mServiceState2Proto,
568                     mServiceState3Proto,
569                     mServiceState4Proto,
570                     mServiceState5Proto
571                 };
572 
573         // IMS over LTE on slot 0, unregistered for 5 seconds at the registered state
574         mImsRegStatsUnregisteredLte0 = new ImsRegistrationStats();
575         mImsRegStatsUnregisteredLte0.carrierId = CARRIER1_ID;
576         mImsRegStatsUnregisteredLte0.simSlotIndex = 0;
577         mImsRegStatsUnregisteredLte0.rat = TelephonyManager.NETWORK_TYPE_LTE;
578         mImsRegStatsUnregisteredLte0.registeredMillis = 0;
579         mImsRegStatsUnregisteredLte0.voiceCapableMillis = 5000L;
580         mImsRegStatsUnregisteredLte0.voiceAvailableMillis = 5000L;
581         mImsRegStatsUnregisteredLte0.smsCapableMillis = 5000L;
582         mImsRegStatsUnregisteredLte0.smsAvailableMillis = 5000L;
583         mImsRegStatsUnregisteredLte0.videoCapableMillis = 5000L;
584         mImsRegStatsUnregisteredLte0.videoAvailableMillis = 5000L;
585         mImsRegStatsUnregisteredLte0.utCapableMillis = 5000L;
586         mImsRegStatsUnregisteredLte0.utAvailableMillis = 5000L;
587         mImsRegStatsUnregisteredLte0.registeringMillis = 0;
588         mImsRegStatsUnregisteredLte0.unregisteredMillis = 5000L;
589         mImsRegStatsUnregisteredLte0.registeredTimes = 0;
590 
591         // IMS over LTE on slot 0, registering for 5 seconds at the registered state
592         mImsRegStatsRegisteringLte0 = new ImsRegistrationStats();
593         mImsRegStatsRegisteringLte0.carrierId = CARRIER1_ID;
594         mImsRegStatsRegisteringLte0.simSlotIndex = 0;
595         mImsRegStatsRegisteringLte0.rat = TelephonyManager.NETWORK_TYPE_LTE;
596         mImsRegStatsRegisteringLte0.registeredMillis = 0;
597         mImsRegStatsRegisteringLte0.voiceCapableMillis = 5000L;
598         mImsRegStatsRegisteringLte0.voiceAvailableMillis = 5000L;
599         mImsRegStatsRegisteringLte0.smsCapableMillis = 5000L;
600         mImsRegStatsRegisteringLte0.smsAvailableMillis = 5000L;
601         mImsRegStatsRegisteringLte0.videoCapableMillis = 5000L;
602         mImsRegStatsRegisteringLte0.videoAvailableMillis = 5000L;
603         mImsRegStatsRegisteringLte0.utCapableMillis = 5000L;
604         mImsRegStatsRegisteringLte0.utAvailableMillis = 5000L;
605         mImsRegStatsRegisteringLte0.registeringMillis = 5000L;
606         mImsRegStatsRegisteringLte0.unregisteredMillis = 0;
607         mImsRegStatsRegisteringLte0.registeredTimes = 1;
608 
609         // IMS over LTE on slot 0, registered for 5 seconds
610         mImsRegistrationStatsLte0 = new ImsRegistrationStats();
611         mImsRegistrationStatsLte0.carrierId = CARRIER1_ID;
612         mImsRegistrationStatsLte0.simSlotIndex = 0;
613         mImsRegistrationStatsLte0.rat = TelephonyManager.NETWORK_TYPE_LTE;
614         mImsRegistrationStatsLte0.registeredMillis = 5000L;
615         mImsRegistrationStatsLte0.voiceCapableMillis = 5000L;
616         mImsRegistrationStatsLte0.voiceAvailableMillis = 5000L;
617         mImsRegistrationStatsLte0.smsCapableMillis = 5000L;
618         mImsRegistrationStatsLte0.smsAvailableMillis = 5000L;
619         mImsRegistrationStatsLte0.videoCapableMillis = 5000L;
620         mImsRegistrationStatsLte0.videoAvailableMillis = 5000L;
621         mImsRegistrationStatsLte0.utCapableMillis = 5000L;
622         mImsRegistrationStatsLte0.utAvailableMillis = 5000L;
623         mImsRegistrationStatsLte0.registeringMillis = 0;
624         mImsRegistrationStatsLte0.unregisteredMillis = 0;
625         mImsRegistrationStatsLte0.registeredTimes = 0;
626 
627         // IMS over WiFi on slot 0, registered for 10 seconds (voice only)
628         mImsRegistrationStatsWifi0 = new ImsRegistrationStats();
629         mImsRegistrationStatsWifi0.carrierId = CARRIER2_ID;
630         mImsRegistrationStatsWifi0.simSlotIndex = 0;
631         mImsRegistrationStatsWifi0.rat = TelephonyManager.NETWORK_TYPE_IWLAN;
632         mImsRegistrationStatsWifi0.registeredMillis = 10000L;
633         mImsRegistrationStatsWifi0.voiceCapableMillis = 10000L;
634         mImsRegistrationStatsWifi0.voiceAvailableMillis = 10000L;
635 
636         // IMS over LTE on slot 1, registered for 20 seconds
637         mImsRegistrationStatsLte1 = new ImsRegistrationStats();
638         mImsRegistrationStatsLte1.carrierId = CARRIER1_ID;
639         mImsRegistrationStatsLte1.simSlotIndex = 0;
640         mImsRegistrationStatsLte1.rat = TelephonyManager.NETWORK_TYPE_LTE;
641         mImsRegistrationStatsLte1.registeredMillis = 20000L;
642         mImsRegistrationStatsLte1.voiceCapableMillis = 20000L;
643         mImsRegistrationStatsLte1.voiceAvailableMillis = 20000L;
644         mImsRegistrationStatsLte1.smsCapableMillis = 20000L;
645         mImsRegistrationStatsLte1.smsAvailableMillis = 20000L;
646         mImsRegistrationStatsLte1.videoCapableMillis = 20000L;
647         mImsRegistrationStatsLte1.videoAvailableMillis = 20000L;
648         mImsRegistrationStatsLte1.utCapableMillis = 20000L;
649         mImsRegistrationStatsLte1.utAvailableMillis = 20000L;
650         mImsRegistrationStatsLte1.registeringMillis = 0;
651         mImsRegistrationStatsLte1.unregisteredMillis = 0;
652         mImsRegistrationStatsLte1.registeredTimes = 0;
653 
654         // IMS terminations on LTE
655         mImsRegistrationTerminationLte = new ImsRegistrationTermination();
656         mImsRegistrationTerminationLte.carrierId = CARRIER1_ID;
657         mImsRegistrationTerminationLte.isMultiSim = true;
658         mImsRegistrationTerminationLte.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
659         mImsRegistrationTerminationLte.setupFailed = false;
660         mImsRegistrationTerminationLte.reasonCode = ImsReasonInfo.CODE_REGISTRATION_ERROR;
661         mImsRegistrationTerminationLte.extraCode = 999;
662         mImsRegistrationTerminationLte.extraMessage = "Request Timeout";
663         mImsRegistrationTerminationLte.count = 2;
664 
665         // IMS terminations on WiFi
666         mImsRegistrationTerminationWifi = new ImsRegistrationTermination();
667         mImsRegistrationTerminationWifi.carrierId = CARRIER2_ID;
668         mImsRegistrationTerminationWifi.isMultiSim = true;
669         mImsRegistrationTerminationWifi.ratAtEnd = TelephonyManager.NETWORK_TYPE_IWLAN;
670         mImsRegistrationTerminationWifi.setupFailed = false;
671         mImsRegistrationTerminationWifi.reasonCode = ImsReasonInfo.CODE_REGISTRATION_ERROR;
672         mImsRegistrationTerminationWifi.extraCode = 0;
673         mImsRegistrationTerminationWifi.extraMessage = "";
674         mImsRegistrationTerminationWifi.count = 1;
675 
676         mImsRegistrationStats =
677                 new ImsRegistrationStats[] {
678                     mImsRegStatsUnregisteredLte0,
679                     mImsRegStatsRegisteringLte0,
680                     mImsRegistrationStatsLte0,
681                     mImsRegistrationStatsWifi0,
682                     mImsRegistrationStatsLte1
683                 };
684 
685         mImsRegistrationTerminations =
686                 new ImsRegistrationTermination[] {
687                     mImsRegistrationTerminationLte, mImsRegistrationTerminationWifi
688                 };
689 
690         mDataCallSession0 = new DataCallSession();
691         mDataCallSession0.dimension = 111;
692         mDataCallSession0.carrierId = CARRIER1_ID;
693         mDataCallSession0.oosAtEnd = false;
694         mDataCallSession0.ratSwitchCount = 3L;
695         mDataCallSession0.setupFailed = false;
696         mDataCallSession0.durationMinutes = 20;
697         mDataCallSession0.ongoing = true;
698         mDataCallSession0.handoverFailureCauses = new int[]{3, 2, 1};
699         mDataCallSession0.handoverFailureRat = new int[]{5, 5, 6};
700 
701         mDataCallSession1 = new DataCallSession();
702         mDataCallSession1.dimension = 222;
703         mDataCallSession1.carrierId = CARRIER2_ID;
704         mDataCallSession1.oosAtEnd = true;
705         mDataCallSession1.ratSwitchCount = 1L;
706         mDataCallSession1.setupFailed = false;
707         mDataCallSession1.durationMinutes = 5;
708         mDataCallSession1.ongoing = false;
709 
710         // RCS registrtion feature tag slot 0
711         mImsRegistrationFeatureTagStats1Proto = new ImsRegistrationFeatureTagStats();
712         mImsRegistrationFeatureTagStats1Proto.carrierId = CARRIER1_ID;
713         mImsRegistrationFeatureTagStats1Proto.slotId = 0;
714         mImsRegistrationFeatureTagStats1Proto.featureTagName = 1;
715         mImsRegistrationFeatureTagStats1Proto.registrationTech = TelephonyManager.NETWORK_TYPE_LTE;
716         mImsRegistrationFeatureTagStats1Proto.registeredMillis = 3600L;
717 
718         // RCS registrtion feature tag slot 1
719         mImsRegistrationFeatureTagStats2Proto = new ImsRegistrationFeatureTagStats();
720         mImsRegistrationFeatureTagStats2Proto.carrierId = CARRIER2_ID;
721         mImsRegistrationFeatureTagStats2Proto.slotId = 1;
722         mImsRegistrationFeatureTagStats2Proto.featureTagName = 0;
723         mImsRegistrationFeatureTagStats2Proto.registrationTech = TelephonyManager.NETWORK_TYPE_LTE;
724         mImsRegistrationFeatureTagStats2Proto.registeredMillis = 3600L;
725 
726         mImsRegistrationFeatureTagStatses =
727                 new ImsRegistrationFeatureTagStats[] {
728                         mImsRegistrationFeatureTagStats1Proto,
729                         mImsRegistrationFeatureTagStats2Proto
730                 };
731 
732         // RCS client provisioning stats slot 0
733         mRcsClientProvisioningStats1Proto = new RcsClientProvisioningStats();
734         mRcsClientProvisioningStats1Proto.carrierId = CARRIER1_ID;
735         mRcsClientProvisioningStats1Proto.slotId = 0;
736         mRcsClientProvisioningStats1Proto.event =
737                 RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
738         mRcsClientProvisioningStats1Proto.count = 1;
739 
740         // RCS client provisioning stats slot 1
741         mRcsClientProvisioningStats2Proto = new RcsClientProvisioningStats();
742         mRcsClientProvisioningStats2Proto.carrierId = CARRIER2_ID;
743         mRcsClientProvisioningStats2Proto.slotId = 1;
744         mRcsClientProvisioningStats2Proto.event =
745                 RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
746         mRcsClientProvisioningStats2Proto.count = 1;
747 
748         mRcsClientProvisioningStatses =
749                 new RcsClientProvisioningStats[] {
750                         mRcsClientProvisioningStats1Proto,
751                         mRcsClientProvisioningStats2Proto
752                 };
753 
754         // RCS ACS provisioning stats : error response
755         mRcsAcsProvisioningStats1Proto = new RcsAcsProvisioningStats();
756         mRcsAcsProvisioningStats1Proto.carrierId = CARRIER1_ID;
757         mRcsAcsProvisioningStats1Proto.slotId = 0;
758         mRcsAcsProvisioningStats1Proto.responseCode = 401;
759         mRcsAcsProvisioningStats1Proto.responseType =
760                 RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
761         mRcsAcsProvisioningStats1Proto.isSingleRegistrationEnabled = true;
762         mRcsAcsProvisioningStats1Proto.count = 1;
763         mRcsAcsProvisioningStats1Proto.stateTimerMillis = START_TIME_MILLIS;
764 
765         // RCS ACS provisioning stats : xml
766         mRcsAcsProvisioningStats2Proto = new RcsAcsProvisioningStats();
767         mRcsAcsProvisioningStats2Proto.carrierId = CARRIER1_ID;
768         mRcsAcsProvisioningStats2Proto.slotId = 0;
769         mRcsAcsProvisioningStats2Proto.responseCode = 200;
770         mRcsAcsProvisioningStats2Proto.responseType =
771                 RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
772         mRcsAcsProvisioningStats2Proto.isSingleRegistrationEnabled = true;
773         mRcsAcsProvisioningStats2Proto.count = 1;
774         mRcsAcsProvisioningStats2Proto.stateTimerMillis = START_TIME_MILLIS;
775 
776         mRcsAcsProvisioningStatses =
777                 new RcsAcsProvisioningStats[] {
778                         mRcsAcsProvisioningStats1Proto,
779                         mRcsAcsProvisioningStats2Proto
780                 };
781 
782         mImsRegistrationServiceIm = new ImsRegistrationServiceDescStats();
783         mImsRegistrationServiceIm.carrierId = CARRIER1_ID;
784         mImsRegistrationServiceIm.slotId = SLOT_ID1;
785         mImsRegistrationServiceIm.serviceIdName = 0;
786         mImsRegistrationServiceIm.serviceIdVersion = 1.0f;
787         mImsRegistrationServiceIm.registrationTech = REGISTRATION1_TECH;
788         mImsRegistrationServiceIm.publishedMillis = START_TIME_MILLIS;
789 
790         mImsRegistrationServiceFt = new ImsRegistrationServiceDescStats();
791         mImsRegistrationServiceFt.carrierId = CARRIER2_ID;
792         mImsRegistrationServiceFt.slotId = SLOT_ID2;
793         mImsRegistrationServiceFt.serviceIdName = 1;
794         mImsRegistrationServiceFt.serviceIdVersion = 2.0f;
795         mImsRegistrationServiceFt.registrationTech = REGISTRATION2_TECH;
796         mImsRegistrationServiceIm.publishedMillis = START_TIME_MILLIS;
797 
798         mImsRegistrationServiceDescStats =
799             new ImsRegistrationServiceDescStats[] {
800                 mImsRegistrationServiceIm, mImsRegistrationServiceFt
801             };
802 
803 
804         mImsDedicatedBearerListenerEvent1 = new ImsDedicatedBearerListenerEvent();
805         mImsDedicatedBearerListenerEvent1.carrierId = CARRIER1_ID;
806         mImsDedicatedBearerListenerEvent1.slotId = SLOT_ID1;
807         mImsDedicatedBearerListenerEvent1.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
808         mImsDedicatedBearerListenerEvent1.qci = 5;
809         mImsDedicatedBearerListenerEvent1.dedicatedBearerEstablished = true;
810         mImsDedicatedBearerListenerEvent1.eventCount = 1;
811 
812         mImsDedicatedBearerListenerEvent2 = new ImsDedicatedBearerListenerEvent();
813         mImsDedicatedBearerListenerEvent2.carrierId = CARRIER2_ID;
814         mImsDedicatedBearerListenerEvent2.slotId = SLOT_ID1;
815         mImsDedicatedBearerListenerEvent2.ratAtEnd = TelephonyManager.NETWORK_TYPE_NR;
816         mImsDedicatedBearerListenerEvent2.qci = 6;
817         mImsDedicatedBearerListenerEvent2.dedicatedBearerEstablished = true;
818         mImsDedicatedBearerListenerEvent2.eventCount = 1;
819 
820         mImsDedicatedBearerListenerEvents =
821                 new ImsDedicatedBearerListenerEvent[] {
822                     mImsDedicatedBearerListenerEvent1, mImsDedicatedBearerListenerEvent2
823                 };
824 
825 
826         mImsDedicatedBearerEvent1 = new ImsDedicatedBearerEvent();
827         mImsDedicatedBearerEvent1.carrierId = CARRIER1_ID;
828         mImsDedicatedBearerEvent1.slotId = SLOT_ID1;
829         mImsDedicatedBearerEvent1.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
830         mImsDedicatedBearerEvent1.qci = 5;
831         mImsDedicatedBearerEvent1.bearerState =
832                 TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED;
833         mImsDedicatedBearerEvent1.localConnectionInfoReceived = true;
834         mImsDedicatedBearerEvent1.remoteConnectionInfoReceived = true;
835         mImsDedicatedBearerEvent1.hasListeners = true;
836         mImsDedicatedBearerEvent1.count = 1;
837 
838         mImsDedicatedBearerEvent2 = new ImsDedicatedBearerEvent();
839         mImsDedicatedBearerEvent2.carrierId = CARRIER1_ID;
840         mImsDedicatedBearerEvent2.slotId = SLOT_ID1;
841         mImsDedicatedBearerEvent2.ratAtEnd = TelephonyManager.NETWORK_TYPE_NR;
842         mImsDedicatedBearerEvent2.qci = 6;
843         mImsDedicatedBearerEvent2.bearerState =
844                 TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_MODIFIED;
845         mImsDedicatedBearerEvent2.localConnectionInfoReceived = true;
846         mImsDedicatedBearerEvent2.remoteConnectionInfoReceived = true;
847         mImsDedicatedBearerEvent2.hasListeners = true;
848         mImsDedicatedBearerEvent2.count = 1;
849 
850         mImsDedicatedBearerEvents =
851                 new ImsDedicatedBearerEvent[] {
852                     mImsDedicatedBearerEvent1, mImsDedicatedBearerEvent2
853                 };
854 
855 
856         mUceEventStats1 = new UceEventStats();
857         mUceEventStats1.carrierId = CARRIER1_ID;
858         mUceEventStats1.slotId = SLOT_ID1;
859         mUceEventStats1.type = 1;
860         mUceEventStats1.successful = true;
861         mUceEventStats1.commandCode = 0;
862         mUceEventStats1.networkResponse = 200;
863         mUceEventStats1.count = 1;
864 
865         mUceEventStats2 = new UceEventStats();
866         mUceEventStats2.carrierId = CARRIER2_ID;
867         mUceEventStats2.slotId = SLOT_ID2;
868         mUceEventStats2.type = 2;
869         mUceEventStats2.successful = false;
870         mUceEventStats2.commandCode = 2;
871         mUceEventStats2.networkResponse = 0;
872         mUceEventStats2.count = 1;
873         mUceEventStatses = new UceEventStats[] {mUceEventStats1, mUceEventStats2};
874 
875         mPresenceNotifyEvent1 = new PresenceNotifyEvent();
876         mPresenceNotifyEvent1.carrierId = CARRIER1_ID;
877         mPresenceNotifyEvent1.slotId = SLOT_ID1;
878         mPresenceNotifyEvent1.reason = 1;
879         mPresenceNotifyEvent1.contentBodyReceived = true;
880         mPresenceNotifyEvent1.rcsCapsCount = 1;
881         mPresenceNotifyEvent1.mmtelCapsCount = 1;
882         mPresenceNotifyEvent1.noCapsCount = 0;
883         mPresenceNotifyEvent1.count = 1;
884 
885         mPresenceNotifyEvent2 = new PresenceNotifyEvent();
886         mPresenceNotifyEvent2.carrierId = CARRIER2_ID;
887         mPresenceNotifyEvent2.slotId = SLOT_ID2;
888         mPresenceNotifyEvent2.reason = 1;
889         mPresenceNotifyEvent2.contentBodyReceived = false;
890         mPresenceNotifyEvent2.rcsCapsCount = 0;
891         mPresenceNotifyEvent2.mmtelCapsCount = 0;
892         mPresenceNotifyEvent2.noCapsCount = 1;
893         mPresenceNotifyEvent2.count = 1;
894         mPresenceNotifyEvents = new PresenceNotifyEvent[] {mPresenceNotifyEvent1,
895                 mPresenceNotifyEvent2};
896 
897         //A destroyed SipDelegate
898         mSipDelegateStats1 = new SipDelegateStats();
899         mSipDelegateStats1.carrierId = CARRIER1_ID;
900         mSipDelegateStats1.slotId = SLOT_ID1;
901         mSipDelegateStats1.uptimeMillis = 1000L;
902         mSipDelegateStats1.destroyReason =
903                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP;
904 
905         //An active SipDelegate
906         mSipDelegateStats2 = new SipDelegateStats();
907         mSipDelegateStats2.carrierId = CARRIER1_ID;
908         mSipDelegateStats2.slotId = SLOT_ID1;
909         mSipDelegateStats2.uptimeMillis = 1000L;
910         mSipDelegateStats2.destroyReason =
911                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD;
912 
913         //An active SipDelegate
914         mSipDelegateStats3 = new SipDelegateStats();
915         mSipDelegateStats3.carrierId = CARRIER2_ID;
916         mSipDelegateStats3.slotId = SLOT_ID2;
917         mSipDelegateStats3.uptimeMillis = 3000L;
918         mSipDelegateStats3.destroyReason =
919                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN;
920 
921         //A registered SipTransportFeatureTag
922         mSipTransportFeatureTagStats1 = new SipTransportFeatureTagStats();
923         mSipTransportFeatureTagStats1.carrierId = CARRIER1_ID;
924         mSipTransportFeatureTagStats1.slotId = SLOT_ID1;
925         mSipTransportFeatureTagStats1.featureTagName = TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_IM;
926         mSipTransportFeatureTagStats1.sipTransportDeniedReason =  RcsStats.NONE;
927         mSipTransportFeatureTagStats1.sipTransportDeregisteredReason = RcsStats.NONE;
928         mSipTransportFeatureTagStats1.associatedMillis = 1000L;
929 
930         //A denied SipTransportFeatureTag
931         mSipTransportFeatureTagStats2 = new SipTransportFeatureTagStats();
932         mSipTransportFeatureTagStats2.carrierId = CARRIER1_ID;
933         mSipTransportFeatureTagStats2.slotId = SLOT_ID1;
934         mSipTransportFeatureTagStats2.featureTagName = 1;
935         mSipTransportFeatureTagStats2.sipTransportDeniedReason =
936                 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE;
937         mSipTransportFeatureTagStats2.sipTransportDeregisteredReason = RcsStats.NONE;
938         mSipTransportFeatureTagStats2.associatedMillis = 1000L;
939 
940         mSipDelegateStatsArray = new SipDelegateStats[]{mSipDelegateStats2, mSipDelegateStats3};
941 
942         mSipTransportFeatureTagStatsArray = new SipTransportFeatureTagStats[]
943                 {mSipTransportFeatureTagStats1, mSipTransportFeatureTagStats2};
944 
945         mGbaEvent1 = new GbaEvent();
946         mGbaEvent1.carrierId = CARRIER1_ID;
947         mGbaEvent1.slotId = SLOT_ID1;
948         mGbaEvent1.successful = true;
949         mGbaEvent1.failedReason = GBA_EVENT__FAILED_REASON__UNKNOWN;
950         mGbaEvent1.count = 1;
951 
952         mGbaEvent2 = new GbaEvent();
953         mGbaEvent2.carrierId = CARRIER2_ID;
954         mGbaEvent2.slotId = SLOT_ID2;
955         mGbaEvent2.successful = false;
956         mGbaEvent2.failedReason = GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
957         mGbaEvent2.count = 1;
958 
959         mGbaEvent = new GbaEvent[] {mGbaEvent1, mGbaEvent2};
960 
961         //stats slot 0
962         mSipMessageResponse1 = new SipMessageResponse();
963         mSipMessageResponse1.carrierId = CARRIER1_ID;
964         mSipMessageResponse1.slotId = SLOT_ID1;
965         //"INVITE"
966         mSipMessageResponse1.sipMessageMethod = 2;
967         mSipMessageResponse1.sipMessageResponse = 200;
968         mSipMessageResponse1.sipMessageDirection = 1;
969         mSipMessageResponse1.messageError = 0;
970         mSipMessageResponse1.count = 1;
971 
972         //stats slot 1
973         mSipMessageResponse2 = new SipMessageResponse();
974         mSipMessageResponse2.carrierId = CARRIER2_ID;
975         mSipMessageResponse2.slotId = SLOT_ID2;
976         //"INVITE"
977         mSipMessageResponse2.sipMessageMethod = 2;
978         mSipMessageResponse2.sipMessageResponse = 200;
979         mSipMessageResponse2.sipMessageDirection = 0;
980         mSipMessageResponse2.messageError = 0;
981         mSipMessageResponse2.count = 1;
982 
983         mSipMessageResponse =
984                 new SipMessageResponse[] {mSipMessageResponse1, mSipMessageResponse2};
985 
986         // stats slot 0
987         mSipTransportSession1 = new SipTransportSession();
988         mSipTransportSession1.carrierId = CARRIER1_ID;
989         mSipTransportSession1.slotId = SLOT_ID1;
990         //"INVITE"
991         mSipTransportSession1.sessionMethod = 2;
992         mSipTransportSession1.sipMessageDirection = 1;
993         mSipTransportSession1.sipResponse = 200;
994         mSipTransportSession1.sessionCount = 1;
995         mSipTransportSession1.endedGracefullyCount = 1;
996         mSipTransportSession1.isEndedGracefully = true;
997 
998         // stats slot 1
999         mSipTransportSession2 = new SipTransportSession();
1000         mSipTransportSession2.carrierId = CARRIER2_ID;
1001         mSipTransportSession2.slotId = SLOT_ID2;
1002         //"INVITE"
1003         mSipTransportSession2.sessionMethod = 2;
1004         mSipTransportSession2.sipMessageDirection = 0;
1005         mSipTransportSession2.sipResponse = 200;
1006         mSipTransportSession2.sessionCount = 1;
1007         mSipTransportSession2.endedGracefullyCount = 1;
1008         mSipTransportSession2.isEndedGracefully = true;
1009 
1010         mSipTransportSession =
1011                 new SipTransportSession[] {mSipTransportSession1, mSipTransportSession2};
1012 
1013         generateTestSmsData();
1014         generateTestSatelliteData();
1015     }
1016 
generateTestSmsData()1017     private void generateTestSmsData() {
1018         mIncomingSms1 = new IncomingSms();
1019         mIncomingSms1.smsFormat = INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP;
1020         mIncomingSms1.smsTech = INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP;
1021         mIncomingSms1.rat = TelephonyManager.NETWORK_TYPE_LTE;
1022         mIncomingSms1.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_NORMAL;
1023         mIncomingSms1.totalParts = 1;
1024         mIncomingSms1.receivedParts = 1;
1025         mIncomingSms1.blocked = false;
1026         mIncomingSms1.error = INCOMING_SMS__ERROR__SMS_SUCCESS;
1027         mIncomingSms1.isRoaming = false;
1028         mIncomingSms1.simSlotIndex = 0;
1029         mIncomingSms1.isMultiSim = false;
1030         mIncomingSms1.isEsim = false;
1031         mIncomingSms1.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
1032         mIncomingSms1.messageId = 0;
1033         mIncomingSms1.count = 1;
1034         mIncomingSms1.isManagedProfile = false;
1035         mIncomingSms1.isNtn = false;
1036         mIncomingSms1.isEmergency = true;
1037 
1038         mIncomingSms2 = new IncomingSms();
1039         mIncomingSms2.smsFormat = INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2;
1040         mIncomingSms2.smsTech = INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2;
1041         mIncomingSms2.rat = TelephonyManager.NETWORK_TYPE_CDMA;
1042         mIncomingSms2.smsType = INCOMING_SMS__SMS_TYPE__SMS_TYPE_SMS_PP;
1043         mIncomingSms2.totalParts = 2;
1044         mIncomingSms2.receivedParts = 2;
1045         mIncomingSms2.blocked = true;
1046         mIncomingSms2.error = INCOMING_SMS__ERROR__SMS_ERROR_GENERIC;
1047         mIncomingSms2.isRoaming = true;
1048         mIncomingSms2.simSlotIndex = 1;
1049         mIncomingSms2.isMultiSim = true;
1050         mIncomingSms2.isEsim = true;
1051         mIncomingSms2.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
1052         mIncomingSms2.messageId = 1;
1053         mIncomingSms2.count = 2;
1054         mIncomingSms2.isManagedProfile = true;
1055         mIncomingSms2.isNtn = true;
1056         mIncomingSms2.isEmergency = true;
1057 
1058         mIncomingSms = new IncomingSms[] {mIncomingSms1, mIncomingSms2};
1059 
1060         mOutgoingSms1 = new OutgoingSms();
1061         mOutgoingSms1.smsFormat = INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP;
1062         mOutgoingSms1.smsTech = INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP;
1063         mOutgoingSms1.rat = TelephonyManager.NETWORK_TYPE_LTE;
1064         mOutgoingSms1.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_SUCCESS;
1065         mOutgoingSms1.errorCode = NO_ERROR_CODE;
1066         mOutgoingSms1.isRoaming = false;
1067         mOutgoingSms1.isFromDefaultApp = true;
1068         mOutgoingSms1.simSlotIndex = 0;
1069         mOutgoingSms1.isMultiSim = false;
1070         mOutgoingSms1.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
1071         mOutgoingSms1.messageId = 0;
1072         mOutgoingSms1.retryId = 0;
1073         mOutgoingSms1.intervalMillis = 0;
1074         mOutgoingSms1.count = 1;
1075         mOutgoingSms1.sendErrorCode = RESULT_ERROR_NONE;
1076         mOutgoingSms1.networkErrorCode = NO_ERROR_CODE;
1077         mOutgoingSms1.isManagedProfile = false;
1078         mOutgoingSms1.isEmergency = false;
1079         mOutgoingSms1.isNtn = false;
1080 
1081         mOutgoingSms2 = new OutgoingSms();
1082         mOutgoingSms2.smsFormat = INCOMING_SMS__SMS_FORMAT__SMS_FORMAT_3GPP2;
1083         mOutgoingSms2.smsTech = INCOMING_SMS__SMS_TECH__SMS_TECH_CS_3GPP2;
1084         mOutgoingSms2.rat = TelephonyManager.NETWORK_TYPE_CDMA;
1085         mOutgoingSms2.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR;
1086         mOutgoingSms2.errorCode = NO_ERROR_CODE;
1087         mOutgoingSms2.isRoaming = true;
1088         mOutgoingSms2.isFromDefaultApp = false;
1089         mOutgoingSms2.simSlotIndex = 1;
1090         mOutgoingSms2.isMultiSim = true;
1091         mOutgoingSms2.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
1092         mOutgoingSms2.messageId = 1;
1093         mOutgoingSms2.retryId = 1;
1094         mOutgoingSms2.intervalMillis = 10;
1095         mOutgoingSms2.count = 2;
1096         mOutgoingSms2.sendErrorCode = RESULT_RIL_SMS_SEND_FAIL_RETRY;
1097         mOutgoingSms2.networkErrorCode = NO_ERROR_CODE;
1098         mOutgoingSms2.isManagedProfile = true;
1099         mOutgoingSms2.isEmergency = true;
1100         mOutgoingSms2.isNtn = true;
1101 
1102         mOutgoingSms = new OutgoingSms[] {mOutgoingSms1, mOutgoingSms2};
1103 
1104         mOutgoingShortCodeSms1 = new OutgoingShortCodeSms();
1105         mOutgoingShortCodeSms1.category = 1;
1106         mOutgoingShortCodeSms1.xmlVersion = 30;
1107         mOutgoingShortCodeSms1.shortCodeSmsCount = 1;
1108 
1109         mOutgoingShortCodeSms2 = new OutgoingShortCodeSms();
1110         mOutgoingShortCodeSms2.category = 2;
1111         mOutgoingShortCodeSms2.xmlVersion  = 31;
1112         mOutgoingShortCodeSms2.shortCodeSmsCount = 1;
1113 
1114         mOutgoingShortCodeSms = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1,
1115                 mOutgoingShortCodeSms2};
1116 
1117         generateTestSatelliteData();
1118 
1119         generateTestDataNetworkValidationsData();
1120     }
1121 
generateTestSatelliteData()1122     private void generateTestSatelliteData() {
1123         mSatelliteController1 = new SatelliteController();
1124         mSatelliteController1.countOfSatelliteServiceEnablementsSuccess = 2;
1125         mSatelliteController1.countOfSatelliteServiceEnablementsFail = 0;
1126         mSatelliteController1.countOfOutgoingDatagramSuccess = 8;
1127         mSatelliteController1.countOfOutgoingDatagramFail = 9;
1128         mSatelliteController1.countOfIncomingDatagramSuccess = 10;
1129         mSatelliteController1.countOfIncomingDatagramFail = 11;
1130         mSatelliteController1.countOfDatagramTypeSosSmsSuccess = 5;
1131         mSatelliteController1.countOfDatagramTypeSosSmsFail = 5;
1132         mSatelliteController1.countOfDatagramTypeLocationSharingSuccess = 6;
1133         mSatelliteController1.countOfDatagramTypeLocationSharingFail = 6;
1134         mSatelliteController1.countOfProvisionSuccess = 3;
1135         mSatelliteController1.countOfProvisionFail = 4;
1136         mSatelliteController1.countOfDeprovisionSuccess = 5;
1137         mSatelliteController1.countOfDeprovisionFail = 6;
1138         mSatelliteController1.totalServiceUptimeSec = 60 * 60 * 24 * 7;
1139         mSatelliteController1.totalBatteryConsumptionPercent = 7;
1140         mSatelliteController1.totalBatteryChargedTimeSec = 60 * 60 * 3 * 1;
1141         mSatelliteController1.countOfDemoModeSatelliteServiceEnablementsSuccess = 3;
1142         mSatelliteController1.countOfDemoModeSatelliteServiceEnablementsFail = 1;
1143         mSatelliteController1.countOfDemoModeOutgoingDatagramSuccess = 4;
1144         mSatelliteController1.countOfDemoModeOutgoingDatagramFail = 2;
1145         mSatelliteController1.countOfDemoModeIncomingDatagramSuccess = 3;
1146         mSatelliteController1.countOfDemoModeIncomingDatagramFail = 2;
1147         mSatelliteController1.countOfDatagramTypeKeepAliveSuccess = 1;
1148         mSatelliteController1.countOfDatagramTypeKeepAliveFail = 2;
1149 
1150         mSatelliteController2 = new SatelliteController();
1151         mSatelliteController2.countOfSatelliteServiceEnablementsSuccess = 2 + 1;
1152         mSatelliteController2.countOfSatelliteServiceEnablementsFail = 0 + 1;
1153         mSatelliteController2.countOfOutgoingDatagramSuccess = 8 + 1;
1154         mSatelliteController2.countOfOutgoingDatagramFail = 9 + 1;
1155         mSatelliteController2.countOfIncomingDatagramSuccess = 10 + 1;
1156         mSatelliteController2.countOfIncomingDatagramFail = 11 + 1;
1157         mSatelliteController2.countOfDatagramTypeSosSmsSuccess = 5 + 1;
1158         mSatelliteController2.countOfDatagramTypeSosSmsFail = 5 + 1;
1159         mSatelliteController2.countOfDatagramTypeLocationSharingSuccess = 6 + 1;
1160         mSatelliteController2.countOfDatagramTypeLocationSharingFail = 6 + 1;
1161         mSatelliteController2.countOfProvisionSuccess = 13;
1162         mSatelliteController2.countOfProvisionFail = 14;
1163         mSatelliteController2.countOfDeprovisionSuccess = 15;
1164         mSatelliteController2.countOfDeprovisionFail = 16;
1165         mSatelliteController2.totalServiceUptimeSec = 60 * 60 * 12;
1166         mSatelliteController2.totalBatteryConsumptionPercent = 14;
1167         mSatelliteController2.totalBatteryChargedTimeSec = 60 * 60 * 3;
1168         mSatelliteController2.countOfDemoModeSatelliteServiceEnablementsSuccess = 5;
1169         mSatelliteController2.countOfDemoModeSatelliteServiceEnablementsFail = 4;
1170         mSatelliteController2.countOfDemoModeOutgoingDatagramSuccess = 3;
1171         mSatelliteController2.countOfDemoModeOutgoingDatagramFail = 7;
1172         mSatelliteController2.countOfDemoModeIncomingDatagramSuccess = 2;
1173         mSatelliteController2.countOfDemoModeIncomingDatagramFail = 3;
1174         mSatelliteController2.countOfDatagramTypeKeepAliveSuccess = 4;
1175         mSatelliteController2.countOfDatagramTypeKeepAliveFail = 5;
1176 
1177         // SatelliteController atom has one data point
1178         mSatelliteControllers =
1179                 new SatelliteController[] {
1180                         mSatelliteController1
1181                 };
1182 
1183         mSatelliteSession1 = new SatelliteSession();
1184         mSatelliteSession1.satelliteServiceInitializationResult =
1185                 SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1186         mSatelliteSession1.satelliteTechnology =
1187                 SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_PROPRIETARY;
1188         mSatelliteSession1.count = 1;
1189         mSatelliteSession1.satelliteServiceTerminationResult =
1190                 SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1191         mSatelliteSession1.initializationProcessingTimeMillis = 100;
1192         mSatelliteSession1.terminationProcessingTimeMillis = 200;
1193         mSatelliteSession1.sessionDurationSeconds = 3;
1194         mSatelliteSession1.countOfOutgoingDatagramSuccess = 1;
1195         mSatelliteSession1.countOfOutgoingDatagramFailed = 0;
1196         mSatelliteSession1.countOfIncomingDatagramSuccess = 1;
1197         mSatelliteSession1.countOfIncomingDatagramFailed = 0;
1198         mSatelliteSession1.isDemoMode = false;
1199         mSatelliteSession1.maxNtnSignalStrengthLevel = 2;
1200 
1201         mSatelliteSession2 = new SatelliteSession();
1202         mSatelliteSession2.satelliteServiceInitializationResult =
1203                 SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
1204         mSatelliteSession2.satelliteTechnology =
1205                 SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_NB_IOT_NTN;
1206         mSatelliteSession2.count = 1;
1207         mSatelliteSession2.satelliteServiceTerminationResult =
1208                 SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1209         mSatelliteSession2.initializationProcessingTimeMillis = 300;
1210         mSatelliteSession2.terminationProcessingTimeMillis = 100;
1211         mSatelliteSession2.sessionDurationSeconds = 10;
1212         mSatelliteSession2.countOfOutgoingDatagramSuccess = 0;
1213         mSatelliteSession2.countOfOutgoingDatagramFailed = 2;
1214         mSatelliteSession2.countOfIncomingDatagramSuccess = 0;
1215         mSatelliteSession2.countOfIncomingDatagramFailed = 1;
1216         mSatelliteSession2.isDemoMode = true;
1217         mSatelliteSession2.maxNtnSignalStrengthLevel = 4;
1218 
1219         mSatelliteSessions =
1220                 new SatelliteSession[] {
1221                         mSatelliteSession1, mSatelliteSession2
1222                 };
1223 
1224         mSatelliteIncomingDatagram1 = new SatelliteIncomingDatagram();
1225         mSatelliteIncomingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1226         mSatelliteIncomingDatagram1.datagramSizeBytes = 1 * 1024;
1227         mSatelliteIncomingDatagram1.datagramTransferTimeMillis = 3 * 1000;
1228         mSatelliteIncomingDatagram1.isDemoMode = false;
1229 
1230         mSatelliteIncomingDatagram2 = new SatelliteIncomingDatagram();
1231         mSatelliteIncomingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
1232         mSatelliteIncomingDatagram2.datagramSizeBytes = 512;
1233         mSatelliteIncomingDatagram2.datagramTransferTimeMillis = 1 * 1000;
1234         mSatelliteIncomingDatagram1.isDemoMode = true;
1235 
1236         mSatelliteIncomingDatagrams =
1237                 new SatelliteIncomingDatagram[] {
1238                         mSatelliteIncomingDatagram1, mSatelliteIncomingDatagram2
1239                 };
1240 
1241         mSatelliteOutgoingDatagram1 = new SatelliteOutgoingDatagram();
1242         mSatelliteOutgoingDatagram1.datagramType =
1243                 SatelliteProtoEnums.DATAGRAM_TYPE_LOCATION_SHARING;
1244         mSatelliteOutgoingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1245         mSatelliteOutgoingDatagram1.datagramSizeBytes = 1 * 1024;
1246         mSatelliteOutgoingDatagram1.datagramTransferTimeMillis = 3 * 1000;
1247         mSatelliteOutgoingDatagram1.isDemoMode = false;
1248 
1249         mSatelliteOutgoingDatagram2 = new SatelliteOutgoingDatagram();
1250         mSatelliteOutgoingDatagram2.datagramType =
1251                 SatelliteProtoEnums.DATAGRAM_TYPE_SOS_MESSAGE;
1252         mSatelliteOutgoingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
1253         mSatelliteOutgoingDatagram2.datagramSizeBytes = 512;
1254         mSatelliteOutgoingDatagram2.datagramTransferTimeMillis = 1 * 1000;
1255         mSatelliteOutgoingDatagram1.isDemoMode = true;
1256 
1257         mSatelliteOutgoingDatagrams =
1258                 new SatelliteOutgoingDatagram[] {
1259                         mSatelliteOutgoingDatagram1, mSatelliteOutgoingDatagram2
1260                 };
1261 
1262         mSatelliteProvision1 = new SatelliteProvision();
1263         mSatelliteProvision1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
1264         mSatelliteProvision1.provisioningTimeSec = 3 * 60;
1265         mSatelliteProvision1.isProvisionRequest = true;
1266         mSatelliteProvision1.isCanceled = false;
1267 
1268         mSatelliteProvision2 = new SatelliteProvision();
1269         mSatelliteProvision2.resultCode =
1270                 SatelliteProtoEnums.SATELLITE_SERVICE_NOT_PROVISIONED;
1271         mSatelliteProvision2.provisioningTimeSec = 0;
1272         mSatelliteProvision2.isProvisionRequest = false;
1273         mSatelliteProvision2.isCanceled = true;
1274 
1275         mSatelliteProvisions =
1276                 new SatelliteProvision[] {
1277                         mSatelliteProvision1, mSatelliteProvision2
1278                 };
1279 
1280         mSatelliteSosMessageRecommender1 = new SatelliteSosMessageRecommender();
1281         mSatelliteSosMessageRecommender1.isDisplaySosMessageSent = true;
1282         mSatelliteSosMessageRecommender1.countOfTimerStarted = 5;
1283         mSatelliteSosMessageRecommender1.isImsRegistered = false;
1284         mSatelliteSosMessageRecommender1.cellularServiceState =
1285                 TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE;
1286         mSatelliteSosMessageRecommender1.isMultiSim = true;
1287         mSatelliteSosMessageRecommender1.recommendingHandoverType = 1;
1288         mSatelliteSosMessageRecommender1.isSatelliteAllowedInCurrentLocation = true;
1289         mSatelliteSosMessageRecommender1.count = 1;
1290 
1291         mSatelliteSosMessageRecommender2 = new SatelliteSosMessageRecommender();
1292         mSatelliteSosMessageRecommender2.isDisplaySosMessageSent = false;
1293         mSatelliteSosMessageRecommender2.countOfTimerStarted = 3;
1294         mSatelliteSosMessageRecommender2.isImsRegistered = true;
1295         mSatelliteSosMessageRecommender2.cellularServiceState =
1296                 TelephonyProtoEnums.SERVICE_STATE_POWER_OFF;
1297         mSatelliteSosMessageRecommender2.isMultiSim = false;
1298         mSatelliteSosMessageRecommender2.recommendingHandoverType = 0;
1299         mSatelliteSosMessageRecommender2.isSatelliteAllowedInCurrentLocation = true;
1300         mSatelliteSosMessageRecommender2.count = 1;
1301 
1302         mSatelliteSosMessageRecommenders =
1303                 new SatelliteSosMessageRecommender[] {
1304                         mSatelliteSosMessageRecommender1, mSatelliteSosMessageRecommender2
1305                 };
1306 
1307         mCarrierRoamingSatelliteSession1 = new CarrierRoamingSatelliteSession();
1308         mCarrierRoamingSatelliteSession1.carrierId = 1;
1309         mCarrierRoamingSatelliteSession1.isNtnRoamingInHomeCountry = false;
1310         mCarrierRoamingSatelliteSession1.totalSatelliteModeTimeSec = 60;
1311         mCarrierRoamingSatelliteSession1.numberOfSatelliteConnections = 3;
1312         mCarrierRoamingSatelliteSession1.avgDurationOfSatelliteConnectionSec = 20;
1313         mCarrierRoamingSatelliteSession1.satelliteConnectionGapMinSec = 2;
1314         mCarrierRoamingSatelliteSession1.satelliteConnectionGapAvgSec = 5;
1315         mCarrierRoamingSatelliteSession1.satelliteConnectionGapMaxSec = 8;
1316         mCarrierRoamingSatelliteSession1.rsrpAvg = 3;
1317         mCarrierRoamingSatelliteSession1.rsrpMedian = 2;
1318         mCarrierRoamingSatelliteSession1.rssnrAvg = 5;
1319         mCarrierRoamingSatelliteSession1.rssnrMedian = 3;
1320         mCarrierRoamingSatelliteSession1.countOfIncomingSms = 2;
1321         mCarrierRoamingSatelliteSession1.countOfOutgoingSms = 4;
1322         mCarrierRoamingSatelliteSession1.countOfIncomingMms = 1;
1323         mCarrierRoamingSatelliteSession1.countOfOutgoingMms = 1;
1324 
1325         mCarrierRoamingSatelliteSession2 = new CarrierRoamingSatelliteSession();
1326         mCarrierRoamingSatelliteSession2.carrierId = 2;
1327         mCarrierRoamingSatelliteSession2.isNtnRoamingInHomeCountry = true;
1328         mCarrierRoamingSatelliteSession2.totalSatelliteModeTimeSec = 120;
1329         mCarrierRoamingSatelliteSession2.numberOfSatelliteConnections = 5;
1330         mCarrierRoamingSatelliteSession2.avgDurationOfSatelliteConnectionSec = 20;
1331         mCarrierRoamingSatelliteSession2.satelliteConnectionGapMinSec = 2;
1332         mCarrierRoamingSatelliteSession2.satelliteConnectionGapAvgSec = 5;
1333         mCarrierRoamingSatelliteSession2.satelliteConnectionGapMaxSec = 8;
1334         mCarrierRoamingSatelliteSession2.rsrpAvg = 3;
1335         mCarrierRoamingSatelliteSession2.rsrpMedian = 2;
1336         mCarrierRoamingSatelliteSession2.rssnrAvg = 8;
1337         mCarrierRoamingSatelliteSession2.rssnrMedian = 15;
1338         mCarrierRoamingSatelliteSession2.countOfIncomingSms = 2;
1339         mCarrierRoamingSatelliteSession2.countOfOutgoingSms = 4;
1340         mCarrierRoamingSatelliteSession2.countOfIncomingMms = 1;
1341         mCarrierRoamingSatelliteSession2.countOfOutgoingMms = 1;
1342 
1343         mCarrierRoamingSatelliteSessions = new CarrierRoamingSatelliteSession[] {
1344                 mCarrierRoamingSatelliteSession1, mCarrierRoamingSatelliteSession2};
1345 
1346         mCarrierRoamingSatelliteControllerStats1 = new CarrierRoamingSatelliteControllerStats();
1347         mCarrierRoamingSatelliteControllerStats1.configDataSource =
1348                 SatelliteProtoEnums.CONFIG_DATA_SOURCE_ENTITLEMENT;
1349         mCarrierRoamingSatelliteControllerStats1.countOfEntitlementStatusQueryRequest = 2;
1350         mCarrierRoamingSatelliteControllerStats1.countOfSatelliteConfigUpdateRequest = 1;
1351         mCarrierRoamingSatelliteControllerStats1.countOfSatelliteNotificationDisplayed = 1;
1352         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapMinSec = 2;
1353         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapAvgSec = 3;
1354         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapMaxSec = 4;
1355 
1356         mCarrierRoamingSatelliteControllerStats2 = new CarrierRoamingSatelliteControllerStats();
1357         mCarrierRoamingSatelliteControllerStats2.configDataSource =
1358                 SatelliteProtoEnums.CONFIG_DATA_SOURCE_CONFIG_UPDATER;
1359         mCarrierRoamingSatelliteControllerStats2.countOfEntitlementStatusQueryRequest = 4;
1360         mCarrierRoamingSatelliteControllerStats2.countOfSatelliteConfigUpdateRequest = 1;
1361         mCarrierRoamingSatelliteControllerStats2.countOfSatelliteNotificationDisplayed = 1;
1362         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMinSec = 5;
1363         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapAvgSec = 10;
1364         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMaxSec = 15;
1365 
1366         // CarrierRoamingSatelliteController has one data point
1367         mCarrierRoamingSatelliteControllerStats = new CarrierRoamingSatelliteControllerStats[] {
1368                 mCarrierRoamingSatelliteControllerStats1};
1369 
1370         mSatelliteEntitlement1 = new SatelliteEntitlement();
1371         mSatelliteEntitlement1.carrierId = 1;
1372         mSatelliteEntitlement1.result = 0;
1373         mSatelliteEntitlement1.entitlementStatus =
1374                 SatelliteProtoEnums.SATELLITE_ENTITLEMENT_STATUS_ENABLED;
1375         mSatelliteEntitlement1.isRetry = false;
1376         mSatelliteEntitlement1.count = 1;
1377 
1378         mSatelliteEntitlement2 = new SatelliteEntitlement();
1379         mSatelliteEntitlement2.carrierId = 2;
1380         mSatelliteEntitlement2.result = 1;
1381         mSatelliteEntitlement2.entitlementStatus =
1382                 SatelliteProtoEnums.SATELLITE_ENTITLEMENT_STATUS_DISABLED;
1383         mSatelliteEntitlement1.isRetry = true;
1384         mSatelliteEntitlement2.count = 1;
1385 
1386         mSatelliteEntitlements = new SatelliteEntitlement[] {mSatelliteEntitlement1,
1387                 mSatelliteEntitlement2};
1388 
1389         mSatelliteConfigUpdater1 = new SatelliteConfigUpdater();
1390         mSatelliteConfigUpdater1.configVersion = 1;
1391         mSatelliteConfigUpdater1.oemConfigResult = SatelliteProtoEnums.CONFIG_UPDATE_RESULT_SUCCESS;
1392         mSatelliteConfigUpdater1.carrierConfigResult =
1393                 SatelliteProtoEnums.CONFIG_UPDATE_RESULT_CARRIER_DATA_INVALID_PLMN;
1394         mSatelliteConfigUpdater1.count = 1;
1395 
1396         mSatelliteConfigUpdater2 = new SatelliteConfigUpdater();
1397         mSatelliteConfigUpdater2.configVersion = 2;
1398         mSatelliteConfigUpdater2.oemConfigResult =
1399                 SatelliteProtoEnums.CONFIG_UPDATE_RESULT_DEVICE_DATA_INVALID_COUNTRY_CODE;
1400         mSatelliteConfigUpdater2.carrierConfigResult =
1401                 SatelliteProtoEnums.CONFIG_UPDATE_RESULT_SUCCESS;
1402         mSatelliteConfigUpdater2.count = 1;
1403 
1404         mSatelliteConfigUpdaters = new SatelliteConfigUpdater[] {mSatelliteConfigUpdater1,
1405                 mSatelliteConfigUpdater2};
1406 
1407         mSatelliteAccessController1 = new SatelliteAccessController();
1408         mSatelliteAccessController1.accessControlType = ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE;
1409         mSatelliteAccessController1.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(1);
1410         mSatelliteAccessController1.onDeviceLookupTimeMillis = TimeUnit.SECONDS.toMillis(2);
1411         mSatelliteAccessController1.totalCheckingTimeMillis = TimeUnit.SECONDS.toMillis(3);
1412         mSatelliteAccessController1.isAllowed = true;
1413         mSatelliteAccessController1.isEmergency = false;
1414         mSatelliteAccessController1.resultCode = SATELLITE_RESULT_SUCCESS;
1415         mSatelliteAccessController1.countryCodes = new String[]{"AB", "CD"};
1416         mSatelliteAccessController1.configDataSource = CONFIG_DATA_SOURCE_DEVICE_CONFIG;
1417 
1418         mSatelliteAccessController2 = new SatelliteAccessController();
1419         mSatelliteAccessController1.accessControlType = ACCESS_CONTROL_TYPE_CURRENT_LOCATION;
1420         mSatelliteAccessController1.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(4);
1421         mSatelliteAccessController2.onDeviceLookupTimeMillis = TimeUnit.SECONDS.toMillis(5);
1422         mSatelliteAccessController2.totalCheckingTimeMillis = TimeUnit.SECONDS.toMillis(6);
1423         mSatelliteAccessController2.isAllowed = false;
1424         mSatelliteAccessController2.isEmergency = true;
1425         mSatelliteAccessController2.resultCode = SATELLITE_RESULT_SUCCESS;
1426         mSatelliteAccessController2.countryCodes = new String[]{"EF", "GH"};
1427         mSatelliteAccessController2.configDataSource = CONFIG_DATA_SOURCE_CONFIG_UPDATER;
1428 
1429         mSatelliteAccessControllers = new SatelliteAccessController[]{
1430                 mSatelliteAccessController1, mSatelliteAccessController2
1431         };
1432     }
1433 
generateTestDataNetworkValidationsData()1434     private void generateTestDataNetworkValidationsData() {
1435 
1436         // for LTE #1
1437         mDataNetworkValidationLte1 = new DataNetworkValidation();
1438         mDataNetworkValidationLte1.networkType = TelephonyManager.NETWORK_TYPE_LTE;
1439         mDataNetworkValidationLte1.apnTypeBitmask = ApnSetting.TYPE_IMS;
1440         mDataNetworkValidationLte1.signalStrength = SignalStrength.SIGNAL_STRENGTH_GREAT;
1441         mDataNetworkValidationLte1.validationResult =
1442                 PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS;
1443         mDataNetworkValidationLte1.elapsedTimeInMillis = 100L;
1444         mDataNetworkValidationLte1.handoverAttempted = false;
1445         mDataNetworkValidationLte1.networkValidationCount = 1;
1446 
1447         // for LTE #2
1448         mDataNetworkValidationLte2 = new DataNetworkValidation();
1449         mDataNetworkValidationLte2.networkType = TelephonyManager.NETWORK_TYPE_LTE;
1450         mDataNetworkValidationLte2.apnTypeBitmask = ApnSetting.TYPE_IMS;
1451         mDataNetworkValidationLte2.signalStrength = SignalStrength.SIGNAL_STRENGTH_GREAT;
1452         mDataNetworkValidationLte2.validationResult =
1453                 PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS;
1454         mDataNetworkValidationLte2.elapsedTimeInMillis = 100L;
1455         mDataNetworkValidationLte2.handoverAttempted = false;
1456         mDataNetworkValidationLte2.networkValidationCount = 1;
1457 
1458         // for IWLAN #1
1459         mDataNetworkValidationIwlan1 = new DataNetworkValidation();
1460         mDataNetworkValidationIwlan1.networkType = TelephonyManager.NETWORK_TYPE_IWLAN;
1461         mDataNetworkValidationIwlan1.apnTypeBitmask = ApnSetting.TYPE_IMS;
1462         mDataNetworkValidationIwlan1.signalStrength = SignalStrength.SIGNAL_STRENGTH_POOR;
1463         mDataNetworkValidationIwlan1.validationResult =
1464                 PreciseDataConnectionState.NETWORK_VALIDATION_FAILURE;
1465         mDataNetworkValidationIwlan1.elapsedTimeInMillis = 10000L;
1466         mDataNetworkValidationIwlan1.handoverAttempted = false;
1467         mDataNetworkValidationIwlan1.networkValidationCount = 1;
1468 
1469         // for IWLAN #2
1470         mDataNetworkValidationIwlan2 = new DataNetworkValidation();
1471         mDataNetworkValidationIwlan2.networkType = TelephonyManager.NETWORK_TYPE_IWLAN;
1472         mDataNetworkValidationIwlan2.apnTypeBitmask = ApnSetting.TYPE_IMS;
1473         mDataNetworkValidationIwlan2.signalStrength = SignalStrength.SIGNAL_STRENGTH_POOR;
1474         mDataNetworkValidationIwlan2.validationResult =
1475                 PreciseDataConnectionState.NETWORK_VALIDATION_FAILURE;
1476         mDataNetworkValidationIwlan2.elapsedTimeInMillis = 30000L;
1477         mDataNetworkValidationIwlan2.handoverAttempted = false;
1478         mDataNetworkValidationIwlan2.networkValidationCount = 1;
1479 
1480         mDataNetworkValidations =
1481                 new DataNetworkValidation[] {
1482                         mDataNetworkValidationLte1,
1483                         mDataNetworkValidationLte1,
1484                         mDataNetworkValidationIwlan1,
1485                         mDataNetworkValidationIwlan2,
1486                 };
1487     }
1488 
1489     private static class TestablePersistAtomsStorage extends PersistAtomsStorage {
1490         private long mTimeMillis = START_TIME_MILLIS;
1491 
TestablePersistAtomsStorage(Context context)1492         TestablePersistAtomsStorage(Context context) {
1493             super(context);
1494             // Remove delay for saving to persistent storage during tests.
1495             mSaveImmediately = true;
1496         }
1497 
1498         @Override
getWallTimeMillis()1499         protected long getWallTimeMillis() {
1500             // NOTE: super class constructor will be executed before private field is set, which
1501             // gives the wrong start time (mTimeMillis will have its default value of 0L)
1502             return mTimeMillis == 0L ? START_TIME_MILLIS : mTimeMillis;
1503         }
1504 
setTimeMillis(long timeMillis)1505         private void setTimeMillis(long timeMillis) {
1506             mTimeMillis = timeMillis;
1507         }
1508 
incTimeMillis(long timeMillis)1509         private void incTimeMillis(long timeMillis) {
1510             mTimeMillis += timeMillis;
1511         }
1512 
getAtomsProto()1513         private PersistAtoms getAtomsProto() {
1514             // NOTE: unlike other methods in PersistAtomsStorage, this is not synchronized, but
1515             // should be fine since the test is single-threaded
1516             return mAtoms;
1517         }
1518     }
1519 
1520     private TestablePersistAtomsStorage mPersistAtomsStorage;
1521 
1522     private static final Comparator<MessageNano> sProtoComparator =
1523             new Comparator<>() {
1524                 @Override
1525                 public int compare(MessageNano o1, MessageNano o2) {
1526                     if (o1 == o2) {
1527                         return 0;
1528                     }
1529                     if (o1 == null) {
1530                         return -1;
1531                     }
1532                     if (o2 == null) {
1533                         return 1;
1534                     }
1535                     assertEquals(o1.getClass(), o2.getClass());
1536                     return o1.toString().compareTo(o2.toString());
1537                 }
1538             };
1539 
1540     @Before
setUp()1541     public void setUp() throws Exception {
1542         super.setUp(getClass().getSimpleName());
1543         mTestFileOutputStream = mock(FileOutputStream.class);
1544         makeTestData();
1545 
1546         // by default, test loading with real file IO and saving with mocks
1547         mTestFile = mFolder.newFile(TEST_FILE);
1548         doReturn(mTestFileOutputStream).when(mContext).openFileOutput(anyString(), anyInt());
1549         doReturn(mTestFile).when(mContext).getFileStreamPath(anyString());
1550     }
1551 
1552     @After
tearDown()1553     public void tearDown() throws Exception {
1554         mTestFile.delete();
1555         mTestFile = null;
1556         mFolder = null;
1557         mCall1Proto = null;
1558         mCall2Proto = null;
1559         mCall3Proto = null;
1560         mCall4Proto = null;
1561         mCarrier1LteUsageProto = null;
1562         mCarrier1UmtsUsageProto = null;
1563         mCarrier2LteUsageProto = null;
1564         mCarrier3LteUsageProto = null;
1565         mCarrier3GsmUsageProto = null;
1566         mVoiceCallRatUsages = null;
1567         mServiceSwitch1Proto = null;
1568         mServiceSwitch2Proto = null;
1569         mServiceState1Proto = null;
1570         mServiceState2Proto = null;
1571         mServiceState3Proto = null;
1572         mServiceState4Proto = null;
1573         mServiceState5Proto = null;
1574         mServiceSwitches = null;
1575         mServiceStates = null;
1576         mImsRegStatsUnregisteredLte0 = null;
1577         mImsRegStatsRegisteringLte0 = null;
1578         mImsRegistrationStatsLte0 = null;
1579         mImsRegistrationStatsWifi0 = null;
1580         mImsRegistrationStatsLte1 = null;
1581         mImsRegistrationTerminationLte = null;
1582         mImsRegistrationTerminationWifi = null;
1583         mImsRegistrationStats = null;
1584         mImsRegistrationTerminations = null;
1585         mDataCallSession0 = null;
1586         mDataCallSession1 = null;
1587         mImsRegistrationFeatureTagStats1Proto = null;
1588         mImsRegistrationFeatureTagStats2Proto = null;
1589         mImsRegistrationFeatureTagStatses = null;
1590         mRcsClientProvisioningStats1Proto = null;
1591         mRcsClientProvisioningStats2Proto = null;
1592         mRcsClientProvisioningStatses = null;
1593         mRcsAcsProvisioningStats1Proto = null;
1594         mRcsAcsProvisioningStats2Proto = null;
1595         mRcsAcsProvisioningStatses = null;
1596         mImsRegistrationServiceIm = null;
1597         mImsRegistrationServiceFt = null;
1598         mImsRegistrationServiceDescStats = null;
1599         mImsDedicatedBearerListenerEvent1 = null;
1600         mImsDedicatedBearerListenerEvent2 = null;
1601         mImsDedicatedBearerListenerEvents = null;
1602         mImsDedicatedBearerEvent1 = null;
1603         mImsDedicatedBearerEvent2 = null;
1604         mImsDedicatedBearerEvents = null;
1605         mUceEventStats1 = null;
1606         mUceEventStats2 = null;
1607         mUceEventStatses = null;
1608         mPresenceNotifyEvent1 = null;
1609         mPresenceNotifyEvent2 = null;
1610         mPresenceNotifyEvents = null;
1611         mSipTransportFeatureTagStats1 = null;
1612         mSipTransportFeatureTagStats2 = null;
1613         mSipTransportFeatureTagStatsArray = null;
1614         mSipDelegateStats1 = null;
1615         mSipDelegateStats2 = null;
1616         mSipDelegateStats3 = null;
1617         mSipDelegateStatsArray = null;
1618         mGbaEvent1 = null;
1619         mGbaEvent2 = null;
1620         mGbaEvent = null;
1621         mSipMessageResponse1 = null;
1622         mSipMessageResponse2 = null;
1623         mSipMessageResponse = null;
1624         mSipTransportSession1 = null;
1625         mSipTransportSession2 = null;
1626         mSipTransportSession = null;
1627         mIncomingSms = null;
1628         mIncomingSms1 = null;
1629         mIncomingSms2 = null;
1630         mOutgoingSms = null;
1631         mOutgoingSms1 = null;
1632         mOutgoingSms2 = null;
1633         mOutgoingShortCodeSms1 = null;
1634         mOutgoingShortCodeSms2 = null;
1635         mOutgoingShortCodeSms = null;
1636         mSatelliteController1 = null;
1637         mSatelliteController2 = null;
1638         mSatelliteControllers = null;
1639         mSatelliteSession1 = null;
1640         mSatelliteSession2 = null;
1641         mSatelliteSessions = null;
1642         mSatelliteIncomingDatagram1 = null;
1643         mSatelliteIncomingDatagram2 = null;
1644         mSatelliteIncomingDatagrams = null;
1645         mSatelliteOutgoingDatagram1 = null;
1646         mSatelliteOutgoingDatagram2 = null;
1647         mSatelliteOutgoingDatagrams = null;
1648         mSatelliteProvision1 = null;
1649         mSatelliteProvision2 = null;
1650         mSatelliteProvisions = null;
1651         mSatelliteSosMessageRecommender1 = null;
1652         mSatelliteSosMessageRecommender2 = null;
1653         mSatelliteSosMessageRecommenders = null;
1654         mDataNetworkValidationLte1 = null;
1655         mDataNetworkValidationLte2 = null;
1656         mDataNetworkValidationIwlan1 = null;
1657         mDataNetworkValidationIwlan2 = null;
1658         mCarrierRoamingSatelliteSession1 = null;
1659         mCarrierRoamingSatelliteSession2 = null;
1660         mCarrierRoamingSatelliteSessions = null;
1661         mCarrierRoamingSatelliteControllerStats1 = null;
1662         mCarrierRoamingSatelliteControllerStats2 = null;
1663         mCarrierRoamingSatelliteControllerStats = null;
1664         mSatelliteEntitlement1 = null;
1665         mSatelliteEntitlement2 = null;
1666         mSatelliteEntitlements = null;
1667         mSatelliteConfigUpdater1 = null;
1668         mSatelliteConfigUpdater2 = null;
1669         mSatelliteConfigUpdaters = null;
1670         mSatelliteAccessController1 = null;
1671         mSatelliteAccessController2 = null;
1672         mSatelliteAccessControllers = null;
1673         super.tearDown();
1674     }
1675 
1676     @Test
1677     @SmallTest
loadAtoms_fileNotExist()1678     public void loadAtoms_fileNotExist() throws Exception {
1679         mTestFile.delete();
1680 
1681         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1682         mPersistAtomsStorage.incTimeMillis(100L);
1683 
1684         // no exception should be thrown, storage should be empty, pull time should be start time
1685         assertAllPullTimestampEquals(START_TIME_MILLIS);
1686         assertStorageIsEmptyForAllAtoms();
1687     }
1688 
1689     @Test
1690     @SmallTest
loadAtoms_unreadable()1691     public void loadAtoms_unreadable() throws Exception {
1692         createEmptyTestFile();
1693         mTestFile.setReadable(false);
1694 
1695         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1696         mPersistAtomsStorage.incTimeMillis(100L);
1697 
1698         // no exception should be thrown, storage should be empty, pull time should be start time
1699         assertAllPullTimestampEquals(START_TIME_MILLIS);
1700         assertStorageIsEmptyForAllAtoms();
1701     }
1702 
1703     @Test
1704     @SmallTest
loadAtoms_emptyProto()1705     public void loadAtoms_emptyProto() throws Exception {
1706         createEmptyTestFile();
1707 
1708         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1709         mPersistAtomsStorage.incTimeMillis(100L);
1710 
1711         // no exception should be thrown, storage should be empty, pull time should be start time
1712         assertAllPullTimestampEquals(START_TIME_MILLIS);
1713         assertStorageIsEmptyForAllAtoms();
1714     }
1715 
1716     @Test
1717     @SmallTest
loadAtoms_malformedFile()1718     public void loadAtoms_malformedFile() throws Exception {
1719         FileOutputStream stream = new FileOutputStream(mTestFile);
1720         stream.write("This is not a proto file.".getBytes(StandardCharsets.UTF_8));
1721         stream.close();
1722 
1723         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1724         mPersistAtomsStorage.incTimeMillis(100L);
1725 
1726         // no exception should be thrown, storage should be empty, pull time should be start time
1727         assertAllPullTimestampEquals(START_TIME_MILLIS);
1728         assertStorageIsEmptyForAllAtoms();
1729     }
1730 
1731     @Test
1732     @SmallTest
loadAtoms_pullTimeMissing()1733     public void loadAtoms_pullTimeMissing() throws Exception {
1734         // create test file with lastPullTimeMillis = 0L, i.e. default/unknown
1735         createTestFile(0L);
1736 
1737         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1738         mPersistAtomsStorage.incTimeMillis(100L);
1739 
1740         // no exception should be thrown, storage should be match, pull time should be start time
1741         assertAllPullTimestampEquals(START_TIME_MILLIS);
1742         assertProtoArrayEquals(mVoiceCallRatUsages, mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1743         assertProtoArrayEquals(mVoiceCallSessions, mPersistAtomsStorage.getVoiceCallSessions(0L));
1744         assertProtoArrayEqualsIgnoringOrder(
1745                 mServiceStates, mPersistAtomsStorage.getCellularServiceStates(0L));
1746         assertProtoArrayEqualsIgnoringOrder(
1747                 mServiceSwitches, mPersistAtomsStorage.getCellularDataServiceSwitches(0L));
1748     }
1749 
1750     @Test
1751     @SmallTest
loadAtoms_validContents()1752     public void loadAtoms_validContents() throws Exception {
1753         createTestFile(/* lastPullTimeMillis= */ 100L);
1754 
1755         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1756 
1757         // no exception should be thrown, storage and pull time should match
1758         assertAllPullTimestampEquals(100L);
1759         assertProtoArrayEquals(mVoiceCallRatUsages, mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1760         assertProtoArrayEquals(mVoiceCallSessions, mPersistAtomsStorage.getVoiceCallSessions(0L));
1761         assertProtoArrayEqualsIgnoringOrder(
1762                 mServiceStates, mPersistAtomsStorage.getCellularServiceStates(0L));
1763         assertProtoArrayEqualsIgnoringOrder(
1764                 mServiceSwitches, mPersistAtomsStorage.getCellularDataServiceSwitches(0L));
1765     }
1766 
1767     @Test
1768     @SmallTest
addVoiceCallSession_emptyProto()1769     public void addVoiceCallSession_emptyProto() throws Exception {
1770         createEmptyTestFile();
1771 
1772         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1773         mPersistAtomsStorage.addVoiceCallSession(mCall1Proto);
1774         mPersistAtomsStorage.incTimeMillis(100L);
1775 
1776         // call should be added successfully, there should be no RAT usage, changes should be saved
1777         verifyCurrentStateSavedToFileOnce();
1778         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1779         VoiceCallSession[] voiceCallSession = mPersistAtomsStorage.getVoiceCallSessions(0L);
1780         assertProtoArrayEquals(new VoiceCallSession[] {mCall1Proto}, voiceCallSession);
1781     }
1782 
1783     @Test
1784     @SmallTest
addVoiceCallSession_withExistingCalls()1785     public void addVoiceCallSession_withExistingCalls() throws Exception {
1786         createTestFile(START_TIME_MILLIS);
1787 
1788         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1789         mPersistAtomsStorage.addVoiceCallSession(mCall1Proto);
1790         mPersistAtomsStorage.incTimeMillis(100L);
1791 
1792         // call should be added successfully, RAT usages should not change, changes should be saved
1793         assertProtoArrayEquals(mVoiceCallRatUsages, mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1794         VoiceCallSession[] expectedVoiceCallSessions =
1795                 new VoiceCallSession[] {
1796                     mCall1Proto, mCall1Proto, mCall2Proto, mCall3Proto, mCall4Proto
1797                 };
1798         // call list is randomized at this point
1799         verifyCurrentStateSavedToFileOnce();
1800         assertProtoArrayEqualsIgnoringOrder(
1801                 expectedVoiceCallSessions, mPersistAtomsStorage.getVoiceCallSessions(0L));
1802     }
1803 
1804     @Test
1805     @SmallTest
addVoiceCallSession_tooManyCalls()1806     public void addVoiceCallSession_tooManyCalls() throws Exception {
1807         createEmptyTestFile();
1808 
1809         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1810         addRepeatedCalls(mPersistAtomsStorage, mCall1Proto, 50);
1811         mPersistAtomsStorage.addVoiceCallSession(mCall2Proto);
1812         mPersistAtomsStorage.incTimeMillis(100L);
1813 
1814         // one previous call should be evicted, the new call should be added
1815         verifyCurrentStateSavedToFileOnce();
1816         VoiceCallSession[] calls = mPersistAtomsStorage.getVoiceCallSessions(0L);
1817         assertHasCall(calls, mCall1Proto, /* expectedCount= */ 49);
1818         assertHasCall(calls, mCall2Proto, /* expectedCount= */ 1);
1819     }
1820 
1821     @Test
1822     @SmallTest
addVoiceCallSession_tooManyCalls_withEmergencyCalls()1823     public void addVoiceCallSession_tooManyCalls_withEmergencyCalls() throws Exception {
1824         createEmptyTestFile();
1825         // We initially have storage full of emergency calls except one.
1826         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1827         addRepeatedCalls(mPersistAtomsStorage, mCall4Proto, 49);
1828         mPersistAtomsStorage.addVoiceCallSession(mCall1Proto);
1829 
1830         mPersistAtomsStorage.addVoiceCallSession(mCall4Proto);
1831         mPersistAtomsStorage.incTimeMillis(100L);
1832 
1833         // after adding one more emergency call, the previous non-emergency call should be evicted
1834         verifyCurrentStateSavedToFileOnce();
1835         VoiceCallSession[] calls = mPersistAtomsStorage.getVoiceCallSessions(0L);
1836         assertHasCall(calls, mCall4Proto, /* expectedCount= */ 50);
1837     }
1838 
1839     @Test
1840     @SmallTest
addVoiceCallRatUsage_emptyProto()1841     public void addVoiceCallRatUsage_emptyProto() throws Exception {
1842         createEmptyTestFile();
1843         VoiceCallRatTracker ratTracker = VoiceCallRatTracker.fromProto(mVoiceCallRatUsages);
1844 
1845         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1846         mPersistAtomsStorage.addVoiceCallRatUsage(ratTracker);
1847         mPersistAtomsStorage.incTimeMillis(100L);
1848 
1849         // RAT should be added successfully, calls should not change, changes should be saved
1850         verifyCurrentStateSavedToFileOnce();
1851         assertProtoArrayEqualsIgnoringOrder(
1852                 mVoiceCallRatUsages, mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1853         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallSessions(0L));
1854     }
1855 
1856     @Test
1857     @SmallTest
addVoiceCallRatUsage_withExistingUsages()1858     public void addVoiceCallRatUsage_withExistingUsages() throws Exception {
1859         createTestFile(START_TIME_MILLIS);
1860         VoiceCallRatTracker ratTracker = VoiceCallRatTracker.fromProto(mVoiceCallRatUsages);
1861 
1862         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1863         mPersistAtomsStorage.addVoiceCallRatUsage(ratTracker);
1864         mPersistAtomsStorage.incTimeMillis(100L);
1865 
1866         // RAT should be added successfully, calls should not change, changes should be saved
1867         // call count and duration should become doubled since mVoiceCallRatUsages applied through
1868         // both file and addVoiceCallRatUsage()
1869         verifyCurrentStateSavedToFileOnce();
1870         VoiceCallRatUsage[] expectedVoiceCallRatUsage =
1871                 multiplyVoiceCallRatUsage(mVoiceCallRatUsages, 2);
1872         assertProtoArrayEqualsIgnoringOrder(
1873                 expectedVoiceCallRatUsage, mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1874         assertProtoArrayEquals(mVoiceCallSessions, mPersistAtomsStorage.getVoiceCallSessions(0L));
1875     }
1876 
1877     @Test
1878     @SmallTest
addVoiceCallRatUsage_empty()1879     public void addVoiceCallRatUsage_empty() throws Exception {
1880         createEmptyTestFile();
1881         VoiceCallRatTracker ratTracker = VoiceCallRatTracker.fromProto(new VoiceCallRatUsage[0]);
1882 
1883         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1884         mPersistAtomsStorage.addVoiceCallRatUsage(ratTracker);
1885         mPersistAtomsStorage.incTimeMillis(100L);
1886 
1887         // RAT should be added successfully, calls should not change
1888         // in this case saving is unnecessarily
1889         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallRatUsages(0L));
1890         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallSessions(0L));
1891     }
1892 
1893     @Test
1894     @SmallTest
getVoiceCallRatUsages_tooFrequent()1895     public void getVoiceCallRatUsages_tooFrequent() throws Exception {
1896         createTestFile(START_TIME_MILLIS);
1897 
1898         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1899         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
1900         VoiceCallRatUsage[] voiceCallRatUsage = mPersistAtomsStorage.getVoiceCallRatUsages(100L);
1901 
1902         // Should be denied
1903         assertNull(voiceCallRatUsage);
1904     }
1905 
1906     @Test
1907     @SmallTest
getVoiceCallRatUsages_withSavedAtoms()1908     public void getVoiceCallRatUsages_withSavedAtoms() throws Exception {
1909         createTestFile(START_TIME_MILLIS);
1910 
1911         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1912         mPersistAtomsStorage.incTimeMillis(100L);
1913         VoiceCallRatUsage[] voiceCallRatUsage1 = mPersistAtomsStorage.getVoiceCallRatUsages(50L);
1914         mPersistAtomsStorage.incTimeMillis(100L);
1915         VoiceCallRatUsage[] voiceCallRatUsage2 = mPersistAtomsStorage.getVoiceCallRatUsages(50L);
1916         long voiceCallSessionPullTimestampMillis =
1917                 mPersistAtomsStorage.getAtomsProto().voiceCallSessionPullTimestampMillis;
1918         VoiceCallSession[] voiceCallSession = mPersistAtomsStorage.getVoiceCallSessions(50L);
1919 
1920         // First set of results should equal to file contents, second should be empty, corresponding
1921         // pull timestamp should be updated and saved, other fields should be unaffected
1922         assertProtoArrayEquals(mVoiceCallRatUsages, voiceCallRatUsage1);
1923         assertProtoArrayIsEmpty(voiceCallRatUsage2);
1924         assertEquals(
1925                 START_TIME_MILLIS + 200L,
1926                 mPersistAtomsStorage.getAtomsProto().voiceCallRatUsagePullTimestampMillis);
1927         assertProtoArrayEquals(mVoiceCallSessions, voiceCallSession);
1928         assertEquals(START_TIME_MILLIS, voiceCallSessionPullTimestampMillis);
1929         InOrder inOrder = inOrder(mTestFileOutputStream);
1930         assertEquals(
1931                 START_TIME_MILLIS + 100L,
1932                 getAtomsWritten(inOrder).voiceCallRatUsagePullTimestampMillis);
1933         assertEquals(
1934                 START_TIME_MILLIS + 200L,
1935                 getAtomsWritten(inOrder).voiceCallRatUsagePullTimestampMillis);
1936         assertEquals(
1937                 START_TIME_MILLIS + 200L,
1938                 getAtomsWritten(inOrder).voiceCallSessionPullTimestampMillis);
1939         inOrder.verifyNoMoreInteractions();
1940     }
1941 
1942     @Test
1943     @SmallTest
getVoiceCallSessions_tooFrequent()1944     public void getVoiceCallSessions_tooFrequent() throws Exception {
1945         createTestFile(START_TIME_MILLIS);
1946 
1947         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1948         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
1949         VoiceCallSession[] voiceCallSession = mPersistAtomsStorage.getVoiceCallSessions(100L);
1950 
1951         // Should be denied
1952         assertNull(voiceCallSession);
1953     }
1954 
1955     @Test
1956     @SmallTest
getVoiceCallSessions_withSavedAtoms()1957     public void getVoiceCallSessions_withSavedAtoms() throws Exception {
1958         createTestFile(START_TIME_MILLIS);
1959 
1960         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1961         mPersistAtomsStorage.incTimeMillis(100L);
1962         VoiceCallSession[] voiceCallSession1 = mPersistAtomsStorage.getVoiceCallSessions(50L);
1963         mPersistAtomsStorage.incTimeMillis(100L);
1964         VoiceCallSession[] voiceCallSession2 = mPersistAtomsStorage.getVoiceCallSessions(50L);
1965         long voiceCallRatUsagePullTimestampMillis =
1966                 mPersistAtomsStorage.getAtomsProto().voiceCallRatUsagePullTimestampMillis;
1967         VoiceCallRatUsage[] voiceCallRatUsage = mPersistAtomsStorage.getVoiceCallRatUsages(50L);
1968 
1969         // First set of results should equal to file contents, second should be empty, corresponding
1970         // pull timestamp should be updated and saved, other fields should be unaffected
1971         assertProtoArrayEquals(mVoiceCallSessions, voiceCallSession1);
1972         assertProtoArrayIsEmpty(voiceCallSession2);
1973         assertEquals(
1974                 START_TIME_MILLIS + 200L,
1975                 mPersistAtomsStorage.getAtomsProto().voiceCallSessionPullTimestampMillis);
1976         assertProtoArrayEquals(mVoiceCallRatUsages, voiceCallRatUsage);
1977         assertEquals(START_TIME_MILLIS, voiceCallRatUsagePullTimestampMillis);
1978         InOrder inOrder = inOrder(mTestFileOutputStream);
1979         assertEquals(
1980                 START_TIME_MILLIS + 100L,
1981                 getAtomsWritten(inOrder).voiceCallSessionPullTimestampMillis);
1982         assertEquals(
1983                 START_TIME_MILLIS + 200L,
1984                 getAtomsWritten(inOrder).voiceCallSessionPullTimestampMillis);
1985         assertEquals(
1986                 START_TIME_MILLIS + 200L,
1987                 getAtomsWritten(inOrder).voiceCallRatUsagePullTimestampMillis);
1988         inOrder.verifyNoMoreInteractions();
1989     }
1990 
1991     @Test
1992     @SmallTest
addCellularServiceStateAndCellularDataServiceSwitch_emptyProto()1993     public void addCellularServiceStateAndCellularDataServiceSwitch_emptyProto() throws Exception {
1994         createEmptyTestFile();
1995 
1996         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
1997         mPersistAtomsStorage.addCellularServiceStateAndCellularDataServiceSwitch(
1998                 mServiceState1Proto, mServiceSwitch1Proto);
1999         mPersistAtomsStorage.incTimeMillis(100L);
2000 
2001         // Service state and service switch should be added successfully
2002         verifyCurrentStateSavedToFileOnce();
2003         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
2004         CellularDataServiceSwitch[] serviceSwitches =
2005                 mPersistAtomsStorage.getCellularDataServiceSwitches(0L);
2006         assertProtoArrayEquals(new CellularServiceState[] {mServiceState1Proto}, serviceStates);
2007         assertProtoArrayEquals(
2008                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto}, serviceSwitches);
2009     }
2010 
2011     @Test
2012     @SmallTest
addCellularServiceStateAndCellularDataServiceSwitch_withExistingEntries()2013     public void addCellularServiceStateAndCellularDataServiceSwitch_withExistingEntries()
2014             throws Exception {
2015         createEmptyTestFile();
2016         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2017         mPersistAtomsStorage.addCellularServiceStateAndCellularDataServiceSwitch(
2018                 mServiceState1Proto, mServiceSwitch1Proto);
2019 
2020         mPersistAtomsStorage.addCellularServiceStateAndCellularDataServiceSwitch(
2021                 mServiceState2Proto, mServiceSwitch2Proto);
2022         mPersistAtomsStorage.incTimeMillis(100L);
2023 
2024         // Service state and service switch should be added successfully
2025         verifyCurrentStateSavedToFileOnce();
2026         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
2027         CellularDataServiceSwitch[] serviceSwitches =
2028                 mPersistAtomsStorage.getCellularDataServiceSwitches(0L);
2029         assertProtoArrayEqualsIgnoringOrder(
2030                 new CellularServiceState[] {mServiceState1Proto, mServiceState2Proto},
2031                 serviceStates);
2032         assertProtoArrayEqualsIgnoringOrder(
2033                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto, mServiceSwitch2Proto},
2034                 serviceSwitches);
2035     }
2036 
2037     @Test
2038     @SmallTest
addCellularServiceStateAndCellularDataServiceSwitch_updateExistingEntries()2039     public void addCellularServiceStateAndCellularDataServiceSwitch_updateExistingEntries()
2040             throws Exception {
2041         createTestFile(START_TIME_MILLIS);
2042         CellularServiceState newServiceState1Proto = copyOf(mServiceState1Proto);
2043         CellularDataServiceSwitch newServiceSwitch1Proto = copyOf(mServiceSwitch1Proto);
2044         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2045 
2046         mPersistAtomsStorage.addCellularServiceStateAndCellularDataServiceSwitch(
2047                 copyOf(mServiceState1Proto), copyOf(mServiceSwitch1Proto));
2048         mPersistAtomsStorage.incTimeMillis(100L);
2049 
2050         // mServiceState1Proto's duration and mServiceSwitch1Proto's switch should be doubled
2051         verifyCurrentStateSavedToFileOnce();
2052         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
2053         newServiceState1Proto.totalTimeMillis *= 2;
2054         assertProtoArrayEqualsIgnoringOrder(
2055                 new CellularServiceState[] {
2056                     newServiceState1Proto,
2057                     mServiceState2Proto,
2058                     mServiceState3Proto,
2059                     mServiceState4Proto,
2060                     mServiceState5Proto
2061                 },
2062                 serviceStates);
2063         CellularDataServiceSwitch[] serviceSwitches =
2064                 mPersistAtomsStorage.getCellularDataServiceSwitches(0L);
2065         newServiceSwitch1Proto.switchCount *= 2;
2066         assertProtoArrayEqualsIgnoringOrder(
2067                 new CellularDataServiceSwitch[] {newServiceSwitch1Proto, mServiceSwitch2Proto},
2068                 serviceSwitches);
2069     }
2070 
2071     @Test
2072     @SmallTest
addCellularServiceStateAndCellularDataServiceSwitch_tooManyServiceStates()2073     public void addCellularServiceStateAndCellularDataServiceSwitch_tooManyServiceStates()
2074             throws Exception {
2075         createEmptyTestFile();
2076         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2077         Queue<CellularServiceState> expectedServiceStates = new LinkedList<>();
2078         Queue<CellularDataServiceSwitch> expectedServiceSwitches = new LinkedList<>();
2079 
2080         // Add 51 service states, with the first being least recent
2081         for (int i = 0; i < 51; i++) {
2082             CellularServiceState state = new CellularServiceState();
2083             state.voiceRat = i / 10;
2084             state.dataRat = i % 10;
2085             expectedServiceStates.add(state);
2086             CellularDataServiceSwitch serviceSwitch = new CellularDataServiceSwitch();
2087             serviceSwitch.ratFrom = i / 10;
2088             serviceSwitch.ratTo = i % 10;
2089             expectedServiceSwitches.add(serviceSwitch);
2090             mPersistAtomsStorage.addCellularServiceStateAndCellularDataServiceSwitch(
2091                     copyOf(state), copyOf(serviceSwitch));
2092             mPersistAtomsStorage.incTimeMillis(100L);
2093         }
2094 
2095         // The least recent (the first) service state should be evicted
2096         verifyCurrentStateSavedToFileOnce();
2097         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
2098         expectedServiceStates.remove();
2099         assertProtoArrayEqualsIgnoringOrder(
2100                 expectedServiceStates.toArray(new CellularServiceState[0]), serviceStates);
2101         CellularDataServiceSwitch[] serviceSwitches =
2102                 mPersistAtomsStorage.getCellularDataServiceSwitches(0L);
2103         expectedServiceSwitches.remove();
2104         assertProtoArrayEqualsIgnoringOrder(
2105                 expectedServiceSwitches.toArray(new CellularDataServiceSwitch[0]), serviceSwitches);
2106     }
2107 
2108     @Test
2109     @SmallTest
getCellularDataServiceSwitches_tooFrequent()2110     public void getCellularDataServiceSwitches_tooFrequent() throws Exception {
2111         createTestFile(START_TIME_MILLIS);
2112 
2113         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2114         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2115         CellularDataServiceSwitch[] serviceSwitches =
2116                 mPersistAtomsStorage.getCellularDataServiceSwitches(100L);
2117 
2118         // Should be denied
2119         assertNull(serviceSwitches);
2120     }
2121 
2122     @Test
2123     @SmallTest
getCellularDataServiceSwitches_withSavedAtoms()2124     public void getCellularDataServiceSwitches_withSavedAtoms() throws Exception {
2125         createTestFile(START_TIME_MILLIS);
2126 
2127         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2128         mPersistAtomsStorage.incTimeMillis(100L);
2129         CellularDataServiceSwitch[] serviceSwitches1 =
2130                 mPersistAtomsStorage.getCellularDataServiceSwitches(50L);
2131         mPersistAtomsStorage.incTimeMillis(100L);
2132         CellularDataServiceSwitch[] serviceSwitches2 =
2133                 mPersistAtomsStorage.getCellularDataServiceSwitches(50L);
2134 
2135         // First set of results should equal to file contents, second should be empty, corresponding
2136         // pull timestamp should be updated and saved
2137         assertProtoArrayEqualsIgnoringOrder(
2138                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto, mServiceSwitch2Proto},
2139                 serviceSwitches1);
2140         assertProtoArrayEquals(new CellularDataServiceSwitch[0], serviceSwitches2);
2141         assertEquals(
2142                 START_TIME_MILLIS + 200L,
2143                 mPersistAtomsStorage.getAtomsProto().cellularDataServiceSwitchPullTimestampMillis);
2144         InOrder inOrder = inOrder(mTestFileOutputStream);
2145         assertEquals(
2146                 START_TIME_MILLIS + 100L,
2147                 getAtomsWritten(inOrder).cellularDataServiceSwitchPullTimestampMillis);
2148         assertEquals(
2149                 START_TIME_MILLIS + 200L,
2150                 getAtomsWritten(inOrder).cellularDataServiceSwitchPullTimestampMillis);
2151         inOrder.verifyNoMoreInteractions();
2152     }
2153 
2154     @Test
2155     @SmallTest
getCellularServiceStates_tooFrequent()2156     public void getCellularServiceStates_tooFrequent() throws Exception {
2157         createTestFile(START_TIME_MILLIS);
2158 
2159         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2160         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2161         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(100L);
2162 
2163         // Should be denied
2164         assertNull(serviceStates);
2165     }
2166 
2167     @Test
2168     @SmallTest
getCellularServiceStates_withSavedAtoms()2169     public void getCellularServiceStates_withSavedAtoms() throws Exception {
2170         createTestFile(START_TIME_MILLIS);
2171 
2172         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2173         mPersistAtomsStorage.incTimeMillis(100L);
2174         CellularServiceState[] serviceStates1 = mPersistAtomsStorage.getCellularServiceStates(50L);
2175         mPersistAtomsStorage.incTimeMillis(100L);
2176         CellularServiceState[] serviceStates2 = mPersistAtomsStorage.getCellularServiceStates(50L);
2177 
2178         // First set of results should equal to file contents, second should be empty, corresponding
2179         // pull timestamp should be updated and saved
2180         assertProtoArrayEqualsIgnoringOrder(
2181                 new CellularServiceState[] {
2182                     mServiceState1Proto,
2183                     mServiceState2Proto,
2184                     mServiceState3Proto,
2185                     mServiceState4Proto,
2186                     mServiceState5Proto
2187                 },
2188                 serviceStates1);
2189         assertProtoArrayEquals(new CellularServiceState[0], serviceStates2);
2190         assertEquals(
2191                 START_TIME_MILLIS + 200L,
2192                 mPersistAtomsStorage.getAtomsProto().cellularServiceStatePullTimestampMillis);
2193         InOrder inOrder = inOrder(mTestFileOutputStream);
2194         assertEquals(
2195                 START_TIME_MILLIS + 100L,
2196                 getAtomsWritten(inOrder).cellularServiceStatePullTimestampMillis);
2197         assertEquals(
2198                 START_TIME_MILLIS + 200L,
2199                 getAtomsWritten(inOrder).cellularServiceStatePullTimestampMillis);
2200         inOrder.verifyNoMoreInteractions();
2201     }
2202 
2203     @Test
2204     @SmallTest
addImsRegistrationStats_emptyProto()2205     public void addImsRegistrationStats_emptyProto() throws Exception {
2206         createEmptyTestFile();
2207 
2208         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2209         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
2210         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2211 
2212         // mImsRegistrationStatsLte0 should be added successfully
2213         verifyCurrentStateSavedToFileOnce();
2214         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2215         assertProtoArrayEquals(new ImsRegistrationStats[] {mImsRegistrationStatsLte0}, regStats);
2216     }
2217 
2218     @Test
2219     @SmallTest
addImsRegistrationStats_withExistingEntries()2220     public void addImsRegistrationStats_withExistingEntries() throws Exception {
2221         createEmptyTestFile();
2222         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2223         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
2224 
2225         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsWifi0));
2226         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2227 
2228         // mImsRegistrationStatsLte0 and mImsRegistrationStatsWifi0 should be added successfully
2229         verifyCurrentStateSavedToFileOnce();
2230         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2231         assertProtoArrayEqualsIgnoringOrder(
2232                 new ImsRegistrationStats[] {mImsRegistrationStatsLte0, mImsRegistrationStatsWifi0},
2233                 regStats);
2234     }
2235 
2236     @Test
2237     @SmallTest
addImsRegistrationStats_withExistingRegisteringEntries()2238     public void addImsRegistrationStats_withExistingRegisteringEntries() throws Exception {
2239         createEmptyTestFile();
2240         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2241         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegStatsRegisteringLte0));
2242         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2243 
2244         // mImsRegStatsRegisteringLte0's info should be added successfully
2245         verifyCurrentStateSavedToFileOnce();
2246         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2247         assertProtoArrayEqualsIgnoringOrder(
2248                 new ImsRegistrationStats[] {mImsRegStatsRegisteringLte0},
2249                 regStats);
2250     }
2251 
2252     @Test
2253     @SmallTest
addImsRegistrationStats_updateExistingEntries()2254     public void addImsRegistrationStats_updateExistingEntries() throws Exception {
2255         createTestFile(START_TIME_MILLIS);
2256         ImsRegistrationStats newImsRegistrationStatsLte0 = copyOf(mImsRegStatsUnregisteredLte0);
2257         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2258 
2259         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegStatsUnregisteredLte0));
2260         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2261 
2262         // mImsRegStatsUnregisteredLte0's durations should be doubled
2263         verifyCurrentStateSavedToFileOnce();
2264         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2265         newImsRegistrationStatsLte0.unregisteredMillis *= 2;
2266         newImsRegistrationStatsLte0.voiceCapableMillis *= 2;
2267         newImsRegistrationStatsLte0.voiceAvailableMillis *= 2;
2268         newImsRegistrationStatsLte0.smsCapableMillis *= 2;
2269         newImsRegistrationStatsLte0.smsAvailableMillis *= 2;
2270         newImsRegistrationStatsLte0.videoCapableMillis *= 2;
2271         newImsRegistrationStatsLte0.videoAvailableMillis *= 2;
2272         newImsRegistrationStatsLte0.utCapableMillis *= 2;
2273         newImsRegistrationStatsLte0.utAvailableMillis *= 2;
2274         assertProtoArrayEqualsIgnoringOrder(
2275                 new ImsRegistrationStats[] {
2276                     newImsRegistrationStatsLte0,
2277                     mImsRegStatsRegisteringLte0,
2278                     mImsRegistrationStatsLte0,
2279                     mImsRegistrationStatsWifi0,
2280                     mImsRegistrationStatsLte1
2281                 },
2282                 regStats);
2283     }
2284 
2285     @Test
2286     @SmallTest
addImsRegistrationStats_tooManyRegistrationStats()2287     public void addImsRegistrationStats_tooManyRegistrationStats() throws Exception {
2288         createEmptyTestFile();
2289         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2290         Queue<ImsRegistrationStats> expectedRegistrationStats = new LinkedList<>();
2291 
2292         // Add 11 registration stats
2293         for (int i = 0; i < 11; i++) {
2294             ImsRegistrationStats stats = copyOf(mImsRegistrationStatsLte0);
2295             stats.rat = i;
2296             expectedRegistrationStats.add(stats);
2297             mPersistAtomsStorage.addImsRegistrationStats(stats);
2298             mPersistAtomsStorage.incTimeMillis(100L);
2299         }
2300 
2301         // The least recent (the first) registration stats should be evicted
2302         verifyCurrentStateSavedToFileOnce();
2303         ImsRegistrationStats[] stats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2304         expectedRegistrationStats.remove();
2305         assertProtoArrayEqualsIgnoringOrder(
2306                 expectedRegistrationStats.toArray(new ImsRegistrationStats[0]), stats);
2307     }
2308 
2309     @Test
2310     @SmallTest
addImsRegistrationStats_withExistingDurationEntries()2311     public void addImsRegistrationStats_withExistingDurationEntries() throws Exception {
2312         createEmptyTestFile();
2313         ImsRegistrationStats newImsRegStatsLte0 = copyOf(mImsRegistrationStatsLte0);
2314         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2315         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegStatsUnregisteredLte0));
2316         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegStatsRegisteringLte0));
2317         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
2318         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2319 
2320         // UnregisteredMillis, registeringMillis and registeredTimes should be added successfully
2321         // capable and available durations should be tripled
2322         verifyCurrentStateSavedToFileOnce();
2323         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
2324         newImsRegStatsLte0.unregisteredMillis += newImsRegStatsLte0.registeredMillis;
2325         newImsRegStatsLte0.registeringMillis += newImsRegStatsLte0.registeredMillis;
2326         newImsRegStatsLte0.registeredTimes += 1;
2327         newImsRegStatsLte0.voiceCapableMillis *= 3;
2328         newImsRegStatsLte0.voiceAvailableMillis *= 3;
2329         newImsRegStatsLte0.smsCapableMillis *= 3;
2330         newImsRegStatsLte0.smsAvailableMillis *= 3;
2331         newImsRegStatsLte0.videoCapableMillis *= 3;
2332         newImsRegStatsLte0.videoAvailableMillis *= 3;
2333         newImsRegStatsLte0.utCapableMillis *= 3;
2334         newImsRegStatsLte0.utAvailableMillis *= 3;
2335         assertProtoArrayEqualsIgnoringOrder(
2336                 new ImsRegistrationStats[] {
2337                     newImsRegStatsLte0
2338                 },
2339                 regStats);
2340     }
2341 
2342     @Test
2343     @SmallTest
addImsRegistrationTermination_emptyProto()2344     public void addImsRegistrationTermination_emptyProto() throws Exception {
2345         createEmptyTestFile();
2346 
2347         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2348         mPersistAtomsStorage.addImsRegistrationTermination(mImsRegistrationTerminationLte);
2349         mPersistAtomsStorage.incTimeMillis(100L);
2350 
2351         // Service state and service switch should be added successfully
2352         verifyCurrentStateSavedToFileOnce();
2353         ImsRegistrationTermination[] terminations =
2354                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
2355         assertProtoArrayEquals(
2356                 new ImsRegistrationTermination[] {mImsRegistrationTerminationLte}, terminations);
2357     }
2358 
2359     @Test
2360     @SmallTest
addImsRegistrationTermination_withExistingEntries()2361     public void addImsRegistrationTermination_withExistingEntries() throws Exception {
2362         createEmptyTestFile();
2363         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2364         mPersistAtomsStorage.addImsRegistrationTermination(mImsRegistrationTerminationLte);
2365 
2366         mPersistAtomsStorage.addImsRegistrationTermination(mImsRegistrationTerminationWifi);
2367         mPersistAtomsStorage.incTimeMillis(100L);
2368 
2369         // Service state and service switch should be added successfully
2370         verifyCurrentStateSavedToFileOnce();
2371         ImsRegistrationTermination[] terminations =
2372                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
2373         assertProtoArrayEqualsIgnoringOrder(
2374                 new ImsRegistrationTermination[] {
2375                     mImsRegistrationTerminationLte, mImsRegistrationTerminationWifi
2376                 },
2377                 terminations);
2378     }
2379 
2380     @Test
2381     @SmallTest
addImsRegistrationTermination_updateExistingEntries()2382     public void addImsRegistrationTermination_updateExistingEntries() throws Exception {
2383         createTestFile(START_TIME_MILLIS);
2384         ImsRegistrationTermination newTermination = copyOf(mImsRegistrationTerminationWifi);
2385         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2386 
2387         mPersistAtomsStorage.addImsRegistrationTermination(copyOf(mImsRegistrationTerminationWifi));
2388         mPersistAtomsStorage.incTimeMillis(100L);
2389 
2390         // mImsRegistrationTerminationWifi's count should be doubled
2391         verifyCurrentStateSavedToFileOnce();
2392         ImsRegistrationTermination[] terminations =
2393                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
2394         newTermination.count *= 2;
2395         assertProtoArrayEqualsIgnoringOrder(
2396                 new ImsRegistrationTermination[] {mImsRegistrationTerminationLte, newTermination},
2397                 terminations);
2398     }
2399 
2400     @Test
2401     @SmallTest
addImsRegistrationTermination_tooManyTerminations()2402     public void addImsRegistrationTermination_tooManyTerminations() throws Exception {
2403         createEmptyTestFile();
2404         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2405         Queue<ImsRegistrationTermination> expectedTerminations = new LinkedList<>();
2406 
2407         // Add 11 registration terminations
2408         for (int i = 0; i < 11; i++) {
2409             ImsRegistrationTermination termination = copyOf(mImsRegistrationTerminationLte);
2410             termination.reasonCode = i;
2411             expectedTerminations.add(termination);
2412             mPersistAtomsStorage.addImsRegistrationTermination(termination);
2413             mPersistAtomsStorage.incTimeMillis(100L);
2414         }
2415 
2416         // The least recent (the first) registration termination should be evicted
2417         verifyCurrentStateSavedToFileOnce();
2418         ImsRegistrationTermination[] terminations =
2419                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
2420         expectedTerminations.remove();
2421         assertProtoArrayEqualsIgnoringOrder(
2422                 expectedTerminations.toArray(new ImsRegistrationTermination[0]), terminations);
2423     }
2424 
2425     @Test
2426     @SmallTest
getImsRegistrationStats_tooFrequent()2427     public void getImsRegistrationStats_tooFrequent() throws Exception {
2428         createTestFile(START_TIME_MILLIS);
2429 
2430         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2431         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2432         ImsRegistrationStats[] stats = mPersistAtomsStorage.getImsRegistrationStats(100L);
2433 
2434         // Should be denied
2435         assertNull(stats);
2436     }
2437 
2438     @Test
2439     @SmallTest
getImsRegistrationStats_withSavedAtoms()2440     public void getImsRegistrationStats_withSavedAtoms() throws Exception {
2441         createTestFile(START_TIME_MILLIS);
2442 
2443         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2444         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2445         ImsRegistrationStats[] stats1 = mPersistAtomsStorage.getImsRegistrationStats(50L);
2446         mPersistAtomsStorage.incTimeMillis(100L);
2447         ImsRegistrationStats[] stats2 = mPersistAtomsStorage.getImsRegistrationStats(50L);
2448 
2449         // First set of results should equal to file contents, second should be empty, corresponding
2450         // pull timestamp should be updated and saved
2451         assertProtoArrayEqualsIgnoringOrder(
2452                 new ImsRegistrationStats[] {
2453                     mImsRegStatsUnregisteredLte0,
2454                     mImsRegStatsRegisteringLte0,
2455                     mImsRegistrationStatsLte0,
2456                     mImsRegistrationStatsWifi0,
2457                     mImsRegistrationStatsLte1
2458                 },
2459                 stats1);
2460         assertProtoArrayEquals(new ImsRegistrationStats[0], stats2);
2461         assertEquals(
2462                 START_TIME_MILLIS + DAY_IN_MILLIS + 100L,
2463                 mPersistAtomsStorage.getAtomsProto().imsRegistrationStatsPullTimestampMillis);
2464         InOrder inOrder = inOrder(mTestFileOutputStream);
2465         assertEquals(
2466                 START_TIME_MILLIS + DAY_IN_MILLIS,
2467                 getAtomsWritten(inOrder).imsRegistrationStatsPullTimestampMillis);
2468         assertEquals(
2469                 START_TIME_MILLIS + DAY_IN_MILLIS + 100L,
2470                 getAtomsWritten(inOrder).imsRegistrationStatsPullTimestampMillis);
2471         inOrder.verifyNoMoreInteractions();
2472     }
2473 
2474     @Test
2475     @SmallTest
getImsRegistrationTerminations_tooFrequent()2476     public void getImsRegistrationTerminations_tooFrequent() throws Exception {
2477         createTestFile(START_TIME_MILLIS);
2478 
2479         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2480         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2481         ImsRegistrationTermination[] terminations =
2482                 mPersistAtomsStorage.getImsRegistrationTerminations(100L);
2483 
2484         // Should be denied
2485         assertNull(terminations);
2486     }
2487 
2488     @Test
2489     @SmallTest
getImsRegistrationTerminations_withSavedAtoms()2490     public void getImsRegistrationTerminations_withSavedAtoms() throws Exception {
2491         createTestFile(START_TIME_MILLIS);
2492 
2493         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2494         mPersistAtomsStorage.incTimeMillis(100L);
2495         ImsRegistrationTermination[] terminations1 =
2496                 mPersistAtomsStorage.getImsRegistrationTerminations(50L);
2497         mPersistAtomsStorage.incTimeMillis(100L);
2498         ImsRegistrationTermination[] terminations2 =
2499                 mPersistAtomsStorage.getImsRegistrationTerminations(50L);
2500 
2501         // First set of results should equal to file contents, second should be empty, corresponding
2502         // pull timestamp should be updated and saved
2503         assertProtoArrayEqualsIgnoringOrder(
2504                 new ImsRegistrationTermination[] {
2505                     mImsRegistrationTerminationLte, mImsRegistrationTerminationWifi
2506                 },
2507                 terminations1);
2508         assertProtoArrayEquals(new ImsRegistrationTermination[0], terminations2);
2509         assertEquals(
2510                 START_TIME_MILLIS + 200L,
2511                 mPersistAtomsStorage.getAtomsProto().imsRegistrationTerminationPullTimestampMillis);
2512         InOrder inOrder = inOrder(mTestFileOutputStream);
2513         assertEquals(
2514                 START_TIME_MILLIS + 100L,
2515                 getAtomsWritten(inOrder).imsRegistrationTerminationPullTimestampMillis);
2516         assertEquals(
2517                 START_TIME_MILLIS + 200L,
2518                 getAtomsWritten(inOrder).imsRegistrationTerminationPullTimestampMillis);
2519         inOrder.verifyNoMoreInteractions();
2520     }
2521 
2522     @Test
2523     @SmallTest
addDataCallSession_newEntry()2524     public void addDataCallSession_newEntry()
2525             throws Exception {
2526         createEmptyTestFile();
2527         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2528 
2529         mPersistAtomsStorage.addDataCallSession(mDataCallSession0);
2530         mPersistAtomsStorage.addDataCallSession(mDataCallSession1);
2531         mPersistAtomsStorage.incTimeMillis(100L);
2532 
2533         // there should be 2 data calls
2534         verifyCurrentStateSavedToFileOnce();
2535         DataCallSession[] dataCalls = mPersistAtomsStorage.getDataCallSessions(0L);
2536         assertProtoArrayEqualsIgnoringOrder(
2537                 new DataCallSession[]{mDataCallSession0, mDataCallSession1},
2538                 dataCalls);
2539         for (DataCallSession dataCallSession : dataCalls) {
2540             if (dataCallSession.dimension == mDataCallSession0.dimension) {
2541                 assertArrayEquals(new int[]{1, 2, 3}, dataCallSession.handoverFailureCauses);
2542                 assertArrayEquals(new int[]{6, 5, 5}, dataCallSession.handoverFailureRat);
2543             }
2544         }
2545     }
2546 
2547     @Test
2548     @SmallTest
addImsRegistrationFeatureTagStats_emptyProto()2549     public void addImsRegistrationFeatureTagStats_emptyProto() throws Exception {
2550         createEmptyTestFile();
2551 
2552         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2553         mPersistAtomsStorage
2554                 .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats1Proto);
2555         mPersistAtomsStorage.incTimeMillis(100L);
2556 
2557         verifyCurrentStateSavedToFileOnce();
2558 
2559         ImsRegistrationFeatureTagStats[] expected =
2560                 new ImsRegistrationFeatureTagStats[] {
2561                         mImsRegistrationFeatureTagStats1Proto
2562                 };
2563         assertProtoArrayEquals(
2564                 expected, mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L));
2565     }
2566 
2567     @Test
2568     @SmallTest
addDataCallSession_existingEntry()2569     public void addDataCallSession_existingEntry()
2570             throws Exception {
2571         createEmptyTestFile();
2572         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2573         DataCallSession newDataCallSession0 = copyOf(mDataCallSession0);
2574         newDataCallSession0.ongoing = false;
2575         newDataCallSession0.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
2576         newDataCallSession0.durationMinutes = 10;
2577         newDataCallSession0.ratSwitchCount = 5;
2578         newDataCallSession0.handoverFailureCauses = new int[]{4};
2579         newDataCallSession0.handoverFailureRat = new int[]{4};
2580         DataCallSession totalDataCallSession0 = copyOf(newDataCallSession0);
2581         totalDataCallSession0.durationMinutes =
2582                 mDataCallSession0.durationMinutes + newDataCallSession0.durationMinutes;
2583         totalDataCallSession0.ratSwitchCount =
2584                 mDataCallSession0.ratSwitchCount + newDataCallSession0.ratSwitchCount;
2585         totalDataCallSession0.handoverFailureCauses = new int[]{1, 2, 3, 4};
2586         totalDataCallSession0.handoverFailureRat = new int[]{6, 5, 5, 4};
2587 
2588         mPersistAtomsStorage.addDataCallSession(mDataCallSession0);
2589         mPersistAtomsStorage.addDataCallSession(newDataCallSession0);
2590         mPersistAtomsStorage.incTimeMillis(100L);
2591 
2592         // there should be 1 data call
2593         verifyCurrentStateSavedToFileOnce();
2594         DataCallSession[] dataCalls = mPersistAtomsStorage.getDataCallSessions(0L);
2595         assertProtoArrayEqualsIgnoringOrder(
2596                 new DataCallSession[]{totalDataCallSession0}, dataCalls);
2597     }
2598 
2599     @Test
2600     @SmallTest
addImsRegistrationFeatureTagStats_withExistingEntries()2601     public void addImsRegistrationFeatureTagStats_withExistingEntries() throws Exception {
2602         createEmptyTestFile();
2603 
2604         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2605         mPersistAtomsStorage
2606                 .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats1Proto);
2607         mPersistAtomsStorage.incTimeMillis(100L);
2608         mPersistAtomsStorage
2609                 .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats2Proto);
2610         mPersistAtomsStorage.incTimeMillis(100L);
2611 
2612         verifyCurrentStateSavedToFileOnce();
2613 
2614         ImsRegistrationFeatureTagStats[] expected =
2615                 new ImsRegistrationFeatureTagStats[] {
2616                         mImsRegistrationFeatureTagStats1Proto,
2617                         mImsRegistrationFeatureTagStats2Proto
2618                 };
2619         // 2 atoms stored on initially and when try to add 2 same atoms, should be increased.
2620         assertProtoArrayEqualsIgnoringOrder(
2621                 expected, mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L));
2622     }
2623 
2624     @Test
2625     @SmallTest
addImsRegistrationFeatureTagStats_tooManyEntries()2626     public void addImsRegistrationFeatureTagStats_tooManyEntries() throws Exception {
2627         createEmptyTestFile();
2628 
2629         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2630 
2631         int maxCount = 10;
2632         for (int i = 0; i < maxCount; i++) {
2633             mPersistAtomsStorage
2634                     .addImsRegistrationFeatureTagStats(
2635                             copyOf(mImsRegistrationFeatureTagStats1Proto));
2636             mPersistAtomsStorage.incTimeMillis(100L);
2637         }
2638 
2639         mPersistAtomsStorage
2640                 .addImsRegistrationFeatureTagStats(copyOf(mImsRegistrationFeatureTagStats2Proto));
2641 
2642         verifyCurrentStateSavedToFileOnce();
2643 
2644         ImsRegistrationFeatureTagStats[] result =
2645                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L);
2646 
2647         // tried store 26 statses, but only 2 statses stored
2648         // total time 3600L * maxCount
2649         assertHasStatsCountTime(result, mImsRegistrationFeatureTagStats1Proto, 1,
2650                 maxCount * 3600L);
2651         // total time 3600L * 1
2652         assertHasStatsCountTime(result, mImsRegistrationFeatureTagStats2Proto, 1,
2653                 1 * 3600L);
2654     }
2655 
2656     @Test
2657     @SmallTest
getImsRegistrationFeatureTagStats_tooFrequent()2658     public void getImsRegistrationFeatureTagStats_tooFrequent() throws Exception {
2659         createTestFile(START_TIME_MILLIS);
2660 
2661         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2662         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2663         ImsRegistrationFeatureTagStats[] result =
2664                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(100L);
2665 
2666         // Should be denied
2667         assertNull(result);
2668     }
2669 
2670     @Test
2671     @SmallTest
getImsRegistrationFeatureTagStats_withSavedAtoms()2672     public void getImsRegistrationFeatureTagStats_withSavedAtoms() throws Exception {
2673         createTestFile(START_TIME_MILLIS);
2674 
2675         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2676         mPersistAtomsStorage.incTimeMillis(100L);
2677         ImsRegistrationFeatureTagStats[] statses1 =
2678                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(50L);
2679         mPersistAtomsStorage.incTimeMillis(100L);
2680         ImsRegistrationFeatureTagStats[] statses2 =
2681                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(50L);
2682 
2683         // First results of get should have two atoms, second should be empty
2684         // pull timestamp should be updated and saved
2685         assertProtoArrayEqualsIgnoringOrder(mImsRegistrationFeatureTagStatses, statses1);
2686         assertProtoArrayEquals(new ImsRegistrationFeatureTagStats[0], statses2);
2687         assertEquals(
2688                 START_TIME_MILLIS + 200L,
2689                 mPersistAtomsStorage.getAtomsProto()
2690                         .imsRegistrationFeatureTagStatsPullTimestampMillis);
2691         InOrder inOrder = inOrder(mTestFileOutputStream);
2692         assertEquals(
2693                 START_TIME_MILLIS + 100L,
2694                 getAtomsWritten(inOrder).imsRegistrationFeatureTagStatsPullTimestampMillis);
2695         assertEquals(
2696                 START_TIME_MILLIS + 200L,
2697                 getAtomsWritten(inOrder).imsRegistrationFeatureTagStatsPullTimestampMillis);
2698         inOrder.verifyNoMoreInteractions();
2699     }
2700 
2701     @Test
2702     @SmallTest
addRcsClientProvisioningStats_emptyProto()2703     public void addRcsClientProvisioningStats_emptyProto() throws Exception {
2704         createEmptyTestFile();
2705 
2706         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2707         mPersistAtomsStorage
2708                 .addRcsClientProvisioningStats(mRcsClientProvisioningStats1Proto);
2709         mPersistAtomsStorage.incTimeMillis(100L);
2710         mPersistAtomsStorage
2711                 .addRcsClientProvisioningStats(mRcsClientProvisioningStats2Proto);
2712         mPersistAtomsStorage.incTimeMillis(100L);
2713 
2714         verifyCurrentStateSavedToFileOnce();
2715 
2716         RcsClientProvisioningStats[] expected =
2717                 new RcsClientProvisioningStats[] {
2718                         mRcsClientProvisioningStats1Proto,
2719                         mRcsClientProvisioningStats2Proto
2720                 };
2721 
2722         assertProtoArrayEqualsIgnoringOrder(
2723                 expected, mPersistAtomsStorage.getRcsClientProvisioningStats(0L));
2724     }
2725 
2726     @Test
2727     @SmallTest
addRcsClientProvisioningStats_tooManyEntries()2728     public void addRcsClientProvisioningStats_tooManyEntries() throws Exception {
2729         createEmptyTestFile();
2730 
2731         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2732 
2733         // Store 11 same atoms, but only 1 atoms stored with count 11
2734         for (int i = 0; i < 11; i++) {
2735             mPersistAtomsStorage
2736                     .addRcsClientProvisioningStats(mRcsClientProvisioningStats1Proto);
2737             mPersistAtomsStorage.incTimeMillis(100L);
2738         }
2739         // Store 1 different atom and count 1
2740         mPersistAtomsStorage
2741                 .addRcsClientProvisioningStats(mRcsClientProvisioningStats2Proto);
2742 
2743         verifyCurrentStateSavedToFileOnce();
2744 
2745         RcsClientProvisioningStats[] result =
2746                 mPersistAtomsStorage.getRcsClientProvisioningStats(0L);
2747 
2748         // First atom has count 11, the other has 1
2749         assertHasStatsAndCount(result, mRcsClientProvisioningStats1Proto, 11);
2750         assertHasStatsAndCount(result, mRcsClientProvisioningStats2Proto, 1);
2751     }
2752 
2753     @Test
2754     @SmallTest
getRcsClientProvisioningStats_tooFrequent()2755     public void getRcsClientProvisioningStats_tooFrequent() throws Exception {
2756         createTestFile(START_TIME_MILLIS);
2757 
2758         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2759         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2760         RcsClientProvisioningStats[] result =
2761                 mPersistAtomsStorage.getRcsClientProvisioningStats(100L);
2762 
2763         // Should be denied
2764         assertNull(result);
2765     }
2766 
2767     @Test
2768     @SmallTest
getRcsClientProvisioningStats_withSavedAtoms()2769     public void getRcsClientProvisioningStats_withSavedAtoms() throws Exception {
2770         createTestFile(START_TIME_MILLIS);
2771 
2772         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2773         mPersistAtomsStorage.incTimeMillis(100L);
2774         RcsClientProvisioningStats[] statses1 =
2775                 mPersistAtomsStorage.getRcsClientProvisioningStats(50L);
2776         mPersistAtomsStorage.incTimeMillis(100L);
2777         RcsClientProvisioningStats[] statses2 =
2778                 mPersistAtomsStorage.getRcsClientProvisioningStats(50L);
2779 
2780         // First results of get should have two atoms, second should be empty
2781         // pull timestamp should be updated and saved
2782         assertProtoArrayEqualsIgnoringOrder(mRcsClientProvisioningStatses, statses1);
2783         assertProtoArrayEquals(new RcsClientProvisioningStats[0], statses2);
2784         assertEquals(
2785                 START_TIME_MILLIS + 200L,
2786                 mPersistAtomsStorage.getAtomsProto()
2787                         .rcsClientProvisioningStatsPullTimestampMillis);
2788         InOrder inOrder = inOrder(mTestFileOutputStream);
2789         assertEquals(
2790                 START_TIME_MILLIS + 100L,
2791                 getAtomsWritten(inOrder).rcsClientProvisioningStatsPullTimestampMillis);
2792         assertEquals(
2793                 START_TIME_MILLIS + 200L,
2794                 getAtomsWritten(inOrder).rcsClientProvisioningStatsPullTimestampMillis);
2795         inOrder.verifyNoMoreInteractions();
2796     }
2797 
2798     @Test
2799     @SmallTest
addRcsAcsProvisioningStats_emptyProto()2800     public void addRcsAcsProvisioningStats_emptyProto() throws Exception {
2801         createEmptyTestFile();
2802 
2803         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2804         mPersistAtomsStorage
2805                 .addRcsAcsProvisioningStats(mRcsAcsProvisioningStats1Proto);
2806         mPersistAtomsStorage.incTimeMillis(100L);
2807         mPersistAtomsStorage
2808                 .addRcsAcsProvisioningStats(mRcsAcsProvisioningStats2Proto);
2809         mPersistAtomsStorage.incTimeMillis(100L);
2810 
2811         verifyCurrentStateSavedToFileOnce();
2812 
2813         RcsAcsProvisioningStats[] expected =
2814                 new RcsAcsProvisioningStats[] {
2815                         mRcsAcsProvisioningStats1Proto,
2816                         mRcsAcsProvisioningStats2Proto
2817                 };
2818 
2819         assertProtoArrayEqualsIgnoringOrder(
2820                 expected, mPersistAtomsStorage.getRcsAcsProvisioningStats(0L));
2821     }
2822 
2823     @Test
2824     @SmallTest
addRcsAcsProvisioningStats_updateExistingEntries()2825     public void addRcsAcsProvisioningStats_updateExistingEntries() throws Exception {
2826         final int maxCount = 5;
2827         final long duration = START_TIME_MILLIS;
2828         createEmptyTestFile();
2829 
2830         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2831 
2832         // Store 5 same atoms (1Proto), but only 1 atoms stored with count 5, total time 2000L * 5
2833         // Store 5 same atoms (2Proto), but only 1 atoms stored with count 5, total time 2000L * 5
2834 
2835         for (int i = 0; i < maxCount; i++) {
2836             mPersistAtomsStorage
2837                     .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats1Proto));
2838             mPersistAtomsStorage.incTimeMillis(100L);
2839             mPersistAtomsStorage
2840                     .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats2Proto));
2841             mPersistAtomsStorage.incTimeMillis(100L);
2842         }
2843         // add one more atoms (2Proto), count 6, total time 2000L * 6
2844         mPersistAtomsStorage
2845                 .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats2Proto));
2846         mPersistAtomsStorage.incTimeMillis(100L);
2847 
2848         verifyCurrentStateSavedToFileOnce();
2849 
2850         RcsAcsProvisioningStats[] result =
2851                 mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);
2852 
2853         // atom (1Proto) : count = 5, time = 2000L * 5
2854         assertHasStatsAndCountDuration(
2855                 result, mRcsAcsProvisioningStats1Proto, 5, duration * maxCount);
2856         // atom (2Proto) : count = 6, time = 2000L * 6
2857         assertHasStatsAndCountDuration(
2858                 result, mRcsAcsProvisioningStats2Proto, 6, duration * (maxCount + 1));
2859     }
2860 
2861     @Test
2862     @SmallTest
getRcsAcsProvisioningStats_tooFrequent()2863     public void getRcsAcsProvisioningStats_tooFrequent() throws Exception {
2864         createTestFile(START_TIME_MILLIS);
2865 
2866         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2867         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2868         RcsAcsProvisioningStats[] result =
2869                 mPersistAtomsStorage.getRcsAcsProvisioningStats(100L);
2870 
2871         // Should be denied
2872         assertNull(result);
2873     }
2874 
2875     @Test
2876     @SmallTest
getRcsAcstProvisioningStats_withSavedAtoms()2877     public void getRcsAcstProvisioningStats_withSavedAtoms() throws Exception {
2878         createTestFile(START_TIME_MILLIS);
2879 
2880         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2881         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2882         RcsAcsProvisioningStats[] statses1 =
2883                 mPersistAtomsStorage.getRcsAcsProvisioningStats(DAY_IN_MILLIS - HOUR_IN_MILLIS);
2884         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
2885         RcsAcsProvisioningStats[] statses2 =
2886                 mPersistAtomsStorage.getRcsAcsProvisioningStats(DAY_IN_MILLIS - HOUR_IN_MILLIS);
2887 
2888         // First results of get should have two atoms, second should be empty
2889         // pull timestamp should be updated and saved
2890         assertProtoArrayEqualsIgnoringOrder(mRcsAcsProvisioningStatses, statses1);
2891         assertProtoArrayEquals(new RcsAcsProvisioningStats[0], statses2);
2892         assertEquals(
2893                 START_TIME_MILLIS + 2 * DAY_IN_MILLIS,
2894                 mPersistAtomsStorage.getAtomsProto()
2895                         .rcsAcsProvisioningStatsPullTimestampMillis);
2896         InOrder inOrder = inOrder(mTestFileOutputStream);
2897         assertEquals(
2898                 START_TIME_MILLIS + DAY_IN_MILLIS,
2899                 getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
2900         assertEquals(
2901                 START_TIME_MILLIS + 2 * DAY_IN_MILLIS,
2902                 getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
2903         inOrder.verifyNoMoreInteractions();
2904     }
2905 
2906     @Test
2907     @SmallTest
addImsRegistrationServiceDescStats_emptyProto()2908     public void addImsRegistrationServiceDescStats_emptyProto() throws Exception {
2909         createEmptyTestFile();
2910         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2911         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceIm);
2912         mPersistAtomsStorage.incTimeMillis(100L);
2913 
2914         // Service state and service switch should be added successfully
2915         verifyCurrentStateSavedToFileOnce();
2916         ImsRegistrationServiceDescStats[] outputs =
2917             mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
2918         assertProtoArrayEquals(
2919                 new ImsRegistrationServiceDescStats[] {mImsRegistrationServiceIm}, outputs);
2920     }
2921 
2922     @Test
2923     @SmallTest
addImsRegistrationServiceDescStats_withExistingEntries()2924     public void addImsRegistrationServiceDescStats_withExistingEntries() throws Exception {
2925         createEmptyTestFile();
2926         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2927         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceIm);
2928 
2929         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceFt);
2930         mPersistAtomsStorage.incTimeMillis(100L);
2931 
2932         // Service state and service switch should be added successfully
2933         verifyCurrentStateSavedToFileOnce();
2934         ImsRegistrationServiceDescStats[] output =
2935             mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
2936         assertProtoArrayEqualsIgnoringOrder(
2937                 new ImsRegistrationServiceDescStats[] {
2938                     mImsRegistrationServiceIm,
2939                     mImsRegistrationServiceFt
2940                 },
2941                 output);
2942     }
2943 
2944     @Test
2945     @SmallTest
addImsRegistrationServiceDescStats_tooManyServiceDesc()2946     public void addImsRegistrationServiceDescStats_tooManyServiceDesc() throws Exception {
2947         createEmptyTestFile();
2948         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2949 
2950         Queue<ImsRegistrationServiceDescStats> expectedOutput = new LinkedList<>();
2951         // Add 101 registration terminations
2952         for (int i = 0; i < 26 + 1; i++) {
2953             ImsRegistrationServiceDescStats stats = copyOf(mImsRegistrationServiceIm);
2954             stats.registrationTech = i;
2955             expectedOutput.add(stats);
2956             mPersistAtomsStorage.addImsRegistrationServiceDescStats(stats);
2957             mPersistAtomsStorage.incTimeMillis(100L);
2958         }
2959         mPersistAtomsStorage.incTimeMillis(100L);
2960 
2961         // The least recent (the first) registration termination should be evicted
2962         verifyCurrentStateSavedToFileOnce();
2963         ImsRegistrationServiceDescStats[] output =
2964             mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
2965         expectedOutput.remove();
2966         assertEquals(expectedOutput.size() - 1, output.length);
2967     }
2968 
2969     @Test
2970     @SmallTest
getImsRegistrationServiceDescStats_tooFrequent()2971     public void getImsRegistrationServiceDescStats_tooFrequent() throws Exception {
2972         createTestFile(START_TIME_MILLIS);
2973 
2974         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2975         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
2976         ImsRegistrationServiceDescStats[] output =
2977             mPersistAtomsStorage.getImsRegistrationServiceDescStats(100L);
2978 
2979         // Should be denied
2980         assertNull(output);
2981     }
2982 
2983     @Test
2984     @SmallTest
getImsRegistrationServiceDescStats_withSavedAtoms()2985     public void getImsRegistrationServiceDescStats_withSavedAtoms() throws Exception {
2986         createTestFile(START_TIME_MILLIS);
2987 
2988         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
2989         mPersistAtomsStorage.incTimeMillis(100L);
2990         ImsRegistrationServiceDescStats[] output1 =
2991             mPersistAtomsStorage.getImsRegistrationServiceDescStats(50L);
2992         mPersistAtomsStorage.incTimeMillis(100L);
2993         ImsRegistrationServiceDescStats[] output2 =
2994             mPersistAtomsStorage.getImsRegistrationServiceDescStats(50L);
2995 
2996         // First set of results should equal to file contents, second should be empty, corresponding
2997         // pull timestamp should be updated and saved
2998         assertProtoArrayEqualsIgnoringOrder(
2999                 new ImsRegistrationServiceDescStats[] {
3000                     mImsRegistrationServiceIm,
3001                     mImsRegistrationServiceFt
3002                 },
3003                 output1);
3004         assertProtoArrayEquals(new ImsRegistrationServiceDescStats[0], output2);
3005         assertEquals(
3006                 START_TIME_MILLIS + 200L,
3007                 mPersistAtomsStorage.getAtomsProto()
3008                     .imsRegistrationServiceDescStatsPullTimestampMillis);
3009         InOrder inOrder = inOrder(mTestFileOutputStream);
3010         assertEquals(
3011                 START_TIME_MILLIS + 100L,
3012                 getAtomsWritten(inOrder).imsRegistrationServiceDescStatsPullTimestampMillis);
3013         assertEquals(
3014                 START_TIME_MILLIS + 200L,
3015                 getAtomsWritten(inOrder).imsRegistrationServiceDescStatsPullTimestampMillis);
3016         inOrder.verifyNoMoreInteractions();
3017     }
3018 
3019     @Test
3020     @SmallTest
getImsRegistrationStats_24hNormalization()3021     public void getImsRegistrationStats_24hNormalization() throws Exception {
3022         createEmptyTestFile();
3023         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3024         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsWifi0));
3025         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS / 2);
3026 
3027         ImsRegistrationStats[] serviceStates = mPersistAtomsStorage.getImsRegistrationStats(0L);
3028         mImsRegistrationStatsWifi0.registeredMillis *= 2;
3029         mImsRegistrationStatsWifi0.voiceCapableMillis *= 2;
3030         mImsRegistrationStatsWifi0.voiceAvailableMillis *= 2;
3031         mImsRegistrationStatsWifi0.smsCapableMillis *= 2;
3032         mImsRegistrationStatsWifi0.smsAvailableMillis *= 2;
3033         mImsRegistrationStatsWifi0.videoCapableMillis *= 2;
3034         mImsRegistrationStatsWifi0.videoAvailableMillis *= 2;
3035         mImsRegistrationStatsWifi0.utCapableMillis *= 2;
3036         mImsRegistrationStatsWifi0.utAvailableMillis *= 2;
3037         assertProtoArrayEqualsIgnoringOrder(
3038                 new ImsRegistrationStats[] {
3039                     mImsRegistrationStatsWifi0
3040                 },
3041                 serviceStates);
3042     }
3043 
3044     @Test
getRcsAcsProvisioningStats_24h_normalization()3045     public void getRcsAcsProvisioningStats_24h_normalization() throws Exception {
3046         // in case pulling interval is greater than a day
3047         final long stateTimer = HOUR_IN_MILLIS;
3048         final long weightFactor = 2;
3049         createTestFile(START_TIME_MILLIS);
3050         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3051         RcsAcsProvisioningStats mSubjectStats = copyOf(mRcsAcsProvisioningStats1Proto);
3052 
3053         mSubjectStats.stateTimerMillis = stateTimer;
3054         mPersistAtomsStorage.addRcsAcsProvisioningStats(mSubjectStats);
3055         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
3056 
3057         RcsAcsProvisioningStats[] savedStats =
3058                 mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);
3059 
3060         assertEquals(
3061                 (START_TIME_MILLIS + stateTimer) / weightFactor, savedStats[0].stateTimerMillis);
3062 
3063         // in case pulling interval is smaller than a day
3064         long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
3065         mSubjectStats = copyOf(mRcsAcsProvisioningStats1Proto);
3066         mSubjectStats.stateTimerMillis = stateTimer;
3067         mPersistAtomsStorage.addRcsAcsProvisioningStats(mSubjectStats);
3068         mPersistAtomsStorage.incTimeMillis(incTimeMillis);
3069         savedStats =
3070                 mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);
3071 
3072 
3073         assertEquals(stateTimer, savedStats[0].stateTimerMillis);
3074     }
3075 
3076     @Test
getSipDelegateStats_24h_normalization()3077     public void getSipDelegateStats_24h_normalization() throws Exception {
3078         final long stateTimer = HOUR_IN_MILLIS;
3079         final long weightFactor = 2;
3080         createTestFile(START_TIME_MILLIS);
3081         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3082         SipDelegateStats mSubjectStats = copyOf(mSipDelegateStats1);
3083         mSubjectStats.uptimeMillis = stateTimer;
3084         mPersistAtomsStorage.addSipDelegateStats(mSubjectStats);
3085         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
3086         SipDelegateStats[] savedStats =
3087                 mPersistAtomsStorage.getSipDelegateStats(0L);
3088         for (SipDelegateStats stat : savedStats) {
3089             if (stat.destroyReason
3090                     == SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP) {
3091                 assertEquals(stateTimer / weightFactor, stat.uptimeMillis);
3092             }
3093         }
3094 
3095         long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
3096         mSubjectStats = copyOf(mSipDelegateStats1);
3097         mSubjectStats.uptimeMillis = stateTimer;
3098         mPersistAtomsStorage.addSipDelegateStats(mSubjectStats);
3099         mPersistAtomsStorage.incTimeMillis(incTimeMillis);
3100         savedStats =
3101                 mPersistAtomsStorage.getSipDelegateStats(0L);
3102         for (SipDelegateStats stat : savedStats) {
3103             if (stat.destroyReason
3104                     == SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP) {
3105                 assertEquals(stateTimer, stat.uptimeMillis);
3106             }
3107         }
3108     }
3109 
3110     @Test
getSipTransportFeatureTagStats_24h_normalization()3111     public void getSipTransportFeatureTagStats_24h_normalization() throws Exception {
3112         final long stateTimer = HOUR_IN_MILLIS;
3113         final long weightFactor = 2;
3114         createTestFile(START_TIME_MILLIS);
3115         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3116         SipTransportFeatureTagStats mSubjectStats = copyOf(mSipTransportFeatureTagStats1);
3117         mSubjectStats.associatedMillis = stateTimer;
3118         mPersistAtomsStorage.addSipTransportFeatureTagStats(mSubjectStats);
3119         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
3120         SipTransportFeatureTagStats[] savedStats =
3121                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3122         assertEquals((stateTimer) / weightFactor, savedStats[0].associatedMillis);
3123 
3124         long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
3125         mSubjectStats = copyOf(mSipTransportFeatureTagStats1);
3126         mSubjectStats.associatedMillis = stateTimer;
3127         mPersistAtomsStorage.addSipTransportFeatureTagStats(mSubjectStats);
3128         mPersistAtomsStorage.incTimeMillis(incTimeMillis);
3129         savedStats =
3130                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3131         assertEquals(stateTimer, savedStats[0].associatedMillis);
3132     }
3133 
3134     @Test
getImsRegistrationServiceDescStats_24h_normalization()3135     public void getImsRegistrationServiceDescStats_24h_normalization() throws Exception {
3136         final long stateTimer = HOUR_IN_MILLIS;
3137         final long weightFactor = 2;
3138         createTestFile(START_TIME_MILLIS);
3139         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3140         ImsRegistrationServiceDescStats mSubjectStats = copyOf(mImsRegistrationServiceIm);
3141         mSubjectStats.publishedMillis = stateTimer;
3142         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mSubjectStats);
3143         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
3144         ImsRegistrationServiceDescStats[] savedStats =
3145                 mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
3146         assertEquals(
3147                 (START_TIME_MILLIS + stateTimer) / weightFactor, savedStats[0].publishedMillis);
3148 
3149         long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
3150         mSubjectStats = copyOf(mImsRegistrationServiceIm);
3151         mSubjectStats.publishedMillis = stateTimer;
3152         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mSubjectStats);
3153         mPersistAtomsStorage.incTimeMillis(incTimeMillis);
3154         savedStats =
3155                 mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
3156         assertEquals(stateTimer, savedStats[0].publishedMillis);
3157     }
3158 
3159     @Test
3160     @SmallTest
addImsDedicatedBearerListenerEvent_emptyProto()3161     public void addImsDedicatedBearerListenerEvent_emptyProto() throws Exception {
3162         createEmptyTestFile();
3163         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3164         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
3165         mPersistAtomsStorage.incTimeMillis(100L);
3166 
3167         // Service state and service switch should be added successfully
3168         verifyCurrentStateSavedToFileOnce();
3169         ImsDedicatedBearerListenerEvent[] outputs =
3170                 mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
3171         assertProtoArrayEquals(
3172                 new ImsDedicatedBearerListenerEvent[] {mImsDedicatedBearerListenerEvent1}, outputs);
3173     }
3174 
3175     @Test
3176     @SmallTest
addImsDedicatedBearerListenerEvent_withExistingEntries()3177     public void addImsDedicatedBearerListenerEvent_withExistingEntries() throws Exception {
3178         createEmptyTestFile();
3179         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3180         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
3181 
3182         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent2);
3183         mPersistAtomsStorage.incTimeMillis(100L);
3184 
3185         // Service state and service switch should be added successfully
3186         verifyCurrentStateSavedToFileOnce();
3187         ImsDedicatedBearerListenerEvent[] output =
3188                 mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
3189         assertProtoArrayEqualsIgnoringOrder(
3190                 new ImsDedicatedBearerListenerEvent[] {
3191                     mImsDedicatedBearerListenerEvent1, mImsDedicatedBearerListenerEvent2}, output);
3192     }
3193 
3194     @Test
3195     @SmallTest
addImsDedicatedBearerListenerEvent_withSameProto()3196     public void addImsDedicatedBearerListenerEvent_withSameProto() throws Exception {
3197         createEmptyTestFile();
3198         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3199 
3200         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
3201         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
3202         mPersistAtomsStorage.incTimeMillis(100L);
3203 
3204         // The least recent (the first) registration termination should be evicted
3205         verifyCurrentStateSavedToFileOnce();
3206         ImsDedicatedBearerListenerEvent[] output =
3207                 mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
3208         assertEquals(mImsDedicatedBearerListenerEvent1.carrierId, output[0].carrierId);
3209         assertEquals(mImsDedicatedBearerListenerEvent1.slotId, output[0].slotId);
3210         assertEquals(mImsDedicatedBearerListenerEvent1.ratAtEnd, output[0].ratAtEnd);
3211         assertEquals(mImsDedicatedBearerListenerEvent1.qci, output[0].qci);
3212         assertEquals(mImsDedicatedBearerListenerEvent1.dedicatedBearerEstablished,
3213                 output[0].dedicatedBearerEstablished);
3214         assertEquals(mImsDedicatedBearerListenerEvent1.eventCount,
3215                 output[0].eventCount);
3216     }
3217 
3218     @Test
3219     @SmallTest
addImsDedicatedBearerEvent_emptyProto()3220     public void addImsDedicatedBearerEvent_emptyProto() throws Exception {
3221         createEmptyTestFile();
3222         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3223         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
3224         mPersistAtomsStorage.incTimeMillis(100L);
3225 
3226         // Service state and service switch should be added successfully
3227         verifyCurrentStateSavedToFileOnce();
3228         ImsDedicatedBearerEvent[] outputs =
3229             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
3230         assertProtoArrayEquals(
3231                 new ImsDedicatedBearerEvent[] {mImsDedicatedBearerEvent1}, outputs);
3232     }
3233 
3234     @Test
3235     @SmallTest
addImsDedicatedBearerEvent_withExistingEntries()3236     public void addImsDedicatedBearerEvent_withExistingEntries() throws Exception {
3237         createEmptyTestFile();
3238         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3239         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
3240 
3241         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent2);
3242         mPersistAtomsStorage.incTimeMillis(100L);
3243 
3244         // Service state and service switch should be added successfully
3245         verifyCurrentStateSavedToFileOnce();
3246         ImsDedicatedBearerEvent[] output =
3247             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
3248         assertProtoArrayEqualsIgnoringOrder(
3249                     new ImsDedicatedBearerEvent[] {
3250                         mImsDedicatedBearerEvent1, mImsDedicatedBearerEvent2}, output);
3251     }
3252 
3253     @Test
3254     @SmallTest
addImsDedicatedBearerEvent_withSameProto()3255     public void addImsDedicatedBearerEvent_withSameProto() throws Exception {
3256         createEmptyTestFile();
3257         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3258 
3259         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
3260         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
3261         mPersistAtomsStorage.incTimeMillis(100L);
3262 
3263         // The least recent (the first) registration termination should be evicted
3264         verifyCurrentStateSavedToFileOnce();
3265         ImsDedicatedBearerEvent[] output =
3266             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
3267         assertEquals(mImsDedicatedBearerEvent1.carrierId, output[0].carrierId);
3268         assertEquals(mImsDedicatedBearerEvent1.slotId, output[0].slotId);
3269         assertEquals(mImsDedicatedBearerEvent1.ratAtEnd, output[0].ratAtEnd);
3270         assertEquals(mImsDedicatedBearerEvent1.qci, output[0].qci);
3271         assertEquals(mImsDedicatedBearerEvent1.localConnectionInfoReceived,
3272                 output[0].localConnectionInfoReceived);
3273         assertEquals(mImsDedicatedBearerEvent1.remoteConnectionInfoReceived,
3274                 output[0].remoteConnectionInfoReceived);
3275         assertEquals(mImsDedicatedBearerEvent1.hasListeners,
3276                 output[0].hasListeners);
3277     }
3278 
3279     @Test
3280     @SmallTest
addImsDedicatedBearerEvent_tooManyEntries()3281     public void addImsDedicatedBearerEvent_tooManyEntries() throws Exception {
3282         createEmptyTestFile();
3283 
3284         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3285 
3286         // Add 11 stats, but max is 10
3287         for (int i = 0; i < 11; i++) {
3288             mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
3289             mPersistAtomsStorage.incTimeMillis(100L);
3290         }
3291         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent2);
3292 
3293         verifyCurrentStateSavedToFileOnce();
3294         ImsDedicatedBearerEvent[] stats =
3295             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
3296         assertHasStatsAndCount(stats, mImsDedicatedBearerEvent1, 11);
3297         assertHasStatsAndCount(stats, mImsDedicatedBearerEvent2, 1);
3298     }
3299 
3300     @Test
3301     @SmallTest
addImsDedicatedBearerEvent_updateExistingEntries()3302     public void addImsDedicatedBearerEvent_updateExistingEntries() throws Exception {
3303         createTestFile(START_TIME_MILLIS);
3304         ImsDedicatedBearerEvent newStats = copyOf(mImsDedicatedBearerEvent1);
3305         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3306 
3307         mPersistAtomsStorage.addImsDedicatedBearerEvent(copyOf(mImsDedicatedBearerEvent1));
3308         mPersistAtomsStorage.incTimeMillis(100L);
3309 
3310         // mImsDedicatedBearerEvent1's count should be doubled
3311         verifyCurrentStateSavedToFileOnce();
3312         ImsDedicatedBearerEvent[] stats =
3313             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
3314         newStats.count *= 2;
3315         assertProtoArrayEqualsIgnoringOrder(new ImsDedicatedBearerEvent[] {
3316                 mImsDedicatedBearerEvent2, newStats}, stats);
3317     }
3318 
3319     @Test
3320     @SmallTest
addUceEventStats_emptyProto()3321     public void addUceEventStats_emptyProto() throws Exception {
3322         createEmptyTestFile();
3323         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3324         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
3325         mPersistAtomsStorage.incTimeMillis(100L);
3326 
3327         // Service state and service switch should be added successfully
3328         verifyCurrentStateSavedToFileOnce();
3329         UceEventStats[] outputs = mPersistAtomsStorage.getUceEventStats(0L);
3330         assertProtoArrayEquals(
3331                 new UceEventStats[] {mUceEventStats1}, outputs);
3332     }
3333 
3334     @Test
3335     @SmallTest
addUceEventStats_withExistingEntries()3336     public void addUceEventStats_withExistingEntries() throws Exception {
3337         createEmptyTestFile();
3338         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3339         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
3340 
3341         mPersistAtomsStorage.addUceEventStats(mUceEventStats2);
3342         mPersistAtomsStorage.incTimeMillis(100L);
3343 
3344         // Service state and service switch should be added successfully
3345         verifyCurrentStateSavedToFileOnce();
3346         UceEventStats[] output = mPersistAtomsStorage.getUceEventStats(0L);
3347         assertProtoArrayEqualsIgnoringOrder(
3348                 new UceEventStats[] {mUceEventStats1, mUceEventStats2}, output);
3349     }
3350 
3351     @Test
3352     @SmallTest
addUceEventStats_withSameProto()3353     public void addUceEventStats_withSameProto() throws Exception {
3354         createEmptyTestFile();
3355         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3356 
3357         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
3358         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
3359         mPersistAtomsStorage.incTimeMillis(100L);
3360 
3361         // The least recent (the first) registration termination should be evicted
3362         verifyCurrentStateSavedToFileOnce();
3363         UceEventStats[] output = mPersistAtomsStorage.getUceEventStats(0L);
3364         assertEquals(mUceEventStats1.carrierId, output[0].carrierId);
3365         assertEquals(mUceEventStats1.slotId, output[0].slotId);
3366         assertEquals(mUceEventStats1.type, output[0].type);
3367         assertEquals(mUceEventStats1.successful, output[0].successful);
3368         assertEquals(mUceEventStats1.commandCode, output[0].commandCode);
3369         assertEquals(mUceEventStats1.networkResponse, output[0].networkResponse);
3370         assertEquals(2, output[0].count);
3371     }
3372 
3373     @Test
3374     @SmallTest
addPresenceNotifyEvent_withSameProto()3375     public void addPresenceNotifyEvent_withSameProto() throws Exception {
3376         createEmptyTestFile();
3377         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3378 
3379         PresenceNotifyEvent event1 = new PresenceNotifyEvent();
3380         event1.carrierId = CARRIER1_ID;
3381         event1.slotId = SLOT_ID1;
3382         event1.reason = 1;
3383         event1.contentBodyReceived = true;
3384         event1.rcsCapsCount = 1;
3385         event1.mmtelCapsCount = 1;
3386         event1.noCapsCount = 0;
3387         event1.count = 1;
3388 
3389         PresenceNotifyEvent event2 = copyOf(event1);
3390         event2.rcsCapsCount = 0;
3391 
3392         mPersistAtomsStorage.addPresenceNotifyEvent(event1);
3393         mPersistAtomsStorage.addPresenceNotifyEvent(event2);
3394 
3395         mPersistAtomsStorage.incTimeMillis(100L);
3396 
3397         // The least recent (the first) registration termination should be evicted
3398         verifyCurrentStateSavedToFileOnce();
3399         PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(0L);
3400 
3401         assertEquals(event1.carrierId, output[0].carrierId);
3402         assertEquals(event1.slotId, output[0].slotId);
3403         assertEquals(event1.contentBodyReceived, output[0].contentBodyReceived);
3404         assertEquals(1, output[0].rcsCapsCount);
3405         assertEquals(2, output[0].mmtelCapsCount);
3406         assertEquals(2, output[0].count);
3407 
3408     }
3409     @Test
3410     @SmallTest
addPresenceNotifyEvent_withExistingEntries()3411     public void addPresenceNotifyEvent_withExistingEntries() throws Exception {
3412         createEmptyTestFile();
3413         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3414         mPersistAtomsStorage.addPresenceNotifyEvent(mPresenceNotifyEvent1);
3415         mPersistAtomsStorage.addPresenceNotifyEvent(mPresenceNotifyEvent2);
3416         mPersistAtomsStorage.incTimeMillis(100L);
3417 
3418         // Service state and service switch should be added successfully
3419         verifyCurrentStateSavedToFileOnce();
3420         PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(0L);
3421         assertProtoArrayEqualsIgnoringOrder(
3422                 new PresenceNotifyEvent[] {mPresenceNotifyEvent1, mPresenceNotifyEvent2}, output);
3423     }
3424 
3425     @Test
3426     @SmallTest
getPresenceNotifyEvent_tooFrequent()3427     public void getPresenceNotifyEvent_tooFrequent() throws Exception {
3428         createTestFile(START_TIME_MILLIS);
3429 
3430         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3431         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
3432         PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(100L);
3433 
3434         // Should be denied
3435         assertNull(output);
3436     }
3437 
3438     @Test
3439     @SmallTest
getPresenceNotifyEvent_withSavedAtoms()3440     public void getPresenceNotifyEvent_withSavedAtoms() throws Exception {
3441         createTestFile(START_TIME_MILLIS);
3442 
3443         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3444         mPersistAtomsStorage.incTimeMillis(100L);
3445         PresenceNotifyEvent[] output1 = mPersistAtomsStorage.getPresenceNotifyEvent(50L);
3446         mPersistAtomsStorage.incTimeMillis(100L);
3447         PresenceNotifyEvent[] output2 = mPersistAtomsStorage.getPresenceNotifyEvent(50L);
3448 
3449         // First set of results should equal to file contents, second should be empty, corresponding
3450         // pull timestamp should be updated and saved
3451         assertProtoArrayEqualsIgnoringOrder(
3452                 new PresenceNotifyEvent[] {mPresenceNotifyEvent1, mPresenceNotifyEvent2}, output1);
3453         assertProtoArrayEquals(new PresenceNotifyEvent[0], output2);
3454         assertEquals(
3455                 START_TIME_MILLIS + 200L,
3456                 mPersistAtomsStorage.getAtomsProto().presenceNotifyEventPullTimestampMillis);
3457         InOrder inOrder = inOrder(mTestFileOutputStream);
3458         assertEquals(
3459                 START_TIME_MILLIS + 100L,
3460                 getAtomsWritten(inOrder).presenceNotifyEventPullTimestampMillis);
3461         assertEquals(
3462                 START_TIME_MILLIS + 200L,
3463                 getAtomsWritten(inOrder).presenceNotifyEventPullTimestampMillis);
3464         inOrder.verifyNoMoreInteractions();
3465     }
3466 
3467     @Test
3468     @SmallTest
addSipTransportFeatureTag_emptyProto()3469     public void addSipTransportFeatureTag_emptyProto() throws Exception {
3470         // verify add atom into new file
3471         createEmptyTestFile();
3472         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3473         mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats1);
3474         mPersistAtomsStorage.incTimeMillis(100L);
3475         verifyCurrentStateSavedToFileOnce();
3476 
3477         SipTransportFeatureTagStats[] outputs =
3478                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3479         assertProtoArrayEquals(
3480                 new SipTransportFeatureTagStats[] {mSipTransportFeatureTagStats1}, outputs);
3481     }
3482 
3483     @Test
3484     @SmallTest
addSipTransportFeatureTagStats_withExistingEntries()3485     public void addSipTransportFeatureTagStats_withExistingEntries() throws Exception {
3486         // verify add atom on existing atom already stored
3487         createEmptyTestFile();
3488 
3489         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3490         //Add two different SipTransportFeatureTagStats.
3491         mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats1);
3492         mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats2);
3493         mPersistAtomsStorage.incTimeMillis(100L);
3494 
3495         // SipTransportFeatureTagStats should be added successfully
3496         verifyCurrentStateSavedToFileOnce();
3497         SipTransportFeatureTagStats[] outputs =
3498                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3499 
3500         assertProtoArrayEqualsIgnoringOrder(new SipTransportFeatureTagStats[]
3501                 {mSipTransportFeatureTagStats1, mSipTransportFeatureTagStats2}, outputs);
3502     }
3503 
3504     @Test
3505     @SmallTest
addSipTransportFeatureTagStats_tooManyEntries()3506     public void addSipTransportFeatureTagStats_tooManyEntries() throws Exception {
3507         // verify add atom excess MAX count (100)
3508         createEmptyTestFile();
3509 
3510         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3511 
3512         // Try to add 26 stats where MAX is 25
3513         int max = 26;
3514         SipTransportFeatureTagStats[] overMaxSipTransportFeatureTagStats =
3515                 new SipTransportFeatureTagStats[max];
3516 
3517         for (int i = 0; i < max; i++) {
3518             overMaxSipTransportFeatureTagStats[i] = copyOf(mSipTransportFeatureTagStats1);
3519             overMaxSipTransportFeatureTagStats[i].sipTransportDeniedReason = i;
3520             mPersistAtomsStorage
3521                     .addSipTransportFeatureTagStats(overMaxSipTransportFeatureTagStats[i]);
3522             mPersistAtomsStorage.incTimeMillis(100L);
3523         }
3524 
3525         mPersistAtomsStorage
3526                 .addSipTransportFeatureTagStats(mSipTransportFeatureTagStats2);
3527         verifyCurrentStateSavedToFileOnce();
3528 
3529         SipTransportFeatureTagStats[] outputs =
3530                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3531 
3532         // The last added SipTransportFeatureTagStat remains
3533         // and two old stats should be removed
3534         assertHasStats(outputs, overMaxSipTransportFeatureTagStats, max - 2);
3535         assertHasStats(outputs, mSipTransportFeatureTagStats2, 1);
3536     }
3537 
3538     @Test
3539     @SmallTest
addSipTransportFeatureTagStats_updateExistingEntries()3540     public void addSipTransportFeatureTagStats_updateExistingEntries() throws Exception {
3541         // verify count
3542         createTestFile(START_TIME_MILLIS);
3543 
3544         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3545         mPersistAtomsStorage.addSipTransportFeatureTagStats(copyOf(mSipTransportFeatureTagStats1));
3546         mPersistAtomsStorage.incTimeMillis(100L);
3547         verifyCurrentStateSavedToFileOnce();
3548 
3549         // SipTransportFeatureTag's durations should be doubled
3550         SipTransportFeatureTagStats newSipTransportFeatureTagStats1 =
3551                 copyOf(mSipTransportFeatureTagStats1);
3552         newSipTransportFeatureTagStats1.associatedMillis *= 2;
3553 
3554         SipTransportFeatureTagStats[] outputs =
3555                 mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
3556 
3557         assertProtoArrayEqualsIgnoringOrder(
3558                 new SipTransportFeatureTagStats[] {
3559                         newSipTransportFeatureTagStats1,
3560                         mSipTransportFeatureTagStats2
3561                 }, outputs);
3562     }
3563 
3564     @Test
3565     @SmallTest
getSipTransportFeatureTagStats_tooFrequent()3566     public void getSipTransportFeatureTagStats_tooFrequent() throws Exception {
3567         // verify get frequently
3568         createTestFile(START_TIME_MILLIS);
3569 
3570         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3571         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
3572 
3573         SipTransportFeatureTagStats[] outputs =
3574                 mPersistAtomsStorage.getSipTransportFeatureTagStats(100L);
3575 
3576         // Should be denied
3577         assertNull(outputs);
3578     }
3579 
3580     @Test
3581     @SmallTest
getSipTransportFeatureTagStats_withSavedAtoms()3582     public void getSipTransportFeatureTagStats_withSavedAtoms() throws Exception {
3583         // verify last get time after get atoms
3584         createTestFile(START_TIME_MILLIS);
3585 
3586         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3587         mPersistAtomsStorage.incTimeMillis(100L);
3588 
3589         SipTransportFeatureTagStats[] output1 =
3590                 mPersistAtomsStorage.getSipTransportFeatureTagStats(50L);
3591         mPersistAtomsStorage.incTimeMillis(100L);
3592         SipTransportFeatureTagStats[] output2 =
3593                 mPersistAtomsStorage.getSipTransportFeatureTagStats(50L);
3594 
3595         // First set of results should equal to file contents, second should be empty, corresponding
3596         // pull timestamp should be updated and saved
3597         assertProtoArrayEqualsIgnoringOrder(
3598                 new SipTransportFeatureTagStats[] {
3599                         mSipTransportFeatureTagStats1,
3600                         mSipTransportFeatureTagStats2
3601                 }, output1);
3602         assertProtoArrayEquals(new SipTransportFeatureTagStats[0], output2);
3603         assertEquals(START_TIME_MILLIS + 200L,
3604                 mPersistAtomsStorage.getAtomsProto()
3605                         .sipTransportFeatureTagStatsPullTimestampMillis);
3606 
3607         InOrder inOrder = inOrder(mTestFileOutputStream);
3608         assertEquals(START_TIME_MILLIS + 100L,
3609                 getAtomsWritten(inOrder).sipTransportFeatureTagStatsPullTimestampMillis);
3610         assertEquals(START_TIME_MILLIS + 200L,
3611                 getAtomsWritten(inOrder).sipTransportFeatureTagStatsPullTimestampMillis);
3612         inOrder.verifyNoMoreInteractions();
3613     }
3614 
3615     @Test
3616     @SmallTest
addSipDelegateStats_emptyProto()3617     public void addSipDelegateStats_emptyProto() throws Exception {
3618         // verify add atom into new file
3619         createEmptyTestFile();
3620 
3621         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3622         mPersistAtomsStorage.addSipDelegateStats(mSipDelegateStats1);
3623         mPersistAtomsStorage.incTimeMillis(100L);
3624         verifyCurrentStateSavedToFileOnce();
3625 
3626         SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(0L);
3627         assertProtoArrayEquals(new SipDelegateStats[] {mSipDelegateStats1}, outputs);
3628     }
3629 
3630     @Test
3631     @SmallTest
addSipDelegateStats_withExistingEntries()3632     public void addSipDelegateStats_withExistingEntries() throws Exception {
3633         // verify add atom on existing atom already stored
3634         createEmptyTestFile();
3635 
3636         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3637         mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats1));
3638         mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats2));
3639         mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats3));
3640         mPersistAtomsStorage.incTimeMillis(100L);
3641         // Three SipDelegateStats should be added successfully
3642         verifyCurrentStateSavedToFileOnce();
3643 
3644         SipDelegateStats[] outputs =
3645                 mPersistAtomsStorage.getSipDelegateStats(0L);
3646 
3647         assertProtoArrayEqualsIgnoringOrder(
3648                 new SipDelegateStats[] {mSipDelegateStats1, mSipDelegateStats2, mSipDelegateStats3},
3649                 outputs);
3650     }
3651 
3652     @Test
3653     @SmallTest
addSipDelegateStats_tooManyEntries()3654     public void addSipDelegateStats_tooManyEntries() throws Exception {
3655         // verify add atom excess MAX count
3656         createEmptyTestFile();
3657 
3658         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3659 
3660         // Try to add 11 stats where MAX is 10
3661         int max = 11;
3662         SipDelegateStats[] overMaxSipDelegateStats = new SipDelegateStats[max];
3663         for (int i = 0; i < max; i++) {
3664             overMaxSipDelegateStats[i] = copyOf(mSipDelegateStats1);
3665             mPersistAtomsStorage
3666                     .addSipDelegateStats(overMaxSipDelegateStats[i]);
3667             mPersistAtomsStorage.incTimeMillis(100L);
3668         }
3669         mPersistAtomsStorage.addSipDelegateStats(mSipDelegateStats3);
3670         verifyCurrentStateSavedToFileOnce();
3671 
3672         SipDelegateStats[] outputs =
3673                 mPersistAtomsStorage.getSipDelegateStats(0L);
3674 
3675         // The last added SipDelegate remains
3676         // and two old stats should be removed
3677         assertHasStats(outputs, overMaxSipDelegateStats, max - 2);
3678         assertHasStats(outputs, mSipDelegateStats3, 1);
3679     }
3680 
3681     @Test
3682     @SmallTest
addSipDelegateStats_updateExistingEntries()3683     public void addSipDelegateStats_updateExistingEntries() throws Exception {
3684         // verify count
3685         createTestFile(START_TIME_MILLIS);
3686 
3687         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3688         SipDelegateStats newSipDelegateStats3 = copyOf(mSipDelegateStats3);
3689         newSipDelegateStats3.destroyReason =
3690                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD;
3691         mPersistAtomsStorage.addSipDelegateStats(newSipDelegateStats3);
3692         mPersistAtomsStorage.incTimeMillis(100L);
3693 
3694         SipDelegateStats newSipDelegateStats1 = copyOf(mSipDelegateStats1);
3695         newSipDelegateStats1.destroyReason =
3696                 SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP;
3697         mPersistAtomsStorage.addSipDelegateStats(newSipDelegateStats1);
3698         mPersistAtomsStorage.incTimeMillis(100L);
3699         verifyCurrentStateSavedToFileOnce();
3700 
3701         SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(0L);
3702 
3703         assertProtoArrayEqualsIgnoringOrder(
3704                 new SipDelegateStats[] {mSipDelegateStats2, mSipDelegateStats3,
3705                         newSipDelegateStats3, newSipDelegateStats1}, outputs);
3706     }
3707 
3708     @Test
3709     @SmallTest
getSipDelegateStats_tooFrequent()3710     public void getSipDelegateStats_tooFrequent() throws Exception {
3711         // verify get frequently
3712         createTestFile(START_TIME_MILLIS);
3713 
3714         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3715         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
3716 
3717         SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(100L);
3718         // Should be denied
3719         assertNull(outputs);
3720     }
3721 
3722     @Test
3723     @SmallTest
getSipDelegateStats_withSavedAtoms()3724     public void getSipDelegateStats_withSavedAtoms() throws Exception {
3725         // verify last get time after get atoms
3726         createTestFile(START_TIME_MILLIS);
3727 
3728         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3729         mPersistAtomsStorage.incTimeMillis(100L);
3730 
3731         SipDelegateStats[] output1 = mPersistAtomsStorage.getSipDelegateStats(50L);
3732         mPersistAtomsStorage.incTimeMillis(100L);
3733         SipDelegateStats[] output2 = mPersistAtomsStorage.getSipDelegateStats(50L);
3734 
3735         // First set of results should equal to file contents, second should be empty, corresponding
3736         // pull timestamp should be updated and saved
3737         assertProtoArrayEqualsIgnoringOrder(
3738                 new SipDelegateStats[] {
3739                         mSipDelegateStats2,
3740                         mSipDelegateStats3}, output1);
3741         assertProtoArrayEquals(new SipDelegateStats[0], output2);
3742         assertEquals(
3743                 START_TIME_MILLIS + 200L,
3744                 mPersistAtomsStorage.getAtomsProto().sipDelegateStatsPullTimestampMillis);
3745         InOrder inOrder = inOrder(mTestFileOutputStream);
3746         assertEquals(
3747                 START_TIME_MILLIS + 100L,
3748                 getAtomsWritten(inOrder).sipDelegateStatsPullTimestampMillis);
3749         assertEquals(
3750                 START_TIME_MILLIS + 200L,
3751                 getAtomsWritten(inOrder).sipDelegateStatsPullTimestampMillis);
3752         inOrder.verifyNoMoreInteractions();
3753     }
3754 
3755     @Test
3756     @SmallTest
addGbaEvent_emptyProto()3757     public void addGbaEvent_emptyProto() throws Exception {
3758         createEmptyTestFile();
3759         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3760         mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
3761         mPersistAtomsStorage.incTimeMillis(100L);
3762 
3763         // gba event should be added successfully
3764         verifyCurrentStateSavedToFileOnce();
3765         GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
3766         assertProtoArrayEquals(new GbaEvent[] {mGbaEvent1}, stats);
3767     }
3768 
3769     @Test
3770     @SmallTest
addGbaEvent_withExistingEntries()3771     public void addGbaEvent_withExistingEntries() throws Exception {
3772         createEmptyTestFile();
3773         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3774         mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
3775         mPersistAtomsStorage.incTimeMillis(100L);
3776         mPersistAtomsStorage.addGbaEvent(mGbaEvent2);
3777         mPersistAtomsStorage.incTimeMillis(100L);
3778 
3779         // gba event1, gba event2 should be added successfully
3780         verifyCurrentStateSavedToFileOnce();
3781         GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
3782         assertProtoArrayEqualsIgnoringOrder(
3783                 new GbaEvent[] {mGbaEvent1, mGbaEvent2}, stats);
3784     }
3785 
3786     @Test
3787     @SmallTest
addGbaEvent_tooManyEntries()3788     public void addGbaEvent_tooManyEntries() throws Exception {
3789         createEmptyTestFile();
3790 
3791         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3792 
3793         // Add 11 stats, but max is 10
3794         for (int i = 0; i < 11; i++) {
3795             mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
3796             mPersistAtomsStorage.incTimeMillis(100L);
3797         }
3798         mPersistAtomsStorage.addGbaEvent(mGbaEvent2);
3799 
3800         verifyCurrentStateSavedToFileOnce();
3801         GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
3802         assertHasStatsAndCount(stats, mGbaEvent1, 11);
3803         assertHasStatsAndCount(stats, mGbaEvent2, 1);
3804     }
3805 
3806     @Test
3807     @SmallTest
addGbaEvent_updateExistingEntries()3808     public void addGbaEvent_updateExistingEntries() throws Exception {
3809         createTestFile(START_TIME_MILLIS);
3810         GbaEvent newStats = copyOf(mGbaEvent1);
3811         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3812 
3813         mPersistAtomsStorage.addGbaEvent(copyOf(mGbaEvent1));
3814         mPersistAtomsStorage.incTimeMillis(100L);
3815 
3816         // mGbaEvent1's count should be doubled
3817         verifyCurrentStateSavedToFileOnce();
3818         GbaEvent[] stats =
3819                 mPersistAtomsStorage.getGbaEvent(0L);
3820         newStats.count *= 2;
3821         assertProtoArrayEqualsIgnoringOrder(new GbaEvent[] {mGbaEvent2, newStats}, stats);
3822     }
3823 
3824     @Test
3825     @SmallTest
addSipMessageResponse_emptyProto()3826     public void addSipMessageResponse_emptyProto() throws Exception {
3827         createEmptyTestFile();
3828         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3829         mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
3830         mPersistAtomsStorage.incTimeMillis(100L);
3831 
3832         verifyCurrentStateSavedToFileOnce();
3833         SipMessageResponse[] expected = mPersistAtomsStorage.getSipMessageResponse(0L);
3834         assertProtoArrayEquals(new SipMessageResponse[] {mSipMessageResponse1}, expected);
3835     }
3836 
3837     @Test
3838     @SmallTest
addSipMessageResponse_withExistingEntries()3839     public void addSipMessageResponse_withExistingEntries() throws Exception {
3840         createEmptyTestFile();
3841         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3842         mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
3843         mPersistAtomsStorage.incTimeMillis(100L);
3844         mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse2);
3845         mPersistAtomsStorage.incTimeMillis(100L);
3846 
3847         verifyCurrentStateSavedToFileOnce();
3848         SipMessageResponse[] expected =
3849                 new SipMessageResponse[] {mSipMessageResponse1, mSipMessageResponse2};
3850 
3851         assertProtoArrayEqualsIgnoringOrder(
3852                 expected, mPersistAtomsStorage.getSipMessageResponse(0L));
3853     }
3854 
3855     @Test
3856     @SmallTest
addSipMessageResponse_tooManyEntries()3857     public void addSipMessageResponse_tooManyEntries() throws Exception {
3858         createEmptyTestFile();
3859         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3860 
3861         // Store 11 same atoms, but only 1 atoms stored with count 11
3862         for (int i = 0; i < 11; i++) {
3863             mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
3864             mPersistAtomsStorage.incTimeMillis(100L);
3865         }
3866         // Store 1 different atom and count 1
3867         mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse2);
3868 
3869         verifyCurrentStateSavedToFileOnce();
3870         SipMessageResponse[] result = mPersistAtomsStorage.getSipMessageResponse(0L);
3871 
3872         // First atom has count 11, the other has 1
3873         assertHasStats(result, mSipMessageResponse1, 11);
3874         assertHasStats(result, mSipMessageResponse2, 1);
3875     }
3876 
3877     @Test
3878     @SmallTest
addSipMessageResponse_updateExistingEntries()3879     public void addSipMessageResponse_updateExistingEntries() throws Exception {
3880         createTestFile(START_TIME_MILLIS);
3881         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3882         mPersistAtomsStorage.addSipMessageResponse(copyOf(mSipMessageResponse2));
3883         mPersistAtomsStorage.incTimeMillis(100L);
3884         verifyCurrentStateSavedToFileOnce();
3885 
3886         SipMessageResponse[] outputs = mPersistAtomsStorage.getSipMessageResponse(0L);
3887         SipMessageResponse newSipMessageResponse = copyOf(mSipMessageResponse2);
3888         newSipMessageResponse.count *= 2;
3889         assertProtoArrayEqualsIgnoringOrder(
3890                 new SipMessageResponse[] {mSipMessageResponse1, newSipMessageResponse}, outputs);
3891     }
3892 
3893     @Test
3894     @SmallTest
addCompleteSipTransportSession_emptyProto()3895     public void addCompleteSipTransportSession_emptyProto() throws Exception {
3896         createEmptyTestFile();
3897         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3898         mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
3899         mPersistAtomsStorage.incTimeMillis(100L);
3900 
3901         verifyCurrentStateSavedToFileOnce();
3902         SipTransportSession[] expected = mPersistAtomsStorage.getSipTransportSession(0L);
3903         assertProtoArrayEquals(new SipTransportSession[] {mSipTransportSession1}, expected);
3904     }
3905 
3906     @Test
3907     @SmallTest
addCompleteSipTransportSession_withExistingEntries()3908     public void addCompleteSipTransportSession_withExistingEntries() throws Exception {
3909         createEmptyTestFile();
3910         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3911         mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
3912         mPersistAtomsStorage.incTimeMillis(100L);
3913         mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession2);
3914         mPersistAtomsStorage.incTimeMillis(100L);
3915 
3916         verifyCurrentStateSavedToFileOnce();
3917         SipTransportSession[] expected =
3918                 new SipTransportSession[] {mSipTransportSession1, mSipTransportSession2};
3919 
3920         assertProtoArrayEqualsIgnoringOrder(
3921                 expected, mPersistAtomsStorage.getSipTransportSession(0L));
3922     }
3923 
3924     @Test
3925     @SmallTest
addCompleteSipTransportSession_tooManyEntries()3926     public void addCompleteSipTransportSession_tooManyEntries() throws Exception {
3927         createEmptyTestFile();
3928         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3929 
3930         // Store 11 same atoms, but only 1 atoms stored with count 11
3931         for (int i = 0; i < 11; i++) {
3932             mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
3933             mPersistAtomsStorage.incTimeMillis(100L);
3934         }
3935         // Store 1 different atom and count 1
3936         mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession2);
3937 
3938         verifyCurrentStateSavedToFileOnce();
3939         SipTransportSession[] result = mPersistAtomsStorage.getSipTransportSession(0L);
3940 
3941         // First atom has count 11, the other has 1
3942         assertHasStats(result, mSipTransportSession1, 11);
3943         assertHasStats(result, mSipTransportSession2, 1);
3944     }
3945 
3946     @Test
3947     @SmallTest
addCompleteSipTransportSession_updateExistingEntries()3948     public void addCompleteSipTransportSession_updateExistingEntries() throws Exception {
3949         createTestFile(START_TIME_MILLIS);
3950         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3951         mPersistAtomsStorage.addCompleteSipTransportSession(copyOf(mSipTransportSession2));
3952         mPersistAtomsStorage.incTimeMillis(100L);
3953         verifyCurrentStateSavedToFileOnce();
3954 
3955         SipTransportSession[] outputs = mPersistAtomsStorage.getSipTransportSession(0L);
3956         SipTransportSession newSipTransportSession = copyOf(mSipTransportSession2);
3957         newSipTransportSession.sessionCount *= 2;
3958         newSipTransportSession.endedGracefullyCount *= 2;
3959         assertProtoArrayEqualsIgnoringOrder(
3960                 new SipTransportSession[] {mSipTransportSession1,
3961                         newSipTransportSession}, outputs);
3962     }
3963 
3964     @Test
3965     @SmallTest
getUnmeteredNetworks_noExistingEntry()3966     public void getUnmeteredNetworks_noExistingEntry() throws Exception {
3967         createTestFile(START_TIME_MILLIS);
3968         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3969         InOrder inOrder = inOrder(mTestFileOutputStream);
3970 
3971         assertEquals(0L, mPersistAtomsStorage.getUnmeteredNetworks(1, 0));
3972 
3973         inOrder.verifyNoMoreInteractions();
3974     }
3975 
3976     @Test
3977     @SmallTest
getUnmeteredNetworks()3978     public void getUnmeteredNetworks() throws Exception {
3979         createTestFile(START_TIME_MILLIS);
3980         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
3981         InOrder inOrder = inOrder(mTestFileOutputStream);
3982 
3983         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
3984         inOrder.verify(mTestFileOutputStream, times(1))
3985                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
3986         inOrder.verify(mTestFileOutputStream, times(1)).close();
3987         inOrder.verifyNoMoreInteractions();
3988 
3989         assertEquals(NETWORK_TYPE_BITMASK_GPRS, mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
3990         inOrder.verify(mTestFileOutputStream, times(1))
3991                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
3992         inOrder.verify(mTestFileOutputStream, times(1)).close();
3993         inOrder.verifyNoMoreInteractions();
3994 
3995         assertEquals(0L, mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
3996         inOrder.verifyNoMoreInteractions();
3997     }
3998 
3999     @Test
4000     @SmallTest
getUnmeteredNetworks_carrierIdMismatch()4001     public void getUnmeteredNetworks_carrierIdMismatch() throws Exception {
4002         createTestFile(START_TIME_MILLIS);
4003         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4004         InOrder inOrder = inOrder(mTestFileOutputStream);
4005 
4006         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
4007         inOrder.verify(mTestFileOutputStream, times(1))
4008                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4009         inOrder.verify(mTestFileOutputStream, times(1)).close();
4010         inOrder.verifyNoMoreInteractions();
4011 
4012         assertEquals(0L, mPersistAtomsStorage.getUnmeteredNetworks(0, 1));
4013         inOrder.verify(mTestFileOutputStream, times(1))
4014                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4015         inOrder.verify(mTestFileOutputStream, times(1)).close();
4016         inOrder.verifyNoMoreInteractions();
4017 
4018         assertEquals(0L, mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
4019         inOrder.verifyNoMoreInteractions();
4020     }
4021 
4022     @Test
4023     @SmallTest
addUnmeteredNetworks()4024     public void addUnmeteredNetworks() throws Exception {
4025         createTestFile(START_TIME_MILLIS);
4026         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4027         InOrder inOrder = inOrder(mTestFileOutputStream);
4028 
4029         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
4030         inOrder.verify(mTestFileOutputStream, times(1))
4031                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4032         inOrder.verify(mTestFileOutputStream, times(1)).close();
4033         inOrder.verifyNoMoreInteractions();
4034 
4035         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GSM);
4036         inOrder.verify(mTestFileOutputStream, times(1))
4037                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4038         inOrder.verify(mTestFileOutputStream, times(1)).close();
4039         inOrder.verifyNoMoreInteractions();
4040 
4041         assertEquals(
4042                 NETWORK_TYPE_BITMASK_GPRS | NETWORK_TYPE_BITMASK_GSM,
4043                 mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
4044         inOrder.verify(mTestFileOutputStream, times(1))
4045                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4046         inOrder.verify(mTestFileOutputStream, times(1)).close();
4047         inOrder.verifyNoMoreInteractions();
4048 
4049         assertEquals(0, mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
4050         inOrder.verifyNoMoreInteractions();
4051 
4052         mPersistAtomsStorage.addUnmeteredNetworks(1, 2, NETWORK_TYPE_BITMASK_GPRS);
4053         inOrder.verify(mTestFileOutputStream, times(1))
4054                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4055         inOrder.verify(mTestFileOutputStream, times(1)).close();
4056         inOrder.verifyNoMoreInteractions();
4057 
4058         mPersistAtomsStorage.addUnmeteredNetworks(1, 2, NETWORK_TYPE_BITMASK_GSM);
4059         inOrder.verify(mTestFileOutputStream, times(1))
4060                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4061         inOrder.verify(mTestFileOutputStream, times(1)).close();
4062         inOrder.verifyNoMoreInteractions();
4063 
4064         assertEquals(
4065                 NETWORK_TYPE_BITMASK_GPRS | NETWORK_TYPE_BITMASK_GSM,
4066                 mPersistAtomsStorage.getUnmeteredNetworks(1, 2));
4067         inOrder.verify(mTestFileOutputStream, times(1))
4068                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4069         inOrder.verify(mTestFileOutputStream, times(1)).close();
4070         inOrder.verifyNoMoreInteractions();
4071 
4072         assertEquals(0, mPersistAtomsStorage.getUnmeteredNetworks(1, 2));
4073         inOrder.verifyNoMoreInteractions();
4074     }
4075 
4076     @Test
4077     @SmallTest
addUnmeteredNetworks_carrierIdMismatch()4078     public void addUnmeteredNetworks_carrierIdMismatch() throws Exception {
4079         createTestFile(START_TIME_MILLIS);
4080         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4081         InOrder inOrder = inOrder(mTestFileOutputStream);
4082 
4083         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
4084         inOrder.verify(mTestFileOutputStream, times(1))
4085                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4086         inOrder.verify(mTestFileOutputStream, times(1)).close();
4087         inOrder.verifyNoMoreInteractions();
4088 
4089         mPersistAtomsStorage.addUnmeteredNetworks(0, 1, NETWORK_TYPE_BITMASK_GSM);
4090         inOrder.verify(mTestFileOutputStream, times(1))
4091                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4092         inOrder.verify(mTestFileOutputStream, times(1)).close();
4093         inOrder.verifyNoMoreInteractions();
4094 
4095         assertEquals(NETWORK_TYPE_BITMASK_GSM, mPersistAtomsStorage.getUnmeteredNetworks(0, 1));
4096         inOrder.verify(mTestFileOutputStream, times(1))
4097                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4098         inOrder.verify(mTestFileOutputStream, times(1)).close();
4099         inOrder.verifyNoMoreInteractions();
4100 
4101         assertEquals(0L, mPersistAtomsStorage.getUnmeteredNetworks(0, 1));
4102         inOrder.verifyNoMoreInteractions();
4103     }
4104 
4105     @Test
4106     @SmallTest
addUnmeteredNetworks_sameBitmask()4107     public void addUnmeteredNetworks_sameBitmask() throws Exception {
4108         createTestFile(START_TIME_MILLIS);
4109         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4110         InOrder inOrder = inOrder(mTestFileOutputStream);
4111 
4112         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
4113         inOrder.verify(mTestFileOutputStream, times(1))
4114                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4115         inOrder.verify(mTestFileOutputStream, times(1)).close();
4116         inOrder.verifyNoMoreInteractions();
4117 
4118         mPersistAtomsStorage.addUnmeteredNetworks(0, 0, NETWORK_TYPE_BITMASK_GPRS);
4119         inOrder.verifyNoMoreInteractions();
4120 
4121         assertEquals(NETWORK_TYPE_BITMASK_GPRS, mPersistAtomsStorage.getUnmeteredNetworks(0, 0));
4122         inOrder.verify(mTestFileOutputStream, times(1))
4123                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
4124         inOrder.verify(mTestFileOutputStream, times(1)).close();
4125         inOrder.verifyNoMoreInteractions();
4126     }
4127 
4128     @Test
addIncomingSms_emptyProto()4129     public void addIncomingSms_emptyProto() throws Exception {
4130         createEmptyTestFile();
4131 
4132         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4133         mPersistAtomsStorage.addIncomingSms(mIncomingSms1);
4134         mPersistAtomsStorage.incTimeMillis(100L);
4135 
4136         // IncomingSms should be added successfully, changes should be saved.
4137         verifyCurrentStateSavedToFileOnce();
4138         IncomingSms[] expectedList = new IncomingSms[] {mIncomingSms1};
4139         assertProtoArrayEquals(expectedList, mPersistAtomsStorage.getIncomingSms(0L));
4140     }
4141 
4142     @Test
addIncomingSms_withExistingEntries()4143     public void addIncomingSms_withExistingEntries() throws Exception {
4144         createEmptyTestFile();
4145 
4146         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4147         mPersistAtomsStorage.addIncomingSms(mIncomingSms1);
4148         mPersistAtomsStorage.addIncomingSms(mIncomingSms2);
4149         mPersistAtomsStorage.incTimeMillis(100L);
4150 
4151         // IncomingSms should be added successfully.
4152         verifyCurrentStateSavedToFileOnce();
4153         IncomingSms[] expectedList = new IncomingSms[] {mIncomingSms1, mIncomingSms2};
4154         assertProtoArrayEqualsIgnoringOrder(expectedList, mPersistAtomsStorage.getIncomingSms(0L));
4155     }
4156 
4157     @Test
getIncomingSms_tooFrequent()4158     public void getIncomingSms_tooFrequent() throws Exception {
4159         createTestFile(START_TIME_MILLIS);
4160 
4161         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4162         // Pull interval less than minimum.
4163         mPersistAtomsStorage.incTimeMillis(50L);
4164         IncomingSms[] outgoingShortCodeSmsList = mPersistAtomsStorage.getIncomingSms(100L);
4165         // Should be denied.
4166         assertNull(outgoingShortCodeSmsList);
4167     }
4168 
4169     @Test
addOutgoingSms_emptyProto()4170     public void addOutgoingSms_emptyProto() throws Exception {
4171         createEmptyTestFile();
4172 
4173         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4174         mPersistAtomsStorage.addOutgoingSms(mOutgoingSms1);
4175         mPersistAtomsStorage.incTimeMillis(100L);
4176 
4177         // OutgoingSms should be added successfully, changes should be saved.
4178         verifyCurrentStateSavedToFileOnce();
4179         OutgoingSms[] expectedList = new OutgoingSms[] {mOutgoingSms1};
4180         assertProtoArrayEquals(expectedList, mPersistAtomsStorage.getOutgoingSms(0L));
4181     }
4182 
4183     @Test
addOutgoingSms_withExistingEntries()4184     public void addOutgoingSms_withExistingEntries() throws Exception {
4185         createEmptyTestFile();
4186 
4187         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4188         mPersistAtomsStorage.addOutgoingSms(mOutgoingSms1);
4189         mPersistAtomsStorage.addOutgoingSms(mOutgoingSms2);
4190         mPersistAtomsStorage.incTimeMillis(100L);
4191 
4192         // OutgoingSms should be added successfully.
4193         verifyCurrentStateSavedToFileOnce();
4194         OutgoingSms[] expectedList = new OutgoingSms[] {mOutgoingSms1, mOutgoingSms2};
4195         assertProtoArrayEqualsIgnoringOrder(expectedList, mPersistAtomsStorage.getOutgoingSms(0L));
4196     }
4197 
4198     @Test
getOutgoingSms_tooFrequent()4199     public void getOutgoingSms_tooFrequent() throws Exception {
4200         createTestFile(START_TIME_MILLIS);
4201 
4202         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4203         // Pull interval less than minimum.
4204         mPersistAtomsStorage.incTimeMillis(50L);
4205         OutgoingSms[] outgoingShortCodeSmsList = mPersistAtomsStorage.getOutgoingSms(100L);
4206         // Should be denied.
4207         assertNull(outgoingShortCodeSmsList);
4208     }
4209 
4210     @Test
addOutgoingShortCodeSms_emptyProto()4211     public void addOutgoingShortCodeSms_emptyProto() throws Exception {
4212         createEmptyTestFile();
4213 
4214         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4215         mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
4216         mPersistAtomsStorage.incTimeMillis(100L);
4217 
4218         // OutgoingShortCodeSms should be added successfully, changes should be saved.
4219         verifyCurrentStateSavedToFileOnce();
4220         OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1};
4221         assertProtoArrayEquals(expectedList,
4222                 mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
4223     }
4224 
4225     @Test
addOutgoingShortCodeSms_withExistingEntries()4226     public void addOutgoingShortCodeSms_withExistingEntries() throws Exception {
4227         createEmptyTestFile();
4228 
4229         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4230         mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
4231         mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms2);
4232         mPersistAtomsStorage.incTimeMillis(100L);
4233 
4234         // OutgoingShortCodeSms should be added successfully.
4235         verifyCurrentStateSavedToFileOnce();
4236         OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1,
4237                 mOutgoingShortCodeSms2};
4238         assertProtoArrayEqualsIgnoringOrder(expectedList,
4239                 mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
4240     }
4241 
4242     @Test
addOutgoingShortCodeSms_updateExistingEntries()4243     public void addOutgoingShortCodeSms_updateExistingEntries() throws Exception {
4244         createTestFile(START_TIME_MILLIS);
4245 
4246         // Add copy of mOutgoingShortCodeSms1.
4247         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4248         mPersistAtomsStorage.addOutgoingShortCodeSms(copyOf(mOutgoingShortCodeSms1));
4249         mPersistAtomsStorage.incTimeMillis(100L);
4250 
4251         // mOutgoingShortCodeSms1's short code sms count should be increased by 1.
4252         verifyCurrentStateSavedToFileOnce();
4253         OutgoingShortCodeSms newOutgoingShortCodeSms1 = copyOf(mOutgoingShortCodeSms1);
4254         newOutgoingShortCodeSms1.shortCodeSmsCount = 2;
4255         OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {newOutgoingShortCodeSms1,
4256                 mOutgoingShortCodeSms2};
4257         assertProtoArrayEqualsIgnoringOrder(expectedList,
4258                 mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
4259     }
4260 
4261     @Test
addOutgoingShortCodeSms_tooManyEntries()4262     public void addOutgoingShortCodeSms_tooManyEntries() throws Exception {
4263         createEmptyTestFile();
4264 
4265         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4266 
4267         // Store mOutgoingShortCodeSms1 11 times.
4268         for (int i = 0; i < 11; i++) {
4269             mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
4270             mPersistAtomsStorage.incTimeMillis(100L);
4271         }
4272         // Store mOutgoingShortCodeSms2 1 time.
4273         mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms2);
4274 
4275         verifyCurrentStateSavedToFileOnce();
4276         OutgoingShortCodeSms[] result = mPersistAtomsStorage
4277                 .getOutgoingShortCodeSms(0L);
4278         assertHasStatsAndCount(result, mOutgoingShortCodeSms1, 11);
4279         assertHasStatsAndCount(result, mOutgoingShortCodeSms2, 1);
4280     }
4281 
4282     @Test
getOutgoingShortCodeSms_tooFrequent()4283     public void getOutgoingShortCodeSms_tooFrequent() throws Exception {
4284         createTestFile(START_TIME_MILLIS);
4285 
4286         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4287         // Pull interval less than minimum.
4288         mPersistAtomsStorage.incTimeMillis(50L);
4289         OutgoingShortCodeSms[] outgoingShortCodeSmsList = mPersistAtomsStorage
4290                 .getOutgoingShortCodeSms(100L);
4291         // Should be denied.
4292         assertNull(outgoingShortCodeSmsList);
4293     }
4294 
4295     @Test
getOutgoingShortCodeSms_withSavedAtoms()4296     public void getOutgoingShortCodeSms_withSavedAtoms() throws Exception {
4297         createTestFile(START_TIME_MILLIS);
4298 
4299         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4300         mPersistAtomsStorage.incTimeMillis(100L);
4301         OutgoingShortCodeSms[] outgoingShortCodeSmsList1 = mPersistAtomsStorage
4302                 .getOutgoingShortCodeSms(50L);
4303         mPersistAtomsStorage.incTimeMillis(100L);
4304         OutgoingShortCodeSms[] outgoingShortCodeSmsList2 = mPersistAtomsStorage
4305                 .getOutgoingShortCodeSms(50L);
4306 
4307         // First set of results should be equal to file contents.
4308         OutgoingShortCodeSms[] expectedOutgoingShortCodeSmsList =
4309                 new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1, mOutgoingShortCodeSms2};
4310         assertProtoArrayEqualsIgnoringOrder(expectedOutgoingShortCodeSmsList,
4311                 outgoingShortCodeSmsList1);
4312         // Second set of results should be empty.
4313         assertProtoArrayEquals(new OutgoingShortCodeSms[0], outgoingShortCodeSmsList2);
4314         // Corresponding pull timestamp should be updated and saved.
4315         assertEquals(START_TIME_MILLIS + 200L, mPersistAtomsStorage
4316                 .getAtomsProto().outgoingShortCodeSmsPullTimestampMillis);
4317         InOrder inOrder = inOrder(mTestFileOutputStream);
4318         assertEquals(START_TIME_MILLIS + 100L,
4319                 getAtomsWritten(inOrder).outgoingShortCodeSmsPullTimestampMillis);
4320         assertEquals(START_TIME_MILLIS + 200L,
4321                 getAtomsWritten(inOrder).outgoingShortCodeSmsPullTimestampMillis);
4322         inOrder.verifyNoMoreInteractions();
4323     }
4324 
4325     @Test
addSatelliteControllerStats_emptyProto()4326     public void addSatelliteControllerStats_emptyProto() throws Exception {
4327         createEmptyTestFile();
4328         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4329         mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController1);
4330         mPersistAtomsStorage.incTimeMillis(100L);
4331 
4332         // Service state and service switch should be added successfully
4333         verifyCurrentStateSavedToFileOnce();
4334         SatelliteController[] output =
4335                 mPersistAtomsStorage.getSatelliteControllerStats(0L);
4336         assertProtoArrayEquals(
4337                 new SatelliteController[] {mSatelliteController1}, output);
4338     }
4339 
4340     @Test
addSatelliteControllerStats_withExistingEntries()4341     public void addSatelliteControllerStats_withExistingEntries() throws Exception {
4342         createEmptyTestFile();
4343         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4344         mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController1);
4345         mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController2);
4346         mPersistAtomsStorage.incTimeMillis(100L);
4347 
4348         SatelliteController expected = new SatelliteController();
4349         expected.countOfSatelliteServiceEnablementsSuccess =
4350                 mSatelliteController1.countOfSatelliteServiceEnablementsSuccess
4351                         + mSatelliteController2.countOfSatelliteServiceEnablementsSuccess;
4352         expected.countOfSatelliteServiceEnablementsFail =
4353                 mSatelliteController1.countOfSatelliteServiceEnablementsFail
4354                         + mSatelliteController2.countOfSatelliteServiceEnablementsFail;
4355         expected.countOfOutgoingDatagramSuccess =
4356                 mSatelliteController1.countOfOutgoingDatagramSuccess
4357                         + mSatelliteController2.countOfOutgoingDatagramSuccess;
4358         expected.countOfOutgoingDatagramFail =
4359                 mSatelliteController1.countOfOutgoingDatagramFail
4360                         + mSatelliteController2.countOfOutgoingDatagramFail;
4361         expected.countOfIncomingDatagramSuccess =
4362                 mSatelliteController1.countOfIncomingDatagramSuccess
4363                         + mSatelliteController2.countOfIncomingDatagramSuccess;
4364         expected.countOfIncomingDatagramFail =
4365                 mSatelliteController1.countOfIncomingDatagramFail
4366                         + mSatelliteController2.countOfIncomingDatagramFail;
4367         expected.countOfDatagramTypeSosSmsSuccess =
4368                 mSatelliteController1.countOfDatagramTypeSosSmsSuccess
4369                         + mSatelliteController2.countOfDatagramTypeSosSmsSuccess;
4370         expected.countOfDatagramTypeSosSmsFail =
4371                 mSatelliteController1.countOfDatagramTypeSosSmsFail
4372                         + mSatelliteController2.countOfDatagramTypeSosSmsFail;
4373         expected.countOfDatagramTypeLocationSharingSuccess =
4374                 mSatelliteController1.countOfDatagramTypeLocationSharingSuccess
4375                         + mSatelliteController2.countOfDatagramTypeLocationSharingSuccess;
4376         expected.countOfDatagramTypeLocationSharingFail =
4377                 mSatelliteController1.countOfDatagramTypeLocationSharingFail
4378                         + mSatelliteController2.countOfDatagramTypeLocationSharingFail;
4379         expected.countOfProvisionSuccess =
4380                 mSatelliteController1.countOfProvisionSuccess
4381                         + mSatelliteController2.countOfProvisionSuccess;
4382         expected.countOfProvisionFail =
4383                 mSatelliteController1.countOfProvisionFail
4384                         + mSatelliteController2.countOfProvisionFail;
4385         expected.countOfDeprovisionSuccess =
4386                 mSatelliteController1.countOfDeprovisionSuccess
4387                         + mSatelliteController2.countOfDeprovisionSuccess;
4388         expected.countOfDeprovisionFail =
4389                 mSatelliteController1.countOfDeprovisionFail
4390                         + mSatelliteController2.countOfDeprovisionFail;
4391         expected.totalServiceUptimeSec =
4392                 mSatelliteController1.totalServiceUptimeSec
4393                         + mSatelliteController2.totalServiceUptimeSec;
4394         expected.totalBatteryConsumptionPercent =
4395                 mSatelliteController1.totalBatteryConsumptionPercent
4396                         + mSatelliteController2.totalBatteryConsumptionPercent;
4397         expected.totalBatteryChargedTimeSec =
4398                 mSatelliteController1.totalBatteryChargedTimeSec
4399                         + mSatelliteController2.totalBatteryChargedTimeSec;
4400         expected.countOfDemoModeSatelliteServiceEnablementsSuccess =
4401                 mSatelliteController1.countOfDemoModeSatelliteServiceEnablementsSuccess
4402                         + mSatelliteController2.countOfDemoModeSatelliteServiceEnablementsSuccess;
4403         expected.countOfDemoModeSatelliteServiceEnablementsFail =
4404                 mSatelliteController1.countOfDemoModeSatelliteServiceEnablementsFail
4405                         + mSatelliteController2.countOfDemoModeSatelliteServiceEnablementsFail;
4406         expected.countOfDemoModeOutgoingDatagramSuccess =
4407                 mSatelliteController1.countOfDemoModeOutgoingDatagramSuccess
4408                         + mSatelliteController2.countOfDemoModeOutgoingDatagramSuccess;
4409         expected.countOfDemoModeOutgoingDatagramFail =
4410                 mSatelliteController1.countOfDemoModeOutgoingDatagramFail
4411                         + mSatelliteController2.countOfDemoModeOutgoingDatagramFail;
4412         expected.countOfDemoModeIncomingDatagramSuccess =
4413                 mSatelliteController1.countOfDemoModeIncomingDatagramSuccess
4414                         + mSatelliteController2.countOfDemoModeIncomingDatagramSuccess;
4415         expected.countOfDemoModeIncomingDatagramFail =
4416                 mSatelliteController1.countOfDemoModeIncomingDatagramFail
4417                         + mSatelliteController2.countOfDemoModeIncomingDatagramFail;
4418         expected.countOfDatagramTypeKeepAliveSuccess =
4419                 mSatelliteController1.countOfDatagramTypeKeepAliveSuccess
4420                         + mSatelliteController2.countOfDatagramTypeKeepAliveSuccess;
4421         expected.countOfDatagramTypeKeepAliveFail =
4422                 mSatelliteController1.countOfDatagramTypeKeepAliveFail
4423                         + mSatelliteController2.countOfDatagramTypeKeepAliveFail;
4424 
4425         // Service state and service switch should be added successfully
4426         verifyCurrentStateSavedToFileOnce();
4427         SatelliteController[] output =
4428                 mPersistAtomsStorage.getSatelliteControllerStats(0L);
4429         assertHasStats(output, expected);
4430     }
4431 
4432     @Test
getSatelliteControllerStats_tooFrequent()4433     public void getSatelliteControllerStats_tooFrequent() throws Exception {
4434         createTestFile(START_TIME_MILLIS);
4435 
4436         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4437         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4438         SatelliteController[] output =
4439                 mPersistAtomsStorage.getSatelliteControllerStats(100L);
4440 
4441         // Should be denied
4442         assertNull(output);
4443     }
4444 
4445     @Test
addSatelliteSessionStats_emptyProto()4446     public void addSatelliteSessionStats_emptyProto() throws Exception {
4447         createEmptyTestFile();
4448         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4449         mPersistAtomsStorage.addSatelliteSessionStats(
4450                 mSatelliteSession1);
4451         mPersistAtomsStorage.incTimeMillis(100L);
4452 
4453         // Service state and service switch should be added successfully
4454         verifyCurrentStateSavedToFileOnce();
4455         SatelliteSession[] output =
4456                 mPersistAtomsStorage.getSatelliteSessionStats(0L);
4457         assertProtoArrayEquals(
4458                 new SatelliteSession[] {mSatelliteSession1}, output);
4459     }
4460 
4461     @Test
addSatelliteSessionStats_withExistingEntries()4462     public void addSatelliteSessionStats_withExistingEntries() throws Exception {
4463         createEmptyTestFile();
4464         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4465         mPersistAtomsStorage.addSatelliteSessionStats(
4466                 mSatelliteSession1);
4467         mPersistAtomsStorage.addSatelliteSessionStats(
4468                 mSatelliteSession2);
4469         mPersistAtomsStorage.incTimeMillis(100L);
4470 
4471         // Service state and service switch should be added successfully
4472         verifyCurrentStateSavedToFileOnce();
4473         SatelliteSession[] output =
4474                 mPersistAtomsStorage.getSatelliteSessionStats(0L);
4475         assertProtoArrayEqualsIgnoringOrder(
4476                 new SatelliteSession[] {
4477                         mSatelliteSession1, mSatelliteSession2},
4478                 output);
4479     }
4480 
4481     @Test
addSatelliteSessionStats_tooManyEntries()4482     public void addSatelliteSessionStats_tooManyEntries() throws Exception {
4483         createEmptyTestFile();
4484 
4485         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4486 
4487         // Store atoms up to maximum number + 1
4488         int maxCount = 15 + 1;
4489         for (int i = 0; i < maxCount; i++) {
4490             mPersistAtomsStorage
4491                     .addSatelliteSessionStats(
4492                             copyOf(mSatelliteSession1));
4493             mPersistAtomsStorage.incTimeMillis(100L);
4494         }
4495 
4496         // Store 1 different atom
4497         mPersistAtomsStorage
4498                 .addSatelliteSessionStats(mSatelliteSession2);
4499 
4500         verifyCurrentStateSavedToFileOnce();
4501 
4502         SatelliteSession[] result =
4503                 mPersistAtomsStorage.getSatelliteSessionStats(0L);
4504 
4505         // First atom has count 16, the other has 1
4506         assertHasStatsAndCount(result, mSatelliteSession1, 16);
4507         assertHasStatsAndCount(result, mSatelliteSession2, 1);
4508 
4509     }
4510 
4511     @Test
getSatelliteSessionStats_tooFrequent()4512     public void getSatelliteSessionStats_tooFrequent() throws Exception {
4513         createTestFile(START_TIME_MILLIS);
4514 
4515         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4516         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4517         SatelliteSession[] output =
4518                 mPersistAtomsStorage.getSatelliteSessionStats(100L);
4519 
4520         // Should be denied
4521         assertNull(output);
4522     }
4523 
4524 
4525 
4526     @Test
addSatelliteIncomingDatagramStats_emptyProto()4527     public void addSatelliteIncomingDatagramStats_emptyProto() throws Exception {
4528         createEmptyTestFile();
4529         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4530         mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram1);
4531         mPersistAtomsStorage.incTimeMillis(100L);
4532 
4533         // Service state and service switch should be added successfully
4534         verifyCurrentStateSavedToFileOnce();
4535         SatelliteIncomingDatagram[] output =
4536                 mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
4537         assertProtoArrayEquals(
4538                 new SatelliteIncomingDatagram[] {mSatelliteIncomingDatagram1}, output);
4539     }
4540 
4541     @Test
addSatelliteIncomingDatagramStats_withExistingEntries()4542     public void addSatelliteIncomingDatagramStats_withExistingEntries() throws Exception {
4543         createEmptyTestFile();
4544         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4545         mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram1);
4546         mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram2);
4547         mPersistAtomsStorage.incTimeMillis(100L);
4548 
4549         // Service state and service switch should be added successfully
4550         verifyCurrentStateSavedToFileOnce();
4551         SatelliteIncomingDatagram[] output =
4552                 mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
4553         assertProtoArrayEqualsIgnoringOrder(
4554                 new SatelliteIncomingDatagram[] {
4555                         mSatelliteIncomingDatagram1, mSatelliteIncomingDatagram2}, output);
4556     }
4557 
4558     @Test
addSatelliteIncomingDatagramStats_tooManyEntries()4559     public void addSatelliteIncomingDatagramStats_tooManyEntries() throws Exception {
4560         createEmptyTestFile();
4561 
4562         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4563 
4564         // Store atoms up to maximum number + 1
4565         int maxCount = 15 + 1;
4566         for (int i = 0; i < maxCount; i++) {
4567             mPersistAtomsStorage
4568                     .addSatelliteIncomingDatagramStats(copyOf(mSatelliteIncomingDatagram1));
4569             mPersistAtomsStorage.incTimeMillis(100L);
4570         }
4571 
4572         // Store 1 different atom
4573         mPersistAtomsStorage
4574                 .addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram2);
4575 
4576         verifyCurrentStateSavedToFileOnce();
4577 
4578         SatelliteIncomingDatagram[] result =
4579                 mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
4580 
4581         // First atom has count 14, the other has 1
4582         assertHasStatsAndCount(result, mSatelliteIncomingDatagram1, 14);
4583         assertHasStatsAndCount(result, mSatelliteIncomingDatagram2, 1);
4584 
4585     }
4586 
4587     @Test
getSatelliteIncomingDatagramStats_tooFrequent()4588     public void getSatelliteIncomingDatagramStats_tooFrequent() throws Exception {
4589         createTestFile(START_TIME_MILLIS);
4590 
4591         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4592         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4593         SatelliteIncomingDatagram[] output =
4594                 mPersistAtomsStorage.getSatelliteIncomingDatagramStats(100L);
4595 
4596         // Should be denied
4597         assertNull(output);
4598     }
4599 
4600     @Test
addSatelliteOutgoingDatagramStats_emptyProto()4601     public void addSatelliteOutgoingDatagramStats_emptyProto() throws Exception {
4602         createEmptyTestFile();
4603         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4604         mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram1);
4605         mPersistAtomsStorage.incTimeMillis(100L);
4606 
4607         // Service state and service switch should be added successfully
4608         verifyCurrentStateSavedToFileOnce();
4609         SatelliteOutgoingDatagram[] output =
4610                 mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
4611         assertProtoArrayEquals(
4612                 new SatelliteOutgoingDatagram[] {mSatelliteOutgoingDatagram1}, output);
4613     }
4614 
4615     @Test
addSatelliteOutgoingDatagramStats_withExistingEntries()4616     public void addSatelliteOutgoingDatagramStats_withExistingEntries() throws Exception {
4617         createEmptyTestFile();
4618         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4619         mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram1);
4620         mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram2);
4621         mPersistAtomsStorage.incTimeMillis(100L);
4622 
4623         // Service state and service switch should be added successfully
4624         verifyCurrentStateSavedToFileOnce();
4625         SatelliteOutgoingDatagram[] output =
4626                 mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
4627         assertProtoArrayEqualsIgnoringOrder(
4628                 new SatelliteOutgoingDatagram[] {
4629                         mSatelliteOutgoingDatagram1, mSatelliteOutgoingDatagram2}, output);
4630     }
4631 
4632     @Test
addSatelliteOutgoingDatagramStats_tooManyEntries()4633     public void addSatelliteOutgoingDatagramStats_tooManyEntries() throws Exception {
4634         createEmptyTestFile();
4635 
4636         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4637 
4638         // Store atoms up to maximum number + 1
4639         int maxCount = 15 + 1;
4640         for (int i = 0; i < maxCount; i++) {
4641             mPersistAtomsStorage
4642                     .addSatelliteOutgoingDatagramStats(copyOf(mSatelliteOutgoingDatagram1));
4643             mPersistAtomsStorage.incTimeMillis(100L);
4644         }
4645 
4646         // Store 1 different atom
4647         mPersistAtomsStorage
4648                 .addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram2);
4649 
4650         verifyCurrentStateSavedToFileOnce();
4651 
4652         SatelliteOutgoingDatagram[] result =
4653                 mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
4654 
4655         // First atom has count 14, the other has 1
4656         assertHasStatsAndCount(result, mSatelliteOutgoingDatagram1, 14);
4657         assertHasStatsAndCount(result, mSatelliteOutgoingDatagram2, 1);
4658 
4659     }
4660 
4661     @Test
getSatelliteOutgoingDatagramStats_tooFrequent()4662     public void getSatelliteOutgoingDatagramStats_tooFrequent() throws Exception {
4663         createTestFile(START_TIME_MILLIS);
4664 
4665         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4666         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4667         SatelliteOutgoingDatagram[] output =
4668                 mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(100L);
4669 
4670         // Should be denied
4671         assertNull(output);
4672     }
4673 
4674     @Test
addSatelliteProvisionStats_emptyProto()4675     public void addSatelliteProvisionStats_emptyProto() throws Exception {
4676         createEmptyTestFile();
4677         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4678         mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision1);
4679         mPersistAtomsStorage.incTimeMillis(100L);
4680 
4681         // Service state and service switch should be added successfully
4682         verifyCurrentStateSavedToFileOnce();
4683         SatelliteProvision[] output =
4684                 mPersistAtomsStorage.getSatelliteProvisionStats(0L);
4685         assertProtoArrayEquals(
4686                 new SatelliteProvision[] {mSatelliteProvision1}, output);
4687     }
4688 
4689     @Test
addSatelliteProvisionStats_withExistingEntries()4690     public void addSatelliteProvisionStats_withExistingEntries() throws Exception {
4691         createEmptyTestFile();
4692         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4693         mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision1);
4694         mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision2);
4695         mPersistAtomsStorage.incTimeMillis(100L);
4696 
4697         // Service state and service switch should be added successfully
4698         verifyCurrentStateSavedToFileOnce();
4699         SatelliteProvision[] output =
4700                 mPersistAtomsStorage.getSatelliteProvisionStats(0L);
4701         assertProtoArrayEqualsIgnoringOrder(
4702                 new SatelliteProvision[] {
4703                         mSatelliteProvision1, mSatelliteProvision2}, output);
4704     }
4705 
4706     @Test
addSatelliteProvisionStats_tooManyEntries()4707     public void addSatelliteProvisionStats_tooManyEntries() throws Exception {
4708         createEmptyTestFile();
4709 
4710         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4711 
4712         // Store atoms up to maximum number + 1
4713         int maxCount = 15 + 1;
4714         for (int i = 0; i < maxCount; i++) {
4715             mPersistAtomsStorage
4716                     .addSatelliteProvisionStats(copyOf(mSatelliteProvision1));
4717             mPersistAtomsStorage.incTimeMillis(100L);
4718         }
4719 
4720         // Store 1 different atom
4721         mPersistAtomsStorage
4722                 .addSatelliteProvisionStats(mSatelliteProvision2);
4723 
4724         verifyCurrentStateSavedToFileOnce();
4725 
4726         SatelliteProvision[] result =
4727                 mPersistAtomsStorage.getSatelliteProvisionStats(0L);
4728 
4729         // First atom has count 14, the other has 1
4730         assertHasStatsAndCount(result, mSatelliteProvision1, 14);
4731         assertHasStatsAndCount(result, mSatelliteProvision2, 1);
4732 
4733     }
4734 
4735     @Test
getSatelliteProvisionStats_tooFrequent()4736     public void getSatelliteProvisionStats_tooFrequent() throws Exception {
4737         createTestFile(START_TIME_MILLIS);
4738 
4739         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4740         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4741         SatelliteProvision[] output =
4742                 mPersistAtomsStorage.getSatelliteProvisionStats(100L);
4743 
4744         // Should be denied
4745         assertNull(output);
4746     }
4747 
4748     @Test
addSatelliteSosMessageRecommenderStats_emptyProto()4749     public void addSatelliteSosMessageRecommenderStats_emptyProto() throws Exception {
4750         createEmptyTestFile();
4751         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4752         mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
4753                 mSatelliteSosMessageRecommender1);
4754         mPersistAtomsStorage.incTimeMillis(100L);
4755 
4756         // Service state and service switch should be added successfully
4757         verifyCurrentStateSavedToFileOnce();
4758         SatelliteSosMessageRecommender[] output =
4759                 mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
4760         assertProtoArrayEquals(
4761                 new SatelliteSosMessageRecommender[] {mSatelliteSosMessageRecommender1}, output);
4762     }
4763 
4764     @Test
addSatelliteSosMessageRecommenderStats_withExistingEntries()4765     public void addSatelliteSosMessageRecommenderStats_withExistingEntries() throws Exception {
4766         createEmptyTestFile();
4767         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4768         mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
4769                 mSatelliteSosMessageRecommender1);
4770         mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
4771                 mSatelliteSosMessageRecommender2);
4772         mPersistAtomsStorage.incTimeMillis(100L);
4773 
4774         // Service state and service switch should be added successfully
4775         verifyCurrentStateSavedToFileOnce();
4776         SatelliteSosMessageRecommender[] output =
4777                 mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
4778         assertProtoArrayEqualsIgnoringOrder(
4779                 new SatelliteSosMessageRecommender[] {
4780                         mSatelliteSosMessageRecommender1, mSatelliteSosMessageRecommender2},
4781                 output);
4782     }
4783 
4784     @Test
addSatelliteSosMessageRecommenderStats_tooManyEntries()4785     public void addSatelliteSosMessageRecommenderStats_tooManyEntries() throws Exception {
4786         createEmptyTestFile();
4787 
4788         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4789 
4790         // Store atoms up to maximum number + 1
4791         int maxCount = 15 + 1;
4792         for (int i = 0; i < maxCount; i++) {
4793             mPersistAtomsStorage
4794                     .addSatelliteSosMessageRecommenderStats(
4795                             copyOf(mSatelliteSosMessageRecommender1));
4796             mPersistAtomsStorage.incTimeMillis(100L);
4797         }
4798 
4799         // Store 1 different atom
4800         mPersistAtomsStorage
4801                 .addSatelliteSosMessageRecommenderStats(mSatelliteSosMessageRecommender2);
4802 
4803         verifyCurrentStateSavedToFileOnce();
4804 
4805         SatelliteSosMessageRecommender[] result =
4806                 mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
4807 
4808         // First atom has count 16, the other has 1
4809         assertHasStatsAndCount(result, mSatelliteSosMessageRecommender1, 16);
4810         assertHasStatsAndCount(result, mSatelliteSosMessageRecommender2, 1);
4811 
4812     }
4813 
4814     @Test
getSatelliteSosMessageRecommenderStats_tooFrequent()4815     public void getSatelliteSosMessageRecommenderStats_tooFrequent() throws Exception {
4816         createTestFile(START_TIME_MILLIS);
4817 
4818         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4819         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4820         SatelliteSosMessageRecommender[] output =
4821                 mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(100L);
4822 
4823         // Should be denied
4824         assertNull(output);
4825     }
4826 
4827     @Test
addCarrierRoamingSatelliteSessionStats_emptyProto()4828     public void addCarrierRoamingSatelliteSessionStats_emptyProto() throws Exception {
4829         createEmptyTestFile();
4830         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4831         mPersistAtomsStorage.addCarrierRoamingSatelliteSessionStats(
4832                 mCarrierRoamingSatelliteSession1);
4833         mPersistAtomsStorage.incTimeMillis(100L);
4834 
4835         verifyCurrentStateSavedToFileOnce();
4836         CarrierRoamingSatelliteSession[] output =
4837                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(0L);
4838         assertProtoArrayEquals(new CarrierRoamingSatelliteSession[] {
4839                 mCarrierRoamingSatelliteSession1}, output);
4840     }
4841 
4842     @Test
addCarrierRoamingSatelliteSessionStats_withExistingEntries()4843     public void addCarrierRoamingSatelliteSessionStats_withExistingEntries() throws Exception {
4844         createEmptyTestFile();
4845         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4846         mPersistAtomsStorage.addCarrierRoamingSatelliteSessionStats(
4847                 mCarrierRoamingSatelliteSession1);
4848         mPersistAtomsStorage.addCarrierRoamingSatelliteSessionStats(
4849                 mCarrierRoamingSatelliteSession2);
4850         mPersistAtomsStorage.incTimeMillis(100L);
4851 
4852         verifyCurrentStateSavedToFileOnce();
4853         CarrierRoamingSatelliteSession[] output =
4854                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(0L);
4855         assertProtoArrayEqualsIgnoringOrder(
4856                 new CarrierRoamingSatelliteSession[] {mCarrierRoamingSatelliteSession2}, output);
4857     }
4858 
4859     @Test
addCarrierRoamingSatelliteSessionStats_tooManyEntries()4860     public void addCarrierRoamingSatelliteSessionStats_tooManyEntries() throws Exception {
4861         createEmptyTestFile();
4862 
4863         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4864 
4865         // Store atoms up to maximum number + 1
4866         int maxCount = 1 + 1;
4867         for (int i = 0; i < maxCount; i++) {
4868             mPersistAtomsStorage.addCarrierRoamingSatelliteSessionStats(
4869                     copyOf(mCarrierRoamingSatelliteSession1));
4870             mPersistAtomsStorage.incTimeMillis(100L);
4871         }
4872 
4873         // Store 1 different atom
4874         mPersistAtomsStorage.addCarrierRoamingSatelliteSessionStats(
4875                 mCarrierRoamingSatelliteSession2);
4876 
4877         verifyCurrentStateSavedToFileOnce();
4878 
4879         CarrierRoamingSatelliteSession[] result =
4880                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(0L);
4881 
4882         // First atom has count 0, the other has 1
4883         assertHasStatsAndCount(result, mCarrierRoamingSatelliteSession1, 0);
4884         assertHasStatsAndCount(result, mCarrierRoamingSatelliteSession2, 1);
4885     }
4886 
4887     @Test
getCarrierRoamingSatelliteSessionStats_tooFrequent()4888     public void getCarrierRoamingSatelliteSessionStats_tooFrequent() throws Exception {
4889         createTestFile(START_TIME_MILLIS);
4890 
4891         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4892         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4893         CarrierRoamingSatelliteSession[] output =
4894                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(100L);
4895 
4896         // Should be denied
4897         assertNull(output);
4898     }
4899 
4900     @Test
getCarrierRoamingSatelliteSessionStats_withSavedAtoms()4901     public void getCarrierRoamingSatelliteSessionStats_withSavedAtoms() throws Exception {
4902         createTestFile(START_TIME_MILLIS);
4903 
4904         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4905         mPersistAtomsStorage.incTimeMillis(100L);
4906         CarrierRoamingSatelliteSession[] carrierRoamingSatelliteSessionStatsList1 =
4907                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(50L);
4908         mPersistAtomsStorage.incTimeMillis(100L);
4909         CarrierRoamingSatelliteSession[] carrierRoamingSatelliteSessionStatsList2 =
4910                 mPersistAtomsStorage.getCarrierRoamingSatelliteSessionStats(50L);
4911 
4912         // First set of results should be equal to file contents.
4913         CarrierRoamingSatelliteSession[] expectedList = new CarrierRoamingSatelliteSession[] {
4914                 mCarrierRoamingSatelliteSession1, mCarrierRoamingSatelliteSession2};
4915         assertProtoArrayEqualsIgnoringOrder(expectedList, carrierRoamingSatelliteSessionStatsList1);
4916         // Second set of results should be empty.
4917         assertProtoArrayEquals(new CarrierRoamingSatelliteSession[0],
4918                 carrierRoamingSatelliteSessionStatsList2);
4919         // Corresponding pull timestamp should be updated and saved.
4920         assertEquals(START_TIME_MILLIS + 200L, mPersistAtomsStorage
4921                 .getAtomsProto().carrierRoamingSatelliteSessionPullTimestampMillis);
4922         InOrder inOrder = inOrder(mTestFileOutputStream);
4923         assertEquals(START_TIME_MILLIS + 100L,
4924                 getAtomsWritten(inOrder).carrierRoamingSatelliteSessionPullTimestampMillis);
4925         assertEquals(START_TIME_MILLIS + 200L,
4926                 getAtomsWritten(inOrder).carrierRoamingSatelliteSessionPullTimestampMillis);
4927         inOrder.verifyNoMoreInteractions();
4928     }
4929 
4930     @Test
addCarrierRoamingSatelliteControllerStats_emptyProto()4931     public void addCarrierRoamingSatelliteControllerStats_emptyProto() throws Exception {
4932         createEmptyTestFile();
4933         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4934         mPersistAtomsStorage.addCarrierRoamingSatelliteControllerStats(
4935                 mCarrierRoamingSatelliteControllerStats1);
4936         mPersistAtomsStorage.incTimeMillis(100L);
4937 
4938         verifyCurrentStateSavedToFileOnce();
4939         CarrierRoamingSatelliteControllerStats[] output =
4940                 mPersistAtomsStorage.getCarrierRoamingSatelliteControllerStats(0L);
4941         assertProtoArrayEquals(new CarrierRoamingSatelliteControllerStats[] {
4942                 mCarrierRoamingSatelliteControllerStats1}, output);
4943     }
4944 
4945     @Test
addCarrierRoamingSatelliteControllerStats_withExistingEntries()4946     public void addCarrierRoamingSatelliteControllerStats_withExistingEntries() throws Exception {
4947         createEmptyTestFile();
4948         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4949         mPersistAtomsStorage.addCarrierRoamingSatelliteControllerStats(
4950                 mCarrierRoamingSatelliteControllerStats1);
4951         mPersistAtomsStorage.addCarrierRoamingSatelliteControllerStats(
4952                 mCarrierRoamingSatelliteControllerStats2);
4953         mPersistAtomsStorage.incTimeMillis(100L);
4954 
4955         CarrierRoamingSatelliteControllerStats expected =
4956                 new CarrierRoamingSatelliteControllerStats();
4957         expected.configDataSource = mCarrierRoamingSatelliteControllerStats2.configDataSource;
4958         expected.countOfEntitlementStatusQueryRequest =
4959                 mCarrierRoamingSatelliteControllerStats1.countOfEntitlementStatusQueryRequest
4960                         + mCarrierRoamingSatelliteControllerStats2
4961                         .countOfEntitlementStatusQueryRequest;
4962         expected.countOfSatelliteConfigUpdateRequest =
4963                 mCarrierRoamingSatelliteControllerStats1.countOfSatelliteConfigUpdateRequest
4964                         + mCarrierRoamingSatelliteControllerStats2
4965                         .countOfSatelliteConfigUpdateRequest;
4966         expected.countOfSatelliteNotificationDisplayed =
4967                 mCarrierRoamingSatelliteControllerStats1.countOfSatelliteNotificationDisplayed
4968                 + mCarrierRoamingSatelliteControllerStats2
4969                         .countOfSatelliteNotificationDisplayed;
4970         expected.satelliteSessionGapMinSec =
4971                 mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMinSec;
4972         expected.satelliteSessionGapAvgSec =
4973                 mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapAvgSec;
4974         expected.satelliteSessionGapMaxSec =
4975                 mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMaxSec;
4976 
4977         verifyCurrentStateSavedToFileOnce();
4978         CarrierRoamingSatelliteControllerStats[] output =
4979                 mPersistAtomsStorage.getCarrierRoamingSatelliteControllerStats(0L);
4980         assertHasStats(output, expected);
4981     }
4982 
4983     @Test
getCarrierRoamingSatelliteControllerStats_tooFrequent()4984     public void getCarrierRoamingSatelliteControllerStats_tooFrequent() throws Exception {
4985         createTestFile(START_TIME_MILLIS);
4986 
4987         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
4988         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
4989         CarrierRoamingSatelliteControllerStats[] output =
4990                 mPersistAtomsStorage.getCarrierRoamingSatelliteControllerStats(100L);
4991 
4992         // Should be denied
4993         assertNull(output);
4994     }
4995 
4996 
4997     @Test
addSatelliteEntitlementStats_emptyProto()4998     public void addSatelliteEntitlementStats_emptyProto() throws Exception {
4999         createEmptyTestFile();
5000         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5001         mPersistAtomsStorage.addSatelliteEntitlementStats(mSatelliteEntitlement1);
5002         mPersistAtomsStorage.incTimeMillis(100L);
5003 
5004         verifyCurrentStateSavedToFileOnce();
5005         SatelliteEntitlement[] output =
5006                 mPersistAtomsStorage.getSatelliteEntitlementStats(0L);
5007         assertProtoArrayEquals(new SatelliteEntitlement[] {mSatelliteEntitlement1}, output);
5008     }
5009 
5010     @Test
addSatelliteEntitlementStats_withExistingEntries()5011     public void addSatelliteEntitlementStats_withExistingEntries() throws Exception {
5012         createEmptyTestFile();
5013         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5014         mPersistAtomsStorage.addSatelliteEntitlementStats(mSatelliteEntitlement1);
5015         mPersistAtomsStorage.addSatelliteEntitlementStats(mSatelliteEntitlement2);
5016         mPersistAtomsStorage.incTimeMillis(100L);
5017 
5018         verifyCurrentStateSavedToFileOnce();
5019         SatelliteEntitlement[] output =
5020                 mPersistAtomsStorage.getSatelliteEntitlementStats(0L);
5021         assertProtoArrayEqualsIgnoringOrder(
5022                 new SatelliteEntitlement[] {
5023                         mSatelliteEntitlement1, mSatelliteEntitlement2}, output);
5024     }
5025 
5026     @Test
addSatelliteEntitlementStats_updateExistingEntries()5027     public void addSatelliteEntitlementStats_updateExistingEntries() throws Exception {
5028         createTestFile(START_TIME_MILLIS);
5029 
5030         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5031         mPersistAtomsStorage.addSatelliteEntitlementStats(copyOf(mSatelliteEntitlement1));
5032         mPersistAtomsStorage.incTimeMillis(100L);
5033 
5034         // Count should be increased by 1.
5035         verifyCurrentStateSavedToFileOnce();
5036         SatelliteEntitlement newSatelliteEntitlement1 = copyOf(mSatelliteEntitlement1);
5037         newSatelliteEntitlement1.count = 2;
5038         SatelliteEntitlement[] expectedList = new SatelliteEntitlement[] {newSatelliteEntitlement1,
5039                 mSatelliteEntitlement2};
5040         assertProtoArrayEqualsIgnoringOrder(expectedList,
5041                 mPersistAtomsStorage.getSatelliteEntitlementStats(0L));
5042     }
5043 
5044     @Test
addSatelliteEntitlementStats_tooManyEntries()5045     public void addSatelliteEntitlementStats_tooManyEntries() throws Exception {
5046         createEmptyTestFile();
5047 
5048         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5049 
5050         // Store atoms up to maximum number + 1
5051         int maxCount = 15 + 1;
5052         for (int i = 0; i < maxCount; i++) {
5053             mPersistAtomsStorage.addSatelliteEntitlementStats(mSatelliteEntitlement1);
5054             mPersistAtomsStorage.incTimeMillis(100L);
5055         }
5056 
5057         // Store 1 different atom
5058         mPersistAtomsStorage.addSatelliteEntitlementStats(mSatelliteEntitlement2);
5059 
5060         verifyCurrentStateSavedToFileOnce();
5061 
5062         SatelliteEntitlement[] result =
5063                 mPersistAtomsStorage.getSatelliteEntitlementStats(0L);
5064 
5065         // First atom has count 14, the other has 1
5066         assertHasStatsAndCount(result, mSatelliteEntitlement1, 16);
5067         assertHasStatsAndCount(result, mSatelliteEntitlement2, 1);
5068     }
5069 
5070     @Test
getSatelliteEntitlementStats_tooFrequent()5071     public void getSatelliteEntitlementStats_tooFrequent() throws Exception {
5072         createTestFile(START_TIME_MILLIS);
5073 
5074         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5075         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
5076         SatelliteEntitlement[] output =
5077                 mPersistAtomsStorage.getSatelliteEntitlementStats(100L);
5078 
5079         // Should be denied
5080         assertNull(output);
5081     }
5082 
5083     @Test
getSatelliteEntitlementStats_withSavedAtoms()5084     public void getSatelliteEntitlementStats_withSavedAtoms() throws Exception {
5085         createTestFile(START_TIME_MILLIS);
5086 
5087         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5088         mPersistAtomsStorage.incTimeMillis(100L);
5089         SatelliteEntitlement[] satelliteEntitlementStatsList1 =
5090                 mPersistAtomsStorage.getSatelliteEntitlementStats(50L);
5091         mPersistAtomsStorage.incTimeMillis(100L);
5092         SatelliteEntitlement[] satelliteEntitlementStatsList2 =
5093                 mPersistAtomsStorage.getSatelliteEntitlementStats(50L);
5094 
5095         // First set of results should be equal to file contents.
5096         SatelliteEntitlement[] expectedList = new SatelliteEntitlement[] {
5097                 mSatelliteEntitlement1, mSatelliteEntitlement2};
5098         assertProtoArrayEqualsIgnoringOrder(expectedList, satelliteEntitlementStatsList1);
5099         // Second set of results should be empty.
5100         assertProtoArrayEquals(new SatelliteEntitlement[0], satelliteEntitlementStatsList2);
5101         // Corresponding pull timestamp should be updated and saved.
5102         assertEquals(START_TIME_MILLIS + 200L, mPersistAtomsStorage
5103                 .getAtomsProto().satelliteEntitlementPullTimestampMillis);
5104         InOrder inOrder = inOrder(mTestFileOutputStream);
5105         assertEquals(START_TIME_MILLIS + 100L,
5106                 getAtomsWritten(inOrder).satelliteEntitlementPullTimestampMillis);
5107         assertEquals(START_TIME_MILLIS + 200L,
5108                 getAtomsWritten(inOrder).satelliteEntitlementPullTimestampMillis);
5109         inOrder.verifyNoMoreInteractions();
5110     }
5111 
5112     @Test
addSatelliteConfigUpdaterStats_emptyProto()5113     public void addSatelliteConfigUpdaterStats_emptyProto() throws Exception {
5114         createEmptyTestFile();
5115         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5116         mPersistAtomsStorage.addSatelliteConfigUpdaterStats(mSatelliteConfigUpdater1);
5117         mPersistAtomsStorage.incTimeMillis(100L);
5118 
5119         verifyCurrentStateSavedToFileOnce();
5120         SatelliteConfigUpdater[] output =
5121                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(0L);
5122         assertProtoArrayEquals(new SatelliteConfigUpdater[] {mSatelliteConfigUpdater1}, output);
5123     }
5124 
5125     @Test
addSatelliteConfigUpdaterStats_withExistingEntries()5126     public void addSatelliteConfigUpdaterStats_withExistingEntries() throws Exception {
5127         createEmptyTestFile();
5128         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5129         mPersistAtomsStorage.addSatelliteConfigUpdaterStats(mSatelliteConfigUpdater1);
5130         mPersistAtomsStorage.addSatelliteConfigUpdaterStats(mSatelliteConfigUpdater2);
5131         mPersistAtomsStorage.incTimeMillis(100L);
5132 
5133         verifyCurrentStateSavedToFileOnce();
5134         SatelliteConfigUpdater[] output =
5135                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(0L);
5136         assertProtoArrayEqualsIgnoringOrder(new SatelliteConfigUpdater[] {
5137                 mSatelliteConfigUpdater1, mSatelliteConfigUpdater2}, output);
5138     }
5139 
5140     @Test
addSatelliteConfigUpdaterStats_updateExistingEntries()5141     public void addSatelliteConfigUpdaterStats_updateExistingEntries() throws Exception {
5142         createTestFile(START_TIME_MILLIS);
5143 
5144         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5145         mPersistAtomsStorage.addSatelliteConfigUpdaterStats(copyOf(mSatelliteConfigUpdater1));
5146         mPersistAtomsStorage.incTimeMillis(100L);
5147 
5148         // Count should be increased by 1.
5149         verifyCurrentStateSavedToFileOnce();
5150         SatelliteConfigUpdater newSatelliteConfigUpdater1 = copyOf(mSatelliteConfigUpdater1);
5151         newSatelliteConfigUpdater1.count = 2;
5152         SatelliteConfigUpdater[] expectedList = new SatelliteConfigUpdater[] {
5153                 newSatelliteConfigUpdater1, mSatelliteConfigUpdater2};
5154         assertProtoArrayEqualsIgnoringOrder(expectedList,
5155                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(0L));
5156     }
5157 
5158     @Test
addSatelliteConfigUpdaterStats_tooManyEntries()5159     public void addSatelliteConfigUpdaterStats_tooManyEntries() throws Exception {
5160         createEmptyTestFile();
5161 
5162         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5163 
5164         // Store atoms up to maximum number + 1
5165         int maxCount = 15 + 1;
5166         for (int i = 0; i < maxCount; i++) {
5167             mPersistAtomsStorage.addSatelliteConfigUpdaterStats(mSatelliteConfigUpdater1);
5168             mPersistAtomsStorage.incTimeMillis(100L);
5169         }
5170 
5171         // Store 1 different atom
5172         mPersistAtomsStorage.addSatelliteConfigUpdaterStats(mSatelliteConfigUpdater2);
5173 
5174         verifyCurrentStateSavedToFileOnce();
5175 
5176         SatelliteConfigUpdater[] result =
5177                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(0L);
5178 
5179         // First atom has count 14, the other has 1
5180         assertHasStatsAndCount(result, mSatelliteConfigUpdater1, 16);
5181         assertHasStatsAndCount(result, mSatelliteConfigUpdater2, 1);
5182     }
5183 
5184     @Test
getSatelliteConfigUpdaterStats_tooFrequent()5185     public void getSatelliteConfigUpdaterStats_tooFrequent() throws Exception {
5186         createTestFile(START_TIME_MILLIS);
5187 
5188         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5189         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
5190         SatelliteConfigUpdater[] output =
5191                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(100L);
5192 
5193         // Should be denied
5194         assertNull(output);
5195     }
5196 
5197     @Test
getSatelliteConfigUpdaterStats_withSavedAtoms()5198     public void getSatelliteConfigUpdaterStats_withSavedAtoms() throws Exception {
5199         createTestFile(START_TIME_MILLIS);
5200 
5201         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5202         mPersistAtomsStorage.incTimeMillis(100L);
5203         SatelliteConfigUpdater[] satelliteConfigUpdaterStatsList1 =
5204                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(50L);
5205         mPersistAtomsStorage.incTimeMillis(100L);
5206         SatelliteConfigUpdater[] satelliteConfigUpdaterStatsList2 =
5207                 mPersistAtomsStorage.getSatelliteConfigUpdaterStats(50L);
5208 
5209         // First set of results should be equal to file contents.
5210         SatelliteConfigUpdater[] expectedList = new SatelliteConfigUpdater[] {
5211                 mSatelliteConfigUpdater1, mSatelliteConfigUpdater2};
5212         assertProtoArrayEqualsIgnoringOrder(expectedList, satelliteConfigUpdaterStatsList1);
5213         // Second set of results should be empty.
5214         assertProtoArrayEquals(new SatelliteConfigUpdater[0], satelliteConfigUpdaterStatsList2);
5215         // Corresponding pull timestamp should be updated and saved.
5216         assertEquals(START_TIME_MILLIS + 200L, mPersistAtomsStorage
5217                 .getAtomsProto().satelliteConfigUpdaterPullTimestampMillis);
5218         InOrder inOrder = inOrder(mTestFileOutputStream);
5219         assertEquals(START_TIME_MILLIS + 100L,
5220                 getAtomsWritten(inOrder).satelliteConfigUpdaterPullTimestampMillis);
5221         assertEquals(START_TIME_MILLIS + 200L,
5222                 getAtomsWritten(inOrder).satelliteConfigUpdaterPullTimestampMillis);
5223         inOrder.verifyNoMoreInteractions();
5224     }
5225 
5226     @Test
addSatelliteAccessControllerStats_emptyProto()5227     public void addSatelliteAccessControllerStats_emptyProto() throws Exception {
5228         createEmptyTestFile();
5229         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5230         mPersistAtomsStorage.addSatelliteAccessControllerStats(
5231                 mSatelliteAccessController1);
5232         mPersistAtomsStorage.incTimeMillis(100L);
5233 
5234         // Service state and service switch should be added successfully
5235         verifyCurrentStateSavedToFileOnce();
5236         SatelliteAccessController[] output =
5237                 mPersistAtomsStorage.getSatelliteAccessControllerStats(0L);
5238         assertProtoArrayEquals(
5239                 new SatelliteAccessController[] {mSatelliteAccessController1}, output);
5240     }
5241 
5242     @Test
addSatelliteAccessControllerStats_tooManyEntries()5243     public void addSatelliteAccessControllerStats_tooManyEntries() throws Exception {
5244         createEmptyTestFile();
5245         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5246 
5247         // Store atoms up to maximum number + 1
5248         int maxCount = 15 + 1;
5249         for (int i = 0; i < maxCount; i++) {
5250             mPersistAtomsStorage
5251                     .addSatelliteAccessControllerStats(//mSatelliteAccessController1);
5252                             copyOf(mSatelliteAccessController1));
5253             mPersistAtomsStorage.incTimeMillis(100L);
5254         }
5255 
5256         // Store 1 different atom
5257         mPersistAtomsStorage
5258                 .addSatelliteAccessControllerStats(mSatelliteAccessController2);
5259         mPersistAtomsStorage.incTimeMillis(100L);
5260 
5261         verifyCurrentStateSavedToFileOnce();
5262 
5263         SatelliteAccessController[] result =
5264                 mPersistAtomsStorage.getSatelliteAccessControllerStats(0L);
5265         // First atom should have count 14, the other should have 1
5266         assertHasStatsAndCount(result, mSatelliteAccessController1, 14);
5267         assertHasStatsAndCount(result, mSatelliteAccessController2, 1);
5268     }
5269 
5270     @Test
getSatelliteAccessControllerStats_tooFrequent()5271     public void getSatelliteAccessControllerStats_tooFrequent() throws Exception {
5272         createTestFile(START_TIME_MILLIS);
5273 
5274         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5275         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
5276         SatelliteAccessController[] output =
5277                 mPersistAtomsStorage.getSatelliteAccessControllerStats(100L);
5278 
5279         // Should be denied
5280         assertNull(output);
5281     }
5282 
5283     @Test
5284     @SmallTest
addDataNetworkValidation_newEntry()5285     public void addDataNetworkValidation_newEntry() throws Exception {
5286         createEmptyTestFile();
5287         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5288 
5289         mPersistAtomsStorage.addDataNetworkValidation(mDataNetworkValidationLte1);
5290         mPersistAtomsStorage.addDataNetworkValidation(mDataNetworkValidationIwlan1);
5291         mPersistAtomsStorage.incTimeMillis(100L);
5292 
5293         // There should be 2 DataNetworkValidation
5294         verifyCurrentStateSavedToFileOnce();
5295         DataNetworkValidation[] output = mPersistAtomsStorage.getDataNetworkValidation(0L);
5296         assertProtoArrayEqualsIgnoringOrder(
5297                 new DataNetworkValidation[] {
5298                         mDataNetworkValidationLte1, mDataNetworkValidationIwlan1},
5299                 output);
5300     }
5301 
5302     @Test
addDataNetworkValidation_existingEntry()5303     public void addDataNetworkValidation_existingEntry() throws Exception {
5304         createEmptyTestFile();
5305         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5306 
5307         int expectedNetworkValidationCount =
5308                 mDataNetworkValidationLte1.networkValidationCount
5309                         + mDataNetworkValidationLte2.networkValidationCount;
5310 
5311         mPersistAtomsStorage.addDataNetworkValidation(mDataNetworkValidationLte1);
5312         mPersistAtomsStorage.addDataNetworkValidation(mDataNetworkValidationLte2);
5313         mPersistAtomsStorage.incTimeMillis(100L);
5314 
5315         DataNetworkValidation expected = copyOf(mDataNetworkValidationLte1);
5316         expected.networkValidationCount = expectedNetworkValidationCount;
5317 
5318         // There should be 1 DataNetworkValidation
5319         verifyCurrentStateSavedToFileOnce();
5320         DataNetworkValidation[] output =
5321                 mPersistAtomsStorage.getDataNetworkValidation(0L);
5322         assertProtoArrayEqualsIgnoringOrder(
5323                 new DataNetworkValidation[] {expected},
5324                 output);
5325     }
5326 
5327     @Test
addDataNetworkValidation_tooManyEntries()5328     public void addDataNetworkValidation_tooManyEntries() throws Exception {
5329 
5330         // Set up
5331         doReturn(false).when(mPackageManager).hasSystemFeature(anyString());
5332 
5333         createEmptyTestFile();
5334         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5335 
5336         // Currently, the maximum number that can be stored for DataNetworkValidation in Atom
5337         // storage is 15. Try saving excess.
5338         int maxNumDataNetworkValidation = 20;
5339         mPersistAtomsStorage.addDataNetworkValidation(mDataNetworkValidationLte1);
5340         for (int i = 0; i < maxNumDataNetworkValidation; i++) {
5341             DataNetworkValidation copied = copyOf(mDataNetworkValidationLte1);
5342             copied.apnTypeBitmask = mDataNetworkValidationLte1.apnTypeBitmask + i;
5343             mPersistAtomsStorage.addDataNetworkValidation(copied);
5344         }
5345         mPersistAtomsStorage.incTimeMillis(100L);
5346 
5347         // There should be less than or equal to maxNumDataNetworkValidation
5348         verifyCurrentStateSavedToFileOnce();
5349         DataNetworkValidation[] output =
5350                 mPersistAtomsStorage.getDataNetworkValidation(0L);
5351         assertTrue(output.length <= maxNumDataNetworkValidation);
5352     }
5353 
5354     @Test
5355     @SmallTest
clearAtoms()5356     public void clearAtoms() throws Exception {
5357         createTestFile(START_TIME_MILLIS);
5358         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
5359         mPersistAtomsStorage.addCompleteSipTransportSession(copyOf(mSipTransportSession1));
5360         mPersistAtomsStorage.incTimeMillis(100L);
5361         verifyCurrentStateSavedToFileOnce();
5362 
5363         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
5364         mPersistAtomsStorage.incTimeMillis(100L);
5365         verifyCurrentStateSavedToFileOnce();
5366 
5367         mPersistAtomsStorage.clearAtoms();
5368         verifyCurrentStateSavedToFileOnce();
5369         UceEventStats[] uceEventStats = mPersistAtomsStorage.getUceEventStats(0L);
5370         assertEquals(null, uceEventStats);
5371         SipTransportSession[] sipTransportSession = mPersistAtomsStorage.getSipTransportSession(0L);
5372         assertEquals(null, sipTransportSession);
5373     }
5374 
5375     /* Utilities */
5376 
createEmptyTestFile()5377     private void createEmptyTestFile() throws Exception {
5378         PersistAtoms atoms = new PersistAtoms();
5379         FileOutputStream stream = new FileOutputStream(mTestFile);
5380         stream.write(PersistAtoms.toByteArray(atoms));
5381         stream.close();
5382     }
5383 
createTestFile(long lastPullTimeMillis)5384     private void createTestFile(long lastPullTimeMillis) throws Exception {
5385         PersistAtoms atoms = new PersistAtoms();
5386         atoms.buildFingerprint = Build.FINGERPRINT;
5387         atoms.voiceCallRatUsagePullTimestampMillis = lastPullTimeMillis;
5388         atoms.voiceCallRatUsage = mVoiceCallRatUsages;
5389         atoms.voiceCallSessionPullTimestampMillis = lastPullTimeMillis;
5390         atoms.voiceCallSession = mVoiceCallSessions;
5391         atoms.cellularServiceStatePullTimestampMillis = lastPullTimeMillis;
5392         atoms.cellularServiceState = mServiceStates;
5393         atoms.cellularDataServiceSwitchPullTimestampMillis = lastPullTimeMillis;
5394         atoms.cellularDataServiceSwitch = mServiceSwitches;
5395         atoms.imsRegistrationStatsPullTimestampMillis = lastPullTimeMillis;
5396         atoms.imsRegistrationStats = mImsRegistrationStats;
5397         atoms.imsRegistrationTerminationPullTimestampMillis = lastPullTimeMillis;
5398         atoms.imsRegistrationTermination = mImsRegistrationTerminations;
5399         atoms.imsRegistrationFeatureTagStatsPullTimestampMillis = lastPullTimeMillis;
5400         atoms.imsRegistrationFeatureTagStats = mImsRegistrationFeatureTagStatses;
5401         atoms.rcsClientProvisioningStatsPullTimestampMillis = lastPullTimeMillis;
5402         atoms.rcsClientProvisioningStats = mRcsClientProvisioningStatses;
5403         atoms.rcsAcsProvisioningStatsPullTimestampMillis = lastPullTimeMillis;
5404         atoms.rcsAcsProvisioningStats = mRcsAcsProvisioningStatses;
5405         atoms.imsRegistrationServiceDescStatsPullTimestampMillis = lastPullTimeMillis;
5406         atoms.imsRegistrationServiceDescStats = mImsRegistrationServiceDescStats;
5407         atoms.imsDedicatedBearerListenerEventPullTimestampMillis = lastPullTimeMillis;
5408         atoms.imsDedicatedBearerListenerEvent = mImsDedicatedBearerListenerEvents;
5409         atoms.imsDedicatedBearerEventPullTimestampMillis = lastPullTimeMillis;
5410         atoms.imsDedicatedBearerEvent = mImsDedicatedBearerEvents;
5411         atoms.uceEventStatsPullTimestampMillis = lastPullTimeMillis;
5412         atoms.uceEventStats = mUceEventStatses;
5413         atoms.presenceNotifyEventPullTimestampMillis = lastPullTimeMillis;
5414         atoms.presenceNotifyEvent = mPresenceNotifyEvents;
5415         atoms.sipTransportFeatureTagStatsPullTimestampMillis = lastPullTimeMillis;
5416         atoms.sipTransportFeatureTagStats = mSipTransportFeatureTagStatsArray;
5417         atoms.sipDelegateStatsPullTimestampMillis = lastPullTimeMillis;
5418         atoms.sipDelegateStats = mSipDelegateStatsArray;
5419         atoms.gbaEventPullTimestampMillis = lastPullTimeMillis;
5420         atoms.gbaEvent = mGbaEvent;
5421         atoms.sipMessageResponsePullTimestampMillis = lastPullTimeMillis;
5422         atoms.sipMessageResponse = mSipMessageResponse;
5423         atoms.sipTransportSessionPullTimestampMillis = lastPullTimeMillis;
5424         atoms.sipTransportSession = mSipTransportSession;
5425         atoms.outgoingShortCodeSms = mOutgoingShortCodeSms;
5426         atoms.outgoingShortCodeSmsPullTimestampMillis = lastPullTimeMillis;
5427         atoms.satelliteController = mSatelliteControllers;
5428         atoms.satelliteControllerPullTimestampMillis = lastPullTimeMillis;
5429         atoms.satelliteSession = mSatelliteSessions;
5430         atoms.satelliteSessionPullTimestampMillis = lastPullTimeMillis;
5431         atoms.satelliteIncomingDatagram = mSatelliteIncomingDatagrams;
5432         atoms.satelliteIncomingDatagramPullTimestampMillis = lastPullTimeMillis;
5433         atoms.satelliteOutgoingDatagram = mSatelliteOutgoingDatagrams;
5434         atoms.satelliteOutgoingDatagramPullTimestampMillis = lastPullTimeMillis;
5435         atoms.satelliteProvision = mSatelliteProvisions;
5436         atoms.satelliteProvisionPullTimestampMillis = lastPullTimeMillis;
5437         atoms.satelliteSosMessageRecommender = mSatelliteSosMessageRecommenders;
5438         atoms.satelliteSosMessageRecommenderPullTimestampMillis = lastPullTimeMillis;
5439         atoms.dataNetworkValidation = mDataNetworkValidations;
5440         atoms.dataNetworkValidationPullTimestampMillis = lastPullTimeMillis;
5441         atoms.carrierRoamingSatelliteSession = mCarrierRoamingSatelliteSessions;
5442         atoms.carrierRoamingSatelliteSessionPullTimestampMillis = lastPullTimeMillis;
5443         atoms.carrierRoamingSatelliteControllerStats = mCarrierRoamingSatelliteControllerStats;
5444         atoms.carrierRoamingSatelliteControllerStatsPullTimestampMillis = lastPullTimeMillis;
5445         atoms.satelliteEntitlement = mSatelliteEntitlements;
5446         atoms.satelliteEntitlementPullTimestampMillis = lastPullTimeMillis;
5447         atoms.satelliteConfigUpdater = mSatelliteConfigUpdaters;
5448         atoms.satelliteConfigUpdaterPullTimestampMillis = lastPullTimeMillis;
5449         atoms.satelliteAccessControllerPullTimestampMillis = lastPullTimeMillis;
5450         FileOutputStream stream = new FileOutputStream(mTestFile);
5451         stream.write(PersistAtoms.toByteArray(atoms));
5452         stream.close();
5453     }
5454 
getAtomsWritten(@ullable InOrder inOrder)5455     private PersistAtoms getAtomsWritten(@Nullable InOrder inOrder) throws Exception {
5456         if (inOrder == null) {
5457             inOrder = inOrder(mTestFileOutputStream);
5458         }
5459         ArgumentCaptor bytesCaptor = ArgumentCaptor.forClass(Object.class);
5460         inOrder.verify(mTestFileOutputStream, times(1)).write((byte[]) bytesCaptor.capture());
5461         PersistAtoms savedAtoms = PersistAtoms.parseFrom((byte[]) bytesCaptor.getValue());
5462         inOrder.verify(mTestFileOutputStream, times(1)).close();
5463         return savedAtoms;
5464     }
5465 
addRepeatedCalls( PersistAtomsStorage storage, VoiceCallSession call, int count)5466     private static void addRepeatedCalls(
5467             PersistAtomsStorage storage, VoiceCallSession call, int count) {
5468         for (int i = 0; i < count; i++) {
5469             storage.addVoiceCallSession(call);
5470         }
5471     }
5472 
multiplyVoiceCallRatUsage( VoiceCallRatUsage[] usages, int times)5473     private static VoiceCallRatUsage[] multiplyVoiceCallRatUsage(
5474             VoiceCallRatUsage[] usages, int times) {
5475         VoiceCallRatUsage[] multipliedUsages = new VoiceCallRatUsage[usages.length];
5476         for (int i = 0; i < usages.length; i++) {
5477             multipliedUsages[i] = new VoiceCallRatUsage();
5478             multipliedUsages[i].carrierId = usages[i].carrierId;
5479             multipliedUsages[i].rat = usages[i].rat;
5480             multipliedUsages[i].callCount = usages[i].callCount * 2;
5481             multipliedUsages[i].totalDurationMillis = usages[i].totalDurationMillis * 2;
5482         }
5483         return multipliedUsages;
5484     }
5485 
copyOf(CellularServiceState source)5486     private static CellularServiceState copyOf(CellularServiceState source) throws Exception {
5487         return CellularServiceState.parseFrom(MessageNano.toByteArray(source));
5488     }
5489 
copyOf(CellularDataServiceSwitch source)5490     private static CellularDataServiceSwitch copyOf(CellularDataServiceSwitch source)
5491             throws Exception {
5492         return CellularDataServiceSwitch.parseFrom(MessageNano.toByteArray(source));
5493     }
5494 
copyOf(ImsRegistrationStats source)5495     private static ImsRegistrationStats copyOf(ImsRegistrationStats source) throws Exception {
5496         return ImsRegistrationStats.parseFrom(MessageNano.toByteArray(source));
5497     }
5498 
copyOf(ImsRegistrationTermination source)5499     private static ImsRegistrationTermination copyOf(ImsRegistrationTermination source)
5500             throws Exception {
5501         return ImsRegistrationTermination.parseFrom(MessageNano.toByteArray(source));
5502     }
5503 
copyOf(DataCallSession source)5504     private static DataCallSession copyOf(DataCallSession source)
5505             throws Exception {
5506         return DataCallSession.parseFrom(MessageNano.toByteArray(source));
5507     }
5508 
copyOf(ImsRegistrationFeatureTagStats source)5509     private static ImsRegistrationFeatureTagStats copyOf(ImsRegistrationFeatureTagStats source)
5510             throws Exception {
5511         return ImsRegistrationFeatureTagStats.parseFrom(MessageNano.toByteArray(source));
5512     }
5513 
copyOf(RcsAcsProvisioningStats source)5514     private static RcsAcsProvisioningStats copyOf(RcsAcsProvisioningStats source)
5515             throws Exception {
5516         return RcsAcsProvisioningStats.parseFrom(MessageNano.toByteArray(source));
5517     }
5518 
copyOf(ImsRegistrationServiceDescStats source)5519     private static ImsRegistrationServiceDescStats copyOf(ImsRegistrationServiceDescStats source)
5520             throws Exception {
5521         return ImsRegistrationServiceDescStats.parseFrom(MessageNano.toByteArray(source));
5522     }
5523 
copyOf(ImsDedicatedBearerListenerEvent source)5524     private static ImsDedicatedBearerListenerEvent copyOf(ImsDedicatedBearerListenerEvent source)
5525             throws Exception {
5526         return ImsDedicatedBearerListenerEvent.parseFrom(MessageNano.toByteArray(source));
5527     }
5528 
copyOf(ImsDedicatedBearerEvent source)5529     private static ImsDedicatedBearerEvent copyOf(ImsDedicatedBearerEvent source)
5530             throws Exception {
5531         return ImsDedicatedBearerEvent.parseFrom(MessageNano.toByteArray(source));
5532     }
5533 
copyOf(UceEventStats source)5534     private static UceEventStats copyOf(UceEventStats source)
5535             throws Exception {
5536         return UceEventStats.parseFrom(MessageNano.toByteArray(source));
5537     }
5538 
copyOf(PresenceNotifyEvent source)5539     private static PresenceNotifyEvent copyOf(PresenceNotifyEvent source)
5540             throws Exception {
5541         return PresenceNotifyEvent.parseFrom(MessageNano.toByteArray(source));
5542     }
5543 
copyOf(SipDelegateStats source)5544     private static SipDelegateStats copyOf(SipDelegateStats source)
5545             throws Exception {
5546         return SipDelegateStats.parseFrom(MessageNano.toByteArray(source));
5547     }
copyOf(SipTransportFeatureTagStats source)5548     private static SipTransportFeatureTagStats copyOf(SipTransportFeatureTagStats source)
5549             throws Exception {
5550         return SipTransportFeatureTagStats.parseFrom(MessageNano.toByteArray(source));
5551     }
5552 
copyOf(GbaEvent source)5553     private static GbaEvent copyOf(GbaEvent source)
5554             throws Exception {
5555         return GbaEvent.parseFrom(MessageNano.toByteArray(source));
5556     }
5557 
copyOf(SipMessageResponse source)5558     private static SipMessageResponse copyOf(SipMessageResponse source)
5559             throws Exception {
5560         return SipMessageResponse.parseFrom(MessageNano.toByteArray(source));
5561     }
5562 
copyOf(SipTransportSession source)5563     private static SipTransportSession copyOf(SipTransportSession source)
5564             throws Exception {
5565         return SipTransportSession.parseFrom(MessageNano.toByteArray(source));
5566     }
5567 
copyOf(IncomingSms source)5568     private static IncomingSms copyOf(IncomingSms source)
5569             throws Exception {
5570         return IncomingSms.parseFrom(MessageNano.toByteArray(source));
5571     }
5572 
copyOf(OutgoingSms source)5573     private static OutgoingSms copyOf(OutgoingSms source)
5574             throws Exception {
5575         return OutgoingSms.parseFrom(MessageNano.toByteArray(source));
5576     }
5577 
copyOf(OutgoingShortCodeSms source)5578     private static OutgoingShortCodeSms copyOf(OutgoingShortCodeSms source)
5579             throws Exception {
5580         return OutgoingShortCodeSms.parseFrom(MessageNano.toByteArray(source));
5581     }
5582 
copyOf(SatelliteController source)5583     private static SatelliteController copyOf(SatelliteController source)
5584             throws Exception {
5585         return SatelliteController.parseFrom(MessageNano.toByteArray(source));
5586     }
5587 
copyOf(SatelliteSession source)5588     private static SatelliteSession copyOf(SatelliteSession source)
5589             throws Exception {
5590         return SatelliteSession.parseFrom(MessageNano.toByteArray(source));
5591     }
5592 
copyOf(SatelliteIncomingDatagram source)5593     private static SatelliteIncomingDatagram copyOf(SatelliteIncomingDatagram source)
5594             throws Exception {
5595         return SatelliteIncomingDatagram.parseFrom(MessageNano.toByteArray(source));
5596     }
5597 
copyOf(SatelliteOutgoingDatagram source)5598     private static SatelliteOutgoingDatagram copyOf(SatelliteOutgoingDatagram source)
5599             throws Exception {
5600         return SatelliteOutgoingDatagram.parseFrom(MessageNano.toByteArray(source));
5601     }
5602 
copyOf(SatelliteProvision source)5603     private static SatelliteProvision copyOf(SatelliteProvision source)
5604             throws Exception {
5605         return SatelliteProvision.parseFrom(MessageNano.toByteArray(source));
5606     }
5607 
copyOf(SatelliteSosMessageRecommender source)5608     private static SatelliteSosMessageRecommender copyOf(SatelliteSosMessageRecommender source)
5609             throws Exception {
5610         return SatelliteSosMessageRecommender.parseFrom(MessageNano.toByteArray(source));
5611     }
5612 
copyOf(DataNetworkValidation source)5613     private static DataNetworkValidation copyOf(DataNetworkValidation source)
5614             throws Exception {
5615         return DataNetworkValidation.parseFrom(MessageNano.toByteArray(source));
5616     }
5617 
copyOf(CarrierRoamingSatelliteSession source)5618     private static CarrierRoamingSatelliteSession copyOf(CarrierRoamingSatelliteSession source)
5619             throws Exception {
5620         return CarrierRoamingSatelliteSession.parseFrom(MessageNano.toByteArray(source));
5621     }
5622 
copyOf( CarrierRoamingSatelliteControllerStats source)5623     private static CarrierRoamingSatelliteControllerStats copyOf(
5624             CarrierRoamingSatelliteControllerStats source) throws Exception {
5625         return CarrierRoamingSatelliteControllerStats.parseFrom(MessageNano.toByteArray(source));
5626     }
5627 
copyOf(SatelliteEntitlement source)5628     private static SatelliteEntitlement copyOf(SatelliteEntitlement source) throws Exception {
5629         return SatelliteEntitlement.parseFrom(MessageNano.toByteArray(source));
5630     }
5631 
copyOf(SatelliteConfigUpdater source)5632     private static SatelliteConfigUpdater copyOf(SatelliteConfigUpdater source) throws Exception {
5633         return SatelliteConfigUpdater.parseFrom(MessageNano.toByteArray(source));
5634     }
5635 
copyOf(SatelliteAccessController source)5636     private static SatelliteAccessController copyOf(SatelliteAccessController source)
5637             throws Exception {
5638         return SatelliteAccessController.parseFrom(MessageNano.toByteArray(source));
5639     }
5640 
assertAllPullTimestampEquals(long timestamp)5641     private void assertAllPullTimestampEquals(long timestamp) {
5642         assertEquals(
5643                 timestamp,
5644                 mPersistAtomsStorage.getAtomsProto().voiceCallRatUsagePullTimestampMillis);
5645         assertEquals(
5646                 timestamp,
5647                 mPersistAtomsStorage.getAtomsProto().voiceCallSessionPullTimestampMillis);
5648         assertEquals(
5649                 timestamp,
5650                 mPersistAtomsStorage.getAtomsProto().cellularServiceStatePullTimestampMillis);
5651         assertEquals(
5652                 timestamp,
5653                 mPersistAtomsStorage.getAtomsProto().cellularDataServiceSwitchPullTimestampMillis);
5654     }
5655 
assertStorageIsEmptyForAllAtoms()5656     private void assertStorageIsEmptyForAllAtoms() {
5657         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallRatUsages(0L));
5658         assertProtoArrayIsEmpty(mPersistAtomsStorage.getVoiceCallSessions(0L));
5659         assertProtoArrayIsEmpty(mPersistAtomsStorage.getCellularServiceStates(0L));
5660         assertProtoArrayIsEmpty(mPersistAtomsStorage.getCellularDataServiceSwitches(0L));
5661     }
5662 
assertProtoArrayIsEmpty(T[] array)5663     private static <T extends MessageNano> void assertProtoArrayIsEmpty(T[] array) {
5664         assertNotNull(array);
5665         assertEquals(0, array.length);
5666     }
5667 
assertProtoArrayEquals(MessageNano[] expected, MessageNano[] actual)5668     private static void assertProtoArrayEquals(MessageNano[] expected, MessageNano[] actual) {
5669         assertNotNull(expected);
5670         assertNotNull(actual);
5671         String message =
5672                 "Expected:\n" + Arrays.toString(expected) + "\nGot:\n" + Arrays.toString(actual);
5673         assertEquals(message, expected.length, actual.length);
5674         for (int i = 0; i < expected.length; i++) {
5675             assertTrue(message, MessageNano.messageNanoEquals(expected[i], actual[i]));
5676         }
5677     }
5678 
assertProtoArrayEqualsIgnoringOrder( MessageNano[] expected, MessageNano[] actual)5679     private static void assertProtoArrayEqualsIgnoringOrder(
5680             MessageNano[] expected, MessageNano[] actual) {
5681         assertNotNull(expected);
5682         assertNotNull(actual);
5683         expected = expected.clone();
5684         actual = actual.clone();
5685         Arrays.sort(expected, sProtoComparator);
5686         Arrays.sort(actual, sProtoComparator);
5687         assertProtoArrayEquals(expected, actual);
5688     }
5689 
assertHasCall( VoiceCallSession[] calls, @Nullable VoiceCallSession expectedCall, int expectedCount)5690     private static void assertHasCall(
5691             VoiceCallSession[] calls, @Nullable VoiceCallSession expectedCall, int expectedCount) {
5692         assertNotNull(calls);
5693         int actualCount = 0;
5694         for (VoiceCallSession call : calls) {
5695             if (call != null && expectedCall != null) {
5696                 if (MessageNano.messageNanoEquals(call, expectedCall)) {
5697                     actualCount++;
5698                 }
5699             }
5700         }
5701         assertEquals(expectedCount, actualCount);
5702     }
5703 
verifyCurrentStateSavedToFileOnce()5704     private void verifyCurrentStateSavedToFileOnce() throws Exception {
5705         InOrder inOrder = inOrder(mTestFileOutputStream);
5706         inOrder.verify(mTestFileOutputStream, times(1))
5707                 .write(eq(PersistAtoms.toByteArray(mPersistAtomsStorage.getAtomsProto())));
5708         inOrder.verify(mTestFileOutputStream, times(1)).close();
5709         inOrder.verifyNoMoreInteractions();
5710     }
5711 
assertHasStatsCountTime( ImsRegistrationFeatureTagStats[] statses, @Nullable ImsRegistrationFeatureTagStats expectedStats, int expectedCount, long expectedTime)5712     private static void assertHasStatsCountTime(
5713             ImsRegistrationFeatureTagStats[] statses,
5714             @Nullable ImsRegistrationFeatureTagStats expectedStats,
5715             int expectedCount, long expectedTime) {
5716         assertNotNull(statses);
5717         int actualCount = 0;
5718         long actualTime = 0;
5719         for (ImsRegistrationFeatureTagStats stats : statses) {
5720             if (stats != null && expectedStats != null) {
5721                 if (stats.carrierId == expectedStats.carrierId
5722                         && stats.slotId == expectedStats.slotId
5723                         && stats.featureTagName == expectedStats.featureTagName
5724                         && stats.registrationTech == expectedStats.registrationTech) {
5725                     actualCount++;
5726                     actualTime += stats.registeredMillis;
5727                 }
5728             }
5729         }
5730         assertEquals(expectedCount, actualCount);
5731         assertEquals(expectedTime, actualTime);
5732     }
5733 
assertHasStatsAndCount( RcsClientProvisioningStats[] statses, @Nullable RcsClientProvisioningStats expectedStats, int expectedCount)5734     private static void assertHasStatsAndCount(
5735             RcsClientProvisioningStats[] statses,
5736             @Nullable RcsClientProvisioningStats expectedStats, int expectedCount) {
5737         assertNotNull(statses);
5738         int actualCount = -1;
5739         for (RcsClientProvisioningStats stats : statses) {
5740             if (stats.carrierId == expectedStats.carrierId
5741                     && stats.slotId == expectedStats.slotId
5742                     && stats.event == expectedStats.event) {
5743                 actualCount = stats.count;
5744             }
5745         }
5746         assertEquals(expectedCount, actualCount);
5747     }
5748 
assertHasStats( ImsDedicatedBearerListenerEvent[] statses, @Nullable ImsDedicatedBearerListenerEvent expectedStats, int expectedCount)5749     private static void assertHasStats(
5750             ImsDedicatedBearerListenerEvent[] statses,
5751             @Nullable ImsDedicatedBearerListenerEvent expectedStats, int expectedCount) {
5752         assertNotNull(statses);
5753         int actualCount = 0;
5754         for (ImsDedicatedBearerListenerEvent stats : statses) {
5755             if (stats != null && expectedStats != null) {
5756                 if (MessageNano.messageNanoEquals(stats, expectedStats)) {
5757                     actualCount++;
5758                 }
5759             }
5760         }
5761         assertEquals(expectedCount, actualCount);
5762     }
5763 
assertHasStatsAndCount( ImsDedicatedBearerEvent[] statses, @Nullable ImsDedicatedBearerEvent expectedStats, int expectedCount)5764     private static void assertHasStatsAndCount(
5765             ImsDedicatedBearerEvent[] statses,
5766             @Nullable ImsDedicatedBearerEvent expectedStats, int expectedCount) {
5767         assertNotNull(statses);
5768         int actualCount = -1;
5769         for (ImsDedicatedBearerEvent stats : statses) {
5770             if (stats.carrierId == expectedStats.carrierId
5771                     && stats.slotId == expectedStats.slotId
5772                     && stats.ratAtEnd == expectedStats.ratAtEnd
5773                     && stats.qci == expectedStats.qci
5774                     && stats.bearerState == expectedStats.bearerState
5775                     && stats.localConnectionInfoReceived
5776                             == expectedStats.localConnectionInfoReceived
5777                     && stats.remoteConnectionInfoReceived
5778                             == expectedStats.remoteConnectionInfoReceived
5779                     && stats.hasListeners == expectedStats.hasListeners) {
5780                 actualCount = stats.count;
5781             }
5782         }
5783         assertEquals(expectedCount, actualCount);
5784     }
5785 
assertHasStats( SatelliteController[] tested, @Nullable SatelliteController expectedStats)5786     private static void assertHasStats(
5787             SatelliteController[] tested,
5788             @Nullable SatelliteController expectedStats) {
5789         assertNotNull(tested);
5790         assertEquals(tested[0].countOfSatelliteServiceEnablementsSuccess,
5791                 expectedStats.countOfSatelliteServiceEnablementsSuccess);
5792         assertEquals(tested[0].countOfSatelliteServiceEnablementsFail,
5793                 expectedStats.countOfSatelliteServiceEnablementsFail);
5794         assertEquals(tested[0].countOfOutgoingDatagramSuccess,
5795                 expectedStats.countOfOutgoingDatagramSuccess);
5796         assertEquals(tested[0].countOfOutgoingDatagramFail,
5797                 expectedStats.countOfOutgoingDatagramFail);
5798         assertEquals(tested[0].countOfIncomingDatagramSuccess,
5799                 expectedStats.countOfIncomingDatagramSuccess);
5800         assertEquals(tested[0].countOfIncomingDatagramFail,
5801                 expectedStats.countOfIncomingDatagramFail);
5802         assertEquals(tested[0].countOfDatagramTypeSosSmsSuccess,
5803                 expectedStats.countOfDatagramTypeSosSmsSuccess);
5804         assertEquals(tested[0].countOfDatagramTypeSosSmsFail,
5805                 expectedStats.countOfDatagramTypeSosSmsFail);
5806         assertEquals(tested[0].countOfDatagramTypeLocationSharingSuccess,
5807                 expectedStats.countOfDatagramTypeLocationSharingSuccess);
5808         assertEquals(tested[0].countOfDatagramTypeLocationSharingFail,
5809                 expectedStats.countOfDatagramTypeLocationSharingFail);
5810         assertEquals(tested[0].totalServiceUptimeSec,
5811                 expectedStats.totalServiceUptimeSec);
5812         assertEquals(tested[0].totalBatteryConsumptionPercent,
5813                 expectedStats.totalBatteryConsumptionPercent);
5814         assertEquals(tested[0].totalBatteryChargedTimeSec,
5815                 expectedStats.totalBatteryChargedTimeSec);
5816         assertEquals(tested[0].countOfDemoModeSatelliteServiceEnablementsSuccess,
5817                 expectedStats.countOfDemoModeSatelliteServiceEnablementsSuccess);
5818         assertEquals(tested[0].countOfDemoModeSatelliteServiceEnablementsFail,
5819                 expectedStats.countOfDemoModeSatelliteServiceEnablementsFail);
5820         assertEquals(tested[0].countOfDemoModeOutgoingDatagramSuccess,
5821                 expectedStats.countOfDemoModeOutgoingDatagramSuccess);
5822         assertEquals(tested[0].countOfDemoModeOutgoingDatagramFail,
5823                 expectedStats.countOfDemoModeOutgoingDatagramFail);
5824         assertEquals(tested[0].countOfDemoModeIncomingDatagramSuccess,
5825                 expectedStats.countOfDemoModeIncomingDatagramSuccess);
5826         assertEquals(tested[0].countOfDemoModeIncomingDatagramFail,
5827                 expectedStats.countOfDemoModeIncomingDatagramFail);
5828     }
5829 
assertHasStatsAndCount( SatelliteSession[] tested, @Nullable SatelliteSession expectedStats, int expectedCount)5830     private static void assertHasStatsAndCount(
5831             SatelliteSession[] tested,
5832             @Nullable SatelliteSession expectedStats, int expectedCount) {
5833         assertNotNull(tested);
5834         int actualCount = 0;
5835         for (SatelliteSession stats : tested) {
5836             if (stats.satelliteServiceInitializationResult
5837                     == expectedStats.satelliteServiceInitializationResult
5838                     && stats.satelliteTechnology == expectedStats.satelliteTechnology
5839                     && stats.satelliteServiceTerminationResult
5840                         == expectedStats.satelliteServiceTerminationResult
5841                     && stats.initializationProcessingTimeMillis
5842                         == expectedStats.initializationProcessingTimeMillis
5843                     && stats.terminationProcessingTimeMillis
5844                         == expectedStats.terminationProcessingTimeMillis
5845                     && stats.sessionDurationSeconds == expectedStats.sessionDurationSeconds
5846                     && stats.countOfOutgoingDatagramSuccess
5847                         == expectedStats.countOfOutgoingDatagramSuccess
5848                     && stats.countOfOutgoingDatagramFailed
5849                         == expectedStats.countOfOutgoingDatagramFailed
5850                     && stats.countOfIncomingDatagramSuccess
5851                         == expectedStats.countOfIncomingDatagramSuccess
5852                     && stats.countOfIncomingDatagramFailed
5853                         == expectedStats.countOfIncomingDatagramFailed
5854                     && stats.isDemoMode == expectedStats.isDemoMode) {
5855                 actualCount = stats.count;
5856             }
5857         }
5858         assertEquals(expectedCount, actualCount);
5859     }
5860 
assertHasStatsAndCount( SatelliteIncomingDatagram[] tested, @Nullable SatelliteIncomingDatagram expectedStats, int expectedCount)5861     private static void assertHasStatsAndCount(
5862             SatelliteIncomingDatagram[] tested,
5863             @Nullable SatelliteIncomingDatagram expectedStats, int expectedCount) {
5864         assertNotNull(tested);
5865         int actualCount = 0;
5866         for (SatelliteIncomingDatagram stats : tested) {
5867             if (stats.resultCode == expectedStats.resultCode
5868                     && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
5869                     && stats.datagramTransferTimeMillis
5870                         == expectedStats.datagramTransferTimeMillis
5871                     && stats.isDemoMode == expectedStats.isDemoMode) {
5872                 actualCount++;
5873             }
5874         }
5875         assertEquals(expectedCount, actualCount);
5876     }
5877 
assertHasStatsAndCount( SatelliteOutgoingDatagram[] tested, @Nullable SatelliteOutgoingDatagram expectedStats, int expectedCount)5878     private static void assertHasStatsAndCount(
5879             SatelliteOutgoingDatagram[] tested,
5880             @Nullable SatelliteOutgoingDatagram expectedStats, int expectedCount) {
5881         assertNotNull(tested);
5882         int actualCount = 0;
5883         for (SatelliteOutgoingDatagram stats : tested) {
5884             if (stats.datagramType == expectedStats.datagramType
5885                     && stats.resultCode == expectedStats.resultCode
5886                     && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
5887                     && stats.datagramTransferTimeMillis
5888                         == expectedStats.datagramTransferTimeMillis
5889                     && stats.isDemoMode == expectedStats.isDemoMode) {
5890                 actualCount++;
5891             }
5892         }
5893         assertEquals(expectedCount, actualCount);
5894     }
5895 
assertHasStatsAndCount( SatelliteProvision[] tested, @Nullable SatelliteProvision expectedStats, int expectedCount)5896     private static void assertHasStatsAndCount(
5897             SatelliteProvision[] tested,
5898             @Nullable SatelliteProvision expectedStats, int expectedCount) {
5899         assertNotNull(tested);
5900         int actualCount = 0;
5901         for (SatelliteProvision stats : tested) {
5902             if (stats.resultCode == expectedStats.resultCode
5903                     && stats.provisioningTimeSec == expectedStats.provisioningTimeSec
5904                     && stats.isProvisionRequest == expectedStats.isProvisionRequest
5905                     && stats.isCanceled == expectedStats.isCanceled) {
5906                 actualCount++;
5907             }
5908         }
5909         assertEquals(expectedCount, actualCount);
5910     }
5911 
assertHasStatsAndCount( SatelliteSosMessageRecommender[] tested, @Nullable SatelliteSosMessageRecommender expectedStats, int expectedCount)5912     private static void assertHasStatsAndCount(
5913             SatelliteSosMessageRecommender[] tested,
5914             @Nullable SatelliteSosMessageRecommender expectedStats, int expectedCount) {
5915         assertNotNull(tested);
5916         int actualCount = 0;
5917         for (SatelliteSosMessageRecommender stats : tested) {
5918             if (stats.isDisplaySosMessageSent
5919                     == expectedStats.isDisplaySosMessageSent
5920                     && stats.countOfTimerStarted == expectedStats.countOfTimerStarted
5921                     && stats.isImsRegistered == expectedStats.isImsRegistered
5922                     && stats.cellularServiceState == expectedStats.cellularServiceState
5923                     && stats.isMultiSim == expectedStats.isMultiSim
5924                     && stats.recommendingHandoverType == expectedStats.recommendingHandoverType
5925                     && stats.isSatelliteAllowedInCurrentLocation
5926                     == expectedStats.isSatelliteAllowedInCurrentLocation) {
5927                 actualCount = stats.count;
5928             }
5929         }
5930         assertEquals(expectedCount, actualCount);
5931     }
5932 
assertHasStatsAndCount( SatelliteAccessController[] tested, @Nullable SatelliteAccessController expectedStats, int expectedCount)5933     private static void assertHasStatsAndCount(
5934             SatelliteAccessController[] tested,
5935             @Nullable SatelliteAccessController expectedStats, int expectedCount) {
5936         assertNotNull(tested);
5937         int actualCount = 0;
5938         for (SatelliteAccessController stats : tested) {
5939             if (stats.accessControlType
5940                     == expectedStats.accessControlType
5941                     && stats.locationQueryTimeMillis == expectedStats.locationQueryTimeMillis
5942                     && stats.onDeviceLookupTimeMillis == expectedStats.onDeviceLookupTimeMillis
5943                     && stats.totalCheckingTimeMillis == expectedStats.totalCheckingTimeMillis
5944                     && stats.isAllowed == expectedStats.isAllowed
5945                     && stats.isEmergency == expectedStats.isEmergency
5946                     && stats.resultCode == expectedStats.resultCode
5947                     && Arrays.equals(stats.countryCodes, expectedStats.countryCodes)
5948                     && stats.configDataSource == expectedStats.configDataSource) {
5949                 actualCount++;
5950             }
5951         }
5952         assertEquals(expectedCount, actualCount);
5953     }
5954 
assertHasStatsAndCountDuration( RcsAcsProvisioningStats[] statses, @Nullable RcsAcsProvisioningStats expectedStats, int count, long duration)5955     private static void assertHasStatsAndCountDuration(
5956             RcsAcsProvisioningStats[] statses,
5957             @Nullable RcsAcsProvisioningStats expectedStats, int count, long duration) {
5958         assertNotNull(statses);
5959         int actualCount = -1;
5960         long actualDuration = -1;
5961         for (RcsAcsProvisioningStats stats : statses) {
5962             if (stats.carrierId == expectedStats.carrierId
5963                     && stats.slotId == expectedStats.slotId
5964                     && stats.responseCode == expectedStats.responseCode
5965                     && stats.responseType == expectedStats.responseType
5966                     && stats.isSingleRegistrationEnabled
5967                             == expectedStats.isSingleRegistrationEnabled) {
5968                 actualCount = stats.count;
5969                 actualDuration = stats.stateTimerMillis;
5970             }
5971         }
5972         assertEquals(count, actualCount);
5973         assertEquals(duration, actualDuration);
5974     }
5975 
assertHasStats(SipDelegateStats[] results, Object expectedStats, int expectedCount)5976     private static void assertHasStats(SipDelegateStats[] results,
5977             Object expectedStats, int expectedCount) {
5978         assertNotNull(results);
5979         assertNotNull(expectedStats);
5980 
5981         int realCount = 0;
5982         if (expectedStats instanceof SipDelegateStats[]) {
5983             SipDelegateStats[] expectedResults = (SipDelegateStats[]) expectedStats;
5984             for (SipDelegateStats stat: results) {
5985                 for (SipDelegateStats estat : expectedResults) {
5986                     if (stat != null && estat != null) {
5987                         if (MessageNano.messageNanoEquals(stat, estat)) {
5988                             realCount++;
5989                             break;
5990                         }
5991                     }
5992                 }
5993             }
5994         } else {
5995             SipDelegateStats expectedResult = (SipDelegateStats) expectedStats;
5996             for (SipDelegateStats stat : results) {
5997                 if (stat != null && expectedStats != null) {
5998                     if (MessageNano.messageNanoEquals(stat, expectedResult)) {
5999                         realCount++;
6000                     }
6001                 }
6002             }
6003         }
6004         assertEquals(expectedCount, realCount);
6005     }
6006 
assertHasStats(SipTransportFeatureTagStats[] results, Object expectedStats, int expectedCount)6007     private static void assertHasStats(SipTransportFeatureTagStats[] results,
6008             Object expectedStats, int expectedCount) {
6009         assertNotNull(results);
6010         assertNotNull(expectedStats);
6011 
6012         int realCount = 0;
6013         if (expectedStats instanceof SipTransportFeatureTagStats[]) {
6014             SipTransportFeatureTagStats[] expectedResults =
6015                     (SipTransportFeatureTagStats[]) expectedStats;
6016             for (SipTransportFeatureTagStats stat: results) {
6017                 for (SipTransportFeatureTagStats estat : expectedResults) {
6018                     if (stat != null && estat != null) {
6019                         if (MessageNano.messageNanoEquals(stat, estat)) {
6020                             realCount++;
6021                             break;
6022                         }
6023                     }
6024                 }
6025             }
6026         } else {
6027             SipTransportFeatureTagStats expectedResult =
6028                     (SipTransportFeatureTagStats) expectedStats;
6029             for (SipTransportFeatureTagStats stat : results) {
6030                 if (stat != null && expectedStats != null) {
6031                     if (MessageNano.messageNanoEquals(stat, expectedResult)) {
6032                         realCount++;
6033                     }
6034                 }
6035             }
6036         }
6037         assertEquals(expectedCount, realCount);
6038     }
6039 
assertHasStatsAndCount( GbaEvent[] statses, @Nullable GbaEvent expectedStats, int expectedCount)6040     private static void assertHasStatsAndCount(
6041             GbaEvent[] statses,
6042             @Nullable GbaEvent expectedStats, int expectedCount) {
6043         assertNotNull(statses);
6044         int actualCount = -1;
6045         for (GbaEvent stats : statses) {
6046             if (stats.carrierId == expectedStats.carrierId
6047                     && stats.slotId == expectedStats.slotId
6048                     && stats.successful == expectedStats.successful
6049                     && stats.failedReason == expectedStats.failedReason) {
6050                 actualCount = stats.count;
6051             }
6052         }
6053         assertEquals(expectedCount, actualCount);
6054     }
6055 
assertHasStats( SipMessageResponse[] statses, @Nullable SipMessageResponse expectedStats, int expectedCount)6056     private static void assertHasStats(
6057             SipMessageResponse[] statses,
6058             @Nullable SipMessageResponse expectedStats, int expectedCount) {
6059         assertNotNull(statses);
6060         int actualCount = -1;
6061         for (SipMessageResponse stats : statses) {
6062             if (stats.carrierId == expectedStats.carrierId
6063                     && stats.slotId == expectedStats.slotId
6064                     && stats.sipMessageMethod == expectedStats.sipMessageMethod
6065                     && stats.sipMessageResponse == expectedStats.sipMessageResponse
6066                     && stats.sipMessageDirection == expectedStats.sipMessageDirection) {
6067                 actualCount = stats.count;
6068             }
6069         }
6070         assertEquals(expectedCount, actualCount);
6071     }
6072 
assertHasStats( SipTransportSession[] statses, @Nullable SipTransportSession expectedStats, int expectedCount)6073     private static void assertHasStats(
6074             SipTransportSession[] statses,
6075             @Nullable SipTransportSession expectedStats, int expectedCount) {
6076         assertNotNull(statses);
6077         int actualCount = -1;
6078         for (SipTransportSession stats : statses) {
6079             if (stats.carrierId == expectedStats.carrierId
6080                     && stats.slotId == expectedStats.slotId
6081                     && stats.sessionMethod == expectedStats.sessionMethod
6082                     && stats.sipMessageDirection == expectedStats.sipMessageDirection
6083                     && stats.sipResponse == expectedStats.sipResponse) {
6084                 actualCount = stats.sessionCount;
6085             }
6086         }
6087         assertEquals(expectedCount, actualCount);
6088     }
6089 
assertHasStatsAndCount( IncomingSms[] incomingSmsList, @Nullable IncomingSms expectedIncomingSms, int expectedCount)6090     private static void assertHasStatsAndCount(
6091             IncomingSms[] incomingSmsList,
6092             @Nullable IncomingSms expectedIncomingSms, int expectedCount) {
6093         assertNotNull(incomingSmsList);
6094         int actualCount = -1;
6095         for (IncomingSms incomingSms : incomingSmsList) {
6096             if (incomingSms.smsFormat == expectedIncomingSms.smsFormat
6097                     && incomingSms.smsTech == expectedIncomingSms.smsTech
6098                     && incomingSms.rat == expectedIncomingSms.rat
6099                     && incomingSms.smsType == expectedIncomingSms.smsType
6100                     && incomingSms.totalParts == expectedIncomingSms.totalParts
6101                     && incomingSms.receivedParts == expectedIncomingSms.receivedParts
6102                     && incomingSms.blocked == expectedIncomingSms.blocked
6103                     && incomingSms.error == expectedIncomingSms.error
6104                     && incomingSms.isRoaming == expectedIncomingSms.isRoaming
6105                     && incomingSms.simSlotIndex == expectedIncomingSms.simSlotIndex
6106                     && incomingSms.isMultiSim == expectedIncomingSms.isMultiSim
6107                     && incomingSms.isEsim == expectedIncomingSms.isEsim
6108                     && incomingSms.carrierId == expectedIncomingSms.carrierId
6109                     && incomingSms.messageId == expectedIncomingSms.messageId
6110                     && incomingSms.isManagedProfile == expectedIncomingSms.isManagedProfile
6111                     && incomingSms.isNtn == expectedIncomingSms.isNtn
6112                     && incomingSms.isEmergency == expectedIncomingSms.isEmergency) {
6113                 actualCount = incomingSms.count;
6114             }
6115         }
6116         assertEquals(expectedCount, actualCount);
6117     }
6118 
assertHasStatsAndCount( OutgoingSms[] outgoingSmsList, @Nullable OutgoingSms expectedOutgoingSms, int expectedCount)6119     private static void assertHasStatsAndCount(
6120             OutgoingSms[] outgoingSmsList,
6121             @Nullable OutgoingSms expectedOutgoingSms, int expectedCount) {
6122         assertNotNull(outgoingSmsList);
6123         int actualCount = -1;
6124         for (OutgoingSms outgoingSms : outgoingSmsList) {
6125             if (outgoingSms.smsFormat == expectedOutgoingSms.smsFormat
6126                     && outgoingSms.smsTech == expectedOutgoingSms.smsTech
6127                     && outgoingSms.rat == expectedOutgoingSms.rat
6128                     && outgoingSms.sendResult == expectedOutgoingSms.sendResult
6129                     && outgoingSms.errorCode == expectedOutgoingSms.errorCode
6130                     && outgoingSms.isRoaming == expectedOutgoingSms.isRoaming
6131                     && outgoingSms.isFromDefaultApp == expectedOutgoingSms.isFromDefaultApp
6132                     && outgoingSms.simSlotIndex == expectedOutgoingSms.simSlotIndex
6133                     && outgoingSms.isMultiSim == expectedOutgoingSms.isMultiSim
6134                     && outgoingSms.carrierId == expectedOutgoingSms.carrierId
6135                     && outgoingSms.messageId == expectedOutgoingSms.messageId
6136                     && outgoingSms.retryId == expectedOutgoingSms.retryId
6137                     && outgoingSms.intervalMillis == expectedOutgoingSms.intervalMillis
6138                     && outgoingSms.sendErrorCode == expectedOutgoingSms.sendErrorCode
6139                     && outgoingSms.networkErrorCode == expectedOutgoingSms.networkErrorCode
6140                     && outgoingSms.isManagedProfile == expectedOutgoingSms.isManagedProfile
6141                     && outgoingSms.isEmergency == expectedOutgoingSms.isEmergency
6142                     && outgoingSms.isNtn == expectedOutgoingSms.isNtn) {
6143                 actualCount = outgoingSms.count;
6144             }
6145         }
6146         assertEquals(expectedCount, actualCount);
6147     }
6148 
assertHasStatsAndCount( OutgoingShortCodeSms[] outgoingShortCodeSmsList, @Nullable OutgoingShortCodeSms expectedOutgoingShortCodeSms, int expectedCount)6149     private static void assertHasStatsAndCount(
6150             OutgoingShortCodeSms[] outgoingShortCodeSmsList,
6151             @Nullable OutgoingShortCodeSms expectedOutgoingShortCodeSms, int expectedCount) {
6152         assertNotNull(outgoingShortCodeSmsList);
6153         int actualCount = -1;
6154         for (OutgoingShortCodeSms outgoingShortCodeSms : outgoingShortCodeSmsList) {
6155             if (outgoingShortCodeSms.category == expectedOutgoingShortCodeSms.category
6156                     && outgoingShortCodeSms.xmlVersion == expectedOutgoingShortCodeSms.xmlVersion) {
6157                 actualCount = outgoingShortCodeSms.shortCodeSmsCount;
6158             }
6159         }
6160         assertEquals(expectedCount, actualCount);
6161     }
6162 
assertHasStatsAndCount(CarrierRoamingSatelliteSession[] tested, @Nullable CarrierRoamingSatelliteSession expectedStats, int expectedCount)6163     private static void assertHasStatsAndCount(CarrierRoamingSatelliteSession[] tested,
6164             @Nullable CarrierRoamingSatelliteSession expectedStats, int expectedCount) {
6165         assertNotNull(tested);
6166         int actualCount = 0;
6167         for (CarrierRoamingSatelliteSession stats : tested) {
6168             if (stats.carrierId == expectedStats.carrierId
6169                     && stats.isNtnRoamingInHomeCountry == expectedStats.isNtnRoamingInHomeCountry
6170                     && stats.totalSatelliteModeTimeSec == expectedStats.totalSatelliteModeTimeSec
6171                     && stats.numberOfSatelliteConnections
6172                     == expectedStats.numberOfSatelliteConnections
6173                     && stats.avgDurationOfSatelliteConnectionSec
6174                     == expectedStats.avgDurationOfSatelliteConnectionSec
6175                     && stats.satelliteConnectionGapMinSec
6176                     == expectedStats.satelliteConnectionGapMinSec
6177                     && stats.satelliteConnectionGapAvgSec
6178                     == expectedStats.satelliteConnectionGapAvgSec
6179                     && stats.satelliteConnectionGapMaxSec
6180                     == expectedStats.satelliteConnectionGapMaxSec
6181                     && stats.rsrpAvg == expectedStats.rsrpAvg
6182                     && stats.rsrpMedian == expectedStats.rsrpMedian
6183                     && stats.rssnrAvg == expectedStats.rssnrAvg
6184                     && stats.rssnrMedian == expectedStats.rssnrMedian
6185                     && stats.countOfIncomingSms == expectedStats.countOfIncomingSms
6186                     && stats.countOfOutgoingSms == expectedStats.countOfOutgoingSms
6187                     && stats.countOfIncomingMms == expectedStats.countOfIncomingMms
6188                     && stats.countOfOutgoingMms == expectedStats.countOfOutgoingMms) {
6189                 actualCount++;
6190             }
6191         }
6192         assertEquals(expectedCount, actualCount);
6193     }
6194 
assertHasStats(CarrierRoamingSatelliteControllerStats[] tested, @Nullable CarrierRoamingSatelliteControllerStats expectedStats)6195     private static void assertHasStats(CarrierRoamingSatelliteControllerStats[] tested,
6196             @Nullable CarrierRoamingSatelliteControllerStats expectedStats) {
6197         assertNotNull(tested);
6198         assertEquals(tested[0].configDataSource, expectedStats.configDataSource);
6199         assertEquals(tested[0].countOfEntitlementStatusQueryRequest,
6200                 expectedStats.countOfEntitlementStatusQueryRequest);
6201         assertEquals(tested[0].countOfSatelliteConfigUpdateRequest,
6202                 expectedStats.countOfSatelliteConfigUpdateRequest);
6203         assertEquals(tested[0].countOfSatelliteNotificationDisplayed,
6204                 expectedStats.countOfSatelliteNotificationDisplayed);
6205         assertEquals(tested[0].satelliteSessionGapMinSec, expectedStats.satelliteSessionGapMinSec);
6206         assertEquals(tested[0].satelliteSessionGapAvgSec, expectedStats.satelliteSessionGapAvgSec);
6207         assertEquals(tested[0].satelliteSessionGapMaxSec, expectedStats.satelliteSessionGapMaxSec);
6208     }
6209 
assertHasStatsAndCount( SatelliteEntitlement[] tested, @Nullable SatelliteEntitlement expectedStats, int expectedCount)6210     private static void assertHasStatsAndCount(
6211             SatelliteEntitlement[] tested,
6212             @Nullable SatelliteEntitlement expectedStats, int expectedCount) {
6213         assertNotNull(tested);
6214         int actualCount = 0;
6215         for (SatelliteEntitlement stats : tested) {
6216             if (stats.carrierId == expectedStats.carrierId
6217                     && stats.result == expectedStats.result
6218                     && stats.entitlementStatus == expectedStats.entitlementStatus
6219                     && stats.isRetry == expectedStats.isRetry) {
6220                 actualCount = stats.count;
6221             }
6222         }
6223         assertEquals(expectedCount, actualCount);
6224     }
6225 
assertHasStatsAndCount( SatelliteConfigUpdater[] tested, @Nullable SatelliteConfigUpdater expectedStats, int expectedCount)6226     private static void assertHasStatsAndCount(
6227             SatelliteConfigUpdater[] tested,
6228             @Nullable SatelliteConfigUpdater expectedStats, int expectedCount) {
6229         assertNotNull(tested);
6230         int actualCount = 0;
6231         for (SatelliteConfigUpdater stats : tested) {
6232             if (stats.configVersion == expectedStats.configVersion
6233                     && stats.oemConfigResult == expectedStats.oemConfigResult
6234                     && stats.carrierConfigResult == expectedStats.carrierConfigResult) {
6235                 actualCount = stats.count;
6236             }
6237         }
6238         assertEquals(expectedCount, actualCount);
6239     }
6240 }
6241