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 com.android.internal.telephony.TelephonyStatsLog.CARRIER_ID_TABLE_VERSION;
20 import static com.android.internal.telephony.TelephonyStatsLog.CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS;
21 import static com.android.internal.telephony.TelephonyStatsLog.CARRIER_ROAMING_SATELLITE_SESSION;
22 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_DATA_SERVICE_SWITCH;
23 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE;
24 import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION;
25 import static com.android.internal.telephony.TelephonyStatsLog.DATA_NETWORK_VALIDATION;
26 import static com.android.internal.telephony.TelephonyStatsLog.DEVICE_TELEPHONY_PROPERTIES;
27 import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO;
28 import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT;
29 import static com.android.internal.telephony.TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT;
30 import static com.android.internal.telephony.TelephonyStatsLog.IMS_DEDICATED_BEARER_LISTENER_EVENT;
31 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_FEATURE_TAG_STATS;
32 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS;
33 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_STATS;
34 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_TERMINATION;
35 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS;
36 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SHORT_CODE_SMS;
37 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS;
38 import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS;
39 import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT;
40 import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS;
41 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS;
42 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_ACCESS_CONTROLLER;
43 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_CONFIG_UPDATER;
44 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_CONTROLLER;
45 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_ENTITLEMENT;
46 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_INCOMING_DATAGRAM;
47 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_OUTGOING_DATAGRAM;
48 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_PROVISION;
49 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_SESSION;
50 import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_SOS_MESSAGE_RECOMMENDER;
51 import static com.android.internal.telephony.TelephonyStatsLog.SIM_SLOT_STATE;
52 import static com.android.internal.telephony.TelephonyStatsLog.SIP_DELEGATE_STATS;
53 import static com.android.internal.telephony.TelephonyStatsLog.SIP_MESSAGE_RESPONSE;
54 import static com.android.internal.telephony.TelephonyStatsLog.SIP_TRANSPORT_FEATURE_TAG_STATS;
55 import static com.android.internal.telephony.TelephonyStatsLog.SIP_TRANSPORT_SESSION;
56 import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY;
57 import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_NETWORK_REQUESTS_V2;
58 import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS;
59 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
60 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
61 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
62 import static com.android.internal.telephony.util.TelephonyUtils.IS_DEBUGGABLE;
63 
64 import android.annotation.NonNull;
65 import android.app.StatsManager;
66 import android.content.Context;
67 import android.telephony.SubscriptionManager;
68 import android.telephony.TelephonyManager;
69 import android.util.StatsEvent;
70 
71 import com.android.internal.annotations.VisibleForTesting;
72 import com.android.internal.telephony.Phone;
73 import com.android.internal.telephony.PhoneFactory;
74 import com.android.internal.telephony.TelephonyStatsLog;
75 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
76 import com.android.internal.telephony.flags.FeatureFlags;
77 import com.android.internal.telephony.imsphone.ImsPhone;
78 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteControllerStats;
79 import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteSession;
80 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
81 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
82 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
83 import com.android.internal.telephony.nano.PersistAtomsProto.DataNetworkValidation;
84 import com.android.internal.telephony.nano.PersistAtomsProto.EmergencyNumbersInfo;
85 import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
86 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
87 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
88 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
89 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
90 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
91 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
92 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
93 import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2;
94 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms;
95 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
96 import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
97 import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
98 import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
99 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController;
100 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater;
101 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController;
102 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement;
103 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
104 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
105 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
106 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
107 import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
108 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
109 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
110 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
111 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
112 import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
113 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
114 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
115 import com.android.internal.telephony.uicc.UiccController;
116 import com.android.internal.telephony.uicc.UiccSlot;
117 import com.android.internal.util.ConcurrentUtils;
118 import com.android.telephony.Rlog;
119 
120 import java.time.Duration;
121 import java.util.Arrays;
122 import java.util.Comparator;
123 import java.util.List;
124 import java.util.Random;
125 import java.util.Set;
126 import java.util.concurrent.ConcurrentHashMap;
127 
128 /**
129  * Implements statsd pullers for Telephony.
130  *
131  * <p>This class registers pullers to statsd, which will be called once a day to obtain telephony
132  * statistics that cannot be sent to statsd in real time.
133  */
134 public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
135     private static final String TAG = MetricsCollector.class.getSimpleName();
136 
137     /** Disables various restrictions to ease debugging during development. */
138     private static final boolean DBG = false; // STOPSHIP if true
139 
140     private static final long MILLIS_PER_HOUR = Duration.ofHours(1).toMillis();
141     private static final long MILLIS_PER_MINUTE = Duration.ofMinutes(1).toMillis();
142     private static final long MILLIS_PER_SECOND = Duration.ofSeconds(1).toMillis();
143 
144     /**
145      * Sets atom pull cool down to 23 hours to help enforcing privacy requirement.
146      *
147      * <p>Applies to certain atoms. The interval of 23 hours leaves some margin for pull operations
148      * that occur once a day.
149      */
150     private static final long MIN_COOLDOWN_MILLIS =
151             DBG ? 10L * MILLIS_PER_SECOND : 23L * MILLIS_PER_HOUR;
152 
153 
154     /**
155      * Buckets with less than these many calls will be dropped.
156      *
157      * <p>Applies to metrics with duration fields. Currently used by voice call RAT usages.
158      */
159     private static final long MIN_CALLS_PER_BUCKET = DBG ? 0L : 5L;
160 
161     /** Bucket size in milliseconds to round call durations info. */
162     private static final long DURATION_BUCKET_MILLIS =
163             DBG ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
164 
165     /**
166      * Sets smaller bucket size to round call durations for userdebug build.
167      *
168      * <p>Applies to certain atoms: CellularServiceState.
169      */
170     private static final long CELL_SERVICE_DURATION_BUCKET_MILLIS =
171             DBG || IS_DEBUGGABLE ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
172 
173     /**
174      * Sets atom pull cool down to 4 minutes for userdebug build, 5 hours for user build.
175      *
176      * <p>Applies to certain atoms: CellularServiceState, DataCallSession,
177      * ImsRegistrationTermination.
178      */
179     private final long mPowerCorrelatedMinCooldownMillis;
180     private final PersistAtomsStorage mStorage;
181     private final DeviceStateHelper mDeviceStateHelper;
182     private final StatsManager mStatsManager;
183     private final VonrHelper mVonrHelper;
184     private final AirplaneModeStats mAirplaneModeStats;
185     private final DefaultNetworkMonitor mDefaultNetworkMonitor;
186     private final Set<DataCallSessionStats> mOngoingDataCallStats = ConcurrentHashMap.newKeySet();
187     private static final Random sRandom = new Random();
188 
MetricsCollector(Context context, @NonNull FeatureFlags featureFlags)189     public MetricsCollector(Context context, @NonNull FeatureFlags featureFlags) {
190         this(context, new PersistAtomsStorage(context),
191                 new DeviceStateHelper(context), new VonrHelper(featureFlags),
192                 new DefaultNetworkMonitor(context, featureFlags), featureFlags);
193     }
194 
195     /** Allows dependency injection. Used during unit tests. */
196     @VisibleForTesting
MetricsCollector(Context context, PersistAtomsStorage storage, DeviceStateHelper deviceStateHelper, VonrHelper vonrHelper, DefaultNetworkMonitor defaultNetworkMonitor, @NonNull FeatureFlags featureFlags)197     public MetricsCollector(Context context, PersistAtomsStorage storage,
198             DeviceStateHelper deviceStateHelper, VonrHelper vonrHelper,
199             DefaultNetworkMonitor defaultNetworkMonitor, @NonNull FeatureFlags featureFlags) {
200         mStorage = storage;
201         mDeviceStateHelper = deviceStateHelper;
202         mStatsManager = (StatsManager) context.getSystemService(Context.STATS_MANAGER);
203         mVonrHelper = vonrHelper;
204         if (mStatsManager != null) {
205             // Most (but not all) of these are subject to cooldown specified by MIN_COOLDOWN_MILLIS.
206             registerAtom(CELLULAR_DATA_SERVICE_SWITCH);
207             registerAtom(CELLULAR_SERVICE_STATE);
208             registerAtom(SIM_SLOT_STATE);
209             registerAtom(SUPPORTED_RADIO_ACCESS_FAMILY);
210             registerAtom(VOICE_CALL_RAT_USAGE);
211             registerAtom(VOICE_CALL_SESSION);
212             registerAtom(INCOMING_SMS);
213             registerAtom(OUTGOING_SMS);
214             registerAtom(CARRIER_ID_TABLE_VERSION);
215             registerAtom(DATA_CALL_SESSION);
216             registerAtom(IMS_REGISTRATION_STATS);
217             registerAtom(IMS_REGISTRATION_TERMINATION);
218             registerAtom(TELEPHONY_NETWORK_REQUESTS_V2);
219             registerAtom(IMS_REGISTRATION_FEATURE_TAG_STATS);
220             registerAtom(RCS_CLIENT_PROVISIONING_STATS);
221             registerAtom(RCS_ACS_PROVISIONING_STATS);
222             registerAtom(SIP_DELEGATE_STATS);
223             registerAtom(SIP_TRANSPORT_FEATURE_TAG_STATS);
224             registerAtom(SIP_MESSAGE_RESPONSE);
225             registerAtom(SIP_TRANSPORT_SESSION);
226             registerAtom(DEVICE_TELEPHONY_PROPERTIES);
227             registerAtom(IMS_DEDICATED_BEARER_LISTENER_EVENT);
228             registerAtom(IMS_DEDICATED_BEARER_EVENT);
229             registerAtom(IMS_REGISTRATION_SERVICE_DESC_STATS);
230             registerAtom(UCE_EVENT_STATS);
231             registerAtom(PRESENCE_NOTIFY_EVENT);
232             registerAtom(GBA_EVENT);
233             registerAtom(PER_SIM_STATUS);
234             registerAtom(OUTGOING_SHORT_CODE_SMS);
235             registerAtom(EMERGENCY_NUMBERS_INFO);
236             registerAtom(SATELLITE_CONTROLLER);
237             registerAtom(SATELLITE_SESSION);
238             registerAtom(SATELLITE_INCOMING_DATAGRAM);
239             registerAtom(SATELLITE_OUTGOING_DATAGRAM);
240             registerAtom(SATELLITE_PROVISION);
241             registerAtom(SATELLITE_SOS_MESSAGE_RECOMMENDER);
242             registerAtom(DATA_NETWORK_VALIDATION);
243             registerAtom(CARRIER_ROAMING_SATELLITE_SESSION);
244             registerAtom(CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS);
245             registerAtom(SATELLITE_ENTITLEMENT);
246             registerAtom(SATELLITE_CONFIG_UPDATER);
247             registerAtom(SATELLITE_ACCESS_CONTROLLER);
248             Rlog.d(TAG, "registered");
249         } else {
250             Rlog.e(TAG, "could not get StatsManager, atoms not registered");
251         }
252 
253         mAirplaneModeStats = new AirplaneModeStats(context);
254         mDefaultNetworkMonitor = new DefaultNetworkMonitor(context, featureFlags);
255         mPowerCorrelatedMinCooldownMillis = DBG ? 10L * MILLIS_PER_SECOND :
256                 IS_DEBUGGABLE ? 4L * MILLIS_PER_MINUTE : (long) context.getResources().getInteger(
257                 com.android.internal.R.integer.config_metrics_pull_cooldown_millis);
258     }
259 
260     /**
261      * {@inheritDoc}
262      *
263      * @return {@link StatsManager#PULL_SUCCESS} with list of atoms (potentially empty) if pull
264      *     succeeded, {@link StatsManager#PULL_SKIP} if pull was too frequent or atom ID is
265      *     unexpected.
266      */
267     @Override
onPullAtom(int atomTag, List<StatsEvent> data)268     public int onPullAtom(int atomTag, List<StatsEvent> data) {
269         switch (atomTag) {
270             case CELLULAR_DATA_SERVICE_SWITCH:
271                 return pullCellularDataServiceSwitch(data);
272             case CELLULAR_SERVICE_STATE:
273                 return pullCellularServiceState(data);
274             case SIM_SLOT_STATE:
275                 return pullSimSlotState(data);
276             case SUPPORTED_RADIO_ACCESS_FAMILY:
277                 return pullSupportedRadioAccessFamily(data);
278             case VOICE_CALL_RAT_USAGE:
279                 return pullVoiceCallRatUsages(data);
280             case VOICE_CALL_SESSION:
281                 return pullVoiceCallSessions(data);
282             case INCOMING_SMS:
283                 return pullIncomingSms(data);
284             case OUTGOING_SMS:
285                 return pullOutgoingSms(data);
286             case CARRIER_ID_TABLE_VERSION:
287                 return pullCarrierIdTableVersion(data);
288             case DATA_CALL_SESSION:
289                 return pullDataCallSession(data);
290             case IMS_REGISTRATION_STATS:
291                 return pullImsRegistrationStats(data);
292             case IMS_REGISTRATION_TERMINATION:
293                 return pullImsRegistrationTermination(data);
294             case TELEPHONY_NETWORK_REQUESTS_V2:
295                 return pullTelephonyNetworkRequestsV2(data);
296             case DEVICE_TELEPHONY_PROPERTIES:
297                 return pullDeviceTelephonyProperties(data);
298             case IMS_REGISTRATION_FEATURE_TAG_STATS:
299                 return pullImsRegistrationFeatureTagStats(data);
300             case RCS_CLIENT_PROVISIONING_STATS:
301                 return pullRcsClientProvisioningStats(data);
302             case RCS_ACS_PROVISIONING_STATS:
303                 return pullRcsAcsProvisioningStats(data);
304             case SIP_DELEGATE_STATS:
305                 return pullSipDelegateStats(data);
306             case SIP_TRANSPORT_FEATURE_TAG_STATS:
307                 return pullSipTransportFeatureTagStats(data);
308             case SIP_MESSAGE_RESPONSE:
309                 return pullSipMessageResponse(data);
310             case SIP_TRANSPORT_SESSION:
311                 return pullSipTransportSession(data);
312             case IMS_DEDICATED_BEARER_LISTENER_EVENT:
313                 return pullImsDedicatedBearerListenerEvent(data);
314             case IMS_DEDICATED_BEARER_EVENT:
315                 return pullImsDedicatedBearerEvent(data);
316             case IMS_REGISTRATION_SERVICE_DESC_STATS:
317                 return pullImsRegistrationServiceDescStats(data);
318             case UCE_EVENT_STATS:
319                 return pullUceEventStats(data);
320             case PRESENCE_NOTIFY_EVENT:
321                 return pullPresenceNotifyEvent(data);
322             case GBA_EVENT:
323                 return pullGbaEvent(data);
324             case PER_SIM_STATUS:
325                 return pullPerSimStatus(data);
326             case OUTGOING_SHORT_CODE_SMS:
327                 return pullOutgoingShortCodeSms(data);
328             case EMERGENCY_NUMBERS_INFO:
329                 return pullEmergencyNumbersInfo(data);
330             case SATELLITE_CONTROLLER:
331                 return pullSatelliteController(data);
332             case SATELLITE_SESSION:
333                 return pullSatelliteSession(data);
334             case SATELLITE_INCOMING_DATAGRAM:
335                 return pullSatelliteIncomingDatagram(data);
336             case SATELLITE_OUTGOING_DATAGRAM:
337                 return pullSatelliteOutgoingDatagram(data);
338             case SATELLITE_PROVISION:
339                 return pullSatelliteProvision(data);
340             case SATELLITE_SOS_MESSAGE_RECOMMENDER:
341                 return pullSatelliteSosMessageRecommender(data);
342             case DATA_NETWORK_VALIDATION:
343                 return pullDataNetworkValidation(data);
344             case CARRIER_ROAMING_SATELLITE_SESSION:
345                 return pullCarrierRoamingSatelliteSession(data);
346             case CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS:
347                 return pullCarrierRoamingSatelliteControllerStats(data);
348             case SATELLITE_ENTITLEMENT:
349                 return pullSatelliteEntitlement(data);
350             case SATELLITE_CONFIG_UPDATER:
351                 return pullSatelliteConfigUpdater(data);
352             case SATELLITE_ACCESS_CONTROLLER:
353                 return pullSatelliteAccessController(data);
354             default:
355                 Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag));
356                 return StatsManager.PULL_SKIP;
357         }
358     }
359 
360     /** Returns the {@link PersistAtomsStorage} backing the puller. */
getAtomsStorage()361     public PersistAtomsStorage getAtomsStorage() {
362         return mStorage;
363     }
364 
365     /** Returns the {@link DeviceStateHelper}. */
getDeviceStateHelper()366     public DeviceStateHelper getDeviceStateHelper() {
367         return mDeviceStateHelper;
368     }
369 
370     /** Returns the {@link VonrHelper}. */
getVonrHelper()371     public VonrHelper getVonrHelper() {
372         return mVonrHelper;
373     }
374 
375     /** Updates duration segments and calls {@link PersistAtomsStorage#flushAtoms()}. */
flushAtomsStorage()376     public void flushAtomsStorage() {
377         concludeAll();
378         mStorage.flushAtoms();
379     }
380 
381     /** Updates duration segments and calls {@link PersistAtomsStorage#clearAtoms()}. */
clearAtomsStorage()382     public void clearAtomsStorage() {
383         concludeAll();
384         mStorage.clearAtoms();
385     }
386 
387     /**
388      * Registers a {@link DataCallSessionStats} which will be pinged for on-going data calls when
389      * data call atoms are pulled.
390      */
registerOngoingDataCallStat(DataCallSessionStats call)391     public void registerOngoingDataCallStat(DataCallSessionStats call) {
392         mOngoingDataCallStats.add(call);
393     }
394 
395     /** Unregisters a {@link DataCallSessionStats} when it no longer handles an active data call. */
unregisterOngoingDataCallStat(DataCallSessionStats call)396     public void unregisterOngoingDataCallStat(DataCallSessionStats call) {
397         mOngoingDataCallStats.remove(call);
398     }
399 
getDefaultNetworkMonitor()400     public DefaultNetworkMonitor getDefaultNetworkMonitor() {
401         return mDefaultNetworkMonitor;
402     }
403 
concludeDataCallSessionStats()404     private void concludeDataCallSessionStats() {
405         for (DataCallSessionStats stats : mOngoingDataCallStats) {
406             stats.conclude();
407         }
408     }
409 
concludeImsStats()410     private void concludeImsStats() {
411         for (Phone phone : getPhonesIfAny()) {
412             ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
413             if (imsPhone != null) {
414                 imsPhone.getImsStats().conclude();
415             }
416         }
417     }
418 
concludeServiceStateStats()419     private void concludeServiceStateStats() {
420         for (Phone phone : getPhonesIfAny()) {
421             phone.getServiceStateTracker().getServiceStateStats().conclude();
422         }
423     }
424 
concludeRcsStats()425     private void concludeRcsStats() {
426         RcsStats rcsStats = RcsStats.getInstance();
427         if (rcsStats != null) {
428             rcsStats.concludeSipTransportFeatureTagsStat();
429             rcsStats.onFlushIncompleteRcsAcsProvisioningStats();
430             rcsStats.onFlushIncompleteImsRegistrationServiceDescStats();
431             rcsStats.onFlushIncompleteImsRegistrationFeatureTagStats();
432         }
433     }
434 
concludeAll()435     private void concludeAll() {
436         concludeDataCallSessionStats();
437         concludeImsStats();
438         concludeServiceStateStats();
439         concludeRcsStats();
440     }
441 
pullSimSlotState(List<StatsEvent> data)442     private static int pullSimSlotState(List<StatsEvent> data) {
443         SimSlotState state;
444         try {
445             state = SimSlotState.getCurrentState();
446         } catch (RuntimeException e) {
447             // UiccController has not been made yet
448             return StatsManager.PULL_SKIP;
449         }
450 
451         data.add(
452                 TelephonyStatsLog.buildStatsEvent(
453                         SIM_SLOT_STATE,
454                         state.numActiveSlots,
455                         state.numActiveSims,
456                         state.numActiveEsims,
457                         state.numActiveEsimSlots,
458                         state.numActiveMepSlots));
459         return StatsManager.PULL_SUCCESS;
460     }
461 
pullSupportedRadioAccessFamily(List<StatsEvent> data)462     private static int pullSupportedRadioAccessFamily(List<StatsEvent> data) {
463         Phone[] phones = getPhonesIfAny();
464         if (phones.length == 0) {
465             return StatsManager.PULL_SKIP;
466         }
467 
468         // The bitmask is defined in android.telephony.TelephonyManager.NetworkTypeBitMask
469         long rafSupported = 0L;
470         for (Phone phone : PhoneFactory.getPhones()) {
471             rafSupported |= phone.getRadioAccessFamily();
472         }
473 
474         data.add(TelephonyStatsLog.buildStatsEvent(SUPPORTED_RADIO_ACCESS_FAMILY, rafSupported));
475         return StatsManager.PULL_SUCCESS;
476     }
477 
pullCarrierIdTableVersion(List<StatsEvent> data)478     private static int pullCarrierIdTableVersion(List<StatsEvent> data) {
479         Phone[] phones = getPhonesIfAny();
480         if (phones.length == 0) {
481             return StatsManager.PULL_SKIP;
482         } else {
483             // All phones should have the same version of the carrier ID table, so only query the
484             // first one.
485             int version = phones[0].getCarrierIdListVersion();
486             data.add(TelephonyStatsLog.buildStatsEvent(CARRIER_ID_TABLE_VERSION, version));
487             return StatsManager.PULL_SUCCESS;
488         }
489     }
490 
pullVoiceCallRatUsages(List<StatsEvent> data)491     private int pullVoiceCallRatUsages(List<StatsEvent> data) {
492         VoiceCallRatUsage[] usages = mStorage.getVoiceCallRatUsages(MIN_COOLDOWN_MILLIS);
493         if (usages != null) {
494             // sort by carrier/RAT and remove buckets with insufficient number of calls
495             Arrays.stream(usages)
496                     .sorted(
497                             Comparator.comparingLong(
498                                     usage -> ((long) usage.carrierId << 32) | usage.rat))
499                     .filter(usage -> usage.callCount >= MIN_CALLS_PER_BUCKET)
500                     .forEach(usage -> data.add(buildStatsEvent(usage)));
501             Rlog.d(
502                     TAG,
503                     String.format(
504                             "%d out of %d VOICE_CALL_RAT_USAGE pulled",
505                             data.size(), usages.length));
506             return StatsManager.PULL_SUCCESS;
507         } else {
508             Rlog.w(TAG, "VOICE_CALL_RAT_USAGE pull too frequent, skipping");
509             return StatsManager.PULL_SKIP;
510         }
511     }
512 
pullVoiceCallSessions(List<StatsEvent> data)513     private int pullVoiceCallSessions(List<StatsEvent> data) {
514         VoiceCallSession[] calls = mStorage.getVoiceCallSessions(MIN_COOLDOWN_MILLIS);
515         if (calls != null) {
516             // call session list is already shuffled when calls were inserted
517             Arrays.stream(calls).forEach(call -> data.add(buildStatsEvent(call)));
518             return StatsManager.PULL_SUCCESS;
519         } else {
520             Rlog.w(TAG, "VOICE_CALL_SESSION pull too frequent, skipping");
521             return StatsManager.PULL_SKIP;
522         }
523     }
524 
pullIncomingSms(List<StatsEvent> data)525     private int pullIncomingSms(List<StatsEvent> data) {
526         IncomingSms[] smsList = mStorage.getIncomingSms(MIN_COOLDOWN_MILLIS);
527         if (smsList != null) {
528             // SMS list is already shuffled when SMS were inserted
529             Arrays.stream(smsList).forEach(sms -> data.add(buildStatsEvent(sms)));
530             return StatsManager.PULL_SUCCESS;
531         } else {
532             Rlog.w(TAG, "INCOMING_SMS pull too frequent, skipping");
533             return StatsManager.PULL_SKIP;
534         }
535     }
536 
pullOutgoingSms(List<StatsEvent> data)537     private int pullOutgoingSms(List<StatsEvent> data) {
538         OutgoingSms[] smsList = mStorage.getOutgoingSms(MIN_COOLDOWN_MILLIS);
539         if (smsList != null) {
540             // SMS list is already shuffled when SMS were inserted
541             Arrays.stream(smsList).forEach(sms -> data.add(buildStatsEvent(sms)));
542             return StatsManager.PULL_SUCCESS;
543         } else {
544             Rlog.w(TAG, "OUTGOING_SMS pull too frequent, skipping");
545             return StatsManager.PULL_SKIP;
546         }
547     }
548 
pullDataCallSession(List<StatsEvent> data)549     private int pullDataCallSession(List<StatsEvent> data) {
550         // Include ongoing data call segments
551         concludeDataCallSessionStats();
552         DataCallSession[] dataCallSessions = mStorage.getDataCallSessions(
553                 mPowerCorrelatedMinCooldownMillis);
554         if (dataCallSessions != null) {
555             Arrays.stream(dataCallSessions)
556                     .forEach(dataCall -> data.add(buildStatsEvent(dataCall)));
557             return StatsManager.PULL_SUCCESS;
558         } else {
559             Rlog.w(TAG, "DATA_CALL_SESSION pull too frequent, skipping");
560             return StatsManager.PULL_SKIP;
561         }
562     }
563 
pullCellularDataServiceSwitch(List<StatsEvent> data)564     private int pullCellularDataServiceSwitch(List<StatsEvent> data) {
565         CellularDataServiceSwitch[] persistAtoms =
566                 mStorage.getCellularDataServiceSwitches(MIN_COOLDOWN_MILLIS);
567         if (persistAtoms != null) {
568             // list is already shuffled when instances were inserted
569             Arrays.stream(persistAtoms)
570                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
571             return StatsManager.PULL_SUCCESS;
572         } else {
573             Rlog.w(TAG, "CELLULAR_DATA_SERVICE_SWITCH pull too frequent, skipping");
574             return StatsManager.PULL_SKIP;
575         }
576     }
577 
pullCellularServiceState(List<StatsEvent> data)578     private int pullCellularServiceState(List<StatsEvent> data) {
579         // Include the latest durations
580         concludeServiceStateStats();
581         CellularServiceState[] persistAtoms = mStorage.getCellularServiceStates(
582                 mPowerCorrelatedMinCooldownMillis);
583         if (persistAtoms != null) {
584             // list is already shuffled when instances were inserted
585             Arrays.stream(persistAtoms)
586                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
587             return StatsManager.PULL_SUCCESS;
588         } else {
589             Rlog.w(TAG, "CELLULAR_SERVICE_STATE pull too frequent, skipping");
590             return StatsManager.PULL_SKIP;
591         }
592     }
593 
pullImsRegistrationStats(List<StatsEvent> data)594     private int pullImsRegistrationStats(List<StatsEvent> data) {
595         // Include the latest durations
596         concludeImsStats();
597         ImsRegistrationStats[] persistAtoms = mStorage.getImsRegistrationStats(MIN_COOLDOWN_MILLIS);
598         if (persistAtoms != null) {
599             // list is already shuffled when instances were inserted
600             Arrays.stream(persistAtoms)
601                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
602             return StatsManager.PULL_SUCCESS;
603         } else {
604             Rlog.w(TAG, "IMS_REGISTRATION_STATS pull too frequent, skipping");
605             return StatsManager.PULL_SKIP;
606         }
607     }
608 
pullImsRegistrationTermination(List<StatsEvent> data)609     private int pullImsRegistrationTermination(List<StatsEvent> data) {
610         ImsRegistrationTermination[] persistAtoms = mStorage.getImsRegistrationTerminations(
611                 mPowerCorrelatedMinCooldownMillis);
612         if (persistAtoms != null) {
613             // list is already shuffled when instances were inserted
614             Arrays.stream(persistAtoms)
615                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
616             return StatsManager.PULL_SUCCESS;
617         } else {
618             Rlog.w(TAG, "IMS_REGISTRATION_TERMINATION pull too frequent, skipping");
619             return StatsManager.PULL_SKIP;
620         }
621     }
622 
pullTelephonyNetworkRequestsV2(List<StatsEvent> data)623     private int pullTelephonyNetworkRequestsV2(List<StatsEvent> data) {
624         NetworkRequestsV2[] persistAtoms = mStorage.getNetworkRequestsV2(MIN_COOLDOWN_MILLIS);
625         if (persistAtoms != null) {
626             Arrays.stream(persistAtoms)
627                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
628             return StatsManager.PULL_SUCCESS;
629         } else {
630             Rlog.w(TAG, "TELEPHONY_NETWORK_REQUESTS_V2 pull too frequent, skipping");
631             return StatsManager.PULL_SKIP;
632         }
633     }
634 
pullDeviceTelephonyProperties(List<StatsEvent> data)635     private int pullDeviceTelephonyProperties(List<StatsEvent> data) {
636         Phone[] phones = getPhonesIfAny();
637         if (phones.length == 0) {
638             return StatsManager.PULL_SKIP;
639         }
640         boolean isAutoDataSwitchOn = Arrays.stream(phones)
641                 .anyMatch(phone ->
642                         phone.getSubId() != SubscriptionManager.getDefaultDataSubscriptionId()
643                                 && phone.getDataSettingsManager().isMobileDataPolicyEnabled(
644                         TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH));
645         boolean hasDedicatedManagedProfileSub = Arrays.stream(phones)
646                 .anyMatch(Phone::isManagedProfile);
647 
648         UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
649         int mepSupportedSlotCount = (int) Arrays.stream(slots)
650                 .filter(UiccSlot::isMultipleEnabledProfileSupported)
651                 .count();
652 
653         data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES, true,
654                 isAutoDataSwitchOn, mStorage.getAutoDataSwitchToggleCount(),
655                 hasDedicatedManagedProfileSub, mepSupportedSlotCount));
656         return StatsManager.PULL_SUCCESS;
657     }
658 
pullImsRegistrationFeatureTagStats(List<StatsEvent> data)659     private int pullImsRegistrationFeatureTagStats(List<StatsEvent> data) {
660         RcsStats.getInstance().onFlushIncompleteImsRegistrationFeatureTagStats();
661 
662         ImsRegistrationFeatureTagStats[] persistAtoms =
663                 mStorage.getImsRegistrationFeatureTagStats(MIN_COOLDOWN_MILLIS);
664         if (persistAtoms != null) {
665             Arrays.stream(persistAtoms)
666                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
667             return StatsManager.PULL_SUCCESS;
668         } else {
669             Rlog.w(TAG, "IMS_REGISTRATION_FEATURE_TAG_STATS pull too frequent, skipping");
670             return StatsManager.PULL_SKIP;
671         }
672     }
673 
pullRcsClientProvisioningStats(List<StatsEvent> data)674     private int pullRcsClientProvisioningStats(List<StatsEvent> data) {
675         RcsClientProvisioningStats[] persistAtoms =
676                 mStorage.getRcsClientProvisioningStats(MIN_COOLDOWN_MILLIS);
677         if (persistAtoms != null) {
678             Arrays.stream(persistAtoms)
679                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
680             return StatsManager.PULL_SUCCESS;
681         } else {
682             Rlog.w(TAG, "RCS_CLIENT_PROVISIONING_STATS pull too frequent, skipping");
683             return StatsManager.PULL_SKIP;
684         }
685     }
686 
pullRcsAcsProvisioningStats(List<StatsEvent> data)687     private int pullRcsAcsProvisioningStats(List<StatsEvent> data) {
688         RcsStats.getInstance().onFlushIncompleteRcsAcsProvisioningStats();
689 
690         RcsAcsProvisioningStats[] persistAtoms =
691                 mStorage.getRcsAcsProvisioningStats(MIN_COOLDOWN_MILLIS);
692         if (persistAtoms != null) {
693             Arrays.stream(persistAtoms)
694                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
695             return StatsManager.PULL_SUCCESS;
696         } else {
697             Rlog.w(TAG, "RCS_ACS_PROVISIONING_STATS pull too frequent, skipping");
698             return StatsManager.PULL_SKIP;
699         }
700     }
701 
pullSipDelegateStats(List<StatsEvent> data)702     private int pullSipDelegateStats(List<StatsEvent> data) {
703         SipDelegateStats[] persisAtoms =
704                 mStorage.getSipDelegateStats(MIN_COOLDOWN_MILLIS);
705         if (persisAtoms != null) {
706             Arrays.stream(persisAtoms)
707                     .forEach(persisAtom -> data.add(buildStatsEvent(persisAtom)));
708             return StatsManager.PULL_SUCCESS;
709         } else {
710             Rlog.w(TAG, "SIP_DELEGATE_STATS pull too frequent, skipping");
711             return StatsManager.PULL_SKIP;
712         }
713     }
714 
pullSipTransportFeatureTagStats(List<StatsEvent> data)715     private int pullSipTransportFeatureTagStats(List<StatsEvent> data) {
716         RcsStats.getInstance().concludeSipTransportFeatureTagsStat();
717 
718         SipTransportFeatureTagStats[] persisAtoms =
719                 mStorage.getSipTransportFeatureTagStats(MIN_COOLDOWN_MILLIS);
720         if (persisAtoms != null) {
721             Arrays.stream(persisAtoms)
722                     .forEach(persisAtom -> data.add(buildStatsEvent(persisAtom)));
723             return StatsManager.PULL_SUCCESS;
724         } else {
725             Rlog.w(TAG, "SIP_DELEGATE_STATS pull too frequent, skipping");
726             return StatsManager.PULL_SKIP;
727         }
728     }
729 
pullSipMessageResponse(List<StatsEvent> data)730     private int pullSipMessageResponse(List<StatsEvent> data) {
731         SipMessageResponse[] persistAtoms =
732                 mStorage.getSipMessageResponse(MIN_COOLDOWN_MILLIS);
733         if (persistAtoms != null) {
734             Arrays.stream(persistAtoms)
735                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
736             return StatsManager.PULL_SUCCESS;
737         } else {
738             Rlog.w(TAG, "RCS_SIP_MESSAGE_RESPONSE pull too frequent, skipping");
739             return StatsManager.PULL_SKIP;
740         }
741     }
742 
pullSipTransportSession(List<StatsEvent> data)743     private int pullSipTransportSession(List<StatsEvent> data) {
744         SipTransportSession[] persistAtoms =
745                 mStorage.getSipTransportSession(MIN_COOLDOWN_MILLIS);
746         if (persistAtoms != null) {
747             Arrays.stream(persistAtoms)
748                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
749             return StatsManager.PULL_SUCCESS;
750         } else {
751             Rlog.w(TAG, "RCS_SIP_TRANSPORT_SESSION pull too frequent, skipping");
752             return StatsManager.PULL_SKIP;
753         }
754     }
755 
pullImsDedicatedBearerListenerEvent(List<StatsEvent> data)756     private int pullImsDedicatedBearerListenerEvent(List<StatsEvent> data) {
757         ImsDedicatedBearerListenerEvent[] persistAtoms =
758             mStorage.getImsDedicatedBearerListenerEvent(MIN_COOLDOWN_MILLIS);
759         if (persistAtoms != null) {
760             Arrays.stream(persistAtoms)
761                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
762             return StatsManager.PULL_SUCCESS;
763         } else {
764             Rlog.w(TAG, "IMS_DEDICATED_BEARER_LISTENER_EVENT pull too frequent, skipping");
765             return StatsManager.PULL_SKIP;
766         }
767     }
768 
pullImsDedicatedBearerEvent(List<StatsEvent> data)769     private int pullImsDedicatedBearerEvent(List<StatsEvent> data) {
770         ImsDedicatedBearerEvent[] persistAtoms =
771             mStorage.getImsDedicatedBearerEvent(MIN_COOLDOWN_MILLIS);
772         if (persistAtoms != null) {
773             Arrays.stream(persistAtoms)
774                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
775             return StatsManager.PULL_SUCCESS;
776         } else {
777             Rlog.w(TAG, "IMS_DEDICATED_BEARER_EVENT pull too frequent, skipping");
778             return StatsManager.PULL_SKIP;
779         }
780     }
781 
pullImsRegistrationServiceDescStats(List<StatsEvent> data)782     private int pullImsRegistrationServiceDescStats(List<StatsEvent> data) {
783         RcsStats.getInstance().onFlushIncompleteImsRegistrationServiceDescStats();
784         ImsRegistrationServiceDescStats[] persistAtoms =
785             mStorage.getImsRegistrationServiceDescStats(MIN_COOLDOWN_MILLIS);
786         if (persistAtoms != null) {
787             Arrays.stream(persistAtoms)
788                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
789             return StatsManager.PULL_SUCCESS;
790         } else {
791             Rlog.w(TAG, "IMS_REGISTRATION_SERVICE_DESC_STATS pull too frequent, skipping");
792             return StatsManager.PULL_SKIP;
793         }
794     }
795 
pullUceEventStats(List<StatsEvent> data)796     private int pullUceEventStats(List<StatsEvent> data) {
797         UceEventStats[] persistAtoms = mStorage.getUceEventStats(MIN_COOLDOWN_MILLIS);
798         if (persistAtoms != null) {
799             Arrays.stream(persistAtoms)
800                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
801             return StatsManager.PULL_SUCCESS;
802         } else {
803             Rlog.w(TAG, "UCE_EVENT_STATS pull too frequent, skipping");
804             return StatsManager.PULL_SKIP;
805         }
806     }
807 
pullPresenceNotifyEvent(List<StatsEvent> data)808     private int pullPresenceNotifyEvent(List<StatsEvent> data) {
809         PresenceNotifyEvent[] persistAtoms = mStorage.getPresenceNotifyEvent(MIN_COOLDOWN_MILLIS);
810         if (persistAtoms != null) {
811             Arrays.stream(persistAtoms)
812                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
813             return StatsManager.PULL_SUCCESS;
814         } else {
815             Rlog.w(TAG, "PRESENCE_NOTIFY_EVENT pull too frequent, skipping");
816             return StatsManager.PULL_SKIP;
817         }
818     }
819 
pullGbaEvent(List<StatsEvent> data)820     private int pullGbaEvent(List<StatsEvent> data) {
821         GbaEvent[] persistAtoms = mStorage.getGbaEvent(MIN_COOLDOWN_MILLIS);
822         if (persistAtoms != null) {
823             Arrays.stream(persistAtoms)
824                 .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
825             return StatsManager.PULL_SUCCESS;
826         } else {
827             Rlog.w(TAG, "GBA_EVENT pull too frequent, skipping");
828             return StatsManager.PULL_SKIP;
829         }
830     }
831 
pullPerSimStatus(List<StatsEvent> data)832     private int pullPerSimStatus(List<StatsEvent> data) {
833         int result = StatsManager.PULL_SKIP;
834         for (Phone phone : getPhonesIfAny()) {
835             PerSimStatus perSimStatus = PerSimStatus.getCurrentState(phone);
836             if (perSimStatus == null) {
837                 continue;
838             }
839             StatsEvent statsEvent = TelephonyStatsLog.buildStatsEvent(
840                     PER_SIM_STATUS,
841                     phone.getPhoneId(), // simSlotIndex
842                     perSimStatus.carrierId, // carrierId
843                     perSimStatus.phoneNumberSourceUicc, // phoneNumberSourceUicc
844                     perSimStatus.phoneNumberSourceCarrier, // phoneNumberSourceCarrier
845                     perSimStatus.phoneNumberSourceIms, // phoneNumberSourceIms
846                     perSimStatus.advancedCallingSettingEnabled, // volteEnabled
847                     perSimStatus.voWiFiSettingEnabled, // wfcEnabled
848                     perSimStatus.voWiFiModeSetting, // wfcMode
849                     perSimStatus.voWiFiRoamingModeSetting, // wfcRoamingMode
850                     perSimStatus.vtSettingEnabled, // videoCallingEnabled
851                     perSimStatus.dataRoamingEnabled, // dataRoamingEnabled
852                     perSimStatus.preferredNetworkType, // allowedNetworksByUser
853                     perSimStatus.disabled2g, // is2gDisabled
854                     perSimStatus.pin1Enabled, // isPin1Enabled
855                     perSimStatus.minimumVoltageClass, // simVoltageClass
856                     perSimStatus.userModifiedApnTypes, // userModifiedApnTypeBitmask
857                     perSimStatus.unmeteredNetworks, // unmeteredNetworks
858                     perSimStatus.vonrEnabled, // vonrEnabled
859                     perSimStatus.crossSimCallingEnabled); // crossSimCallingEnabled
860             data.add(statsEvent);
861             result = StatsManager.PULL_SUCCESS;
862         }
863         return result;
864     }
865 
pullOutgoingShortCodeSms(List<StatsEvent> data)866     private int pullOutgoingShortCodeSms(List<StatsEvent> data) {
867         OutgoingShortCodeSms[] outgoingShortCodeSmsList = mStorage
868                 .getOutgoingShortCodeSms(MIN_COOLDOWN_MILLIS);
869         if (outgoingShortCodeSmsList != null) {
870             // Outgoing short code SMS list is already shuffled when SMS were inserted
871             Arrays.stream(outgoingShortCodeSmsList).forEach(sms -> data.add(buildStatsEvent(sms)));
872             return StatsManager.PULL_SUCCESS;
873         } else {
874             Rlog.w(TAG, "OUTGOING_SHORT_CODE_SMS pull too frequent, skipping");
875             return StatsManager.PULL_SKIP;
876         }
877     }
878 
pullEmergencyNumbersInfo(List<StatsEvent> data)879     private int pullEmergencyNumbersInfo(List<StatsEvent> data) {
880         boolean isDataLogged = false;
881         for (Phone phone : getPhonesIfAny()) {
882             if (phone != null) {
883                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
884                 if (tracker != null) {
885                     EmergencyNumbersInfo[] numList = tracker.getEmergencyNumbersProtoArray();
886                     Arrays.stream(numList).forEach(number -> data.add(buildStatsEvent(number)));
887                     isDataLogged = true;
888                 }
889             }
890         }
891         return isDataLogged ? StatsManager.PULL_SUCCESS : StatsManager.PULL_SKIP;
892     }
893 
pullSatelliteController(List<StatsEvent> data)894     private int pullSatelliteController(List<StatsEvent> data) {
895         SatelliteController[] controllerAtoms =
896                 mStorage.getSatelliteControllerStats(MIN_COOLDOWN_MILLIS);
897         if (controllerAtoms != null) {
898             Arrays.stream(controllerAtoms)
899                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
900             return StatsManager.PULL_SUCCESS;
901         } else {
902             Rlog.w(TAG, "SATELLITE_CONTROLLER pull too frequent, skipping");
903             return StatsManager.PULL_SKIP;
904         }
905     }
906 
pullSatelliteSession(List<StatsEvent> data)907     private int pullSatelliteSession(List<StatsEvent> data) {
908         SatelliteSession[] sessionAtoms =
909                 mStorage.getSatelliteSessionStats(MIN_COOLDOWN_MILLIS);
910         if (sessionAtoms != null) {
911             Arrays.stream(sessionAtoms)
912                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
913             return StatsManager.PULL_SUCCESS;
914         } else {
915             Rlog.w(TAG, "SATELLITE_SESSION pull too frequent, skipping");
916             return StatsManager.PULL_SKIP;
917         }
918     }
919 
pullSatelliteIncomingDatagram(List<StatsEvent> data)920     private int pullSatelliteIncomingDatagram(List<StatsEvent> data) {
921         SatelliteIncomingDatagram[] incomingDatagramAtoms =
922                 mStorage.getSatelliteIncomingDatagramStats(MIN_COOLDOWN_MILLIS);
923         if (incomingDatagramAtoms != null) {
924             Arrays.stream(incomingDatagramAtoms)
925                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
926             return StatsManager.PULL_SUCCESS;
927         } else {
928             Rlog.w(TAG, "SATELLITE_INCOMING_DATAGRAM pull too frequent, skipping");
929             return StatsManager.PULL_SKIP;
930         }
931     }
932 
933 
pullSatelliteOutgoingDatagram(List<StatsEvent> data)934     private int pullSatelliteOutgoingDatagram(List<StatsEvent> data) {
935         SatelliteOutgoingDatagram[] outgoingDatagramAtoms =
936                 mStorage.getSatelliteOutgoingDatagramStats(MIN_COOLDOWN_MILLIS);
937         if (outgoingDatagramAtoms != null) {
938             Arrays.stream(outgoingDatagramAtoms)
939                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
940             return StatsManager.PULL_SUCCESS;
941         } else {
942             Rlog.w(TAG, "SATELLITE_OUTGOING_DATAGRAM pull too frequent, skipping");
943             return StatsManager.PULL_SKIP;
944         }
945     }
946 
947 
pullSatelliteProvision(List<StatsEvent> data)948     private int pullSatelliteProvision(List<StatsEvent> data) {
949         SatelliteProvision[] provisionAtoms =
950                 mStorage.getSatelliteProvisionStats(MIN_COOLDOWN_MILLIS);
951         if (provisionAtoms != null) {
952             Arrays.stream(provisionAtoms)
953                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
954             return StatsManager.PULL_SUCCESS;
955         } else {
956             Rlog.w(TAG, "SATELLITE_PROVISION pull too frequent, skipping");
957             return StatsManager.PULL_SKIP;
958         }
959     }
960 
pullSatelliteSosMessageRecommender(List<StatsEvent> data)961     private int pullSatelliteSosMessageRecommender(List<StatsEvent> data) {
962         SatelliteSosMessageRecommender[] sosMessageRecommenderAtoms =
963                 mStorage.getSatelliteSosMessageRecommenderStats(MIN_COOLDOWN_MILLIS);
964         if (sosMessageRecommenderAtoms != null) {
965             Arrays.stream(sosMessageRecommenderAtoms)
966                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
967             return StatsManager.PULL_SUCCESS;
968         } else {
969             Rlog.w(TAG, "SATELLITE_SOS_MESSAGE_RECOMMENDER pull too frequent, skipping");
970             return StatsManager.PULL_SKIP;
971         }
972     }
973 
pullDataNetworkValidation(@onNull List<StatsEvent> data)974     private int pullDataNetworkValidation(@NonNull List<StatsEvent> data) {
975         DataNetworkValidation[] dataNetworkValidations =
976                 mStorage.getDataNetworkValidation(mPowerCorrelatedMinCooldownMillis);
977         if (dataNetworkValidations != null) {
978             Arrays.stream(dataNetworkValidations)
979                     .forEach(d -> data.add(buildStatsEvent(d)));
980             return StatsManager.PULL_SUCCESS;
981         } else {
982             Rlog.w(TAG, "DATA_NETWORK_VALIDATION pull too frequent, skipping");
983             return StatsManager.PULL_SKIP;
984         }
985     }
986 
pullCarrierRoamingSatelliteSession(List<StatsEvent> data)987     private int pullCarrierRoamingSatelliteSession(List<StatsEvent> data) {
988         CarrierRoamingSatelliteSession[] carrierRoamingSatelliteSessionAtoms =
989                 mStorage.getCarrierRoamingSatelliteSessionStats(MIN_COOLDOWN_MILLIS);
990         if (carrierRoamingSatelliteSessionAtoms != null) {
991             Arrays.stream(carrierRoamingSatelliteSessionAtoms)
992                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
993             return StatsManager.PULL_SUCCESS;
994         } else {
995             Rlog.w(TAG, "CARRIER_ROAMING_SATELLITE_SESSION pull too frequent, skipping");
996             return StatsManager.PULL_SKIP;
997         }
998     }
999 
pullCarrierRoamingSatelliteControllerStats(List<StatsEvent> data)1000     private int pullCarrierRoamingSatelliteControllerStats(List<StatsEvent> data) {
1001         CarrierRoamingSatelliteControllerStats[] carrierRoamingSatelliteControllerStatsAtoms =
1002                 mStorage.getCarrierRoamingSatelliteControllerStats(MIN_COOLDOWN_MILLIS);
1003         if (carrierRoamingSatelliteControllerStatsAtoms != null) {
1004             Arrays.stream(carrierRoamingSatelliteControllerStatsAtoms)
1005                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
1006             return StatsManager.PULL_SUCCESS;
1007         } else {
1008             Rlog.w(TAG, "CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS "
1009                     + "pull too frequent, skipping");
1010             return StatsManager.PULL_SKIP;
1011         }
1012     }
1013 
pullSatelliteEntitlement(List<StatsEvent> data)1014     private int pullSatelliteEntitlement(List<StatsEvent> data) {
1015         SatelliteEntitlement[] satelliteEntitlementAtoms =
1016                 mStorage.getSatelliteEntitlementStats(MIN_COOLDOWN_MILLIS);
1017         if (satelliteEntitlementAtoms != null) {
1018             Arrays.stream(satelliteEntitlementAtoms)
1019                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
1020             return StatsManager.PULL_SUCCESS;
1021         } else {
1022             Rlog.w(TAG, "SATELLITE_ENTITLEMENT pull too frequent, skipping");
1023             return StatsManager.PULL_SKIP;
1024         }
1025     }
1026 
pullSatelliteConfigUpdater(List<StatsEvent> data)1027     private int pullSatelliteConfigUpdater(List<StatsEvent> data) {
1028         SatelliteConfigUpdater[] satelliteConfigUpdaterAtoms =
1029                 mStorage.getSatelliteConfigUpdaterStats(MIN_COOLDOWN_MILLIS);
1030         if (satelliteConfigUpdaterAtoms != null) {
1031             Arrays.stream(satelliteConfigUpdaterAtoms)
1032                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
1033             return StatsManager.PULL_SUCCESS;
1034         } else {
1035             Rlog.w(TAG, "SATELLITE_CONFIG_UPDATER pull too frequent, skipping");
1036             return StatsManager.PULL_SKIP;
1037         }
1038     }
1039 
pullSatelliteAccessController(List<StatsEvent> data)1040     private int pullSatelliteAccessController(List<StatsEvent> data) {
1041         SatelliteAccessController[] satelliteAccessControllerAtoms =
1042                 mStorage.getSatelliteAccessControllerStats(MIN_COOLDOWN_MILLIS);
1043         if (satelliteAccessControllerAtoms != null) {
1044             Arrays.stream(satelliteAccessControllerAtoms)
1045                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
1046             return StatsManager.PULL_SUCCESS;
1047         } else {
1048             Rlog.w(TAG, "SATELLITE_ACCESS_CONTROLLER pull too frequent, skipping");
1049             return StatsManager.PULL_SKIP;
1050         }
1051     }
1052 
1053     /** Registers a pulled atom ID {@code atomId}. */
registerAtom(int atomId)1054     private void registerAtom(int atomId) {
1055         mStatsManager.setPullAtomCallback(atomId, /* metadata= */ null,
1056                 ConcurrentUtils.DIRECT_EXECUTOR, this);
1057     }
1058 
buildStatsEvent(CellularDataServiceSwitch serviceSwitch)1059     private static StatsEvent buildStatsEvent(CellularDataServiceSwitch serviceSwitch) {
1060         return TelephonyStatsLog.buildStatsEvent(
1061                 CELLULAR_DATA_SERVICE_SWITCH,
1062                 serviceSwitch.ratFrom,
1063                 serviceSwitch.ratTo,
1064                 serviceSwitch.simSlotIndex,
1065                 serviceSwitch.isMultiSim,
1066                 serviceSwitch.carrierId,
1067                 serviceSwitch.switchCount);
1068     }
1069 
buildStatsEvent(CellularServiceState state)1070     private static StatsEvent buildStatsEvent(CellularServiceState state) {
1071         return TelephonyStatsLog.buildStatsEvent(
1072                 CELLULAR_SERVICE_STATE,
1073                 state.voiceRat,
1074                 state.dataRat,
1075                 state.voiceRoamingType,
1076                 state.dataRoamingType,
1077                 state.isEndc,
1078                 state.simSlotIndex,
1079                 state.isMultiSim,
1080                 state.carrierId,
1081                 roundAndConvertMillisToSeconds(state.totalTimeMillis,
1082                         CELL_SERVICE_DURATION_BUCKET_MILLIS),
1083                 state.isEmergencyOnly,
1084                 state.isInternetPdnUp,
1085                 state.foldState,
1086                 state.overrideVoiceService,
1087                 state.isDataEnabled,
1088                 state.isIwlanCrossSim,
1089                 state.isNtn);
1090     }
1091 
buildStatsEvent(VoiceCallRatUsage usage)1092     private static StatsEvent buildStatsEvent(VoiceCallRatUsage usage) {
1093         return TelephonyStatsLog.buildStatsEvent(
1094                 VOICE_CALL_RAT_USAGE,
1095                 usage.carrierId,
1096                 usage.rat,
1097                 roundAndConvertMillisToSeconds(usage.totalDurationMillis),
1098                 usage.callCount);
1099     }
1100 
buildStatsEvent(VoiceCallSession session)1101     private static StatsEvent buildStatsEvent(VoiceCallSession session) {
1102         return TelephonyStatsLog.buildStatsEvent(
1103                 VOICE_CALL_SESSION,
1104                 session.bearerAtStart,
1105                 session.bearerAtEnd,
1106                 session.direction,
1107                 // deprecated and replaced by setupDurationMillis
1108                 VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN,
1109                 session.setupFailed,
1110                 session.disconnectReasonCode,
1111                 session.disconnectExtraCode,
1112                 session.disconnectExtraMessage,
1113                 session.ratAtStart,
1114                 session.ratAtEnd,
1115                 session.ratSwitchCount,
1116                 session.codecBitmask,
1117                 session.concurrentCallCountAtStart,
1118                 session.concurrentCallCountAtEnd,
1119                 session.simSlotIndex,
1120                 session.isMultiSim,
1121                 session.isEsim,
1122                 session.carrierId,
1123                 session.srvccCompleted,
1124                 session.srvccFailureCount,
1125                 session.srvccCancellationCount,
1126                 session.rttEnabled,
1127                 session.isEmergency,
1128                 session.isRoaming,
1129                 // workaround: dimension required for keeping multiple pulled atoms
1130                 sRandom.nextInt(),
1131                 // New fields introduced in Android S
1132                 session.signalStrengthAtEnd,
1133                 session.bandAtEnd,
1134                 session.setupDurationMillis,
1135                 session.mainCodecQuality,
1136                 session.videoEnabled,
1137                 session.ratAtConnected,
1138                 session.isMultiparty,
1139                 session.callDuration,
1140                 session.lastKnownRat,
1141                 session.foldState,
1142                 session.ratSwitchCountAfterConnected,
1143                 session.handoverInProgress,
1144                 session.isIwlanCrossSimAtStart,
1145                 session.isIwlanCrossSimAtEnd,
1146                 session.isIwlanCrossSimAtConnected,
1147                 session.vonrEnabled,
1148                 session.isNtn,
1149                 session.supportsBusinessCallComposer,
1150                 session.callComposerStatus);
1151 
1152     }
1153 
buildStatsEvent(IncomingSms sms)1154     private static StatsEvent buildStatsEvent(IncomingSms sms) {
1155         return TelephonyStatsLog.buildStatsEvent(
1156                 INCOMING_SMS,
1157                 sms.smsFormat,
1158                 sms.smsTech,
1159                 sms.rat,
1160                 sms.smsType,
1161                 sms.totalParts,
1162                 sms.receivedParts,
1163                 sms.blocked,
1164                 sms.error,
1165                 sms.isRoaming,
1166                 sms.simSlotIndex,
1167                 sms.isMultiSim,
1168                 sms.isEsim,
1169                 sms.carrierId,
1170                 sms.messageId,
1171                 sms.count,
1172                 sms.isManagedProfile,
1173                 sms.isNtn,
1174                 sms.isEmergency);
1175     }
1176 
buildStatsEvent(OutgoingSms sms)1177     private static StatsEvent buildStatsEvent(OutgoingSms sms) {
1178         return TelephonyStatsLog.buildStatsEvent(
1179                 OUTGOING_SMS,
1180                 sms.smsFormat,
1181                 sms.smsTech,
1182                 sms.rat,
1183                 sms.sendResult,
1184                 sms.errorCode,
1185                 sms.isRoaming,
1186                 sms.isFromDefaultApp,
1187                 sms.simSlotIndex,
1188                 sms.isMultiSim,
1189                 sms.isEsim,
1190                 sms.carrierId,
1191                 sms.messageId,
1192                 sms.retryId,
1193                 sms.intervalMillis,
1194                 sms.count,
1195                 sms.sendErrorCode,
1196                 sms.networkErrorCode,
1197                 sms.isManagedProfile,
1198                 sms.isEmergency,
1199                 sms.isNtn);
1200     }
1201 
buildStatsEvent(DataCallSession dataCallSession)1202     private static StatsEvent buildStatsEvent(DataCallSession dataCallSession) {
1203         return TelephonyStatsLog.buildStatsEvent(
1204                 DATA_CALL_SESSION,
1205                 dataCallSession.dimension,
1206                 dataCallSession.isMultiSim,
1207                 dataCallSession.isEsim,
1208                 0, // profile is deprecated, so we default to 0
1209                 dataCallSession.apnTypeBitmask,
1210                 dataCallSession.carrierId,
1211                 dataCallSession.isRoaming,
1212                 dataCallSession.ratAtEnd,
1213                 dataCallSession.oosAtEnd,
1214                 dataCallSession.ratSwitchCount,
1215                 dataCallSession.isOpportunistic,
1216                 dataCallSession.ipType,
1217                 dataCallSession.setupFailed,
1218                 dataCallSession.failureCause,
1219                 dataCallSession.suggestedRetryMillis,
1220                 dataCallSession.deactivateReason,
1221                 roundAndConvertMillisToMinutes(
1222                         dataCallSession.durationMinutes * MILLIS_PER_MINUTE),
1223                 dataCallSession.ongoing,
1224                 dataCallSession.bandAtEnd,
1225                 dataCallSession.handoverFailureCauses,
1226                 dataCallSession.handoverFailureRat,
1227                 dataCallSession.isNonDds,
1228                 dataCallSession.isIwlanCrossSim,
1229                 dataCallSession.isNtn,
1230                 dataCallSession.isSatelliteTransport,
1231                 dataCallSession.isProvisioningProfile);
1232     }
1233 
buildStatsEvent(ImsRegistrationStats stats)1234     private static StatsEvent buildStatsEvent(ImsRegistrationStats stats) {
1235         return TelephonyStatsLog.buildStatsEvent(
1236                 IMS_REGISTRATION_STATS,
1237                 stats.carrierId,
1238                 stats.simSlotIndex,
1239                 stats.rat,
1240                 roundAndConvertMillisToSeconds(stats.registeredMillis),
1241                 roundAndConvertMillisToSeconds(stats.voiceCapableMillis),
1242                 roundAndConvertMillisToSeconds(stats.voiceAvailableMillis),
1243                 roundAndConvertMillisToSeconds(stats.smsCapableMillis),
1244                 roundAndConvertMillisToSeconds(stats.smsAvailableMillis),
1245                 roundAndConvertMillisToSeconds(stats.videoCapableMillis),
1246                 roundAndConvertMillisToSeconds(stats.videoAvailableMillis),
1247                 roundAndConvertMillisToSeconds(stats.utCapableMillis),
1248                 roundAndConvertMillisToSeconds(stats.utAvailableMillis),
1249                 roundAndConvertMillisToSeconds(stats.registeringMillis),
1250                 roundAndConvertMillisToSeconds(stats.unregisteredMillis),
1251                 stats.isIwlanCrossSim,
1252                 stats.registeredTimes);
1253     }
1254 
buildStatsEvent(ImsRegistrationTermination termination)1255     private static StatsEvent buildStatsEvent(ImsRegistrationTermination termination) {
1256         return TelephonyStatsLog.buildStatsEvent(
1257                 IMS_REGISTRATION_TERMINATION,
1258                 termination.carrierId,
1259                 termination.isMultiSim,
1260                 termination.ratAtEnd,
1261                 termination.setupFailed,
1262                 termination.reasonCode,
1263                 termination.extraCode,
1264                 termination.extraMessage,
1265                 termination.count,
1266                 termination.isIwlanCrossSim);
1267     }
1268 
buildStatsEvent(NetworkRequestsV2 networkRequests)1269     private static StatsEvent buildStatsEvent(NetworkRequestsV2 networkRequests) {
1270         return TelephonyStatsLog.buildStatsEvent(
1271                 TELEPHONY_NETWORK_REQUESTS_V2,
1272                 networkRequests.carrierId,
1273                 networkRequests.capability,
1274                 networkRequests.requestCount);
1275     }
1276 
buildStatsEvent(ImsRegistrationFeatureTagStats stats)1277     private static StatsEvent buildStatsEvent(ImsRegistrationFeatureTagStats stats) {
1278         return TelephonyStatsLog.buildStatsEvent(
1279                 IMS_REGISTRATION_FEATURE_TAG_STATS,
1280                 stats.carrierId,
1281                 stats.slotId,
1282                 stats.featureTagName,
1283                 stats.registrationTech,
1284                 roundAndConvertMillisToSeconds(stats.registeredMillis));
1285     }
1286 
buildStatsEvent(RcsClientProvisioningStats stats)1287     private static StatsEvent buildStatsEvent(RcsClientProvisioningStats stats) {
1288         return TelephonyStatsLog.buildStatsEvent(
1289                 RCS_CLIENT_PROVISIONING_STATS,
1290                 stats.carrierId,
1291                 stats.slotId,
1292                 stats.event,
1293                 stats.count);
1294     }
1295 
buildStatsEvent(RcsAcsProvisioningStats stats)1296     private static StatsEvent buildStatsEvent(RcsAcsProvisioningStats stats) {
1297         return TelephonyStatsLog.buildStatsEvent(
1298                 RCS_ACS_PROVISIONING_STATS,
1299                 stats.carrierId,
1300                 stats.slotId,
1301                 stats.responseCode,
1302                 stats.responseType,
1303                 stats.isSingleRegistrationEnabled,
1304                 stats.count,
1305                 roundAndConvertMillisToSeconds(stats.stateTimerMillis));
1306     }
1307 
buildStatsEvent(SipDelegateStats stats)1308     private static StatsEvent buildStatsEvent(SipDelegateStats stats) {
1309         return TelephonyStatsLog.buildStatsEvent(
1310                 SIP_DELEGATE_STATS,
1311                 stats.dimension,
1312                 stats.carrierId,
1313                 stats.slotId,
1314                 roundAndConvertMillisToSeconds(stats.uptimeMillis),
1315                 stats.destroyReason);
1316     }
1317 
buildStatsEvent(SipTransportFeatureTagStats stats)1318     private static StatsEvent buildStatsEvent(SipTransportFeatureTagStats stats) {
1319         return TelephonyStatsLog.buildStatsEvent(
1320                 SIP_TRANSPORT_FEATURE_TAG_STATS,
1321                 stats.carrierId,
1322                 stats.slotId,
1323                 stats.featureTagName,
1324                 stats.sipTransportDeniedReason,
1325                 stats.sipTransportDeregisteredReason,
1326                 roundAndConvertMillisToSeconds(stats.associatedMillis));
1327     }
1328 
buildStatsEvent(SipMessageResponse stats)1329     private static StatsEvent buildStatsEvent(SipMessageResponse stats) {
1330         return TelephonyStatsLog.buildStatsEvent(
1331                 SIP_MESSAGE_RESPONSE,
1332                 stats.carrierId,
1333                 stats.slotId,
1334                 stats.sipMessageMethod,
1335                 stats.sipMessageResponse,
1336                 stats.sipMessageDirection,
1337                 stats.messageError,
1338                 stats.count);
1339     }
1340 
buildStatsEvent(SipTransportSession stats)1341     private static StatsEvent buildStatsEvent(SipTransportSession stats) {
1342         return TelephonyStatsLog.buildStatsEvent(
1343                 SIP_TRANSPORT_SESSION,
1344                 stats.carrierId,
1345                 stats.slotId,
1346                 stats.sessionMethod,
1347                 stats.sipMessageDirection,
1348                 stats.sipResponse,
1349                 stats.sessionCount,
1350                 stats.endedGracefullyCount);
1351     }
1352 
buildStatsEvent(ImsDedicatedBearerListenerEvent stats)1353     private static StatsEvent buildStatsEvent(ImsDedicatedBearerListenerEvent stats) {
1354         return TelephonyStatsLog.buildStatsEvent(
1355                 IMS_DEDICATED_BEARER_LISTENER_EVENT,
1356                 stats.carrierId,
1357                 stats.slotId,
1358                 stats.ratAtEnd,
1359                 stats.qci,
1360                 stats.dedicatedBearerEstablished,
1361                 stats.eventCount);
1362     }
1363 
buildStatsEvent(ImsDedicatedBearerEvent stats)1364     private static StatsEvent buildStatsEvent(ImsDedicatedBearerEvent stats) {
1365         return TelephonyStatsLog.buildStatsEvent(
1366                 IMS_DEDICATED_BEARER_EVENT,
1367                 stats.carrierId,
1368                 stats.slotId,
1369                 stats.ratAtEnd,
1370                 stats.qci,
1371                 stats.bearerState,
1372                 stats.localConnectionInfoReceived,
1373                 stats.remoteConnectionInfoReceived,
1374                 stats.hasListeners,
1375                 stats.count);
1376     }
1377 
buildStatsEvent(ImsRegistrationServiceDescStats stats)1378     private static StatsEvent buildStatsEvent(ImsRegistrationServiceDescStats stats) {
1379         return TelephonyStatsLog.buildStatsEvent(
1380                 IMS_REGISTRATION_SERVICE_DESC_STATS,
1381                 stats.carrierId,
1382                 stats.slotId,
1383                 stats.serviceIdName,
1384                 stats.serviceIdVersion,
1385                 stats.registrationTech,
1386                 roundAndConvertMillisToSeconds(stats.publishedMillis));
1387     }
1388 
buildStatsEvent(UceEventStats stats)1389     private static StatsEvent buildStatsEvent(UceEventStats stats) {
1390         return TelephonyStatsLog.buildStatsEvent(
1391                 UCE_EVENT_STATS,
1392                 stats.carrierId,
1393                 stats.slotId,
1394                 stats.type,
1395                 stats.successful,
1396                 stats.commandCode,
1397                 stats.networkResponse,
1398                 stats.count);
1399     }
1400 
buildStatsEvent(PresenceNotifyEvent stats)1401     private static StatsEvent buildStatsEvent(PresenceNotifyEvent stats) {
1402         return TelephonyStatsLog.buildStatsEvent(
1403                 PRESENCE_NOTIFY_EVENT,
1404                 stats.carrierId,
1405                 stats.slotId,
1406                 stats.reason,
1407                 stats.contentBodyReceived,
1408                 stats.rcsCapsCount,
1409                 stats.mmtelCapsCount,
1410                 stats.noCapsCount,
1411                 stats.count);
1412     }
1413 
buildStatsEvent(GbaEvent stats)1414     private static StatsEvent buildStatsEvent(GbaEvent stats) {
1415         return TelephonyStatsLog.buildStatsEvent(
1416                 GBA_EVENT,
1417                 stats.carrierId,
1418                 stats.slotId,
1419                 stats.successful,
1420                 stats.failedReason,
1421                 stats.count);
1422     }
1423 
buildStatsEvent(OutgoingShortCodeSms shortCodeSms)1424     private static StatsEvent buildStatsEvent(OutgoingShortCodeSms shortCodeSms) {
1425         return TelephonyStatsLog.buildStatsEvent(
1426                 OUTGOING_SHORT_CODE_SMS,
1427                 shortCodeSms.category,
1428                 shortCodeSms.xmlVersion,
1429                 shortCodeSms.shortCodeSmsCount);
1430     }
1431 
buildStatsEvent(EmergencyNumbersInfo emergencyNumber)1432     private static StatsEvent buildStatsEvent(EmergencyNumbersInfo emergencyNumber) {
1433         return TelephonyStatsLog.buildStatsEvent(
1434                 EMERGENCY_NUMBERS_INFO,
1435                 emergencyNumber.isDbVersionIgnored,
1436                 emergencyNumber.assetVersion,
1437                 emergencyNumber.otaVersion,
1438                 emergencyNumber.number,
1439                 emergencyNumber.countryIso,
1440                 emergencyNumber.mnc,
1441                 emergencyNumber.route,
1442                 emergencyNumber.urns,
1443                 emergencyNumber.serviceCategories,
1444                 emergencyNumber.sources);
1445     }
1446 
buildStatsEvent(SatelliteController satelliteController)1447     private static StatsEvent buildStatsEvent(SatelliteController satelliteController) {
1448         return TelephonyStatsLog.buildStatsEvent(
1449                 SATELLITE_CONTROLLER,
1450                 satelliteController.countOfSatelliteServiceEnablementsSuccess,
1451                 satelliteController.countOfSatelliteServiceEnablementsFail,
1452                 satelliteController.countOfOutgoingDatagramSuccess,
1453                 satelliteController.countOfOutgoingDatagramFail,
1454                 satelliteController.countOfIncomingDatagramSuccess,
1455                 satelliteController.countOfIncomingDatagramFail,
1456                 satelliteController.countOfDatagramTypeSosSmsSuccess,
1457                 satelliteController.countOfDatagramTypeSosSmsFail,
1458                 satelliteController.countOfDatagramTypeLocationSharingSuccess,
1459                 satelliteController.countOfDatagramTypeLocationSharingFail,
1460                 satelliteController.countOfProvisionSuccess,
1461                 satelliteController.countOfProvisionFail,
1462                 satelliteController.countOfDeprovisionSuccess,
1463                 satelliteController.countOfDeprovisionFail,
1464                 satelliteController.totalServiceUptimeSec,
1465                 satelliteController.totalBatteryConsumptionPercent,
1466                 satelliteController.totalBatteryChargedTimeSec,
1467                 satelliteController.countOfDemoModeSatelliteServiceEnablementsSuccess,
1468                 satelliteController.countOfDemoModeSatelliteServiceEnablementsFail,
1469                 satelliteController.countOfDemoModeOutgoingDatagramSuccess,
1470                 satelliteController.countOfDemoModeOutgoingDatagramFail,
1471                 satelliteController.countOfDemoModeIncomingDatagramSuccess,
1472                 satelliteController.countOfDemoModeIncomingDatagramFail,
1473                 satelliteController.countOfDatagramTypeKeepAliveSuccess,
1474                 satelliteController.countOfDatagramTypeKeepAliveFail,
1475                 satelliteController.countOfAllowedSatelliteAccess,
1476                 satelliteController.countOfDisallowedSatelliteAccess,
1477                 satelliteController.countOfSatelliteAccessCheckFail);
1478     }
1479 
buildStatsEvent(SatelliteSession satelliteSession)1480     private static StatsEvent buildStatsEvent(SatelliteSession satelliteSession) {
1481         return TelephonyStatsLog.buildStatsEvent(
1482                 SATELLITE_SESSION,
1483                 satelliteSession.satelliteServiceInitializationResult,
1484                 satelliteSession.satelliteTechnology,
1485                 satelliteSession.count,
1486                 satelliteSession.satelliteServiceTerminationResult,
1487                 satelliteSession.initializationProcessingTimeMillis,
1488                 satelliteSession.terminationProcessingTimeMillis,
1489                 satelliteSession.sessionDurationSeconds,
1490                 satelliteSession.countOfOutgoingDatagramSuccess,
1491                 satelliteSession.countOfOutgoingDatagramFailed,
1492                 satelliteSession.countOfIncomingDatagramSuccess,
1493                 satelliteSession.countOfIncomingDatagramFailed,
1494                 satelliteSession.isDemoMode,
1495                 satelliteSession.maxNtnSignalStrengthLevel);
1496     }
1497 
buildStatsEvent(SatelliteIncomingDatagram stats)1498     private static StatsEvent buildStatsEvent(SatelliteIncomingDatagram stats) {
1499         return TelephonyStatsLog.buildStatsEvent(
1500                 SATELLITE_INCOMING_DATAGRAM,
1501                 stats.resultCode,
1502                 stats.datagramSizeBytes,
1503                 stats.datagramTransferTimeMillis,
1504                 stats.isDemoMode);
1505     }
1506 
buildStatsEvent(SatelliteOutgoingDatagram stats)1507     private static StatsEvent buildStatsEvent(SatelliteOutgoingDatagram stats) {
1508         return TelephonyStatsLog.buildStatsEvent(
1509                 SATELLITE_OUTGOING_DATAGRAM,
1510                 stats.datagramType,
1511                 stats.resultCode,
1512                 stats.datagramSizeBytes,
1513                 stats.datagramTransferTimeMillis,
1514                 stats.isDemoMode);
1515     }
1516 
buildStatsEvent(SatelliteProvision stats)1517     private static StatsEvent buildStatsEvent(SatelliteProvision stats) {
1518         return TelephonyStatsLog.buildStatsEvent(
1519                 SATELLITE_PROVISION,
1520                 stats.resultCode,
1521                 stats.provisioningTimeSec,
1522                 stats.isProvisionRequest,
1523                 stats.isCanceled);
1524     }
1525 
buildStatsEvent(SatelliteSosMessageRecommender stats)1526     private static StatsEvent buildStatsEvent(SatelliteSosMessageRecommender stats) {
1527         return TelephonyStatsLog.buildStatsEvent(
1528                 SATELLITE_SOS_MESSAGE_RECOMMENDER,
1529                 stats.isDisplaySosMessageSent,
1530                 stats.countOfTimerStarted,
1531                 stats.isImsRegistered,
1532                 stats.cellularServiceState,
1533                 stats.count,
1534                 stats.isMultiSim,
1535                 stats.recommendingHandoverType,
1536                 stats.isSatelliteAllowedInCurrentLocation);
1537     }
1538 
buildStatsEvent(DataNetworkValidation stats)1539     private static StatsEvent buildStatsEvent(DataNetworkValidation stats) {
1540         return TelephonyStatsLog.buildStatsEvent(
1541                 DATA_NETWORK_VALIDATION,
1542                 stats.networkType,
1543                 stats.apnTypeBitmask,
1544                 stats.signalStrength,
1545                 stats.validationResult,
1546                 stats.elapsedTimeInMillis,
1547                 stats.handoverAttempted,
1548                 stats.networkValidationCount);
1549     }
1550 
buildStatsEvent(CarrierRoamingSatelliteSession stats)1551     private static StatsEvent buildStatsEvent(CarrierRoamingSatelliteSession stats) {
1552         return TelephonyStatsLog.buildStatsEvent(
1553                 CARRIER_ROAMING_SATELLITE_SESSION,
1554                 stats.carrierId,
1555                 stats.isNtnRoamingInHomeCountry,
1556                 stats.totalSatelliteModeTimeSec,
1557                 stats.numberOfSatelliteConnections,
1558                 stats.avgDurationOfSatelliteConnectionSec,
1559                 stats.satelliteConnectionGapMinSec,
1560                 stats.satelliteConnectionGapAvgSec,
1561                 stats.satelliteConnectionGapMaxSec,
1562                 stats.rsrpAvg,
1563                 stats.rsrpMedian,
1564                 stats.rssnrAvg,
1565                 stats.rssnrMedian,
1566                 stats.countOfIncomingSms,
1567                 stats.countOfOutgoingSms,
1568                 stats.countOfIncomingMms,
1569                 stats.countOfOutgoingMms);
1570     }
1571 
buildStatsEvent(CarrierRoamingSatelliteControllerStats stats)1572     private static StatsEvent buildStatsEvent(CarrierRoamingSatelliteControllerStats stats) {
1573         return TelephonyStatsLog.buildStatsEvent(
1574                 CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS,
1575                 stats.configDataSource,
1576                 stats.countOfEntitlementStatusQueryRequest,
1577                 stats.countOfSatelliteConfigUpdateRequest,
1578                 stats.countOfSatelliteNotificationDisplayed,
1579                 stats.satelliteSessionGapMinSec,
1580                 stats.satelliteSessionGapAvgSec,
1581                 stats.satelliteSessionGapMaxSec);
1582     }
1583 
buildStatsEvent(SatelliteEntitlement stats)1584     private static StatsEvent buildStatsEvent(SatelliteEntitlement stats) {
1585         return TelephonyStatsLog.buildStatsEvent(
1586                 SATELLITE_ENTITLEMENT,
1587                 stats.carrierId,
1588                 stats.result,
1589                 stats.entitlementStatus,
1590                 stats.isRetry,
1591                 stats.count);
1592     }
1593 
buildStatsEvent(SatelliteConfigUpdater stats)1594     private static StatsEvent buildStatsEvent(SatelliteConfigUpdater stats) {
1595         return TelephonyStatsLog.buildStatsEvent(SATELLITE_CONFIG_UPDATER,
1596                 stats.configVersion,
1597                 stats.oemConfigResult,
1598                 stats.carrierConfigResult,
1599                 stats.count);
1600     }
1601 
buildStatsEvent(SatelliteAccessController stats)1602     private static StatsEvent buildStatsEvent(SatelliteAccessController stats) {
1603         return TelephonyStatsLog.buildStatsEvent(
1604                 SATELLITE_ACCESS_CONTROLLER,
1605                 stats.accessControlType,
1606                 stats.locationQueryTimeMillis,
1607                 stats.onDeviceLookupTimeMillis,
1608                 stats.totalCheckingTimeMillis,
1609                 stats.isAllowed,
1610                 stats.isEmergency,
1611                 stats.resultCode,
1612                 stats.countryCodes,
1613                 stats.configDataSource);
1614     }
1615 
1616     /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
getPhonesIfAny()1617     static Phone[] getPhonesIfAny() {
1618         try {
1619             return PhoneFactory.getPhones();
1620         } catch (IllegalStateException e) {
1621             // Phones have not been made yet
1622             return new Phone[0];
1623         }
1624     }
1625 
1626     /**
1627      * Rounds the duration and converts it from milliseconds to seconds.
1628      */
roundAndConvertMillisToSeconds(long valueMillis)1629     private static int roundAndConvertMillisToSeconds(long valueMillis) {
1630         return roundAndConvertMillisToSeconds(valueMillis, DURATION_BUCKET_MILLIS);
1631     }
1632 
1633     /**
1634      * Rounds the duration and converts it from milliseconds to seconds.
1635      */
roundAndConvertMillisToSeconds(long valueMillis, long durationBucketSize)1636     private static int roundAndConvertMillisToSeconds(long valueMillis, long durationBucketSize) {
1637         long roundedValueMillis = Math.round((double) valueMillis / durationBucketSize)
1638                 * durationBucketSize;
1639         return (int) (roundedValueMillis / MILLIS_PER_SECOND);
1640     }
1641 
1642     /**
1643      * Rounds the duration and converts it from milliseconds to minutes.
1644      */
roundAndConvertMillisToMinutes(long valueMillis)1645     private static int roundAndConvertMillisToMinutes(long valueMillis) {
1646         long roundedValueMillis = Math.round((double) valueMillis / DURATION_BUCKET_MILLIS)
1647                 * DURATION_BUCKET_MILLIS;
1648         return (int) (roundedValueMillis / MILLIS_PER_MINUTE);
1649     }
1650 }
1651