• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.TelephonyManager.UNKNOWN_CARRIER_ID;
20 import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
21 import static android.telephony.satellite.SatelliteManager.KEY_SESSION_STATS_V2;
22 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
23 
24 import android.annotation.NonNull;
25 import android.os.Bundle;
26 import android.os.ResultReceiver;
27 import android.telephony.satellite.NtnSignalStrength;
28 import android.telephony.satellite.SatelliteManager;
29 import android.telephony.satellite.SatelliteSessionStats;
30 import android.util.Log;
31 
32 import com.android.internal.telephony.metrics.SatelliteStats;
33 import com.android.internal.telephony.satellite.DatagramDispatcher;
34 
35 /**
36  * Stats to log to satellite session metrics
37  */
38 public class SessionMetricsStats {
39     private static final String TAG = SessionMetricsStats.class.getSimpleName();
40 
41     private static SessionMetricsStats sInstance = null;
42     private @SatelliteManager.SatelliteResult int mInitializationResult;
43     private @SatelliteManager.NTRadioTechnology int mRadioTechnology;
44     private @SatelliteManager.SatelliteResult int mTerminationResult;
45     private long mInitializationProcessingTimeMillis;
46     private long mTerminationProcessingTimeMillis;
47     private int mSessionDurationSec;
48     private int mCountOfSuccessfulOutgoingDatagram;
49     private int mShadowCountOfSuccessfulOutgoingDatagram;
50     private int mCountOfFailedOutgoingDatagram;
51     private int mShadowCountOfFailedOutgoingDatagram;
52     private int mCountOfTimedOutUserMessagesWaitingForConnection;
53     private int mShadowCountOfTimedOutUserMessagesWaitingForConnection;
54     private int mCountOfTimedOutUserMessagesWaitingForAck;
55     private int mShadowCountOfTimedOutUserMessagesWaitingForAck;
56     private int mCountOfSuccessfulIncomingDatagram;
57     private int mCountOfIncomingDatagramFailed;
58     private boolean mIsDemoMode;
59     private @NtnSignalStrength.NtnSignalStrengthLevel int mMaxNtnSignalStrengthLevel;
60     private int mCarrierId;
61     private int mCountOfSatelliteNotificationDisplayed;
62     private int mCountOfAutoExitDueToScreenOff;
63     private int mCountOfAutoExitDueToTnNetwork;
64     private boolean mIsEmergency;
65     private boolean mIsNtnOnlyCarrier;
66     private int mMaxInactivityDurationSec;
67     private SatelliteSessionStats mDatagramStats;
68 
SessionMetricsStats()69     private SessionMetricsStats() {
70         initializeSessionMetricsParam();
71         mDatagramStats = new SatelliteSessionStats();
72     }
73 
74     /**
75      * Returns the Singleton instance of SessionMetricsStats class.
76      * If an instance of the Singleton class has not been created,
77      * it creates a new instance and returns it. Otherwise, it returns
78      * the existing instance.
79      * @return the Singleton instance of SessionMetricsStats.
80      */
getInstance()81     public static SessionMetricsStats getInstance() {
82         if (sInstance == null) {
83             loge("create new SessionMetricsStats.");
84             sInstance = new SessionMetricsStats();
85         }
86         return sInstance;
87     }
88 
89     /** Sets the satellite initialization result. */
setInitializationResult( @atelliteManager.SatelliteResult int result)90     public SessionMetricsStats setInitializationResult(
91             @SatelliteManager.SatelliteResult int result) {
92         logd("setInitializationResult(" + result + ")");
93         mInitializationResult = result;
94         return this;
95     }
96 
97     /** Sets the satellite ratio technology. */
setSatelliteTechnology( @atelliteManager.NTRadioTechnology int radioTechnology)98     public SessionMetricsStats setSatelliteTechnology(
99             @SatelliteManager.NTRadioTechnology int radioTechnology) {
100         logd("setSatelliteTechnology(" + radioTechnology + ")");
101         mRadioTechnology = radioTechnology;
102         return this;
103     }
104 
105     /** Sets the satellite de-initialization result. */
setTerminationResult( @atelliteManager.SatelliteResult int result)106     public SessionMetricsStats setTerminationResult(
107             @SatelliteManager.SatelliteResult int result) {
108         logd("setTerminationResult(" + result + ")");
109         mTerminationResult = result;
110         return this;
111     }
112 
113     /** Sets the satellite initialization processing time. */
setInitializationProcessingTime(long processingTime)114     public SessionMetricsStats setInitializationProcessingTime(long processingTime) {
115         logd("setInitializationProcessingTime(" + processingTime + ")");
116         mInitializationProcessingTimeMillis = processingTime;
117         return this;
118     }
119 
120     /** Sets the satellite de-initialization processing time. */
setTerminationProcessingTime(long processingTime)121     public SessionMetricsStats setTerminationProcessingTime(long processingTime) {
122         logd("setTerminationProcessingTime(" + processingTime + ")");
123         mTerminationProcessingTimeMillis = processingTime;
124         return this;
125     }
126 
127     /** Sets the total enabled time for the satellite session. */
setSessionDurationSec(int sessionDurationSec)128     public SessionMetricsStats setSessionDurationSec(int sessionDurationSec) {
129         logd("setSessionDuration(" + sessionDurationSec + ")");
130         mSessionDurationSec = sessionDurationSec;
131         return this;
132     }
133 
134     /** Increase the count of successful outgoing datagram transmission. */
addCountOfSuccessfulOutgoingDatagram( @onNull @atelliteManager.DatagramType int datagramType, long datagramTransmissionTime)135     public SessionMetricsStats addCountOfSuccessfulOutgoingDatagram(
136             @NonNull @SatelliteManager.DatagramType int datagramType,
137             long datagramTransmissionTime) {
138         logd("addCountOfSuccessfulOutgoingDatagram: datagramType=" + datagramType);
139         mDatagramStats.recordSuccessfulOutgoingDatagramStats(datagramType,
140                 datagramTransmissionTime);
141         if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
142             // Ignore KEEP_ALIVE messages
143             return this;
144         }
145 
146         mCountOfSuccessfulOutgoingDatagram++;
147         mShadowCountOfSuccessfulOutgoingDatagram++;
148         return this;
149     }
150 
151     /** Increase the count of failed outgoing datagram transmission. */
addCountOfFailedOutgoingDatagram( @onNull @atelliteManager.DatagramType int datagramType, @NonNull @SatelliteManager.SatelliteResult int resultCode)152     public SessionMetricsStats addCountOfFailedOutgoingDatagram(
153             @NonNull @SatelliteManager.DatagramType int datagramType,
154             @NonNull @SatelliteManager.SatelliteResult int resultCode) {
155         logd("addCountOfFailedOutgoingDatagram: datagramType=" + datagramType + "  resultCode = "
156                 + resultCode);
157         mDatagramStats.addCountOfUnsuccessfulUserMessages(datagramType, resultCode);
158         if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
159             // Ignore KEEP_ALIVE messages
160             return this;
161         }
162 
163         mCountOfFailedOutgoingDatagram++;
164         mShadowCountOfFailedOutgoingDatagram++;
165         if (resultCode == SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE) {
166             addCountOfTimedOutUserMessagesWaitingForConnection(datagramType);
167         } else if (resultCode == SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT) {
168             addCountOfTimedOutUserMessagesWaitingForAck(datagramType);
169         }
170         return this;
171     }
172 
173     /** Increase the count of user messages that timed out waiting for connection. */
addCountOfTimedOutUserMessagesWaitingForConnection( @onNull @atelliteManager.DatagramType int datagramType)174     private SessionMetricsStats addCountOfTimedOutUserMessagesWaitingForConnection(
175             @NonNull @SatelliteManager.DatagramType int datagramType) {
176         if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
177             // Ignore KEEP_ALIVE messages
178             return this;
179         }
180 
181         mCountOfTimedOutUserMessagesWaitingForConnection++;
182         mShadowCountOfTimedOutUserMessagesWaitingForConnection++;
183         logd("addCountOfTimedOutUserMessagesWaitingForConnection: current count="
184                 + mCountOfTimedOutUserMessagesWaitingForConnection);
185         return this;
186     }
187 
188     /** Increase the count of user messages that timed out waiting for ack. */
addCountOfTimedOutUserMessagesWaitingForAck( @onNull @atelliteManager.DatagramType int datagramType)189     private SessionMetricsStats addCountOfTimedOutUserMessagesWaitingForAck(
190             @NonNull @SatelliteManager.DatagramType int datagramType) {
191         if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
192             // Ignore KEEP_ALIVE messages
193             return this;
194         }
195 
196         mCountOfTimedOutUserMessagesWaitingForAck++;
197         mShadowCountOfTimedOutUserMessagesWaitingForAck++;
198         logd("addCountOfTimedOutUserMessagesWaitingForAck: current count="
199                 + mCountOfTimedOutUserMessagesWaitingForAck);
200         return this;
201     }
202 
203     /** Increase the count of successful incoming datagram transmission. */
addCountOfSuccessfulIncomingDatagram()204     public SessionMetricsStats addCountOfSuccessfulIncomingDatagram() {
205         mCountOfSuccessfulIncomingDatagram++;
206         logd("addCountOfSuccessfulIncomingDatagram: current count="
207                 + mCountOfSuccessfulIncomingDatagram);
208         return this;
209     }
210 
211     /** Increase the count of failed incoming datagram transmission. */
addCountOfFailedIncomingDatagram()212     public SessionMetricsStats addCountOfFailedIncomingDatagram() {
213         mCountOfIncomingDatagramFailed++;
214         logd("addCountOfFailedIncomingDatagram: current count=" + mCountOfIncomingDatagramFailed);
215         return this;
216     }
217 
218     /** Sets whether the session is enabled for demo mode or not. */
setIsDemoMode(boolean isDemoMode)219     public SessionMetricsStats setIsDemoMode(boolean isDemoMode) {
220         mIsDemoMode = isDemoMode;
221         logd("setIsDemoMode(" + mIsDemoMode + ")");
222         return this;
223     }
224 
225     /** Updates the max Ntn signal strength level for the session. */
updateMaxNtnSignalStrengthLevel( @tnSignalStrength.NtnSignalStrengthLevel int latestNtnSignalStrengthLevel)226     public SessionMetricsStats updateMaxNtnSignalStrengthLevel(
227             @NtnSignalStrength.NtnSignalStrengthLevel int latestNtnSignalStrengthLevel) {
228         if (latestNtnSignalStrengthLevel > mMaxNtnSignalStrengthLevel) {
229             mMaxNtnSignalStrengthLevel = latestNtnSignalStrengthLevel;
230         }
231         logd("updateMaxNtnSignalsStrength: latest signal strength=" + latestNtnSignalStrengthLevel
232                 + ", max signal strength=" + mMaxNtnSignalStrengthLevel);
233         return this;
234     }
235 
236     /** Sets the Carrier ID of this NTN session. */
setCarrierId(int carrierId)237     public SessionMetricsStats setCarrierId(int carrierId) {
238         mCarrierId = carrierId;
239         logd("setCarrierId(" + carrierId + ")");
240         return this;
241     }
242 
243     /** Increase the count of Satellite Notification Display. */
addCountOfSatelliteNotificationDisplayed()244     public SessionMetricsStats addCountOfSatelliteNotificationDisplayed() {
245         mCountOfSatelliteNotificationDisplayed++;
246         logd("addCountOfSatelliteNotificationDisplayed: current count="
247                 + mCountOfSatelliteNotificationDisplayed);
248         return this;
249     }
250 
251     /** Increase the count of auto exit from P2P satellite messaging due to screen off. */
addCountOfAutoExitDueToScreenOff()252     public SessionMetricsStats addCountOfAutoExitDueToScreenOff() {
253         mCountOfAutoExitDueToScreenOff++;
254         logd("addCountOfAutoExitDueToScreenOff: current count=" + mCountOfAutoExitDueToScreenOff);
255         return this;
256     }
257 
258     /** Increase the count of auto exit from P2P satellite messaging due to scan TN network. */
addCountOfAutoExitDueToTnNetwork()259     public SessionMetricsStats addCountOfAutoExitDueToTnNetwork() {
260         mCountOfAutoExitDueToTnNetwork++;
261         logd("addCountOfAutoExitDueToTnNetwork: current count=" + mCountOfAutoExitDueToTnNetwork);
262         return this;
263     }
264 
265     /** Sets whether the session is enabled for emergency or not. */
setIsEmergency(boolean isEmergency)266     public SessionMetricsStats setIsEmergency(boolean isEmergency) {
267         mIsEmergency = isEmergency;
268         logd("setIsEmergency(" + mIsEmergency + ")");
269         return this;
270     }
271 
272     /** Capture the latest provisioned state for satellite service */
setIsNtnOnlyCarrier(boolean isNtnOnlyCarrier)273     public SessionMetricsStats setIsNtnOnlyCarrier(boolean isNtnOnlyCarrier) {
274         mIsNtnOnlyCarrier = isNtnOnlyCarrier;
275         logd("setIsNtnOnlyCarrier(" + mIsNtnOnlyCarrier + ")");
276         return this;
277     }
278 
279     /** Updates the max inactivity duration session metric. */
updateMaxInactivityDurationSec(int inactivityDurationSec)280     public SessionMetricsStats updateMaxInactivityDurationSec(int inactivityDurationSec) {
281         if (inactivityDurationSec > mMaxInactivityDurationSec) {
282             mMaxInactivityDurationSec = inactivityDurationSec;
283         }
284         logd("updateMaxInactivityDurationSec: latest inactivty duration (sec)="
285                 + inactivityDurationSec
286                 + ", max inactivity duration="
287                 + mMaxInactivityDurationSec);
288         return this;
289     }
290 
291     /** Report the session metrics atoms to PersistAtomsStorage in telephony. */
reportSessionMetrics()292     public void reportSessionMetrics() {
293         SatelliteStats.SatelliteSessionParams sessionParams =
294                 new SatelliteStats.SatelliteSessionParams.Builder()
295                         .setSatelliteServiceInitializationResult(mInitializationResult)
296                         .setSatelliteTechnology(mRadioTechnology)
297                         .setTerminationResult(mTerminationResult)
298                         .setInitializationProcessingTime(mInitializationProcessingTimeMillis)
299                         .setTerminationProcessingTime(mTerminationProcessingTimeMillis)
300                         .setSessionDuration(mSessionDurationSec)
301                         .setCountOfOutgoingDatagramSuccess(mCountOfSuccessfulOutgoingDatagram)
302                         .setCountOfOutgoingDatagramFailed(mCountOfFailedOutgoingDatagram)
303                         .setCountOfIncomingDatagramSuccess(mCountOfSuccessfulIncomingDatagram)
304                         .setCountOfIncomingDatagramFailed(mCountOfIncomingDatagramFailed)
305                         .setIsDemoMode(mIsDemoMode)
306                         .setMaxNtnSignalStrengthLevel(mMaxNtnSignalStrengthLevel)
307                         .setCarrierId(mCarrierId)
308                         .setCountOfSatelliteNotificationDisplayed(
309                                 mCountOfSatelliteNotificationDisplayed)
310                         .setCountOfAutoExitDueToScreenOff(mCountOfAutoExitDueToScreenOff)
311                         .setCountOfAutoExitDueToTnNetwork(mCountOfAutoExitDueToTnNetwork)
312                         .setIsEmergency(mIsEmergency)
313                         .setIsNtnOnlyCarrier(mIsNtnOnlyCarrier)
314                         .setMaxInactivityDurationSec(mMaxInactivityDurationSec)
315                         .build();
316         logd("reportSessionMetrics: " + sessionParams.toString());
317         SatelliteStats.getInstance().onSatelliteSessionMetrics(sessionParams);
318         initializeSessionMetricsParam();
319     }
320 
321     /** Returns {@link SatelliteSessionStats} of the satellite service. */
requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result)322     public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) {
323         Log.i(TAG, "requestSatelliteSessionStats called");
324         Bundle bundle = new Bundle();
325         SatelliteSessionStats sessionStats = new SatelliteSessionStats.Builder()
326                 .setCountOfSuccessfulUserMessages(mShadowCountOfSuccessfulOutgoingDatagram)
327                 .setCountOfUnsuccessfulUserMessages(mShadowCountOfFailedOutgoingDatagram)
328                 .setCountOfTimedOutUserMessagesWaitingForConnection(
329                         mShadowCountOfTimedOutUserMessagesWaitingForConnection)
330                 .setCountOfTimedOutUserMessagesWaitingForAck(
331                         mShadowCountOfTimedOutUserMessagesWaitingForAck)
332                 .setCountOfUserMessagesInQueueToBeSent(
333                         DatagramDispatcher.getInstance().getPendingUserMessagesCount())
334                 .build();
335         bundle.putParcelable(SatelliteManager.KEY_SESSION_STATS, sessionStats);
336 
337         // Reset countOfUserMessagesInQueueToBeSent for each datagramType to 0.
338         mDatagramStats.resetCountOfUserMessagesInQueueToBeSent();
339 
340         DatagramDispatcher.getInstance().updateSessionStatsWithPendingUserMsgCount(mDatagramStats);
341         bundle.putParcelable(KEY_SESSION_STATS_V2, mDatagramStats);
342         Log.i(TAG, "[END] DatagramStats = " + mDatagramStats);
343         result.send(SATELLITE_RESULT_SUCCESS, bundle);
344     }
345 
346     /** Returns the processing time for satellite session initialization. */
getSessionInitializationProcessingTimeMillis()347     public long getSessionInitializationProcessingTimeMillis() {
348         return mInitializationProcessingTimeMillis;
349     }
350 
351     /** Returns the processing time for satellite session termination. */
getSessionTerminationProcessingTimeMillis()352     public long getSessionTerminationProcessingTimeMillis() {
353         return mTerminationProcessingTimeMillis;
354     }
355 
initializeSessionMetricsParam()356     private void initializeSessionMetricsParam() {
357         mInitializationResult = SATELLITE_RESULT_SUCCESS;
358         mRadioTechnology = SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN;
359         mTerminationResult = SATELLITE_RESULT_SUCCESS;
360         mInitializationProcessingTimeMillis = 0;
361         mTerminationProcessingTimeMillis = 0;
362         mSessionDurationSec = 0;
363         mCountOfSuccessfulOutgoingDatagram = 0;
364         mCountOfFailedOutgoingDatagram = 0;
365         mCountOfTimedOutUserMessagesWaitingForConnection = 0;
366         mCountOfTimedOutUserMessagesWaitingForAck = 0;
367         mCountOfSuccessfulIncomingDatagram = 0;
368         mCountOfIncomingDatagramFailed = 0;
369         mIsDemoMode = false;
370         mMaxNtnSignalStrengthLevel = NTN_SIGNAL_STRENGTH_NONE;
371         mCarrierId = UNKNOWN_CARRIER_ID;
372         mCountOfSatelliteNotificationDisplayed = 0;
373         mCountOfAutoExitDueToScreenOff = 0;
374         mCountOfAutoExitDueToTnNetwork = 0;
375         mIsEmergency = false;
376         mIsNtnOnlyCarrier = false;
377         mMaxInactivityDurationSec = 0;
378     }
379 
resetSessionStatsShadowCounters()380     public void resetSessionStatsShadowCounters() {
381         logd("resetTheStatsCounters");
382         mShadowCountOfSuccessfulOutgoingDatagram = 0;
383         mShadowCountOfFailedOutgoingDatagram = 0;
384         mShadowCountOfTimedOutUserMessagesWaitingForConnection = 0;
385         mShadowCountOfTimedOutUserMessagesWaitingForAck = 0;
386         mDatagramStats.clear();
387     }
388 
logd(@onNull String log)389     private static void logd(@NonNull String log) {
390         Log.d(TAG, log);
391     }
392 
loge(@onNull String log)393     private static void loge(@NonNull String log) {
394         Log.e(TAG, log);
395     }
396 }
397