1 /* 2 * Copyright (C) 2014 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.os.connectivity; 18 19 import android.annotation.ElapsedRealtimeLong; 20 import android.annotation.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.annotation.SystemApi; 24 import android.app.ActivityThread; 25 import android.content.Context; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 29 import com.android.internal.os.PowerProfile; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * Record of energy and activity information from controller and 36 * underlying wifi stack state. Timestamp the record with elapsed 37 * real-time. 38 * @hide 39 */ 40 @android.ravenwood.annotation.RavenwoodKeepWholeClass 41 @SystemApi 42 public final class WifiActivityEnergyInfo implements Parcelable { 43 private static final long DEFERRED_ENERGY_ESTIMATE = -1; 44 @ElapsedRealtimeLong 45 private final long mTimeSinceBootMillis; 46 @StackState 47 private final int mStackState; 48 @IntRange(from = 0) 49 private final long mControllerTxDurationMillis; 50 @IntRange(from = 0) 51 private final long mControllerRxDurationMillis; 52 @IntRange(from = 0) 53 private final long mControllerScanDurationMillis; 54 @IntRange(from = 0) 55 private final long mControllerIdleDurationMillis; 56 @IntRange(from = 0) 57 private long mControllerEnergyUsedMicroJoules; 58 59 /** @hide */ 60 @Retention(RetentionPolicy.SOURCE) 61 @IntDef(prefix = {"STACK_STATE_"}, value = { 62 STACK_STATE_INVALID, 63 STACK_STATE_STATE_ACTIVE, 64 STACK_STATE_STATE_SCANNING, 65 STACK_STATE_STATE_IDLE}) 66 public @interface StackState {} 67 68 /** Invalid Wifi stack state. */ 69 public static final int STACK_STATE_INVALID = 0; 70 /** Wifi stack is active. */ 71 public static final int STACK_STATE_STATE_ACTIVE = 1; 72 /** Wifi stack is scanning. */ 73 public static final int STACK_STATE_STATE_SCANNING = 2; 74 /** Wifi stack is idle. */ 75 public static final int STACK_STATE_STATE_IDLE = 3; 76 77 /** 78 * Constructor. 79 * 80 * @param timeSinceBootMillis the elapsed real time since boot, in milliseconds. 81 * @param stackState The current state of the Wifi Stack. One of {@link #STACK_STATE_INVALID}, 82 * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, 83 * or {@link #STACK_STATE_STATE_IDLE}. 84 * @param txDurationMillis Cumulative milliseconds of active transmission. 85 * @param rxDurationMillis Cumulative milliseconds of active receive. 86 * @param scanDurationMillis Cumulative milliseconds when radio is awake due to scan. 87 * @param idleDurationMillis Cumulative milliseconds when radio is awake but not transmitting or 88 * receiving. 89 */ WifiActivityEnergyInfo( @lapsedRealtimeLong long timeSinceBootMillis, @StackState int stackState, @IntRange(from = 0) long txDurationMillis, @IntRange(from = 0) long rxDurationMillis, @IntRange(from = 0) long scanDurationMillis, @IntRange(from = 0) long idleDurationMillis)90 public WifiActivityEnergyInfo( 91 @ElapsedRealtimeLong long timeSinceBootMillis, 92 @StackState int stackState, 93 @IntRange(from = 0) long txDurationMillis, 94 @IntRange(from = 0) long rxDurationMillis, 95 @IntRange(from = 0) long scanDurationMillis, 96 @IntRange(from = 0) long idleDurationMillis) { 97 98 this(timeSinceBootMillis, 99 stackState, 100 txDurationMillis, 101 rxDurationMillis, 102 scanDurationMillis, 103 idleDurationMillis, 104 DEFERRED_ENERGY_ESTIMATE); 105 } 106 107 @android.ravenwood.annotation.RavenwoodReplace calculateEnergyMicroJoules( long txDurationMillis, long rxDurationMillis, long idleDurationMillis)108 private static long calculateEnergyMicroJoules( 109 long txDurationMillis, long rxDurationMillis, long idleDurationMillis) { 110 final Context context = ActivityThread.currentActivityThread().getSystemContext(); 111 if (context == null) { 112 return 0L; 113 } 114 // Calculate energy used using PowerProfile. 115 PowerProfile powerProfile = new PowerProfile(context); 116 final double idleCurrent = powerProfile.getAveragePower( 117 PowerProfile.POWER_WIFI_CONTROLLER_IDLE); 118 final double rxCurrent = powerProfile.getAveragePower( 119 PowerProfile.POWER_WIFI_CONTROLLER_RX); 120 final double txCurrent = powerProfile.getAveragePower( 121 PowerProfile.POWER_WIFI_CONTROLLER_TX); 122 final double voltage = powerProfile.getAveragePower( 123 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 124 125 return (long) ((txDurationMillis * txCurrent 126 + rxDurationMillis * rxCurrent 127 + idleDurationMillis * idleCurrent) 128 * voltage); 129 } 130 calculateEnergyMicroJoules$ravenwood(long txDurationMillis, long rxDurationMillis, long idleDurationMillis)131 private static long calculateEnergyMicroJoules$ravenwood(long txDurationMillis, 132 long rxDurationMillis, long idleDurationMillis) { 133 return 0; 134 } 135 136 /** @hide */ WifiActivityEnergyInfo( @lapsedRealtimeLong long timeSinceBootMillis, @StackState int stackState, @IntRange(from = 0) long txDurationMillis, @IntRange(from = 0) long rxDurationMillis, @IntRange(from = 0) long scanDurationMillis, @IntRange(from = 0) long idleDurationMillis, @IntRange(from = 0) long energyUsedMicroJoules)137 public WifiActivityEnergyInfo( 138 @ElapsedRealtimeLong long timeSinceBootMillis, 139 @StackState int stackState, 140 @IntRange(from = 0) long txDurationMillis, 141 @IntRange(from = 0) long rxDurationMillis, 142 @IntRange(from = 0) long scanDurationMillis, 143 @IntRange(from = 0) long idleDurationMillis, 144 @IntRange(from = 0) long energyUsedMicroJoules) { 145 mTimeSinceBootMillis = timeSinceBootMillis; 146 mStackState = stackState; 147 mControllerTxDurationMillis = txDurationMillis; 148 mControllerRxDurationMillis = rxDurationMillis; 149 mControllerScanDurationMillis = scanDurationMillis; 150 mControllerIdleDurationMillis = idleDurationMillis; 151 mControllerEnergyUsedMicroJoules = energyUsedMicroJoules; 152 } 153 154 @Override toString()155 public String toString() { 156 return "WifiActivityEnergyInfo{" 157 + " mTimeSinceBootMillis=" + mTimeSinceBootMillis 158 + " mStackState=" + mStackState 159 + " mControllerTxDurationMillis=" + mControllerTxDurationMillis 160 + " mControllerRxDurationMillis=" + mControllerRxDurationMillis 161 + " mControllerScanDurationMillis=" + mControllerScanDurationMillis 162 + " mControllerIdleDurationMillis=" + mControllerIdleDurationMillis 163 + " mControllerEnergyUsedMicroJoules=" + getControllerEnergyUsedMicroJoules() 164 + " }"; 165 } 166 167 public static final @NonNull Parcelable.Creator<WifiActivityEnergyInfo> CREATOR = 168 new Parcelable.Creator<WifiActivityEnergyInfo>() { 169 public WifiActivityEnergyInfo createFromParcel(Parcel in) { 170 long timestamp = in.readLong(); 171 int stackState = in.readInt(); 172 long txTime = in.readLong(); 173 long rxTime = in.readLong(); 174 long scanTime = in.readLong(); 175 long idleTime = in.readLong(); 176 return new WifiActivityEnergyInfo(timestamp, stackState, 177 txTime, rxTime, scanTime, idleTime); 178 } 179 public WifiActivityEnergyInfo[] newArray(int size) { 180 return new WifiActivityEnergyInfo[size]; 181 } 182 }; 183 184 @Override writeToParcel(@onNull Parcel out, int flags)185 public void writeToParcel(@NonNull Parcel out, int flags) { 186 out.writeLong(mTimeSinceBootMillis); 187 out.writeInt(mStackState); 188 out.writeLong(mControllerTxDurationMillis); 189 out.writeLong(mControllerRxDurationMillis); 190 out.writeLong(mControllerScanDurationMillis); 191 out.writeLong(mControllerIdleDurationMillis); 192 } 193 194 @Override describeContents()195 public int describeContents() { 196 return 0; 197 } 198 199 /** Get the timestamp (elapsed real time milliseconds since boot) of record creation. */ 200 @ElapsedRealtimeLong getTimeSinceBootMillis()201 public long getTimeSinceBootMillis() { 202 return mTimeSinceBootMillis; 203 } 204 205 /** 206 * Get the Wifi stack reported state. One of {@link #STACK_STATE_INVALID}, 207 * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, 208 * {@link #STACK_STATE_STATE_IDLE}. 209 */ 210 @StackState getStackState()211 public int getStackState() { 212 return mStackState; 213 } 214 215 /** Get the Wifi transmission duration, in milliseconds. */ 216 @IntRange(from = 0) getControllerTxDurationMillis()217 public long getControllerTxDurationMillis() { 218 return mControllerTxDurationMillis; 219 } 220 221 /** Get the Wifi receive duration, in milliseconds. */ 222 @IntRange(from = 0) getControllerRxDurationMillis()223 public long getControllerRxDurationMillis() { 224 return mControllerRxDurationMillis; 225 } 226 227 /** Get the Wifi scan duration, in milliseconds. */ 228 @IntRange(from = 0) getControllerScanDurationMillis()229 public long getControllerScanDurationMillis() { 230 return mControllerScanDurationMillis; 231 } 232 233 /** Get the Wifi idle duration, in milliseconds. */ 234 @IntRange(from = 0) getControllerIdleDurationMillis()235 public long getControllerIdleDurationMillis() { 236 return mControllerIdleDurationMillis; 237 } 238 239 /** Get the energy consumed by Wifi, in microjoules. */ 240 @IntRange(from = 0) getControllerEnergyUsedMicroJoules()241 public long getControllerEnergyUsedMicroJoules() { 242 if (mControllerEnergyUsedMicroJoules == DEFERRED_ENERGY_ESTIMATE) { 243 mControllerEnergyUsedMicroJoules = calculateEnergyMicroJoules( 244 mControllerTxDurationMillis, mControllerRxDurationMillis, 245 mControllerIdleDurationMillis); 246 } 247 return mControllerEnergyUsedMicroJoules; 248 } 249 250 /** 251 * Returns true if the record is valid, false otherwise. 252 * @hide 253 */ isValid()254 public boolean isValid() { 255 return mControllerTxDurationMillis >= 0 256 && mControllerRxDurationMillis >= 0 257 && mControllerScanDurationMillis >= 0 258 && mControllerIdleDurationMillis >= 0; 259 } 260 } 261