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