1 /*
2  * Copyright (C) 2022 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;
18 
19 import android.annotation.DurationMillisLong;
20 import android.annotation.NonNull;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.telephony.ServiceState.FrequencyRange;
24 
25 import java.util.Arrays;
26 import java.util.Objects;
27 
28 /**
29  * Technology specific activity stats info. List of the activity stats for each RATs (2G, 3G, 4G and
30  * 5G) and frequency ranges (HIGH for sub6 and MMWAVE) in case of 5G. In case implementation doesn't
31  * have RAT specific activity stats then send only one activity stats info with RAT unknown.
32  *
33  * @hide
34  */
35 @android.ravenwood.annotation.RavenwoodKeepWholeClass
36 public final class ActivityStatsTechSpecificInfo implements Parcelable {
37     private static final int TX_POWER_LEVELS = 5;
38 
39     private int mRat;
40     private int mFrequencyRange;
41     private int[] mTxTimeMs;
42     private int mRxTimeMs;
43 
44     /** @hide */
ActivityStatsTechSpecificInfo( int rat, @FrequencyRange int frequencyRange, @NonNull int[] txTimeMs, int rxTimeMs)45     public ActivityStatsTechSpecificInfo(
46             int rat, @FrequencyRange int frequencyRange, @NonNull int[] txTimeMs, int rxTimeMs) {
47         Objects.requireNonNull(txTimeMs);
48         if (txTimeMs.length != TX_POWER_LEVELS) {
49             throw new IllegalArgumentException("txTimeMs must have length == TX_POWER_LEVELS");
50         }
51         mRat = rat;
52         mFrequencyRange = frequencyRange;
53         mTxTimeMs = txTimeMs;
54         mRxTimeMs = rxTimeMs;
55     }
56 
57     /**
58      * Returns the radio access technology for this activity stats info.
59      *
60      * The returned value is define in {@link AccessNetworkConstants.AccessNetworkType};
61      * @hide
62      */
getRat()63     public int getRat() {
64         return mRat;
65     }
66 
67     /**
68      * Returns the rough frequency range for this activity stats info.
69      *
70      * The returned value is define in {@link ServiceState.FrequencyRange};
71      * @hide
72      */
getFrequencyRange()73     public @FrequencyRange int getFrequencyRange() {
74         return mFrequencyRange;
75     }
76 
77     /**
78      * Gets the amount of time the modem spent transmitting at a certain power level.
79      *
80      * @return The amount of time, in milliseconds, that the modem spent transmitting at the given
81      *     power level.
82      */
getTransmitTimeMillis(int powerLevel)83     public @DurationMillisLong long getTransmitTimeMillis(int powerLevel) {
84         return mTxTimeMs[powerLevel];
85     }
86 
87     /**
88      * @return The raw array of transmit power durations
89      * @hide
90      */
91     @NonNull
getTransmitTimeMillis()92     public int[] getTransmitTimeMillis() {
93         return mTxTimeMs;
94     }
95 
96     /**
97      * Gets the amount of time (in milliseconds) when the modem is awake and receiving data.
98      *
99      * @return Time in milliseconds.
100      * @hide
101      */
getReceiveTimeMillis()102     public @DurationMillisLong long getReceiveTimeMillis() {
103         return mRxTimeMs;
104     }
105     /** @hide */
setRat(int rat)106     public void setRat(int rat) {
107         mRat = rat;
108     }
109 
110     /** @hide */
setFrequencyRange(@requencyRange int frequencyRange)111     public void setFrequencyRange(@FrequencyRange int frequencyRange) {
112         mFrequencyRange = frequencyRange;
113     }
114 
115     /** @hide */
setReceiveTimeMillis(int receiveTimeMillis)116     public void setReceiveTimeMillis(int receiveTimeMillis) {
117         mRxTimeMs = receiveTimeMillis;
118     }
119 
120     /**
121      * Provided for convenience, since the API surface needs to return longs but internal
122      * representations are ints.
123      *
124      * @hide
125      */
setReceiveTimeMillis(long receiveTimeMillis)126     public void setReceiveTimeMillis(long receiveTimeMillis) {
127         mRxTimeMs = (int) receiveTimeMillis;
128     }
129 
130     /** @hide */
setTransmitTimeMillis(int[] txTimeMs)131     public void setTransmitTimeMillis(int[] txTimeMs) {
132         mTxTimeMs = Arrays.copyOf(txTimeMs, TX_POWER_LEVELS);
133     }
134 
135     /** @hide */
isTxPowerValid()136     public boolean isTxPowerValid() {
137         return Arrays.stream(mTxTimeMs).allMatch((i) -> i >= 0);
138     }
139 
140     /** @hide */
isRxPowerValid()141     public boolean isRxPowerValid() {
142         return getReceiveTimeMillis() >= 0;
143     }
144 
145     /** @hide */
isTxPowerEmpty()146     public boolean isTxPowerEmpty() {
147         boolean isTxPowerEmpty =
148                 mTxTimeMs == null
149                         || mTxTimeMs.length == 0
150                         || Arrays.stream(mTxTimeMs).allMatch((i) -> i == 0);
151         return isTxPowerEmpty;
152     }
153 
154     /** @hide */
isRxPowerEmpty()155     public boolean isRxPowerEmpty() {
156         return getReceiveTimeMillis() == 0;
157     }
158 
159     @Override
hashCode()160     public int hashCode() {
161         int result = Objects.hash(mRat, mFrequencyRange, mRxTimeMs);
162         result = 31 * result + Arrays.hashCode(mTxTimeMs);
163         return result;
164     }
165 
166     @Override
equals(Object o)167     public boolean equals(Object o) {
168         if (this == o) return true;
169         if (!(o instanceof ActivityStatsTechSpecificInfo)) return false;
170         ActivityStatsTechSpecificInfo that = (ActivityStatsTechSpecificInfo) o;
171         return mRat == that.mRat
172                 && mFrequencyRange == that.mFrequencyRange
173                 && Arrays.equals(mTxTimeMs, that.mTxTimeMs)
174                 && mRxTimeMs == that.mRxTimeMs;
175     }
176 
ratToString(int type)177     private static String ratToString(int type) {
178         switch (type) {
179             case AccessNetworkConstants.AccessNetworkType.UNKNOWN:
180                 return "UNKNOWN";
181             case AccessNetworkConstants.AccessNetworkType.GERAN:
182                 return "GERAN";
183             case AccessNetworkConstants.AccessNetworkType.UTRAN:
184                 return "UTRAN";
185             case AccessNetworkConstants.AccessNetworkType.EUTRAN:
186                 return "EUTRAN";
187             case AccessNetworkConstants.AccessNetworkType.CDMA2000:
188                 return "CDMA2000";
189             case AccessNetworkConstants.AccessNetworkType.IWLAN:
190                 return "IWLAN";
191             case AccessNetworkConstants.AccessNetworkType.NGRAN:
192                 return "NGRAN";
193             default:
194                 return Integer.toString(type);
195         }
196     }
197 
198     @Override
toString()199     public String toString() {
200         return new StringBuilder()
201                 .append("{mRat=")
202                 .append(ratToString(mRat))
203                 .append(",mFrequencyRange=")
204                 .append(ServiceState.frequencyRangeToString(mFrequencyRange))
205                 .append(",mTxTimeMs[]=")
206                 .append(Arrays.toString(mTxTimeMs))
207                 .append(",mRxTimeMs=")
208                 .append(mRxTimeMs)
209                 .append("}")
210                 .toString();
211     }
212 
213     /**
214      * {@link Parcelable#describeContents}
215      */
describeContents()216     public int describeContents() {
217         return 0;
218     }
219 
220     public static final @android.annotation.NonNull Parcelable.Creator<
221                     ActivityStatsTechSpecificInfo>
222             CREATOR =
223                     new Parcelable.Creator<ActivityStatsTechSpecificInfo>() {
224                 public ActivityStatsTechSpecificInfo createFromParcel(@NonNull Parcel in) {
225                     int rat = in.readInt();
226                     int frequencyRange = in.readInt();
227                     int[] txTimeMs = new int[TX_POWER_LEVELS];
228                     in.readIntArray(txTimeMs);
229                     int rxTimeMs = in.readInt();
230                     return new ActivityStatsTechSpecificInfo(
231                             rat, frequencyRange, txTimeMs, rxTimeMs);
232                 }
233 
234                 public ActivityStatsTechSpecificInfo[] newArray(int size) {
235                     return new ActivityStatsTechSpecificInfo[size];
236                 }
237     };
238 
239     @Override
writeToParcel(@onNull Parcel dest, int flags)240     public void writeToParcel(@NonNull Parcel dest, int flags) {
241         dest.writeInt(mRat);
242         dest.writeInt(mFrequencyRange);
243         dest.writeIntArray(mTxTimeMs);
244         dest.writeInt(mRxTimeMs);
245     }
246 }
247