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