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