diff options
author | Hall Liu <hallliu@google.com> | 2020-10-09 18:58:45 -0700 |
---|---|---|
committer | Sarah Chin <sarahchin@google.com> | 2021-09-07 11:40:55 -0700 |
commit | f4fe3ac665f326a69c0fda19468a21e0dd7f2fbf (patch) | |
tree | 852f87e3a5be6ca2e486badbda66423a971b2f66 | |
parent | 733dd0f1e9e64493b167b9d3b771520dcfed0a13 (diff) | |
download | base-f4fe3ac665f326a69c0fda19468a21e0dd7f2fbf.tar.gz |
Update and expose ModemActivityInfo
Update ModemActivityInfo to present a nicer API surface and expose it as
a SystemApi. Also change clients in BatteryStats to match the new
surface.
This is part 1. Part 2 will modify the methods in TelephonyManager to
use a more up-to-standards threading model.
Bug: 170427831
Test: atest ModemActivityInfoTest
Change-Id: I762ed949342861c75d94eafce88335e7bd8c9139
Merged-In: I762ed949342861c75d94eafce88335e7bd8c9139
-rw-r--r-- | core/api/system-current.txt | 19 | ||||
-rw-r--r-- | core/api/test-current.txt | 21 | ||||
-rw-r--r-- | core/java/android/os/connectivity/CellularBatteryStats.java | 2 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 69 | ||||
-rw-r--r-- | services/core/java/com/android/server/stats/pull/StatsPullAtomService.java | 12 | ||||
-rw-r--r-- | telephony/java/android/telephony/ModemActivityInfo.java | 284 |
6 files changed, 241 insertions, 166 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index cd41e58ba882..84c602faffe9 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9671,6 +9671,25 @@ package android.telephony { field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; } + public final class ModemActivityInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.ModemActivityInfo getDelta(@NonNull android.telephony.ModemActivityInfo); + method public long getIdleTimeMillis(); + method public static int getNumTxPowerLevels(); + method public long getReceiveTimeMillis(); + method public long getSleepTimeMillis(); + method public long getTimestampMillis(); + method public long getTransmitDurationMillisAtPowerLevel(int); + method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; + field public static final int TX_POWER_LEVEL_0 = 0; // 0x0 + field public static final int TX_POWER_LEVEL_1 = 1; // 0x1 + field public static final int TX_POWER_LEVEL_2 = 2; // 0x2 + field public static final int TX_POWER_LEVEL_3 = 3; // 0x3 + field public static final int TX_POWER_LEVEL_4 = 4; // 0x4 + } + public final class NetworkRegistrationInfo implements android.os.Parcelable { method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); method public int getRegistrationState(); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 661394732a12..95de4e34ed7c 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1649,6 +1649,27 @@ package android.telephony { field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override"; } + public final class ModemActivityInfo implements android.os.Parcelable { + ctor public ModemActivityInfo(long, int, int, @NonNull int[], int); + method public int describeContents(); + method @NonNull public android.telephony.ModemActivityInfo getDelta(@NonNull android.telephony.ModemActivityInfo); + method public long getIdleTimeMillis(); + method public static int getNumTxPowerLevels(); + method public long getReceiveTimeMillis(); + method public long getSleepTimeMillis(); + method public long getTimestampMillis(); + method public long getTransmitDurationMillisAtPowerLevel(int); + method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int); + method public boolean isValid(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; + field public static final int TX_POWER_LEVEL_0 = 0; // 0x0 + field public static final int TX_POWER_LEVEL_1 = 1; // 0x1 + field public static final int TX_POWER_LEVEL_2 = 2; // 0x2 + field public static final int TX_POWER_LEVEL_3 = 3; // 0x3 + field public static final int TX_POWER_LEVEL_4 = 4; // 0x4 + } + public class PhoneNumberUtils { method public static int getMinMatchForTest(); method public static void setMinMatchForTest(int); diff --git a/core/java/android/os/connectivity/CellularBatteryStats.java b/core/java/android/os/connectivity/CellularBatteryStats.java index 121fd333d17f..fc17002ba056 100644 --- a/core/java/android/os/connectivity/CellularBatteryStats.java +++ b/core/java/android/os/connectivity/CellularBatteryStats.java @@ -109,7 +109,7 @@ public final class CellularBatteryStats implements Parcelable { CellSignalStrength.getNumSignalStrengthLevels())); mTxTimeMs = Arrays.copyOfRange( txTimeMs, 0, - Math.min(txTimeMs.length, ModemActivityInfo.TX_POWER_LEVELS)); + Math.min(txTimeMs.length, ModemActivityInfo.getNumTxPowerLevels())); mMonitoredRailChargeConsumedMaMs = monitoredRailChargeConsumedMaMs; } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index dd2940f8c110..e8db609ee991 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -66,7 +66,6 @@ import android.provider.Settings; import android.telephony.CellSignalStrength; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ModemActivityInfo; -import android.telephony.ModemActivityInfo.TransmitPower; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; @@ -7205,7 +7204,7 @@ public class BatteryStatsImpl extends BatteryStats { public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { if (mModemControllerActivity == null) { mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, - ModemActivityInfo.TX_POWER_LEVELS); + ModemActivityInfo.getNumTxPowerLevels()); } return mModemControllerActivity; } @@ -8687,7 +8686,7 @@ public class BatteryStatsImpl extends BatteryStats { if (in.readInt() != 0) { mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, - ModemActivityInfo.TX_POWER_LEVELS, in); + ModemActivityInfo.getNumTxPowerLevels(), in); } else { mModemControllerActivity = null; } @@ -9953,7 +9952,7 @@ public class BatteryStatsImpl extends BatteryStats { mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_BT_TX_LEVELS); mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, - ModemActivityInfo.TX_POWER_LEVELS); + ModemActivityInfo.getNumTxPowerLevels()); mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, mOnBatteryTimeBase); @@ -11131,26 +11130,7 @@ public class BatteryStatsImpl extends BatteryStats { } } - private ModemActivityInfo mLastModemActivityInfo = - new ModemActivityInfo(0, 0, 0, new int[0], 0); - - private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) { - if (activityInfo == null) { - return null; - } - int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; - for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { - txTimeMs[i] = activityInfo.getTransmitPowerInfo().get(i).getTimeInMillis() - - mLastModemActivityInfo.getTransmitPowerInfo().get(i).getTimeInMillis(); - } - ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(), - activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(), - activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(), - txTimeMs, - activityInfo.getReceiveTimeMillis() - mLastModemActivityInfo.getReceiveTimeMillis()); - mLastModemActivityInfo = activityInfo; - return deltaInfo; - } + private ModemActivityInfo mLastModemActivityInfo = null; /** * Distribute Cell radio energy info and network traffic to apps. @@ -11159,7 +11139,9 @@ public class BatteryStatsImpl extends BatteryStats { if (DEBUG_ENERGY) { Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); } - ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); + ModemActivityInfo deltaInfo = mLastModemActivityInfo == null ? activityInfo + : mLastModemActivityInfo.getDelta(activityInfo); + mLastModemActivityInfo = activityInfo; // Add modem tx power to history. addModemTxPowerToHistory(deltaInfo); @@ -11191,10 +11173,9 @@ public class BatteryStatsImpl extends BatteryStats { mModemActivity.getSleepTimeCounter().addCountLocked( deltaInfo.getSleepTimeMillis()); mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis()); - for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { + for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { mModemActivity.getTxTimeCounters()[lvl] - .addCountLocked(deltaInfo.getTransmitPowerInfo() - .get(lvl).getTimeInMillis()); + .addCountLocked(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl)); } // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. @@ -11208,11 +11189,11 @@ public class BatteryStatsImpl extends BatteryStats { mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) + deltaInfo.getReceiveTimeMillis() * mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); - List<TransmitPower> txPowerInfo = deltaInfo.getTransmitPowerInfo(); - for (int i = 0; i < Math.min(txPowerInfo.size(), + for (int i = 0; i < Math.min(ModemActivityInfo.getNumTxPowerLevels(), CellSignalStrength.getNumSignalStrengthLevels()); i++) { - energyUsed += txPowerInfo.get(i).getTimeInMillis() * mPowerProfile - .getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, i); + energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) + * mPowerProfile.getAveragePower( + PowerProfile.POWER_MODEM_CONTROLLER_TX, i); } // We store the power drain as mAms. @@ -11307,10 +11288,10 @@ public class BatteryStatsImpl extends BatteryStats { } if (totalTxPackets > 0 && entry.txPackets > 0) { - for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { - long txMs = - entry.txPackets * deltaInfo.getTransmitPowerInfo() - .get(lvl).getTimeInMillis(); + for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); + lvl++) { + long txMs = entry.txPackets + * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); txMs /= totalTxPackets; activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); } @@ -11341,20 +11322,16 @@ public class BatteryStatsImpl extends BatteryStats { if (activityInfo == null) { return; } - List<TransmitPower> txPowerInfo = activityInfo.getTransmitPowerInfo(); - if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) { - return; - } final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); int levelMaxTimeSpent = 0; - for (int i = 1; i < txPowerInfo.size(); i++) { - if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent) - .getTimeInMillis()) { + for (int i = 1; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { + if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) + > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { levelMaxTimeSpent = i; } } - if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { + if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) { mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; addHistoryRecordLocked(elapsedRealtime, uptime); } @@ -12771,7 +12748,7 @@ public class BatteryStatsImpl extends BatteryStats { timeInRxSignalStrengthLevelMs[i] = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000; } - long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS, + long[] txTimeMs = new long[Math.min(ModemActivityInfo.getNumTxPowerLevels(), counter.getTxTimeCounters().length)]; long totalTxTimeMs = 0; for (int i = 0; i < txTimeMs.length; i++) { @@ -14817,7 +14794,7 @@ public class BatteryStatsImpl extends BatteryStats { mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_BT_TX_LEVELS, in); mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, - ModemActivityInfo.TX_POWER_LEVELS, in); + ModemActivityInfo.getNumTxPowerLevels(), in); mHasWifiReporting = in.readInt() != 0; mHasBluetoothReporting = in.readInt() != 0; mHasModemReporting = in.readInt() != 0; diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 03900150cfae..a24a6532290f 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -1739,14 +1739,14 @@ public class StatsPullAtomService extends SystemService { } StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) - .writeLong(modemInfo.getTimestamp()) + .writeLong(modemInfo.getTimestampMillis()) .writeLong(modemInfo.getSleepTimeMillis()) .writeLong(modemInfo.getIdleTimeMillis()) - .writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis()) - .writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis()) - .writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis()) - .writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis()) - .writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis()) + .writeLong(modemInfo.getTransmitDurationMillisAtPowerLevel(0)) + .writeLong(modemInfo.getTransmitDurationMillisAtPowerLevel(1)) + .writeLong(modemInfo.getTransmitDurationMillisAtPowerLevel(2)) + .writeLong(modemInfo.getTransmitDurationMillisAtPowerLevel(3)) + .writeLong(modemInfo.getTransmitDurationMillisAtPowerLevel(4)) .writeLong(modemInfo.getReceiveTimeMillis()) .build(); pulledData.add(e); diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java index debb119c94bc..881d85c73b5d 100644 --- a/telephony/java/android/telephony/ModemActivityInfo.java +++ b/telephony/java/android/telephony/ModemActivityInfo.java @@ -16,8 +16,12 @@ package android.telephony; +import android.annotation.DurationMillisLong; +import android.annotation.ElapsedRealtimeLong; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -25,46 +29,50 @@ import android.util.Range; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; +import java.util.Objects; /** - * Reports modem activity information. + * Contains information about the modem's activity. May be useful for power stats reporting. * @hide */ +@SystemApi +@TestApi public final class ModemActivityInfo implements Parcelable { + private static final int TX_POWER_LEVELS = 5; + /** - * 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 + * Corresponds to transmit power of less than 0dBm. */ public static final int TX_POWER_LEVEL_0 = 0; + /** - * Tx(transmit) power level 1: 0dBm < tx_power < 5dBm + * Corresponds to transmit power between 0dBm and 5dBm. */ public static final int TX_POWER_LEVEL_1 = 1; + /** - * Tx(transmit) power level 2: 5dBm < tx_power < 15dBm + * Corresponds to transmit power between 5dBm and 15dBm. */ public static final int TX_POWER_LEVEL_2 = 2; + /** - * Tx(transmit) power level 3: 15dBm < tx_power < 20dBm. + * Corresponds to transmit power between 15dBm and 20dBm. */ public static final int TX_POWER_LEVEL_3 = 3; + /** - * Tx(transmit) power level 4: tx_power > 20dBm + * Corresponds to transmit power above 20dBm. */ public static final int TX_POWER_LEVEL_4 = 4; + /** + * The number of transmit power levels. Fixed by HAL definition. + */ + public static int getNumTxPowerLevels() { + return TX_POWER_LEVELS; + } + /** @hide */ @IntDef(prefix = {"TX_POWER_LEVEL_"}, value = { TX_POWER_LEVEL_0, @@ -82,34 +90,39 @@ public final class ModemActivityInfo implements Parcelable { 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[] mTxTimeMs; private int mRxTimeMs; + /** + * @hide + */ + @TestApi public ModemActivityInfo(long timestamp, int sleepTimeMs, int idleTimeMs, @NonNull int[] txTimeMs, int rxTimeMs) { + Objects.requireNonNull(txTimeMs); + if (txTimeMs.length != TX_POWER_LEVELS) { + throw new IllegalArgumentException("txTimeMs must have length == TX_POWER_LEVELS"); + } mTimestamp = timestamp; mSleepTimeMs = sleepTimeMs; mIdleTimeMs = idleTimeMs; - populateTransmitPowerRange(txTimeMs); + mTxTimeMs = 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)); - } + /** + * Provided for convenience in manipulation since the API exposes long values but internal + * representations are ints. + * @hide + */ + public ModemActivityInfo(long timestamp, long sleepTimeMs, long idleTimeMs, + @NonNull int[] txTimeMs, long rxTimeMs) { + this(timestamp, (int) sleepTimeMs, (int) idleTimeMs, txTimeMs, (int) rxTimeMs); } @Override @@ -118,7 +131,7 @@ public final class ModemActivityInfo implements Parcelable { + " mTimestamp=" + mTimestamp + " mSleepTimeMs=" + mSleepTimeMs + " mIdleTimeMs=" + mIdleTimeMs - + " mTransmitPowerInfo[]=" + mTransmitPowerInfo.toString() + + " mTxTimeMs[]=" + mTxTimeMs + " mRxTimeMs=" + mRxTimeMs + "}"; } @@ -129,14 +142,12 @@ public final class ModemActivityInfo implements Parcelable { public static final @android.annotation.NonNull Parcelable.Creator<ModemActivityInfo> CREATOR = new Parcelable.Creator<ModemActivityInfo>() { - public ModemActivityInfo createFromParcel(Parcel in) { + public ModemActivityInfo createFromParcel(@NonNull 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(); - } + in.readIntArray(txTimeMs); int rxTimeMs = in.readInt(); return new ModemActivityInfo(timestamp, sleepTimeMs, idleTimeMs, txTimeMs, rxTimeMs); @@ -147,21 +158,25 @@ public final class ModemActivityInfo implements Parcelable { } }; - public void writeToParcel(Parcel dest, int flags) { + /** + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written. + */ + public void writeToParcel(@NonNull 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.writeIntArray(mTxTimeMs); dest.writeInt(mRxTimeMs); } /** - * @return milliseconds since boot, including mTimeInMillis spent in sleep. - * @see SystemClock#elapsedRealtime() + * Gets the timestamp at which this modem activity info was recorded. + * + * @return The timestamp, as returned by {@link SystemClock#elapsedRealtime()}, when this + * {@link ModemActivityInfo} was recorded. */ - public long getTimestamp() { + public @ElapsedRealtimeLong long getTimestampMillis() { return mTimestamp; } @@ -171,35 +186,48 @@ public final class ModemActivityInfo implements Parcelable { } /** - * @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). + * Gets the amount of time the modem spent transmitting at a certain power level. * - * @see #TX_POWER_LEVELS + * @param powerLevel The power level to query. + * @return The amount of time, in milliseconds, that the modem spent transmitting at the + * given power level. */ - @NonNull - public List<TransmitPower> getTransmitPowerInfo() { - return mTransmitPowerInfo; + public @DurationMillisLong long getTransmitDurationMillisAtPowerLevel( + @TxPowerLevel int powerLevel) { + return mTxTimeMs[powerLevel]; + } + + /** + * Gets the range of transmit powers corresponding to a certain power level. + * + * @param powerLevel The power level to query + * @return A {@link Range} object representing the range of intensities (in dBm) to which this + * power level corresponds. + */ + public @NonNull Range<Integer> getTransmitPowerRange(@TxPowerLevel int powerLevel) { + return TX_POWER_RANGES[powerLevel]; } /** @hide */ public void setTransmitTimeMillis(int[] txTimeMs) { - populateTransmitPowerRange(txTimeMs); + mTxTimeMs = Arrays.copyOf(txTimeMs, TX_POWER_LEVELS); } - /** @hide */ + /** + * @return The raw array of transmit power durations + * @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 mTxTimeMs; } /** - * @return total mTimeInMillis (in ms) when modem is in a low power or sleep state. + * Gets the amount of time (in milliseconds) when the modem is in a low power or sleep state. + * + * @return Time in milliseconds. */ - public int getSleepTimeMillis() { + public @DurationMillisLong long getSleepTimeMillis() { return mSleepTimeMs; } @@ -209,10 +237,44 @@ public final class ModemActivityInfo implements Parcelable { } /** - * @return total mTimeInMillis (in ms) when modem is awake but neither the transmitter nor receiver are - * active. + * Provided for convenience, since the API surface needs to return longs but internal + * representations are ints. + * @hide */ - public int getIdleTimeMillis() { + public void setSleepTimeMillis(long sleepTimeMillis) { + mSleepTimeMs = (int) sleepTimeMillis; + } + + /** + * Computes the difference between this instance of {@link ModemActivityInfo} and another + * instance. + * + * This method should be used to compute the amount of activity that has happened between two + * samples of modem activity taken at separate times. The sample passed in as an argument to + * this method should be the one that's taken later in time (and therefore has more activity). + * @param other The other instance of {@link ModemActivityInfo} to diff against. + * @return An instance of {@link ModemActivityInfo} representing the difference in modem + * activity. + */ + public @NonNull ModemActivityInfo getDelta(@NonNull ModemActivityInfo other) { + int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; + for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { + txTimeMs[i] = other.mTxTimeMs[i] - mTxTimeMs[i]; + } + return new ModemActivityInfo(other.getTimestampMillis(), + other.getSleepTimeMillis() - getSleepTimeMillis(), + other.getIdleTimeMillis() - getIdleTimeMillis(), + txTimeMs, + other.getReceiveTimeMillis() - getReceiveTimeMillis()); + } + + /** + * Gets the amount of time (in milliseconds) when the modem is awake but neither transmitting + * nor receiving. + * + * @return Time in milliseconds. + */ + public @DurationMillisLong long getIdleTimeMillis() { return mIdleTimeMs; } @@ -222,9 +284,20 @@ public final class ModemActivityInfo implements Parcelable { } /** - * @return rx(receive) mTimeInMillis in ms. + * Provided for convenience, since the API surface needs to return longs but internal + * representations are ints. + * @hide + */ + public void setIdleTimeMillis(long idleTimeMillis) { + mIdleTimeMs = (int) idleTimeMillis; + } + + /** + * Gets the amount of time (in milliseconds) when the modem is awake and receiving data. + * + * @return Time in milliseconds. */ - public int getReceiveTimeMillis() { + public @DurationMillisLong long getReceiveTimeMillis() { return mRxTimeMs; } @@ -234,71 +307,56 @@ public final class ModemActivityInfo implements Parcelable { } /** + * Provided for convenience, since the API surface needs to return longs but internal + * representations are ints. + * @hide + */ + public void setReceiveTimeMillis(long receiveTimeMillis) { + mRxTimeMs = (int) receiveTimeMillis; + } + + /** * Indicates if the modem has reported valid {@link ModemActivityInfo}. * * @return {@code true} if this {@link ModemActivityInfo} record is valid, * {@code false} otherwise. + * TODO: remove usages of this outside Telephony by always returning a valid (or null) result + * from telephony. + * @hide */ + @TestApi public boolean isValid() { - for (TransmitPower powerInfo : getTransmitPowerInfo()) { - if(powerInfo.getTimeInMillis() < 0) { - return false; - } - } + boolean isTxPowerValid = Arrays.stream(mTxTimeMs).allMatch((i) -> i >= 0); - return ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0) + return isTxPowerValid && ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0) && (getReceiveTimeMillis() >= 0) && !isEmpty()); } private boolean isEmpty() { - for (TransmitPower txVal : getTransmitPowerInfo()) { - if(txVal.getTimeInMillis() != 0) { - return false; - } - } + boolean isTxPowerEmpty = mTxTimeMs == null || mTxTimeMs.length == 0 + || Arrays.stream(mTxTimeMs).allMatch((i) -> i == 0); - return ((getIdleTimeMillis() == 0) && (getSleepTimeMillis() == 0) + return isTxPowerEmpty && ((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 boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ModemActivityInfo that = (ModemActivityInfo) o; + return mTimestamp == that.mTimestamp + && mSleepTimeMs == that.mSleepTimeMs + && mIdleTimeMs == that.mIdleTimeMs + && mRxTimeMs == that.mRxTimeMs + && Arrays.equals(mTxTimeMs, that.mTxTimeMs); + } - @Override - public String toString() { - return "TransmitPower{" - + " mTimeInMillis=" + mTimeInMillis - + " mPowerRangeInDbm={" + mPowerRangeInDbm.getLower() - + "," + mPowerRangeInDbm.getUpper() - + "}}"; - } + @Override + public int hashCode() { + int result = Objects.hash(mTimestamp, mSleepTimeMs, mIdleTimeMs, mRxTimeMs); + result = 31 * result + Arrays.hashCode(mTxTimeMs); + return result; } } |