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