blob: 2b72ab7635c3fb9e8d3fce75381882b555de7042 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.Range;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* Reports modem activity information.
* @hide
*/
public final class ModemActivityInfo implements Parcelable {
/**
* Tx(transmit) power level. see power index below
* <ul>
* <li> index 0 = tx_power < 0dBm. </li>
* <li> index 1 = 0dBm < tx_power < 5dBm. </li>
* <li> index 2 = 5dBm < tx_power < 15dBm. </li>
* <li> index 3 = 15dBm < tx_power < 20dBm. </li>
* <li> index 4 = tx_power > 20dBm. </li>
* </ul>
*/
public static final int TX_POWER_LEVELS = 5;
/**
* Tx(transmit) power level 0: tx_power < 0dBm
*/
public static final int TX_POWER_LEVEL_0 = 0;
/**
* Tx(transmit) power level 1: 0dBm < tx_power < 5dBm
*/
public static final int TX_POWER_LEVEL_1 = 1;
/**
* Tx(transmit) power level 2: 5dBm < tx_power < 15dBm
*/
public static final int TX_POWER_LEVEL_2 = 2;
/**
* Tx(transmit) power level 3: 15dBm < tx_power < 20dBm.
*/
public static final int TX_POWER_LEVEL_3 = 3;
/**
* Tx(transmit) power level 4: tx_power > 20dBm
*/
public static final int TX_POWER_LEVEL_4 = 4;
/** @hide */
@IntDef(prefix = {"TX_POWER_LEVEL_"}, value = {
TX_POWER_LEVEL_0,
TX_POWER_LEVEL_1,
TX_POWER_LEVEL_2,
TX_POWER_LEVEL_3,
TX_POWER_LEVEL_4,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TxPowerLevel {}
private static final Range<Integer>[] TX_POWER_RANGES = new Range[] {
new Range<>(Integer.MIN_VALUE, 0),
new Range<>(0, 5),
new Range<>(5, 15),
new Range<>(15, 20),
new Range<>(20, Integer.MAX_VALUE)
};
private long mTimestamp;
private int mSleepTimeMs;
private int mIdleTimeMs;
private List<TransmitPower> mTransmitPowerInfo = new ArrayList<>(TX_POWER_LEVELS);
private int mRxTimeMs;
public ModemActivityInfo(long timestamp, int sleepTimeMs, int idleTimeMs,
@NonNull int[] txTimeMs, int rxTimeMs) {
mTimestamp = timestamp;
mSleepTimeMs = sleepTimeMs;
mIdleTimeMs = idleTimeMs;
populateTransmitPowerRange(txTimeMs);
mRxTimeMs = rxTimeMs;
}
/** helper API to populate tx power range for each bucket **/
private void populateTransmitPowerRange(@NonNull int[] transmitPowerMs) {
int i = 0;
for ( ; i < Math.min(transmitPowerMs.length, TX_POWER_LEVELS); i++) {
mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], transmitPowerMs[i]));
}
// Make sure that mTransmitPowerInfo is fully initialized.
for ( ; i < TX_POWER_LEVELS; i++) {
mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], 0));
}
}
@Override
public String toString() {
return "ModemActivityInfo{"
+ " mTimestamp=" + mTimestamp
+ " mSleepTimeMs=" + mSleepTimeMs
+ " mIdleTimeMs=" + mIdleTimeMs
+ " mTransmitPowerInfo[]=" + mTransmitPowerInfo.toString()
+ " mRxTimeMs=" + mRxTimeMs
+ "}";
}
public int describeContents() {
return 0;
}
public static final @android.annotation.NonNull Parcelable.Creator<ModemActivityInfo> CREATOR =
new Parcelable.Creator<ModemActivityInfo>() {
public ModemActivityInfo createFromParcel(Parcel in) {
long timestamp = in.readLong();
int sleepTimeMs = in.readInt();
int idleTimeMs = in.readInt();
int[] txTimeMs = new int[TX_POWER_LEVELS];
for (int i = 0; i < TX_POWER_LEVELS; i++) {
txTimeMs[i] = in.readInt();
}
int rxTimeMs = in.readInt();
return new ModemActivityInfo(timestamp, sleepTimeMs, idleTimeMs,
txTimeMs, rxTimeMs);
}
public ModemActivityInfo[] newArray(int size) {
return new ModemActivityInfo[size];
}
};
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mTimestamp);
dest.writeInt(mSleepTimeMs);
dest.writeInt(mIdleTimeMs);
for (int i = 0; i < TX_POWER_LEVELS; i++) {
dest.writeInt(mTransmitPowerInfo.get(i).getTimeInMillis());
}
dest.writeInt(mRxTimeMs);
}
/**
* @return milliseconds since boot, including mTimeInMillis spent in sleep.
* @see SystemClock#elapsedRealtime()
*/
public long getTimestamp() {
return mTimestamp;
}
/** @hide */
public void setTimestamp(long timestamp) {
mTimestamp = timestamp;
}
/**
* @return an arrayList of {@link TransmitPower} with each element representing the total time where
* transmitter is awake time (in ms) for a given power range (in dbm).
*
* @see #TX_POWER_LEVELS
*/
@NonNull
public List<TransmitPower> getTransmitPowerInfo() {
return mTransmitPowerInfo;
}
/** @hide */
public void setTransmitTimeMillis(int[] txTimeMs) {
populateTransmitPowerRange(txTimeMs);
}
/** @hide */
@NonNull
public int[] getTransmitTimeMillis() {
int[] transmitTimeMillis = new int[TX_POWER_LEVELS];
for (int i = 0; i < transmitTimeMillis.length; i++) {
transmitTimeMillis[i] = mTransmitPowerInfo.get(i).getTimeInMillis();
}
return transmitTimeMillis;
}
/**
* @return total mTimeInMillis (in ms) when modem is in a low power or sleep state.
*/
public int getSleepTimeMillis() {
return mSleepTimeMs;
}
/** @hide */
public void setSleepTimeMillis(int sleepTimeMillis) {
mSleepTimeMs = sleepTimeMillis;
}
/**
* @return total mTimeInMillis (in ms) when modem is awake but neither the transmitter nor receiver are
* active.
*/
public int getIdleTimeMillis() {
return mIdleTimeMs;
}
/** @hide */
public void setIdleTimeMillis(int idleTimeMillis) {
mIdleTimeMs = idleTimeMillis;
}
/**
* @return rx(receive) mTimeInMillis in ms.
*/
public int getReceiveTimeMillis() {
return mRxTimeMs;
}
/** @hide */
public void setReceiveTimeMillis(int rxTimeMillis) {
mRxTimeMs = rxTimeMillis;
}
/**
* Indicate if the ModemActivityInfo is invalid due to modem's invalid reporting.
*
* @return {@code true} if this {@link ModemActivityInfo} record is valid,
* {@code false} otherwise.
*/
public boolean isValid() {
for (TransmitPower powerInfo : getTransmitPowerInfo()) {
if(powerInfo.getTimeInMillis() < 0) {
return false;
}
}
return ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0)
&& (getReceiveTimeMillis() >= 0) && !isEmpty());
}
private boolean isEmpty() {
for (TransmitPower txVal : getTransmitPowerInfo()) {
if(txVal.getTimeInMillis() != 0) {
return false;
}
}
return ((getIdleTimeMillis() == 0) && (getSleepTimeMillis() == 0)
&& (getReceiveTimeMillis() == 0));
}
/**
* Transmit power Information, including the power range in dbm and the total time (in ms) where
* the transmitter is active/awake for this power range.
* e.g, range: 0dbm(lower) ~ 5dbm(upper)
* time: 5ms
*/
public class TransmitPower {
private int mTimeInMillis;
private Range<Integer> mPowerRangeInDbm;
/** @hide */
public TransmitPower(@NonNull Range<Integer> range, int time) {
this.mTimeInMillis = time;
this.mPowerRangeInDbm = range;
}
/**
* @return the total time in ms where the transmitter is active/wake for this power range
* {@link #getPowerRangeInDbm()}.
*/
public int getTimeInMillis() {
return mTimeInMillis;
}
/**
* @return the power range in dbm. e.g, range: 0dbm(lower) ~ 5dbm(upper)
*/
@NonNull
public Range<Integer> getPowerRangeInDbm() {
return mPowerRangeInDbm;
}
@Override
public String toString() {
return "TransmitPower{"
+ " mTimeInMillis=" + mTimeInMillis
+ " mPowerRangeInDbm={" + mPowerRangeInDbm.getLower()
+ "," + mPowerRangeInDbm.getUpper()
+ "}}";
}
}
}