1 /* 2 * Copyright (C) 2023 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.satellite.metrics; 18 19 import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE; 20 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; 21 22 import android.annotation.NonNull; 23 import android.os.Bundle; 24 import android.os.ResultReceiver; 25 import android.telephony.satellite.NtnSignalStrength; 26 import android.telephony.satellite.SatelliteManager; 27 import android.telephony.satellite.SatelliteSessionStats; 28 import android.util.Log; 29 30 import com.android.internal.telephony.metrics.SatelliteStats; 31 import com.android.internal.telephony.satellite.DatagramDispatcher; 32 33 /** 34 * Stats to log to satellite session metrics 35 */ 36 public class SessionMetricsStats { 37 private static final String TAG = SessionMetricsStats.class.getSimpleName(); 38 private static final boolean DBG = false; 39 40 private static SessionMetricsStats sInstance = null; 41 private @SatelliteManager.SatelliteResult int mInitializationResult; 42 private @SatelliteManager.NTRadioTechnology int mRadioTechnology; 43 private @SatelliteManager.SatelliteResult int mTerminationResult; 44 private long mInitializationProcessingTimeMillis; 45 private long mTerminationProcessingTimeMillis; 46 private int mSessionDurationSec; 47 private int mCountOfSuccessfulOutgoingDatagram; 48 private int mCountOfFailedOutgoingDatagram; 49 private int mCountOfTimedOutUserMessagesWaitingForConnection; 50 private int mCountOfTimedOutUserMessagesWaitingForAck; 51 private int mCountOfSuccessfulIncomingDatagram; 52 private int mCountOfIncomingDatagramFailed; 53 private boolean mIsDemoMode; 54 private @NtnSignalStrength.NtnSignalStrengthLevel int mMaxNtnSignalStrengthLevel; 55 SessionMetricsStats()56 private SessionMetricsStats() { 57 initializeSessionMetricsParam(); 58 } 59 60 /** 61 * Returns the Singleton instance of SessionMetricsStats class. 62 * If an instance of the Singleton class has not been created, 63 * it creates a new instance and returns it. Otherwise, it returns 64 * the existing instance. 65 * @return the Singleton instance of SessionMetricsStats. 66 */ getInstance()67 public static SessionMetricsStats getInstance() { 68 if (sInstance == null) { 69 loge("create new SessionMetricsStats."); 70 sInstance = new SessionMetricsStats(); 71 } 72 return sInstance; 73 } 74 75 /** Sets the satellite initialization result. */ setInitializationResult( @atelliteManager.SatelliteResult int result)76 public SessionMetricsStats setInitializationResult( 77 @SatelliteManager.SatelliteResult int result) { 78 logd("setInitializationResult(" + result + ")"); 79 mInitializationResult = result; 80 return this; 81 } 82 83 /** Sets the satellite ratio technology. */ setSatelliteTechnology( @atelliteManager.NTRadioTechnology int radioTechnology)84 public SessionMetricsStats setSatelliteTechnology( 85 @SatelliteManager.NTRadioTechnology int radioTechnology) { 86 logd("setSatelliteTechnology(" + radioTechnology + ")"); 87 mRadioTechnology = radioTechnology; 88 return this; 89 } 90 91 /** Sets the satellite de-initialization result. */ setTerminationResult( @atelliteManager.SatelliteResult int result)92 public SessionMetricsStats setTerminationResult( 93 @SatelliteManager.SatelliteResult int result) { 94 logd("setTerminationResult(" + result + ")"); 95 mTerminationResult = result; 96 return this; 97 } 98 99 /** Sets the satellite initialization processing time. */ setInitializationProcessingTime(long processingTime)100 public SessionMetricsStats setInitializationProcessingTime(long processingTime) { 101 logd("setInitializationProcessingTime(" + processingTime + ")"); 102 mInitializationProcessingTimeMillis = processingTime; 103 return this; 104 } 105 106 /** Sets the satellite de-initialization processing time. */ setTerminationProcessingTime(long processingTime)107 public SessionMetricsStats setTerminationProcessingTime(long processingTime) { 108 logd("setTerminationProcessingTime(" + processingTime + ")"); 109 mTerminationProcessingTimeMillis = processingTime; 110 return this; 111 } 112 113 /** Sets the total enabled time for the satellite session. */ setSessionDurationSec(int sessionDurationSec)114 public SessionMetricsStats setSessionDurationSec(int sessionDurationSec) { 115 logd("setSessionDuration(" + sessionDurationSec + ")"); 116 mSessionDurationSec = sessionDurationSec; 117 return this; 118 } 119 120 /** Increase the count of successful outgoing datagram transmission. */ addCountOfSuccessfulOutgoingDatagram( @onNull @atelliteManager.DatagramType int datagramType)121 public SessionMetricsStats addCountOfSuccessfulOutgoingDatagram( 122 @NonNull @SatelliteManager.DatagramType int datagramType) { 123 if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) { 124 // Ignore KEEP_ALIVE messages 125 return this; 126 } 127 128 mCountOfSuccessfulOutgoingDatagram++; 129 logd("addCountOfSuccessfulOutgoingDatagram: current count=" 130 + mCountOfSuccessfulOutgoingDatagram); 131 return this; 132 } 133 134 /** Increase the count of failed outgoing datagram transmission. */ addCountOfFailedOutgoingDatagram( @onNull @atelliteManager.DatagramType int datagramType, @NonNull @SatelliteManager.SatelliteResult int resultCode)135 public SessionMetricsStats addCountOfFailedOutgoingDatagram( 136 @NonNull @SatelliteManager.DatagramType int datagramType, 137 @NonNull @SatelliteManager.SatelliteResult int resultCode) { 138 if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) { 139 // Ignore KEEP_ALIVE messages 140 return this; 141 } 142 143 mCountOfFailedOutgoingDatagram++; 144 logd("addCountOfFailedOutgoingDatagram: current count=" + mCountOfFailedOutgoingDatagram); 145 146 if (resultCode == SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE) { 147 addCountOfTimedOutUserMessagesWaitingForConnection(datagramType); 148 } else if (resultCode == SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT) { 149 addCountOfTimedOutUserMessagesWaitingForAck(datagramType); 150 } 151 152 return this; 153 } 154 155 /** Increase the count of user messages that timed out waiting for connection. */ addCountOfTimedOutUserMessagesWaitingForConnection( @onNull @atelliteManager.DatagramType int datagramType)156 private SessionMetricsStats addCountOfTimedOutUserMessagesWaitingForConnection( 157 @NonNull @SatelliteManager.DatagramType int datagramType) { 158 if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) { 159 // Ignore KEEP_ALIVE messages 160 return this; 161 } 162 163 mCountOfTimedOutUserMessagesWaitingForConnection++; 164 logd("addCountOfTimedOutUserMessagesWaitingForConnection: current count=" 165 + mCountOfTimedOutUserMessagesWaitingForConnection); 166 return this; 167 } 168 169 /** Increase the count of user messages that timed out waiting for ack. */ addCountOfTimedOutUserMessagesWaitingForAck( @onNull @atelliteManager.DatagramType int datagramType)170 private SessionMetricsStats addCountOfTimedOutUserMessagesWaitingForAck( 171 @NonNull @SatelliteManager.DatagramType int datagramType) { 172 if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) { 173 // Ignore KEEP_ALIVE messages 174 return this; 175 } 176 177 mCountOfTimedOutUserMessagesWaitingForAck++; 178 logd("addCountOfTimedOutUserMessagesWaitingForAck: current count=" 179 + mCountOfTimedOutUserMessagesWaitingForAck); 180 return this; 181 } 182 183 /** Increase the count of successful incoming datagram transmission. */ addCountOfSuccessfulIncomingDatagram()184 public SessionMetricsStats addCountOfSuccessfulIncomingDatagram() { 185 mCountOfSuccessfulIncomingDatagram++; 186 logd("addCountOfSuccessfulIncomingDatagram: current count=" 187 + mCountOfSuccessfulIncomingDatagram); 188 return this; 189 } 190 191 /** Increase the count of failed incoming datagram transmission. */ addCountOfFailedIncomingDatagram()192 public SessionMetricsStats addCountOfFailedIncomingDatagram() { 193 mCountOfIncomingDatagramFailed++; 194 logd("addCountOfFailedIncomingDatagram: current count=" + mCountOfIncomingDatagramFailed); 195 return this; 196 } 197 198 /** Sets whether the session is enabled for demo mode or not. */ setIsDemoMode(boolean isDemoMode)199 public SessionMetricsStats setIsDemoMode(boolean isDemoMode) { 200 mIsDemoMode = isDemoMode; 201 logd("setIsDemoMode(" + mIsDemoMode + ")"); 202 return this; 203 } 204 205 /** Updates the max Ntn signal strength level for the session. */ updateMaxNtnSignalStrengthLevel( @tnSignalStrength.NtnSignalStrengthLevel int latestNtnSignalStrengthLevel)206 public SessionMetricsStats updateMaxNtnSignalStrengthLevel( 207 @NtnSignalStrength.NtnSignalStrengthLevel int latestNtnSignalStrengthLevel) { 208 if (latestNtnSignalStrengthLevel > mMaxNtnSignalStrengthLevel) { 209 mMaxNtnSignalStrengthLevel = latestNtnSignalStrengthLevel; 210 } 211 logd("updateMaxNtnSignalsStrength: latest signal strength=" + latestNtnSignalStrengthLevel 212 + ", max signal strength=" + mMaxNtnSignalStrengthLevel); 213 return this; 214 } 215 216 /** Report the session metrics atoms to PersistAtomsStorage in telephony. */ reportSessionMetrics()217 public void reportSessionMetrics() { 218 SatelliteStats.SatelliteSessionParams sessionParams = 219 new SatelliteStats.SatelliteSessionParams.Builder() 220 .setSatelliteServiceInitializationResult(mInitializationResult) 221 .setSatelliteTechnology(mRadioTechnology) 222 .setTerminationResult(mTerminationResult) 223 .setInitializationProcessingTime(mInitializationProcessingTimeMillis) 224 .setTerminationProcessingTime(mTerminationProcessingTimeMillis) 225 .setSessionDuration(mSessionDurationSec) 226 .setCountOfOutgoingDatagramSuccess(mCountOfSuccessfulOutgoingDatagram) 227 .setCountOfOutgoingDatagramFailed(mCountOfFailedOutgoingDatagram) 228 .setCountOfIncomingDatagramSuccess(mCountOfSuccessfulIncomingDatagram) 229 .setCountOfIncomingDatagramFailed(mCountOfIncomingDatagramFailed) 230 .setIsDemoMode(mIsDemoMode) 231 .setMaxNtnSignalStrengthLevel(mMaxNtnSignalStrengthLevel) 232 .build(); 233 logd("reportSessionMetrics: " + sessionParams.toString()); 234 SatelliteStats.getInstance().onSatelliteSessionMetrics(sessionParams); 235 initializeSessionMetricsParam(); 236 } 237 238 /** Returns {@link SatelliteSessionStats} of the satellite service. */ requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result)239 public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) { 240 Bundle bundle = new Bundle(); 241 SatelliteSessionStats sessionStats = new SatelliteSessionStats.Builder() 242 .setCountOfSuccessfulUserMessages(mCountOfSuccessfulOutgoingDatagram) 243 .setCountOfUnsuccessfulUserMessages(mCountOfFailedOutgoingDatagram) 244 .setCountOfTimedOutUserMessagesWaitingForConnection( 245 mCountOfTimedOutUserMessagesWaitingForConnection) 246 .setCountOfTimedOutUserMessagesWaitingForAck( 247 mCountOfTimedOutUserMessagesWaitingForAck) 248 .setCountOfUserMessagesInQueueToBeSent( 249 DatagramDispatcher.getInstance().getPendingUserMessagesCount()) 250 .build(); 251 bundle.putParcelable(SatelliteManager.KEY_SESSION_STATS, sessionStats); 252 result.send(SATELLITE_RESULT_SUCCESS, bundle); 253 } 254 255 /** Returns the processing time for satellite session initialization. */ getSessionInitializationProcessingTimeMillis()256 public long getSessionInitializationProcessingTimeMillis() { 257 return mInitializationProcessingTimeMillis; 258 } 259 260 /** Returns the processing time for satellite session termination. */ getSessionTerminationProcessingTimeMillis()261 public long getSessionTerminationProcessingTimeMillis() { 262 return mTerminationProcessingTimeMillis; 263 } 264 initializeSessionMetricsParam()265 private void initializeSessionMetricsParam() { 266 mInitializationResult = SatelliteManager.SATELLITE_RESULT_SUCCESS; 267 mRadioTechnology = SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN; 268 mTerminationResult = SatelliteManager.SATELLITE_RESULT_SUCCESS; 269 mInitializationProcessingTimeMillis = 0; 270 mTerminationProcessingTimeMillis = 0; 271 mSessionDurationSec = 0; 272 mCountOfSuccessfulOutgoingDatagram = 0; 273 mCountOfFailedOutgoingDatagram = 0; 274 mCountOfTimedOutUserMessagesWaitingForConnection = 0; 275 mCountOfTimedOutUserMessagesWaitingForAck = 0; 276 mCountOfSuccessfulIncomingDatagram = 0; 277 mCountOfIncomingDatagramFailed = 0; 278 mIsDemoMode = false; 279 mMaxNtnSignalStrengthLevel = NTN_SIGNAL_STRENGTH_NONE; 280 } 281 logd(@onNull String log)282 private static void logd(@NonNull String log) { 283 if (DBG) { 284 Log.d(TAG, log); 285 } 286 } 287 loge(@onNull String log)288 private static void loge(@NonNull String log) { 289 Log.e(TAG, log); 290 } 291 } 292