1 /* 2 * Copyright (C) 2015 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.NonNull; 20 import android.annotation.SystemApi; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.SystemClock; 24 import android.util.Range; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * Reports modem activity information. 31 * @hide 32 */ 33 @SystemApi 34 public final class ModemActivityInfo implements Parcelable { 35 /** 36 * Tx(transmit) power level. see power index below 37 * <ul> 38 * <li> index 0 = tx_power < 0dBm. </li> 39 * <li> index 1 = 0dBm < tx_power < 5dBm. </li> 40 * <li> index 2 = 5dBm < tx_power < 15dBm. </li> 41 * <li> index 3 = 15dBm < tx_power < 20dBm. </li> 42 * <li> index 4 = tx_power > 20dBm. </li> 43 * </ul> 44 */ 45 public static final int TX_POWER_LEVELS = 5; 46 private static final Range<Integer>[] TX_POWER_RANGES = new Range[] { 47 new Range<>(Integer.MIN_VALUE, 0), 48 new Range<>(0, 5), 49 new Range<>(5, 15), 50 new Range<>(15, 20), 51 new Range<>(20, Integer.MAX_VALUE) 52 53 }; 54 55 private long mTimestamp; 56 private int mSleepTimeMs; 57 private int mIdleTimeMs; 58 private List<TransmitPower> mTransmitPowerInfo = new ArrayList<>(TX_POWER_LEVELS); 59 private int mRxTimeMs; 60 ModemActivityInfo(long timestamp, int sleepTimeMs, int idleTimeMs, @NonNull int[] txTimeMs, int rxTimeMs)61 public ModemActivityInfo(long timestamp, int sleepTimeMs, int idleTimeMs, 62 @NonNull int[] txTimeMs, int rxTimeMs) { 63 mTimestamp = timestamp; 64 mSleepTimeMs = sleepTimeMs; 65 mIdleTimeMs = idleTimeMs; 66 populateTransmitPowerRange(txTimeMs); 67 mRxTimeMs = rxTimeMs; 68 } 69 70 /** helper API to populate tx power range for each bucket **/ populateTransmitPowerRange(@onNull int[] transmitPowerMs)71 private void populateTransmitPowerRange(@NonNull int[] transmitPowerMs) { 72 int i = 0; 73 for ( ; i < Math.min(transmitPowerMs.length, TX_POWER_LEVELS); i++) { 74 mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], transmitPowerMs[i])); 75 } 76 // Make sure that mTransmitPowerInfo is fully initialized. 77 for ( ; i < TX_POWER_LEVELS; i++) { 78 mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], 0)); 79 } 80 } 81 82 @Override toString()83 public String toString() { 84 return "ModemActivityInfo{" 85 + " mTimestamp=" + mTimestamp 86 + " mSleepTimeMs=" + mSleepTimeMs 87 + " mIdleTimeMs=" + mIdleTimeMs 88 + " mTransmitPowerInfo[]=" + mTransmitPowerInfo.toString() 89 + " mRxTimeMs=" + mRxTimeMs 90 + "}"; 91 } 92 describeContents()93 public int describeContents() { 94 return 0; 95 } 96 97 public static final @android.annotation.NonNull Parcelable.Creator<ModemActivityInfo> CREATOR = 98 new Parcelable.Creator<ModemActivityInfo>() { 99 public ModemActivityInfo createFromParcel(Parcel in) { 100 long timestamp = in.readLong(); 101 int sleepTimeMs = in.readInt(); 102 int idleTimeMs = in.readInt(); 103 int[] txTimeMs = new int[TX_POWER_LEVELS]; 104 for (int i = 0; i < TX_POWER_LEVELS; i++) { 105 txTimeMs[i] = in.readInt(); 106 } 107 int rxTimeMs = in.readInt(); 108 return new ModemActivityInfo(timestamp, sleepTimeMs, idleTimeMs, 109 txTimeMs, rxTimeMs); 110 } 111 112 public ModemActivityInfo[] newArray(int size) { 113 return new ModemActivityInfo[size]; 114 } 115 }; 116 writeToParcel(@onNull Parcel dest, int flags)117 public void writeToParcel(@NonNull Parcel dest, int flags) { 118 dest.writeLong(mTimestamp); 119 dest.writeInt(mSleepTimeMs); 120 dest.writeInt(mIdleTimeMs); 121 for (int i = 0; i < TX_POWER_LEVELS; i++) { 122 dest.writeInt(mTransmitPowerInfo.get(i).getTimeInMillis()); 123 } 124 dest.writeInt(mRxTimeMs); 125 } 126 127 /** 128 * @return milliseconds since boot, including mTimeInMillis spent in sleep. 129 * @see SystemClock#elapsedRealtime() 130 */ getTimestamp()131 public long getTimestamp() { 132 return mTimestamp; 133 } 134 135 /** @hide */ setTimestamp(long timestamp)136 public void setTimestamp(long timestamp) { 137 mTimestamp = timestamp; 138 } 139 140 /** 141 * @return an arrayList of {@link TransmitPower} with each element representing the total time where 142 * transmitter is awake time (in ms) for a given power range (in dbm). 143 * 144 * @see #TX_POWER_LEVELS 145 */ 146 @NonNull getTransmitPowerInfo()147 public List<TransmitPower> getTransmitPowerInfo() { 148 return mTransmitPowerInfo; 149 } 150 151 /** @hide */ setTransmitTimeMillis(int[] txTimeMs)152 public void setTransmitTimeMillis(int[] txTimeMs) { 153 populateTransmitPowerRange(txTimeMs); 154 } 155 156 /** @hide */ 157 @NonNull getTransmitTimeMillis()158 public int[] getTransmitTimeMillis() { 159 int[] transmitTimeMillis = new int[TX_POWER_LEVELS]; 160 for (int i = 0; i < transmitTimeMillis.length; i++) { 161 transmitTimeMillis[i] = mTransmitPowerInfo.get(i).getTimeInMillis(); 162 } 163 return transmitTimeMillis; 164 } 165 166 /** 167 * @return total mTimeInMillis (in ms) when modem is in a low power or sleep state. 168 */ getSleepTimeMillis()169 public int getSleepTimeMillis() { 170 return mSleepTimeMs; 171 } 172 173 /** @hide */ setSleepTimeMillis(int sleepTimeMillis)174 public void setSleepTimeMillis(int sleepTimeMillis) { 175 mSleepTimeMs = sleepTimeMillis; 176 } 177 178 /** 179 * @return total mTimeInMillis (in ms) when modem is awake but neither the transmitter nor receiver are 180 * active. 181 */ getIdleTimeMillis()182 public int getIdleTimeMillis() { 183 return mIdleTimeMs; 184 } 185 186 /** @hide */ setIdleTimeMillis(int idleTimeMillis)187 public void setIdleTimeMillis(int idleTimeMillis) { 188 mIdleTimeMs = idleTimeMillis; 189 } 190 191 /** 192 * @return rx(receive) mTimeInMillis in ms. 193 */ getReceiveTimeMillis()194 public int getReceiveTimeMillis() { 195 return mRxTimeMs; 196 } 197 198 /** @hide */ setReceiveTimeMillis(int rxTimeMillis)199 public void setReceiveTimeMillis(int rxTimeMillis) { 200 mRxTimeMs = rxTimeMillis; 201 } 202 203 /** 204 * Indicates if the modem has reported valid {@link ModemActivityInfo}. 205 * 206 * @return {@code true} if this {@link ModemActivityInfo} record is valid, 207 * {@code false} otherwise. 208 */ isValid()209 public boolean isValid() { 210 for (TransmitPower powerInfo : getTransmitPowerInfo()) { 211 if(powerInfo.getTimeInMillis() < 0) { 212 return false; 213 } 214 } 215 216 return ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0) 217 && (getReceiveTimeMillis() >= 0) && !isEmpty()); 218 } 219 isEmpty()220 private boolean isEmpty() { 221 for (TransmitPower txVal : getTransmitPowerInfo()) { 222 if(txVal.getTimeInMillis() != 0) { 223 return false; 224 } 225 } 226 227 return ((getIdleTimeMillis() == 0) && (getSleepTimeMillis() == 0) 228 && (getReceiveTimeMillis() == 0)); 229 } 230 231 /** 232 * Transmit power Information, including the power range in dbm and the total time (in ms) where 233 * the transmitter is active/awake for this power range. 234 * e.g, range: 0dbm(lower) ~ 5dbm(upper) 235 * time: 5ms 236 */ 237 public class TransmitPower { 238 private int mTimeInMillis; 239 private Range<Integer> mPowerRangeInDbm; 240 /** @hide */ TransmitPower(@onNull Range<Integer> range, int time)241 public TransmitPower(@NonNull Range<Integer> range, int time) { 242 this.mTimeInMillis = time; 243 this.mPowerRangeInDbm = range; 244 } 245 246 /** 247 * @return the total time in ms where the transmitter is active/wake for this power range 248 * {@link #getPowerRangeInDbm()}. 249 */ getTimeInMillis()250 public int getTimeInMillis() { 251 return mTimeInMillis; 252 } 253 254 /** 255 * @return the power range in dbm. e.g, range: 0dbm(lower) ~ 5dbm(upper) 256 */ 257 @NonNull getPowerRangeInDbm()258 public Range<Integer> getPowerRangeInDbm() { 259 return mPowerRangeInDbm; 260 } 261 262 @Override toString()263 public String toString() { 264 return "TransmitPower{" 265 + " mTimeInMillis=" + mTimeInMillis 266 + " mPowerRangeInDbm={" + mPowerRangeInDbm.getLower() 267 + "," + mPowerRangeInDbm.getUpper() 268 + "}}"; 269 } 270 } 271 } 272