• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 android.telephony.satellite;
18 
19 import android.annotation.NonNull;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.util.Log;
23 
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Objects;
27 
28 /**
29  * SatelliteSessionStats is used to represent the usage stats of the satellite service.
30  *
31  * @hide
32  */
33 public final class SatelliteSessionStats implements Parcelable {
34     private int mCountOfSuccessfulUserMessages;
35     private int mCountOfUnsuccessfulUserMessages;
36     private int mCountOfTimedOutUserMessagesWaitingForConnection;
37     private int mCountOfTimedOutUserMessagesWaitingForAck;
38     private int mCountOfUserMessagesInQueueToBeSent;
39     private long mLatencyOfSuccessfulUserMessages;
40 
41     private Map<Integer, SatelliteSessionStats> datagramStats;
42     private long mMaxLatency;
43     private long mLastMessageLatency;
44 
SatelliteSessionStats()45     public SatelliteSessionStats() {
46         this.datagramStats = new HashMap<>();
47     }
48 
49     /**
50      * SatelliteSessionStats constructor
51      *
52      * @param builder Builder to create SatelliteSessionStats object/
53      */
SatelliteSessionStats(@onNull Builder builder)54     public SatelliteSessionStats(@NonNull Builder builder) {
55         mCountOfSuccessfulUserMessages = builder.mCountOfSuccessfulUserMessages;
56         mCountOfUnsuccessfulUserMessages = builder.mCountOfUnsuccessfulUserMessages;
57         mCountOfTimedOutUserMessagesWaitingForConnection =
58                 builder.mCountOfTimedOutUserMessagesWaitingForConnection;
59         mCountOfTimedOutUserMessagesWaitingForAck =
60                 builder.mCountOfTimedOutUserMessagesWaitingForAck;
61         mCountOfUserMessagesInQueueToBeSent = builder.mCountOfUserMessagesInQueueToBeSent;
62         mLatencyOfSuccessfulUserMessages = builder.mLatencyOfSuccessfulUserMessages;
63     }
64 
SatelliteSessionStats(Parcel in)65     private SatelliteSessionStats(Parcel in) {
66         readFromParcel(in);
67     }
68 
69     @Override
describeContents()70     public int describeContents() {
71         return 0;
72     }
73 
74     @Override
writeToParcel(@onNull Parcel out, int flags)75     public void writeToParcel(@NonNull Parcel out, int flags) {
76         out.writeInt(mCountOfSuccessfulUserMessages);
77         out.writeInt(mCountOfUnsuccessfulUserMessages);
78         out.writeInt(mCountOfTimedOutUserMessagesWaitingForConnection);
79         out.writeInt(mCountOfTimedOutUserMessagesWaitingForAck);
80         out.writeInt(mCountOfUserMessagesInQueueToBeSent);
81         out.writeLong(mLatencyOfSuccessfulUserMessages);
82         out.writeLong(mMaxLatency);
83         out.writeLong(mLastMessageLatency);
84 
85         if (datagramStats != null && !datagramStats.isEmpty()) {
86             out.writeInt(datagramStats.size());
87             for (Map.Entry<Integer, SatelliteSessionStats> entry : datagramStats.entrySet()) {
88                 out.writeInt(entry.getKey());
89                 out.writeParcelable(entry.getValue(), flags);
90             }
91         } else {
92             out.writeInt(0);
93         }
94     }
95 
96     @NonNull
97     public static final Creator<SatelliteSessionStats> CREATOR = new Parcelable.Creator<>() {
98 
99         @Override
100         public SatelliteSessionStats createFromParcel(Parcel in) {
101             return new SatelliteSessionStats(in);
102         }
103 
104         @Override
105         public SatelliteSessionStats[] newArray(int size) {
106             return new SatelliteSessionStats[size];
107         }
108     };
109 
110     @Override
111     @NonNull
toString()112     public String toString() {
113         StringBuilder sb = new StringBuilder();
114         if (datagramStats != null) {
115             sb.append(" ====== SatelliteSessionStatsWrapper Info =============");
116             for (Map.Entry<Integer, SatelliteSessionStats> entry : datagramStats.entrySet()) {
117                 Integer key = entry.getKey();
118                 SatelliteSessionStats value = entry.getValue();
119                 sb.append("\n");
120                 sb.append("Key:");
121                 sb.append(key);
122                 sb.append(", SatelliteSessionStats:[");
123                 value.getPrintableCounters(sb);
124                 sb.append(",");
125                 sb.append(" LatencyOfSuccessfulUserMessages:");
126                 sb.append(value.mLatencyOfSuccessfulUserMessages);
127                 sb.append(",");
128                 sb.append(" mMaxLatency:");
129                 sb.append(value.mMaxLatency);
130                 sb.append(",");
131                 sb.append(" mLastMessageLatency:");
132                 sb.append(value.mLastMessageLatency);
133                 sb.append("]");
134                 sb.append("\n");
135             }
136             sb.append(" ============== ================== ===============");
137             sb.append("\n");
138             sb.append("\n");
139         } else {
140             sb.append("\n");
141             getPrintableCounters(sb);
142         }
143         sb.append("\n");
144         return sb.toString();
145     }
146 
getPrintableCounters(StringBuilder sb)147     private void getPrintableCounters(StringBuilder sb) {
148         sb.append("countOfSuccessfulUserMessages:");
149         sb.append(mCountOfSuccessfulUserMessages);
150         sb.append(",");
151 
152         sb.append("countOfUnsuccessfulUserMessages:");
153         sb.append(mCountOfUnsuccessfulUserMessages);
154         sb.append(",");
155 
156         sb.append("countOfTimedOutUserMessagesWaitingForConnection:");
157         sb.append(mCountOfTimedOutUserMessagesWaitingForConnection);
158         sb.append(",");
159 
160         sb.append("countOfTimedOutUserMessagesWaitingForAck:");
161         sb.append(mCountOfTimedOutUserMessagesWaitingForAck);
162         sb.append(",");
163 
164         sb.append("countOfUserMessagesInQueueToBeSent:");
165         sb.append(mCountOfUserMessagesInQueueToBeSent);
166     }
167 
168     @Override
equals(Object o)169     public boolean equals(Object o) {
170         if (this == o) return true;
171         if (o == null || getClass() != o.getClass()) return false;
172         SatelliteSessionStats that = (SatelliteSessionStats) o;
173         return mCountOfSuccessfulUserMessages == that.mCountOfSuccessfulUserMessages
174                 && mLatencyOfSuccessfulUserMessages == that.mLatencyOfSuccessfulUserMessages
175                 && mCountOfUnsuccessfulUserMessages == that.mCountOfUnsuccessfulUserMessages
176                 && mCountOfTimedOutUserMessagesWaitingForConnection
177                 == that.mCountOfTimedOutUserMessagesWaitingForConnection
178                 && mCountOfTimedOutUserMessagesWaitingForAck
179                 == that.mCountOfTimedOutUserMessagesWaitingForAck
180                 && mCountOfUserMessagesInQueueToBeSent == that.mCountOfUserMessagesInQueueToBeSent;
181     }
182 
183     @Override
hashCode()184     public int hashCode() {
185         return Objects.hash(mCountOfSuccessfulUserMessages, mLatencyOfSuccessfulUserMessages,
186                 mCountOfUnsuccessfulUserMessages, mCountOfTimedOutUserMessagesWaitingForConnection,
187                 mCountOfTimedOutUserMessagesWaitingForAck, mCountOfUserMessagesInQueueToBeSent);
188     }
189 
getCountOfSuccessfulUserMessages()190     public int getCountOfSuccessfulUserMessages() {
191         return mCountOfSuccessfulUserMessages;
192     }
193 
incrementSuccessfulUserMessageCount()194     public void incrementSuccessfulUserMessageCount() {
195         mCountOfSuccessfulUserMessages++;
196     }
197 
getCountOfUnsuccessfulUserMessages()198     public int getCountOfUnsuccessfulUserMessages() {
199         return mCountOfUnsuccessfulUserMessages;
200     }
201 
incrementUnsuccessfulUserMessageCount()202     public void incrementUnsuccessfulUserMessageCount() {
203         mCountOfUnsuccessfulUserMessages++;
204     }
205 
getCountOfTimedOutUserMessagesWaitingForConnection()206     public int getCountOfTimedOutUserMessagesWaitingForConnection() {
207         return mCountOfTimedOutUserMessagesWaitingForConnection;
208     }
209 
incrementTimedOutUserMessagesWaitingForConnection()210     public void incrementTimedOutUserMessagesWaitingForConnection() {
211         mCountOfTimedOutUserMessagesWaitingForConnection++;
212     }
213 
getCountOfTimedOutUserMessagesWaitingForAck()214     public int getCountOfTimedOutUserMessagesWaitingForAck() {
215         return mCountOfTimedOutUserMessagesWaitingForAck;
216     }
217 
incrementTimedOutUserMessagesWaitingForAck()218     public void incrementTimedOutUserMessagesWaitingForAck() {
219         mCountOfTimedOutUserMessagesWaitingForAck++;
220     }
221 
getCountOfUserMessagesInQueueToBeSent()222     public int getCountOfUserMessagesInQueueToBeSent() {
223         return mCountOfUserMessagesInQueueToBeSent;
224     }
225 
incrementUserMessagesInQueueToBeSent()226     public void incrementUserMessagesInQueueToBeSent() {
227         mCountOfUserMessagesInQueueToBeSent++;
228     }
229 
getLatencyOfAllSuccessfulUserMessages()230     public long getLatencyOfAllSuccessfulUserMessages() {
231         return mLatencyOfSuccessfulUserMessages;
232     }
233 
updateLatencyOfAllSuccessfulUserMessages(long messageLatency)234     public void updateLatencyOfAllSuccessfulUserMessages(long messageLatency) {
235         mLatencyOfSuccessfulUserMessages += messageLatency;
236     }
237 
recordSuccessfulOutgoingDatagramStats( @atelliteManager.DatagramType int datagramType, long latency)238     public void recordSuccessfulOutgoingDatagramStats(
239             @SatelliteManager.DatagramType int datagramType, long latency) {
240         try {
241             datagramStats.putIfAbsent(datagramType, new SatelliteSessionStats.Builder().build());
242             SatelliteSessionStats data = datagramStats.get(datagramType);
243             data.incrementSuccessfulUserMessageCount();
244             if (data.mMaxLatency < latency) {
245                 data.mMaxLatency = latency;
246             }
247             data.mLastMessageLatency = latency;
248             data.updateLatencyOfAllSuccessfulUserMessages(latency);
249         } catch (Exception e) {
250             Log.e("SatelliteSessionStats",
251                     "Error while recordSuccessfulOutgoingDatagramStats: " + e.getMessage());
252         }
253     }
254 
resetCountOfUserMessagesInQueueToBeSent()255     public void resetCountOfUserMessagesInQueueToBeSent() {
256         for (Map.Entry<Integer, SatelliteSessionStats> entry : datagramStats.entrySet()) {
257             SatelliteSessionStats statsPerDatagramType = entry.getValue();
258             statsPerDatagramType.mCountOfUserMessagesInQueueToBeSent = 0;
259         }
260     }
261 
getCountOfSuccessfulOutgoingDatagram( @atelliteManager.DatagramType int datagramType)262     public int getCountOfSuccessfulOutgoingDatagram(
263             @SatelliteManager.DatagramType int datagramType) {
264         SatelliteSessionStats data = datagramStats.getOrDefault(datagramType,
265                 new SatelliteSessionStats());
266         return data.getCountOfSuccessfulUserMessages();
267     }
268 
getMaxLatency()269     public long getMaxLatency() {
270         return this.mMaxLatency;
271     }
272 
getLatencyOfAllSuccessfulUserMessages( @atelliteManager.DatagramType int datagramType)273     public Long getLatencyOfAllSuccessfulUserMessages(
274             @SatelliteManager.DatagramType int datagramType) {
275         SatelliteSessionStats data = datagramStats.getOrDefault(datagramType,
276                 new SatelliteSessionStats());
277         return data.getLatencyOfAllSuccessfulUserMessages();
278     }
279 
280 
getLastMessageLatency()281     public long getLastMessageLatency() {
282         return this.mLastMessageLatency;
283     }
284 
addCountOfUnsuccessfulUserMessages(@atelliteManager.DatagramType int datagramType, @SatelliteManager.SatelliteResult int resultCode)285     public void addCountOfUnsuccessfulUserMessages(@SatelliteManager.DatagramType int datagramType,
286             @SatelliteManager.SatelliteResult int resultCode) {
287         try {
288             datagramStats.putIfAbsent(datagramType, new SatelliteSessionStats.Builder().build());
289             SatelliteSessionStats data = datagramStats.get(datagramType);
290             data.incrementUnsuccessfulUserMessageCount();
291             if (resultCode == SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE) {
292                 data.incrementTimedOutUserMessagesWaitingForConnection();
293             } else if (resultCode == SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT) {
294                 data.incrementTimedOutUserMessagesWaitingForAck();
295             }
296         } catch (Exception e) {
297             Log.e("SatelliteSessionStats",
298                     "Error while addCountOfUnsuccessfulUserMessages: " + e.getMessage());
299         }
300     }
301 
updateCountOfUserMessagesInQueueToBeSent( @atelliteManager.DatagramType int datagramType)302     public void updateCountOfUserMessagesInQueueToBeSent(
303             @SatelliteManager.DatagramType int datagramType) {
304         try {
305             datagramStats.putIfAbsent(datagramType, new SatelliteSessionStats.Builder().build());
306             SatelliteSessionStats data = datagramStats.get(datagramType);
307             data.incrementUserMessagesInQueueToBeSent();
308         } catch (Exception e) {
309             Log.e("SatelliteSessionStats",
310                     "Error while addCountOfUserMessagesInQueueToBeSent: " + e.getMessage());
311         }
312     }
313 
getCountOfUnsuccessfulUserMessages(@atelliteManager.DatagramType int datagramType)314     public int getCountOfUnsuccessfulUserMessages(@SatelliteManager.DatagramType int datagramType) {
315         SatelliteSessionStats data = datagramStats.get(datagramType);
316         return data.getCountOfUnsuccessfulUserMessages();
317     }
318 
getCountOfTimedOutUserMessagesWaitingForConnection( @atelliteManager.DatagramType int datagramType)319     public int getCountOfTimedOutUserMessagesWaitingForConnection(
320             @SatelliteManager.DatagramType int datagramType) {
321         SatelliteSessionStats data = datagramStats.get(datagramType);
322         return data.getCountOfTimedOutUserMessagesWaitingForConnection();
323     }
324 
getCountOfTimedOutUserMessagesWaitingForAck( @atelliteManager.DatagramType int datagramType)325     public int getCountOfTimedOutUserMessagesWaitingForAck(
326             @SatelliteManager.DatagramType int datagramType) {
327         SatelliteSessionStats data = datagramStats.get(datagramType);
328         return data.getCountOfTimedOutUserMessagesWaitingForAck();
329     }
330 
getCountOfUserMessagesInQueueToBeSent( @atelliteManager.DatagramType int datagramType)331     public int getCountOfUserMessagesInQueueToBeSent(
332             @SatelliteManager.DatagramType int datagramType) {
333         SatelliteSessionStats data = datagramStats.get(datagramType);
334         return data.getCountOfUserMessagesInQueueToBeSent();
335     }
336 
clear()337     public void clear() {
338         datagramStats.clear();
339     }
340 
getSatelliteSessionStats()341     public Map<Integer, SatelliteSessionStats> getSatelliteSessionStats() {
342         return datagramStats;
343     }
344 
setSatelliteSessionStats(Map<Integer, SatelliteSessionStats> sessionStats)345     public void setSatelliteSessionStats(Map<Integer, SatelliteSessionStats> sessionStats) {
346         this.datagramStats = sessionStats;
347     }
348 
readFromParcel(Parcel in)349     private void readFromParcel(Parcel in) {
350         mCountOfSuccessfulUserMessages = in.readInt();
351         mCountOfUnsuccessfulUserMessages = in.readInt();
352         mCountOfTimedOutUserMessagesWaitingForConnection = in.readInt();
353         mCountOfTimedOutUserMessagesWaitingForAck = in.readInt();
354         mCountOfUserMessagesInQueueToBeSent = in.readInt();
355         mLatencyOfSuccessfulUserMessages = in.readLong();
356         mMaxLatency = in.readLong();
357         mLastMessageLatency = in.readLong();
358 
359         int size = in.readInt();
360         datagramStats = new HashMap<>();
361         for (int i = 0; i < size; i++) {
362             Integer key = in.readInt();
363             SatelliteSessionStats value = in.readParcelable(
364                     SatelliteSessionStats.class.getClassLoader());
365             datagramStats.put(key, value);
366         }
367     }
368 
369     /**
370      * A builder class to create {@link SatelliteSessionStats} data object.
371      */
372     public static final class Builder {
373         private int mCountOfSuccessfulUserMessages;
374         private int mCountOfUnsuccessfulUserMessages;
375         private int mCountOfTimedOutUserMessagesWaitingForConnection;
376         private int mCountOfTimedOutUserMessagesWaitingForAck;
377         private int mCountOfUserMessagesInQueueToBeSent;
378         private long mLatencyOfSuccessfulUserMessages;
379 
380         private long mMaxLatency;
381         private long mLastMessageLatency;
382         /**
383          * Sets countOfSuccessfulUserMessages value of {@link SatelliteSessionStats}
384          * and then returns the Builder class.
385          */
386         @NonNull
setCountOfSuccessfulUserMessages(int count)387         public Builder setCountOfSuccessfulUserMessages(int count) {
388             mCountOfSuccessfulUserMessages = count;
389             return this;
390         }
391 
392         /**
393          * Sets countOfUnsuccessfulUserMessages value of {@link SatelliteSessionStats}
394          * and then returns the Builder class.
395          */
396         @NonNull
setCountOfUnsuccessfulUserMessages(int count)397         public Builder setCountOfUnsuccessfulUserMessages(int count) {
398             mCountOfUnsuccessfulUserMessages = count;
399             return this;
400         }
401 
402         /**
403          * Sets countOfTimedOutUserMessagesWaitingForConnection value of
404          * {@link SatelliteSessionStats} and then returns the Builder class.
405          */
406         @NonNull
setCountOfTimedOutUserMessagesWaitingForConnection(int count)407         public Builder setCountOfTimedOutUserMessagesWaitingForConnection(int count) {
408             mCountOfTimedOutUserMessagesWaitingForConnection = count;
409             return this;
410         }
411 
412         /**
413          * Sets countOfTimedOutUserMessagesWaitingForAck value of {@link SatelliteSessionStats}
414          * and then returns the Builder class.
415          */
416         @NonNull
setCountOfTimedOutUserMessagesWaitingForAck(int count)417         public Builder setCountOfTimedOutUserMessagesWaitingForAck(int count) {
418             mCountOfTimedOutUserMessagesWaitingForAck = count;
419             return this;
420         }
421 
422         /**
423          * Sets countOfUserMessagesInQueueToBeSent value of {@link SatelliteSessionStats}
424          * and then returns the Builder class.
425          */
426         @NonNull
setCountOfUserMessagesInQueueToBeSent(int count)427         public Builder setCountOfUserMessagesInQueueToBeSent(int count) {
428             mCountOfUserMessagesInQueueToBeSent = count;
429             return this;
430         }
431 
432         @NonNull
setLatencyOfSuccessfulUserMessages(long latency)433         public Builder setLatencyOfSuccessfulUserMessages(long latency) {
434             mLatencyOfSuccessfulUserMessages = latency;
435             return this;
436         }
437 
438         @NonNull
setMaxLatency(long maxLatency)439         public Builder setMaxLatency(long maxLatency) {
440             mMaxLatency = maxLatency;
441             return this;
442         }
443 
444         @NonNull
setLastLatency(long lastLatency)445         public Builder setLastLatency(long lastLatency) {
446             mLastMessageLatency = lastLatency;
447             return this;
448         }
449 
450         /** Returns SatelliteSessionStats object. */
451         @NonNull
build()452         public SatelliteSessionStats build() {
453             return new SatelliteSessionStats(this);
454         }
455     }
456 }