OSDN Git Service

Revert "Adding per UID WiFi power distribution."
authorBart Sears <bsears@google.com>
Tue, 7 Apr 2015 06:14:04 +0000 (06:14 +0000)
committerBart Sears <bsears@google.com>
Tue, 7 Apr 2015 06:14:04 +0000 (06:14 +0000)
This CL is breaking the clockwork settings app in master.  Reverting
until Adam has a chance to investigate.

This reverts commit b943fabfc8ddb581dc2fd7288f87428dcb5d27b7.

Change-Id: Ieb11423c11cf9874a6175dce49843d0e1080c590

17 files changed:
core/java/android/os/BatteryStats.java
core/java/com/android/internal/app/IBatteryStats.aidl
core/java/com/android/internal/os/BatterySipper.java
core/java/com/android/internal/os/BatteryStatsHelper.java
core/java/com/android/internal/os/BatteryStatsImpl.java
core/java/com/android/internal/os/BluetoothPowerCalculator.java [deleted file]
core/java/com/android/internal/os/CpuPowerCalculator.java [deleted file]
core/java/com/android/internal/os/MobileRadioPowerCalculator.java [deleted file]
core/java/com/android/internal/os/PowerCalculator.java [deleted file]
core/java/com/android/internal/os/PowerProfile.java
core/java/com/android/internal/os/SensorPowerCalculator.java [deleted file]
core/java/com/android/internal/os/WakelockPowerCalculator.java [deleted file]
core/java/com/android/internal/os/WifiPowerCalculator.java [deleted file]
core/java/com/android/internal/os/WifiPowerEstimator.java [deleted file]
services/core/java/com/android/server/ConnectivityService.java
services/core/java/com/android/server/NetworkManagementService.java
services/core/java/com/android/server/am/BatteryStatsService.java

index 3051926..508fdee 100644 (file)
@@ -269,15 +269,6 @@ public abstract class BatteryStats implements Parcelable {
         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
 
         /**
-         * Returns the total time in microseconds associated with this Timer since the
-         * 'mark' was last set.
-         *
-         * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
-         * @return a time in microseconds
-         */
-        public abstract long getTimeSinceMarkLocked(long elapsedRealtimeUs);
-
-        /**
          * Temporary for debugging.
          */
         public abstract void logState(Printer pw, String prefix);
@@ -341,17 +332,7 @@ public abstract class BatteryStats implements Parcelable {
          * @return a Map from Strings to Uid.Pkg objects.
          */
         public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
-
-        /**
-         * Returns the time in milliseconds that this app kept the WiFi controller in the
-         * specified state <code>type</code>.
-         * @param type one of {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, or
-         *             {@link #CONTROLLER_TX_TIME}.
-         * @param which one of {@link #STATS_CURRENT}, {@link #STATS_SINCE_CHARGED}, or
-         *              {@link #STATS_SINCE_UNPLUGGED}.
-         */
-        public abstract long getWifiControllerActivity(int type, int which);
-
+        
         /**
          * {@hide}
          */
@@ -1933,6 +1914,7 @@ public abstract class BatteryStats implements Parcelable {
     public static final int NETWORK_MOBILE_TX_DATA = 1;
     public static final int NETWORK_WIFI_RX_DATA = 2;
     public static final int NETWORK_WIFI_TX_DATA = 3;
+
     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
 
     public abstract long getNetworkActivityBytes(int type, int which);
@@ -1941,25 +1923,10 @@ public abstract class BatteryStats implements Parcelable {
     public static final int CONTROLLER_IDLE_TIME = 0;
     public static final int CONTROLLER_RX_TIME = 1;
     public static final int CONTROLLER_TX_TIME = 2;
-    public static final int CONTROLLER_POWER_DRAIN = 3;
-    public static final int NUM_CONTROLLER_ACTIVITY_TYPES = CONTROLLER_POWER_DRAIN + 1;
+    public static final int CONTROLLER_ENERGY = 3;
+    public static final int NUM_CONTROLLER_ACTIVITY_TYPES = CONTROLLER_ENERGY + 1;
 
-    /**
-     * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
-     * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
-     * respective state.
-     * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
-     * milli-ampere-milliseconds (mAms).
-     */
     public abstract long getBluetoothControllerActivity(int type, int which);
-
-    /**
-     * For {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, and
-     * {@link #CONTROLLER_TX_TIME}, returns the time spent (in milliseconds) in the
-     * respective state.
-     * For {@link #CONTROLLER_POWER_DRAIN}, returns the power used by the controller in
-     * milli-ampere-milliseconds (mAms).
-     */
     public abstract long getWifiControllerActivity(int type, int which);
 
     /**
@@ -2651,7 +2618,7 @@ public abstract class BatteryStats implements Parcelable {
                         label = "???";
                 }
                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
-                        BatteryStatsHelper.makemAh(bs.totalPowerMah));
+                        BatteryStatsHelper.makemAh(bs.value));
             }
         }
 
@@ -3297,13 +3264,6 @@ public abstract class BatteryStats implements Parcelable {
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  WiFi Energy use: ").append(BatteryStatsHelper.makemAh(
-                getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which) / (double)(1000*60*60)));
-        sb.append(" mAh");
-        pw.println(sb.toString());
-
-        sb.setLength(0);
-        sb.append(prefix);
                 sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
                 sb.append(")");
@@ -3416,48 +3376,48 @@ public abstract class BatteryStats implements Parcelable {
                 final BatterySipper bs = sippers.get(i);
                 switch (bs.drainType) {
                     case IDLE:
-                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case CELL:
-                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case PHONE:
-                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case WIFI:
-                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case BLUETOOTH:
-                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case SCREEN:
-                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case FLASHLIGHT:
-                        pw.print(prefix); pw.print("    Flashlight: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Flashlight: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case APP:
                         pw.print(prefix); pw.print("    Uid ");
                         UserHandle.formatUid(pw, bs.uidObj.getUid());
-                        pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println();
+                        pw.print(": "); printmAh(pw, bs.value); pw.println();
                         break;
                     case USER:
                         pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
-                        pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println();
+                        pw.print(": "); printmAh(pw, bs.value); pw.println();
                         break;
                     case UNACCOUNTED:
-                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                     case OVERCOUNTED:
-                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.totalPowerMah);
+                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
                         pw.println();
                         break;
                 }
index 1746bed..bea4ece 100644 (file)
@@ -109,7 +109,6 @@ interface IBatteryStats {
     void noteWifiBatchedScanStoppedFromSource(in WorkSource ws);
     void noteWifiMulticastEnabledFromSource(in WorkSource ws);
     void noteWifiMulticastDisabledFromSource(in WorkSource ws);
-    void noteWifiRadioPowerState(int powerState, long timestampNs);
     void noteNetworkInterfaceType(String iface, int type);
     void noteNetworkStatsEnabled();
     void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion);
index 056b0aa..4cd959f 100644 (file)
@@ -23,25 +23,17 @@ import android.os.BatteryStats.Uid;
 public class BatterySipper implements Comparable<BatterySipper> {
     public int userId;
     public Uid uidObj;
-    public double totalPowerMah;
+    public double value;
+    public double[] values;
     public DrainType drainType;
 
-    /**
-     * Generic usage time in milliseconds.
-     */
-    public long usageTimeMs;
-
-    /**
-     * Generic power usage in mAh.
-     */
-    public double usagePowerMah;
-
-    // Subsystem usage times.
-    public long cpuTimeMs;
-    public long gpsTimeMs;
-    public long wifiRunningTimeMs;
-    public long cpuFgTimeMs;
-    public long wakeLockTimeMs;
+    // Measured in milliseconds.
+    public long usageTime;
+    public long cpuTime;
+    public long gpsTime;
+    public long wifiRunningTime;
+    public long cpuFgTime;
+    public long wakeLockTime;
 
     public long mobileRxPackets;
     public long mobileTxPackets;
@@ -60,13 +52,12 @@ public class BatterySipper implements Comparable<BatterySipper> {
     public String packageWithHighestDrain;
 
     // Measured in mAh (milli-ampere per hour).
-    // These are included when summed.
-    public double wifiPowerMah;
-    public double cpuPowerMah;
-    public double wakeLockPowerMah;
-    public double mobileRadioPowerMah;
-    public double gpsPowerMah;
-    public double sensorPowerMah;
+    public double wifiPower;
+    public double cpuPower;
+    public double wakeLockPower;
+    public double mobileRadioPower;
+    public double gpsPower;
+    public double sensorPower;
 
     public enum DrainType {
         IDLE,
@@ -82,12 +73,17 @@ public class BatterySipper implements Comparable<BatterySipper> {
         OVERCOUNTED
     }
 
-    public BatterySipper(DrainType drainType, Uid uid, double value) {
-        this.totalPowerMah = value;
+    public BatterySipper(DrainType drainType, Uid uid, double[] values) {
+        this.values = values;
+        if (values != null) value = values[0];
         this.drainType = drainType;
         uidObj = uid;
     }
 
+    public double[] getValues() {
+        return values;
+    }
+
     public void computeMobilemspp() {
         long packets = mobileRxPackets+mobileTxPackets;
         mobilemspp = packets > 0 ? (mobileActive / (double)packets) : 0;
@@ -105,7 +101,7 @@ public class BatterySipper implements Comparable<BatterySipper> {
             }
         }
         // Return the flipped value because we want the items in descending order
-        return Double.compare(other.totalPowerMah, totalPowerMah);
+        return Double.compare(other.value, value);
     }
 
     /**
@@ -127,14 +123,11 @@ public class BatterySipper implements Comparable<BatterySipper> {
      * Add stats from other to this BatterySipper.
      */
     public void add(BatterySipper other) {
-        totalPowerMah += other.totalPowerMah;
-        usageTimeMs += other.usageTimeMs;
-        usagePowerMah += other.usagePowerMah;
-        cpuTimeMs += other.cpuTimeMs;
-        gpsTimeMs += other.gpsTimeMs;
-        wifiRunningTimeMs += other.wifiRunningTimeMs;
-        cpuFgTimeMs += other.cpuFgTimeMs;
-        wakeLockTimeMs += other.wakeLockTimeMs;
+        cpuTime += other.cpuTime;
+        gpsTime += other.gpsTime;
+        wifiRunningTime += other.wifiRunningTime;
+        cpuFgTime += other.cpuFgTime;
+        wakeLockTime += other.wakeLockTime;
         mobileRxPackets += other.mobileRxPackets;
         mobileTxPackets += other.mobileTxPackets;
         mobileActive += other.mobileActive;
@@ -145,20 +138,11 @@ public class BatterySipper implements Comparable<BatterySipper> {
         mobileTxBytes += other.mobileTxBytes;
         wifiRxBytes += other.wifiRxBytes;
         wifiTxBytes += other.wifiTxBytes;
-        wifiPowerMah += other.wifiPowerMah;
-        gpsPowerMah += other.gpsPowerMah;
-        cpuPowerMah += other.cpuPowerMah;
-        sensorPowerMah += other.sensorPowerMah;
-        mobileRadioPowerMah += other.mobileRadioPowerMah;
-        wakeLockPowerMah += other.wakeLockPowerMah;
-    }
-
-    /**
-     * Sum all the powers and store the value into `value`.
-     * @return the sum of all the power in this BatterySipper.
-     */
-    public double sumPower() {
-        return totalPowerMah = usagePowerMah + wifiPowerMah + gpsPowerMah + cpuPowerMah + sensorPowerMah
-                + mobileRadioPowerMah + wakeLockPowerMah;
+        wifiPower += other.wifiPower;
+        gpsPower += other.gpsPower;
+        cpuPower += other.cpuPower;
+        sensorPower += other.sensorPower;
+        mobileRadioPower += other.mobileRadioPower;
+        wakeLockPower += other.wakeLockPower;
     }
 }
index 024b7c5..d3611bf 100644 (file)
 
 package com.android.internal.os;
 
+import static android.os.BatteryStats.NETWORK_MOBILE_RX_DATA;
+import static android.os.BatteryStats.NETWORK_MOBILE_TX_DATA;
+import static android.os.BatteryStats.NETWORK_WIFI_RX_DATA;
+import static android.os.BatteryStats.NETWORK_WIFI_TX_DATA;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.net.ConnectivityManager;
-import android.net.wifi.WifiManager;
 import android.os.BatteryStats;
 import android.os.BatteryStats.Uid;
 import android.os.Bundle;
@@ -33,6 +38,7 @@ import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.telephony.SignalStrength;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
@@ -48,6 +54,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A helper class for retrieving the power usage information for all applications and services.
@@ -56,7 +63,8 @@ import java.util.List;
  * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy().
  */
 public final class BatteryStatsHelper {
-    static final boolean DEBUG = false;
+
+    private static final boolean DEBUG = false;
 
     private static final String TAG = BatteryStatsHelper.class.getSimpleName();
 
@@ -73,24 +81,14 @@ public final class BatteryStatsHelper {
     private Intent mBatteryBroadcast;
     private PowerProfile mPowerProfile;
 
-    /**
-     * List of apps using power.
-     */
-    private final List<BatterySipper> mUsageList = new ArrayList<>();
-
-    /**
-     * List of apps using wifi power.
-     */
-    private final List<BatterySipper> mWifiSippers = new ArrayList<>();
-
-    /**
-     * List of apps using bluetooth power.
-     */
-    private final List<BatterySipper> mBluetoothSippers = new ArrayList<>();
-
-    private final SparseArray<List<BatterySipper>> mUserSippers = new SparseArray<>();
+    private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>();
+    private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>();
+    private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>();
+    private final SparseArray<List<BatterySipper>> mUserSippers
+            = new SparseArray<List<BatterySipper>>();
+    private final SparseArray<Double> mUserPower = new SparseArray<Double>();
 
-    private final List<BatterySipper> mMobilemsppList = new ArrayList<>();
+    private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>();
 
     private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
 
@@ -104,50 +102,29 @@ public final class BatteryStatsHelper {
     long mChargeTimeRemaining;
 
     private long mStatsPeriod = 0;
-
-    // The largest entry by power.
     private double mMaxPower = 1;
-
-    // The largest real entry by power (not undercounted or overcounted).
     private double mMaxRealPower = 1;
-
-    // Total computed power.
     private double mComputedPower;
     private double mTotalPower;
+    private double mWifiPower;
+    private double mBluetoothPower;
     private double mMinDrainedPower;
     private double mMaxDrainedPower;
 
-    PowerCalculator mCpuPowerCalculator;
-    PowerCalculator mWakelockPowerCalculator;
-    MobileRadioPowerCalculator mMobileRadioPowerCalculator;
-    PowerCalculator mWifiPowerCalculator;
-    PowerCalculator mBluetoothPowerCalculator;
-    PowerCalculator mSensorPowerCalculator;
-
-    public static boolean checkWifiOnly(Context context) {
-        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
-    }
+    // How much the apps together have kept the mobile radio active.
+    private long mAppMobileActive;
 
-    public static boolean checkHasWifiPowerReporting(Context context, PowerProfile profile) {
-        WifiManager manager = context.getSystemService(WifiManager.class);
-        if (manager.isEnhancedPowerReportingSupported()) {
-            if (profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE) != 0 &&
-                    profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX) != 0 &&
-                    profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_TX) != 0) {
-                return true;
-            }
-        }
-        return false;
-    }
+    // How much the apps together have left WIFI running.
+    private long mAppWifiRunning;
 
     public BatteryStatsHelper(Context context) {
         this(context, true);
     }
 
     public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast) {
-        this(context, collectBatteryBroadcast, checkWifiOnly(context));
+        mContext = context;
+        mCollectBatteryBroadcast = collectBatteryBroadcast;
+        mWifiOnly = checkWifiOnly(context);
     }
 
     public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast, boolean wifiOnly) {
@@ -156,6 +133,12 @@ public final class BatteryStatsHelper {
         mWifiOnly = wifiOnly;
     }
 
+    public static boolean checkWifiOnly(Context context) {
+        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+    }
+
     public void storeStatsHistoryInFile(String fname) {
         synchronized (sFileXfer) {
             File path = makeFilePath(mContext, fname);
@@ -277,7 +260,7 @@ public final class BatteryStatsHelper {
      * Refreshes the power usage list.
      */
     public void refreshStats(int statsType, int asUser) {
-        SparseArray<UserHandle> users = new SparseArray<>(1);
+        SparseArray<UserHandle> users = new SparseArray<UserHandle>(1);
         users.put(asUser, new UserHandle(asUser));
         refreshStats(statsType, users);
     }
@@ -287,7 +270,7 @@ public final class BatteryStatsHelper {
      */
     public void refreshStats(int statsType, List<UserHandle> asUsers) {
         final int n = asUsers.size();
-        SparseArray<UserHandle> users = new SparseArray<>(n);
+        SparseArray<UserHandle> users = new SparseArray<UserHandle>(n);
         for (int i = 0; i < n; ++i) {
             UserHandle userHandle = asUsers.get(i);
             users.put(userHandle.getIdentifier(), userHandle);
@@ -312,52 +295,22 @@ public final class BatteryStatsHelper {
         mMaxRealPower = 0;
         mComputedPower = 0;
         mTotalPower = 0;
+        mWifiPower = 0;
+        mBluetoothPower = 0;
+        mAppMobileActive = 0;
+        mAppWifiRunning = 0;
 
         mUsageList.clear();
         mWifiSippers.clear();
         mBluetoothSippers.clear();
         mUserSippers.clear();
+        mUserPower.clear();
         mMobilemsppList.clear();
 
         if (mStats == null) {
             return;
         }
 
-        if (mCpuPowerCalculator == null) {
-            mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile);
-        }
-        mCpuPowerCalculator.reset();
-
-        if (mWakelockPowerCalculator == null) {
-            mWakelockPowerCalculator = new WakelockPowerCalculator(mPowerProfile);
-        }
-        mWakelockPowerCalculator.reset();
-
-        if (mMobileRadioPowerCalculator == null) {
-            mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile, mStats);
-        }
-        mMobileRadioPowerCalculator.reset(mStats);
-
-        if (mWifiPowerCalculator == null) {
-            if (checkHasWifiPowerReporting(mContext, mPowerProfile)) {
-                mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile);
-            } else {
-                mWifiPowerCalculator = new WifiPowerEstimator(mPowerProfile);
-            }
-        }
-        mWifiPowerCalculator.reset();
-
-        if (mBluetoothPowerCalculator == null) {
-            mBluetoothPowerCalculator = new BluetoothPowerCalculator();
-        }
-        mBluetoothPowerCalculator.reset();
-
-        if (mSensorPowerCalculator == null) {
-            mSensorPowerCalculator = new SensorPowerCalculator(mPowerProfile,
-                    (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE));
-        }
-        mSensorPowerCalculator.reset();
-
         mStatsType = statsType;
         mRawUptime = rawUptimeUs;
         mRawRealtime = rawRealtimeUs;
@@ -405,113 +358,383 @@ public final class BatteryStatsHelper {
         Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() {
             @Override
             public int compare(BatterySipper lhs, BatterySipper rhs) {
-                return Double.compare(rhs.mobilemspp, lhs.mobilemspp);
+                if (lhs.mobilemspp < rhs.mobilemspp) {
+                    return 1;
+                } else if (lhs.mobilemspp > rhs.mobilemspp) {
+                    return -1;
+                }
+                return 0;
             }
         });
 
         processMiscUsage();
 
-        Collections.sort(mUsageList);
-
-        // At this point, we've sorted the list so we are guaranteed the max values are at the top.
-        // We have only added real powers so far.
-        if (!mUsageList.isEmpty()) {
-            mMaxRealPower = mMaxPower = mUsageList.get(0).totalPowerMah;
-            final int usageListCount = mUsageList.size();
-            for (int i = 0; i < usageListCount; i++) {
-                mComputedPower += mUsageList.get(i).totalPowerMah;
-            }
-        }
-
         if (DEBUG) {
             Log.d(TAG, "Accuracy: total computed=" + makemAh(mComputedPower) + ", min discharge="
                     + makemAh(mMinDrainedPower) + ", max discharge=" + makemAh(mMaxDrainedPower));
         }
-
         mTotalPower = mComputedPower;
         if (mStats.getLowDischargeAmountSinceCharge() > 1) {
             if (mMinDrainedPower > mComputedPower) {
                 double amount = mMinDrainedPower - mComputedPower;
                 mTotalPower = mMinDrainedPower;
-                BatterySipper bs = new BatterySipper(DrainType.UNACCOUNTED, null, amount);
-
-                // Insert the BatterySipper in its sorted position.
-                int index = Collections.binarySearch(mUsageList, bs);
-                if (index < 0) {
-                    index = -(index + 1);
-                }
-                mUsageList.add(index, bs);
-                mMaxPower = Math.max(mMaxPower, amount);
+                addEntryNoTotal(BatterySipper.DrainType.UNACCOUNTED, 0, amount);
             } else if (mMaxDrainedPower < mComputedPower) {
                 double amount = mComputedPower - mMaxDrainedPower;
-
-                // Insert the BatterySipper in its sorted position.
-                BatterySipper bs = new BatterySipper(DrainType.OVERCOUNTED, null, amount);
-                int index = Collections.binarySearch(mUsageList, bs);
-                if (index < 0) {
-                    index = -(index + 1);
-                }
-                mUsageList.add(index, bs);
-                mMaxPower = Math.max(mMaxPower, amount);
+                addEntryNoTotal(BatterySipper.DrainType.OVERCOUNTED, 0, amount);
             }
         }
+
+        Collections.sort(mUsageList);
     }
 
     private void processAppUsage(SparseArray<UserHandle> asUsers) {
         final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null);
+        final SensorManager sensorManager =
+                (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+        final int which = mStatsType;
+        final int speedSteps = mPowerProfile.getNumSpeedSteps();
+        final double[] powerCpuNormal = new double[speedSteps];
+        final long[] cpuSpeedStepTimes = new long[speedSteps];
+        for (int p = 0; p < speedSteps; p++) {
+            powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
+        }
+        final double mobilePowerPerPacket = getMobilePowerPerPacket();
+        final double mobilePowerPerMs = getMobilePowerPerMs();
+        final double wifiPowerPerPacket = getWifiPowerPerPacket();
+        long totalAppWakelockTimeUs = 0;
+        BatterySipper osApp = null;
         mStatsPeriod = mTypeBatteryRealtime;
 
+        final ArrayList<BatterySipper> appList = new ArrayList<>();
+
+        // Max values used to normalize later.
+        double maxWifiPower = 0;
+        double maxCpuPower = 0;
+        double maxWakeLockPower = 0;
+        double maxMobileRadioPower = 0;
+        double maxGpsPower = 0;
+        double maxSensorPower = 0;
+
         final SparseArray<? extends Uid> uidStats = mStats.getUidStats();
         final int NU = uidStats.size();
         for (int iu = 0; iu < NU; iu++) {
             final Uid u = uidStats.valueAt(iu);
-            final BatterySipper app = new BatterySipper(BatterySipper.DrainType.APP, u, 0);
-
-            mCpuPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mWakelockPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mMobileRadioPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mWifiPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mBluetoothPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mSensorPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-
-            final double totalPower = app.sumPower();
-            if (DEBUG && totalPower != 0) {
-                Log.d(TAG, String.format("UID %d: total power=%s", u.getUid(),
-                        makemAh(totalPower)));
+            final BatterySipper app = new BatterySipper(
+                    BatterySipper.DrainType.APP, u, new double[]{0});
+
+            final Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+            if (processStats.size() > 0) {
+                // Process CPU time.
+
+                // Keep track of the package with highest drain.
+                double highestDrain = 0;
+
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+                        : processStats.entrySet()) {
+                    Uid.Proc ps = ent.getValue();
+                    app.cpuFgTime += ps.getForegroundTime(which);
+                    final long totalCpuTime = ps.getUserTime(which) + ps.getSystemTime(which);
+                    app.cpuTime += totalCpuTime;
+
+                    // Calculate the total CPU time spent at the various speed steps.
+                    long totalTimeAtSpeeds = 0;
+                    for (int step = 0; step < speedSteps; step++) {
+                        cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which);
+                        totalTimeAtSpeeds += cpuSpeedStepTimes[step];
+                    }
+                    totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
+
+                    // Then compute the ratio of time spent at each speed and figure out
+                    // the total power consumption.
+                    double cpuPower = 0;
+                    for (int step = 0; step < speedSteps; step++) {
+                        final double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds;
+                        final double cpuSpeedStepPower =
+                                ratio * totalCpuTime * powerCpuNormal[step];
+                        if (DEBUG && ratio != 0) {
+                            Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
+                                    + step + " ratio=" + makemAh(ratio) + " power="
+                                    + makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+                        }
+                        cpuPower += cpuSpeedStepPower;
+                    }
+
+                    if (DEBUG && cpuPower != 0) {
+                        Log.d(TAG, String.format("process %s, cpu power=%s",
+                                ent.getKey(), makemAh(cpuPower / (60 * 60 * 1000))));
+                    }
+                    app.cpuPower += cpuPower;
+
+                    // Each App can have multiple packages and with multiple running processes.
+                    // Keep track of the package who's process has the highest drain.
+                    if (app.packageWithHighestDrain == null ||
+                            app.packageWithHighestDrain.startsWith("*")) {
+                        highestDrain = cpuPower;
+                        app.packageWithHighestDrain = ent.getKey();
+                    } else if (highestDrain < cpuPower && !ent.getKey().startsWith("*")) {
+                        highestDrain = cpuPower;
+                        app.packageWithHighestDrain = ent.getKey();
+                    }
+                }
+            }
+
+            // Ensure that the CPU times make sense.
+            if (app.cpuFgTime > app.cpuTime) {
+                if (DEBUG && app.cpuFgTime > app.cpuTime + 10000) {
+                    Log.d(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time");
+                }
+
+                // Statistics may not have been gathered yet.
+                app.cpuTime = app.cpuFgTime;
+            }
+
+            // Convert the CPU power to mAh
+            app.cpuPower /= (60 * 60 * 1000);
+            maxCpuPower = Math.max(maxCpuPower, app.cpuPower);
+
+            // Process wake lock usage
+            final Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats =
+                    u.getWakelockStats();
+            long wakeLockTimeUs = 0;
+            for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry
+                    : wakelockStats.entrySet()) {
+                final Uid.Wakelock wakelock = wakelockEntry.getValue();
+
+                // Only care about partial wake locks since full wake locks
+                // are canceled when the user turns the screen off.
+                BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
+                if (timer != null) {
+                    wakeLockTimeUs += timer.getTotalTimeLocked(mRawRealtime, which);
+                }
+            }
+            app.wakeLockTime = wakeLockTimeUs / 1000; // convert to millis
+            totalAppWakelockTimeUs += wakeLockTimeUs;
+
+            // Add cost of holding a wake lock.
+            app.wakeLockPower = (app.wakeLockTime *
+                    mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / (60 * 60 * 1000);
+            if (DEBUG && app.wakeLockPower != 0) {
+                Log.d(TAG, "UID " + u.getUid() + ": wake "
+                        + app.wakeLockTime + " power=" + makemAh(app.wakeLockPower));
+            }
+            maxWakeLockPower = Math.max(maxWakeLockPower, app.wakeLockPower);
+
+            // Add cost of mobile traffic.
+            final long mobileActive = u.getMobileRadioActiveTime(mStatsType);
+            app.mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
+            app.mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
+            app.mobileActive = mobileActive / 1000;
+            app.mobileActiveCount = u.getMobileRadioActiveCount(mStatsType);
+            app.mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
+            app.mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
+
+            if (mobileActive > 0) {
+                // We are tracking when the radio is up, so can use the active time to
+                // determine power use.
+                mAppMobileActive += mobileActive;
+                app.mobileRadioPower = (mobilePowerPerMs * mobileActive) / 1000;
+            } else {
+                // We are not tracking when the radio is up, so must approximate power use
+                // based on the number of packets.
+                app.mobileRadioPower = (app.mobileRxPackets + app.mobileTxPackets)
+                        * mobilePowerPerPacket;
+            }
+            if (DEBUG && app.mobileRadioPower != 0) {
+                Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
+                        + (app.mobileRxPackets + app.mobileTxPackets)
+                        + " active time " + mobileActive
+                        + " power=" + makemAh(app.mobileRadioPower));
+            }
+            maxMobileRadioPower = Math.max(maxMobileRadioPower, app.mobileRadioPower);
+
+            // Add cost of wifi traffic
+            app.wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, mStatsType);
+            app.wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, mStatsType);
+            app.wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, mStatsType);
+            app.wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, mStatsType);
+
+            final double wifiPacketPower = (app.wifiRxPackets + app.wifiTxPackets)
+                    * wifiPowerPerPacket;
+            if (DEBUG && wifiPacketPower != 0) {
+                Log.d(TAG, "UID " + u.getUid() + ": wifi packets "
+                        + (app.wifiRxPackets + app.wifiTxPackets)
+                        + " power=" + makemAh(wifiPacketPower));
+            }
+
+            // Add cost of keeping WIFI running.
+            app.wifiRunningTime = u.getWifiRunningTime(mRawRealtime, which) / 1000;
+            mAppWifiRunning += app.wifiRunningTime;
+
+            final double wifiLockPower = (app.wifiRunningTime
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / (60 * 60 * 1000);
+            if (DEBUG && wifiLockPower != 0) {
+                Log.d(TAG, "UID " + u.getUid() + ": wifi running "
+                        + app.wifiRunningTime + " power=" + makemAh(wifiLockPower));
+            }
+
+            // Add cost of WIFI scans
+            final long wifiScanTimeMs = u.getWifiScanTime(mRawRealtime, which) / 1000;
+            final double wifiScanPower = (wifiScanTimeMs
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN))
+                    /  (60 * 60 * 1000);
+            if (DEBUG && wifiScanPower != 0) {
+                Log.d(TAG, "UID " + u.getUid() + ": wifi scan " + wifiScanTimeMs
+                        + " power=" + makemAh(wifiScanPower));
+            }
+
+            // Add cost of WIFI batch scans.
+            double wifiBatchScanPower = 0;
+            for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
+                final long batchScanTimeMs =
+                        u.getWifiBatchedScanTime(bin, mRawRealtime, which) / 1000;
+                final double batchScanPower = ((batchScanTimeMs
+                        * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin))
+                ) / (60 * 60 * 1000);
+                if (DEBUG && batchScanPower != 0) {
+                    Log.d(TAG, "UID " + u.getUid() + ": wifi batched scan # " + bin
+                            + " time=" + batchScanTimeMs + " power=" + makemAh(batchScanPower));
+                }
+                wifiBatchScanPower += batchScanPower;
+            }
+
+            // Add up all the WiFi costs.
+            app.wifiPower = wifiPacketPower + wifiLockPower + wifiScanPower + wifiBatchScanPower;
+            maxWifiPower = Math.max(maxWifiPower, app.wifiPower);
+
+            // Process Sensor usage
+            final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
+            final int NSE = sensorStats.size();
+            for (int ise = 0; ise < NSE; ise++) {
+                final Uid.Sensor sensor = sensorStats.valueAt(ise);
+                final int sensorHandle = sensorStats.keyAt(ise);
+                final BatteryStats.Timer timer = sensor.getSensorTime();
+                final long sensorTime = timer.getTotalTimeLocked(mRawRealtime, which) / 1000;
+                double sensorPower = 0;
+                switch (sensorHandle) {
+                    case Uid.Sensor.GPS:
+                        app.gpsTime = sensorTime;
+                        app.gpsPower = (app.gpsTime
+                                * mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON))
+                                / (60 * 60 * 1000);
+                        sensorPower = app.gpsPower;
+                        maxGpsPower = Math.max(maxGpsPower, app.gpsPower);
+                        break;
+                    default:
+                        List<Sensor> sensorList = sensorManager.getSensorList(
+                                android.hardware.Sensor.TYPE_ALL);
+                        for (android.hardware.Sensor s : sensorList) {
+                            if (s.getHandle() == sensorHandle) {
+                                sensorPower = (sensorTime * s.getPower()) / (60 * 60 * 1000);
+                                app.sensorPower += sensorPower;
+                                break;
+                            }
+                        }
+                }
+                if (DEBUG && sensorPower != 0) {
+                    Log.d(TAG, "UID " + u.getUid() + ": sensor #" + sensorHandle
+                            + " time=" + sensorTime + " power=" + makemAh(sensorPower));
+                }
+            }
+            maxSensorPower = Math.max(maxSensorPower, app.sensorPower);
+
+            final double totalUnnormalizedPower = app.cpuPower + app.wifiPower + app.wakeLockPower
+                    + app.mobileRadioPower + app.gpsPower + app.sensorPower;
+            if (DEBUG && totalUnnormalizedPower != 0) {
+                Log.d(TAG, String.format("UID %d: total power=%s",
+                        u.getUid(), makemAh(totalUnnormalizedPower)));
             }
 
             // Add the app to the list if it is consuming power.
-            if (totalPower != 0 || u.getUid() == 0) {
-                //
-                // Add the app to the app list, WiFi, Bluetooth, etc, or into "Other Users" list.
-                //
-                final int uid = app.getUid();
-                final int userId = UserHandle.getUserId(uid);
-                if (uid == Process.WIFI_UID) {
-                    mWifiSippers.add(app);
-                } else if (uid == Process.BLUETOOTH_UID) {
-                    mBluetoothSippers.add(app);
-                } else if (!forAllUsers && asUsers.get(userId) == null
-                        && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) {
-                    // We are told to just report this user's apps as one large entry.
-                    List<BatterySipper> list = mUserSippers.get(userId);
-                    if (list == null) {
-                        list = new ArrayList<>();
-                        mUserSippers.put(userId, list);
-                    }
-                    list.add(app);
-                } else {
-                    mUsageList.add(app);
+            if (totalUnnormalizedPower != 0 || u.getUid() == 0) {
+                appList.add(app);
+            }
+        }
+
+        // Fetch real power consumption from hardware.
+        double actualTotalWifiPower = 0.0;
+        if (mStats.getWifiControllerActivity(BatteryStats.CONTROLLER_ENERGY, mStatsType) != 0) {
+            final double kDefaultVoltage = 3.36;
+            final long energy = mStats.getWifiControllerActivity(
+                    BatteryStats.CONTROLLER_ENERGY, mStatsType);
+            final double voltage = mPowerProfile.getAveragePowerOrDefault(
+                    PowerProfile.OPERATING_VOLTAGE_WIFI, kDefaultVoltage);
+            actualTotalWifiPower = energy / (voltage * 1000*60*60);
+        }
+
+        final int appCount = appList.size();
+        for (int i = 0; i < appCount; i++) {
+            // Normalize power where possible.
+            final BatterySipper app = appList.get(i);
+            if (actualTotalWifiPower != 0) {
+                app.wifiPower = (app.wifiPower / maxWifiPower) * actualTotalWifiPower;
+            }
+
+            // Assign the final power consumption here.
+            final double power = app.wifiPower + app.cpuPower + app.wakeLockPower
+                    + app.mobileRadioPower + app.gpsPower + app.sensorPower;
+            app.values[0] = app.value = power;
+
+            //
+            // Add the app to the app list, WiFi, Bluetooth, etc, or into "Other Users" list.
+            //
+
+            final int uid = app.getUid();
+            final int userId = UserHandle.getUserId(uid);
+            if (uid == Process.WIFI_UID) {
+                mWifiSippers.add(app);
+                mWifiPower += power;
+            } else if (uid == Process.BLUETOOTH_UID) {
+                mBluetoothSippers.add(app);
+                mBluetoothPower += power;
+            } else if (!forAllUsers && asUsers.get(userId) == null
+                    && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) {
+                // We are told to just report this user's apps as one large entry.
+                List<BatterySipper> list = mUserSippers.get(userId);
+                if (list == null) {
+                    list = new ArrayList<>();
+                    mUserSippers.put(userId, list);
                 }
+                list.add(app);
 
-                if (uid == 0) {
-                    // The device has probably been awake for longer than the screen on
-                    // time and application wake lock time would account for.  Assign
-                    // this remainder to the OS, if possible.
-                    mWakelockPowerCalculator.calculateRemaining(app, mStats, mRawRealtime,
-                                                                mRawUptime, mStatsType);
-                    app.sumPower();
+                Double userPower = mUserPower.get(userId);
+                if (userPower == null) {
+                    userPower = power;
+                } else {
+                    userPower += power;
                 }
+                mUserPower.put(userId, userPower);
+            } else {
+                mUsageList.add(app);
+                if (power > mMaxPower) mMaxPower = power;
+                if (power > mMaxRealPower) mMaxRealPower = power;
+                mComputedPower += power;
+            }
+
+            if (uid == 0) {
+                osApp = app;
+            }
+        }
+
+        // The device has probably been awake for longer than the screen on
+        // time and application wake lock time would account for.  Assign
+        // this remainder to the OS, if possible.
+        if (osApp != null) {
+            long wakeTimeMillis = mBatteryUptime / 1000;
+            wakeTimeMillis -= (totalAppWakelockTimeUs / 1000)
+                    + (mStats.getScreenOnTime(mRawRealtime, which) / 1000);
+            if (wakeTimeMillis > 0) {
+                double power = (wakeTimeMillis
+                        * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE))
+                        /  (60*60*1000);
+                if (DEBUG) Log.d(TAG, "OS wakeLockTime " + wakeTimeMillis + " power "
+                        + makemAh(power));
+                osApp.wakeLockTime += wakeTimeMillis;
+                osApp.value += power;
+                osApp.values[0] += power;
+                if (osApp.value > mMaxPower) mMaxPower = osApp.value;
+                if (osApp.value > mMaxRealPower) mMaxRealPower = osApp.value;
+                mComputedPower += power;
             }
         }
     }
@@ -521,7 +744,7 @@ public final class BatteryStatsHelper {
         double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                 * phoneOnTimeMs / (60*60*1000);
         if (phoneOnPower != 0) {
-            addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
+            BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
         }
     }
 
@@ -550,19 +773,54 @@ public final class BatteryStatsHelper {
     }
 
     private void addRadioUsage() {
-        BatterySipper radio = new BatterySipper(BatterySipper.DrainType.CELL, null, 0);
-        mMobileRadioPowerCalculator.calculateRemaining(radio, mStats, mRawRealtime, mRawUptime,
-                mStatsType);
-        radio.sumPower();
-        if (radio.totalPowerMah > 0) {
-            mUsageList.add(radio);
+        double power = 0;
+        final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+        long signalTimeMs = 0;
+        long noCoverageTimeMs = 0;
+        for (int i = 0; i < BINS; i++) {
+            long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, mRawRealtime, mStatsType)
+                    / 1000;
+            double p = (strengthTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i))
+                        / (60*60*1000);
+            if (DEBUG && p != 0) {
+                Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power="
+                        + makemAh(p));
+            }
+            power += p;
+            signalTimeMs += strengthTimeMs;
+            if (i == 0) {
+                noCoverageTimeMs = strengthTimeMs;
+            }
+        }
+        long scanningTimeMs = mStats.getPhoneSignalScanningTime(mRawRealtime, mStatsType)
+                / 1000;
+        double p = (scanningTimeMs * mPowerProfile.getAveragePower(
+                        PowerProfile.POWER_RADIO_SCANNING))
+                        / (60*60*1000);
+        if (DEBUG && p != 0) {
+            Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p));
+        }
+        power += p;
+        long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType);
+        long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000;
+        if (remainingActiveTime > 0) {
+            power += getMobilePowerPerMs() * remainingActiveTime;
+        }
+        if (power != 0) {
+            BatterySipper bs =
+                    addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power);
+            if (signalTimeMs != 0) {
+                bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
+            }
+            bs.mobileActive = remainingActiveTime;
+            bs.mobileActiveCount = mStats.getMobileRadioActiveUnknownCount(mStatsType);
         }
     }
 
     private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) {
         for (int i=0; i<from.size(); i++) {
             BatterySipper wbs = from.get(i);
-            if (DEBUG) Log.d(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTimeMs);
+            if (DEBUG) Log.d(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime);
             bs.add(wbs);
         }
         bs.computeMobilemspp();
@@ -589,12 +847,41 @@ public final class BatteryStatsHelper {
      * of WiFi to the WiFi subsystem.
      */
     private void addWiFiUsage() {
-        BatterySipper bs = new BatterySipper(DrainType.WIFI, null, 0);
-        mWifiPowerCalculator.calculateRemaining(bs, mStats, mRawRealtime, mRawUptime, mStatsType);
-        bs.sumPower();
-        if (bs.totalPowerMah > 0 || !mWifiSippers.isEmpty()) {
+        final long idleTimeMs = mStats.getWifiControllerActivity(
+                BatteryStats.CONTROLLER_IDLE_TIME, mStatsType);
+        final long txTimeMs = mStats.getWifiControllerActivity(
+                BatteryStats.CONTROLLER_TX_TIME, mStatsType);
+        final long rxTimeMs = mStats.getWifiControllerActivity(
+                BatteryStats.CONTROLLER_RX_TIME, mStatsType);
+        final long energy = mStats.getWifiControllerActivity(
+                BatteryStats.CONTROLLER_ENERGY, mStatsType);
+        final long totalTimeRunning = idleTimeMs + txTimeMs + rxTimeMs;
+
+        double powerDrain = 0;
+        if (energy == 0 && totalTimeRunning > 0) {
+            // Energy is not reported, which means we may have left over power drain not attributed
+            // to any app. Assign this power to the WiFi app.
+            // TODO(adamlesinski): This mimics the old behavior. However, mAppWifiRunningTime
+            // is the accumulation of the time each app kept the WiFi chip on. Multiple apps
+            // can do this at the same time, so these times do not add up to the total time
+            // the WiFi chip was on. Consider normalizing the time spent running and calculating
+            // power from that? Normalizing the times will assign a weight to each app which
+            // should better represent power usage.
+            powerDrain = ((totalTimeRunning - mAppWifiRunning)
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / (60*60*1000);
+        }
+
+        if (DEBUG && powerDrain != 0) {
+            Log.d(TAG, "Wifi active: time=" + (txTimeMs + rxTimeMs)
+                    + " power=" + makemAh(powerDrain));
+        }
+
+        // TODO(adamlesinski): mWifiPower is already added as a BatterySipper...
+        // Are we double counting here?
+        final double power = mWifiPower + powerDrain;
+        if (power > 0) {
+            BatterySipper bs = addEntry(BatterySipper.DrainType.WIFI, totalTimeRunning, power);
             aggregateSippers(bs, mWifiSippers, "WIFI");
-            mUsageList.add(bs);
         }
     }
 
@@ -603,10 +890,30 @@ public final class BatteryStatsHelper {
      * Bluetooth Category.
      */
     private void addBluetoothUsage() {
-        BatterySipper bs = new BatterySipper(BatterySipper.DrainType.BLUETOOTH, null, 0);
-        mBluetoothPowerCalculator.calculateRemaining(bs, mStats, mRawRealtime, mRawUptime,
-                mStatsType);
-        if (bs.sumPower() > 0) {
+        final double kDefaultVoltage = 3.36;
+        final long idleTimeMs = mStats.getBluetoothControllerActivity(
+                BatteryStats.CONTROLLER_IDLE_TIME, mStatsType);
+        final long txTimeMs = mStats.getBluetoothControllerActivity(
+                BatteryStats.CONTROLLER_TX_TIME, mStatsType);
+        final long rxTimeMs = mStats.getBluetoothControllerActivity(
+                BatteryStats.CONTROLLER_RX_TIME, mStatsType);
+        final long energy = mStats.getBluetoothControllerActivity(
+                BatteryStats.CONTROLLER_ENERGY, mStatsType);
+        final double voltage = mPowerProfile.getAveragePowerOrDefault(
+                PowerProfile.OPERATING_VOLTAGE_BLUETOOTH, kDefaultVoltage);
+
+        // energy is measured in mA * V * ms, and we are interested in mAh
+        final double powerDrain = energy / (voltage * 60*60*1000);
+
+        if (DEBUG && powerDrain != 0) {
+            Log.d(TAG, "Bluetooth active: time=" + (txTimeMs + rxTimeMs)
+                    + " power=" + makemAh(powerDrain));
+        }
+
+        final long totalTime = idleTimeMs + txTimeMs + rxTimeMs;
+        final double power = mBluetoothPower + powerDrain;
+        if (power > 0) {
+            BatterySipper bs = addEntry(BatterySipper.DrainType.BLUETOOTH, totalTime, power);
             aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
         }
     }
@@ -621,16 +928,55 @@ public final class BatteryStatsHelper {
     }
 
     private void addUserUsage() {
-        for (int i = 0; i < mUserSippers.size(); i++) {
+        for (int i=0; i<mUserSippers.size(); i++) {
             final int userId = mUserSippers.keyAt(i);
-            BatterySipper bs = new BatterySipper(DrainType.USER, null, 0);
+            final List<BatterySipper> sippers = mUserSippers.valueAt(i);
+            Double userPower = mUserPower.get(userId);
+            double power = (userPower != null) ? userPower : 0.0;
+            BatterySipper bs = addEntry(BatterySipper.DrainType.USER, 0, power);
             bs.userId = userId;
-            aggregateSippers(bs, mUserSippers.valueAt(i), "User");
-            bs.sumPower();
-            mUsageList.add(bs);
+            aggregateSippers(bs, sippers, "User");
         }
     }
 
+    /**
+     * Return estimated power (in mAs) of sending or receiving a packet with the mobile radio.
+     */
+    private double getMobilePowerPerPacket() {
+        final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
+        final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
+                / 3600;
+
+        final long mobileRx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
+        final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
+        final long mobileData = mobileRx + mobileTx;
+
+        final long radioDataUptimeMs
+                = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType) / 1000;
+        final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0)
+                ? (mobileData / (double)radioDataUptimeMs)
+                : (((double)MOBILE_BPS) / 8 / 2048);
+
+        return (MOBILE_POWER / mobilePps) / (60*60);
+    }
+
+    /**
+     * Return estimated power (in mAs) of keeping the radio up
+     */
+    private double getMobilePowerPerMs() {
+        return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000);
+    }
+
+    /**
+     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
+     */
+    private double getWifiPowerPerPacket() {
+        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
+        final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
+                / 3600;
+        return (WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048)) / (60*60);
+    }
+
     private void processMiscUsage() {
         addUserUsage();
         addPhoneUsage();
@@ -646,10 +992,15 @@ public final class BatteryStatsHelper {
     }
 
     private BatterySipper addEntry(DrainType drainType, long time, double power) {
-        BatterySipper bs = new BatterySipper(drainType, null, 0);
-        bs.usagePowerMah = power;
-        bs.usageTimeMs = time;
-        bs.sumPower();
+        mComputedPower += power;
+        if (power > mMaxRealPower) mMaxRealPower = power;
+        return addEntryNoTotal(drainType, time, power);
+    }
+
+    private BatterySipper addEntryNoTotal(DrainType drainType, long time, double power) {
+        if (power > mMaxPower) mMaxPower = power;
+        BatterySipper bs = new BatterySipper(drainType, null, new double[] {power});
+        bs.usageTime = time;
         mUsageList.add(bs);
         return bs;
     }
@@ -664,7 +1015,7 @@ public final class BatteryStatsHelper {
 
     public long getStatsPeriod() { return mStatsPeriod; }
 
-    public int getStatsType() { return mStatsType; }
+    public int getStatsType() { return mStatsType; };
 
     public double getMaxPower() { return mMaxPower; }
 
index 793d0d3..05ed3ab 100644 (file)
@@ -55,7 +55,6 @@ import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
-import android.util.SparseLongArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 import android.view.Display;
@@ -96,7 +95,6 @@ import java.util.concurrent.locks.ReentrantLock;
 public final class BatteryStatsImpl extends BatteryStats {
     private static final String TAG = "BatteryStatsImpl";
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_ENERGY = false;
     private static final boolean DEBUG_HISTORY = false;
     private static final boolean USE_OLD_HISTORY = false;   // for debugging.
 
@@ -184,20 +182,22 @@ public final class BatteryStatsImpl extends BatteryStats {
     // elapsed time by the number of active timers to arrive at that timer's share of the time.
     // In order to do this, we must refresh each timer whenever the number of active timers
     // changes.
-    final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
-    final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
-    final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
-    final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
-    final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
+    final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
+    final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
+            = new SparseArray<ArrayList<StopwatchTimer>>();
+    final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
+    final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
+            new SparseArray<ArrayList<StopwatchTimer>>();
+    final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<StopwatchTimer>();
+    final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<StopwatchTimer>();
 
     // Last partial timers we use for distributing CPU usage.
-    final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
+    final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
 
     // These are the objects that will want to do something when the device
     // is unplugged from power.
@@ -227,7 +227,7 @@ public final class BatteryStatsImpl extends BatteryStats {
     final HistoryItem mHistoryLastLastWritten = new HistoryItem();
     final HistoryItem mHistoryReadTmp = new HistoryItem();
     final HistoryItem mHistoryAddTmp = new HistoryItem();
-    final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
+    final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap();
     String[] mReadHistoryStrings;
     int[] mReadHistoryUids;
     int mReadHistoryChars;
@@ -450,8 +450,6 @@ public final class BatteryStatsImpl extends BatteryStats {
 
     private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
 
-    private PowerProfile mPowerProfile;
-
     /*
      * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
      */
@@ -930,12 +928,6 @@ public final class BatteryStatsImpl extends BatteryStats {
         long mUnpluggedTime;
 
         /**
-         * The total time this timer has been running until the latest mark has been set.
-         * Subtract this from mTotalTime to get the time spent running since the mark was set.
-         */
-        long mTimeBeforeMark;
-
-        /**
          * Constructs from a parcel.
          * @param type
          * @param timeBase
@@ -953,7 +945,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             mLoadedTime = in.readLong();
             mLastTime = 0;
             mUnpluggedTime = in.readLong();
-            mTimeBeforeMark = in.readLong();
             timeBase.add(this);
             if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
         }
@@ -973,7 +964,7 @@ public final class BatteryStatsImpl extends BatteryStats {
          * so can be completely dropped.
          */
         boolean reset(boolean detachIfReset) {
-            mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
+            mTotalTime = mLoadedTime = mLastTime = 0;
             mCount = mLoadedCount = mLastCount = 0;
             if (detachIfReset) {
                 detach();
@@ -994,10 +985,8 @@ public final class BatteryStatsImpl extends BatteryStats {
             out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
             out.writeLong(mLoadedTime);
             out.writeLong(mUnpluggedTime);
-            out.writeLong(mTimeBeforeMark);
         }
 
-        @Override
         public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
             if (DEBUG && mType < 0) {
                 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
@@ -1013,7 +1002,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             }
         }
 
-        @Override
         public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             if (DEBUG && mType < 0) {
                 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
@@ -1067,13 +1055,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             return val;
         }
 
-        @Override
-        public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
-            long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
-            return val - mTimeBeforeMark;
-        }
-
-        @Override
         public void logState(Printer pw, String prefix) {
             pw.println(prefix + "mCount=" + mCount
                     + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
@@ -1099,9 +1080,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             mCount = mLoadedCount = in.readInt();
             mLastCount = 0;
             mUnpluggedCount = mCount;
-
-            // When reading the summary, we set the mark to be the latest information.
-            mTimeBeforeMark = mTotalTime;
         }
     }
 
@@ -1497,6 +1475,21 @@ public final class BatteryStatsImpl extends BatteryStats {
             return mNesting > 0;
         }
 
+        long checkpointRunningLocked(long elapsedRealtimeMs) {
+            if (mNesting > 0) {
+                // We are running...
+                final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+                if (mTimerPool != null) {
+                    return refreshTimersLocked(batteryRealtime, mTimerPool, this);
+                }
+                final long heldTime = batteryRealtime - mUpdateTime;
+                mUpdateTime = batteryRealtime;
+                mTotalTime += heldTime;
+                return heldTime;
+            }
+            return 0;
+        }
+
         void stopRunningLocked(long elapsedRealtimeMs) {
             // Ignore attempt to stop a timer that isn't running
             if (mNesting == 0) {
@@ -1574,7 +1567,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             return mCount;
         }
 
-        @Override
         boolean reset(boolean detachIfReset) {
             boolean canDetach = mNesting <= 0;
             super.reset(canDetach && detachIfReset);
@@ -1585,7 +1577,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             return canDetach;
         }
 
-        @Override
         void detach() {
             super.detach();
             if (mTimerPool != null) {
@@ -1593,31 +1584,10 @@ public final class BatteryStatsImpl extends BatteryStats {
             }
         }
 
-        @Override
         void readSummaryFromParcelLocked(Parcel in) {
             super.readSummaryFromParcelLocked(in);
             mNesting = 0;
         }
-
-        /**
-         * Set the mark so that we can query later for the total time the timer has
-         * accumulated since this point. The timer can be running or not.
-         *
-         * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
-         */
-        public void setMark(long elapsedRealtimeMs) {
-            final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
-            if (mNesting > 0) {
-                // We are running.
-                if (mTimerPool != null) {
-                    refreshTimersLocked(batteryRealtime, mTimerPool, this);
-                } else {
-                    mTotalTime += batteryRealtime - mUpdateTime;
-                    mUpdateTime = batteryRealtime;
-                }
-            }
-            mTimeBeforeMark = mTotalTime;
-        }
     }
 
     public abstract class OverflowArrayMap<T> {
@@ -3920,6 +3890,7 @@ public final class BatteryStatsImpl extends BatteryStats {
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
+            scheduleSyncExternalStatsLocked();
         }
         mWifiFullLockNesting++;
         getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
@@ -3935,6 +3906,7 @@ public final class BatteryStatsImpl extends BatteryStats {
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
+            scheduleSyncExternalStatsLocked();
         }
         getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
     }
@@ -3992,6 +3964,7 @@ public final class BatteryStatsImpl extends BatteryStats {
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
+            scheduleSyncExternalStatsLocked();
         }
         mWifiMulticastNesting++;
         getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
@@ -4007,6 +3980,7 @@ public final class BatteryStatsImpl extends BatteryStats {
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
                     + Integer.toHexString(mHistoryCur.states));
             addHistoryRecordLocked(elapsedRealtime, uptime);
+            scheduleSyncExternalStatsLocked();
         }
         getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
     }
@@ -4114,8 +4088,7 @@ public final class BatteryStatsImpl extends BatteryStats {
         // During device boot, qtaguid isn't enabled until after the inital
         // loading of battery stats. Now that they're enabled, take our initial
         // snapshot for future delta calculation.
-        final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
-        updateMobileRadioStateLocked(elapsedRealtimeMs);
+        updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
         updateWifiStateLocked(null);
     }
 
@@ -4396,18 +4369,6 @@ public final class BatteryStatsImpl extends BatteryStats {
         LongSamplingCounter mMobileRadioActiveCount;
 
         /**
-         * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
-         */
-        LongSamplingCounter[] mWifiControllerTime =
-                new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
-
-        /**
-         * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
-         */
-        LongSamplingCounter[] mBluetoothControllerTime =
-                new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
-
-        /**
          * The CPU times we had at the last history details update.
          */
         long mLastStepUserTime;
@@ -4443,22 +4404,22 @@ public final class BatteryStatsImpl extends BatteryStats {
         /**
          * The statistics we have collected for this uid's sensor activations.
          */
-        final SparseArray<Sensor> mSensorStats = new SparseArray<>();
+        final SparseArray<Sensor> mSensorStats = new SparseArray<Sensor>();
 
         /**
          * The statistics we have collected for this uid's processes.
          */
-        final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
+        final ArrayMap<String, Proc> mProcessStats = new ArrayMap<String, Proc>();
 
         /**
          * The statistics we have collected for this uid's processes.
          */
-        final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
+        final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<String, Pkg>();
 
         /**
          * The transient wake stats we have collected for this uid's pids.
          */
-        final SparseArray<Pid> mPids = new SparseArray<>();
+        final SparseArray<Pid> mPids = new SparseArray<Pid>();
 
         public Uid(int uid) {
             mUid = uid;
@@ -4619,13 +4580,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             }
         }
 
-        public void noteWifiControllerActivityLocked(int type, long timeMs) {
-            if (mWifiControllerTime[type] == null) {
-                mWifiControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
-            }
-            mWifiControllerTime[type].addCountLocked(timeMs);
-        }
-
         public StopwatchTimer createAudioTurnedOnTimerLocked() {
             if (mAudioTurnedOnTimer == null) {
                 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
@@ -4941,15 +4895,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                     ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
         }
 
-        @Override
-        public long getWifiControllerActivity(int type, int which) {
-            if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
-                    mWifiControllerTime[type] != null) {
-                return mWifiControllerTime[type].getCountLocked(which);
-            }
-            return 0;
-        }
-
         void initNetworkActivityLocked() {
             mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
             mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
@@ -5033,16 +4978,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                 mMobileRadioActiveCount.reset(false);
             }
 
-            for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                if (mWifiControllerTime[i] != null) {
-                    mWifiControllerTime[i].reset(false);
-                }
-
-                if (mBluetoothControllerTime[i] != null) {
-                    mBluetoothControllerTime[i].reset(false);
-                }
-            }
-
             final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
             for (int iw=wakeStats.size()-1; iw>=0; iw--) {
                 Wakelock wl = wakeStats.valueAt(iw);
@@ -5165,16 +5100,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                         mNetworkPacketActivityCounters[i].detach();
                     }
                 }
-
-                for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                    if (mWifiControllerTime[i] != null) {
-                        mWifiControllerTime[i].detach();
-                    }
-
-                    if (mBluetoothControllerTime[i] != null) {
-                        mBluetoothControllerTime[i].detach();
-                    }
-                }
                 mPids.clear();
             }
 
@@ -5264,7 +5189,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             } else {
                 out.writeInt(0);
             }
-
             if (mAudioTurnedOnTimer != null) {
                 out.writeInt(1);
                 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -5316,24 +5240,6 @@ public final class BatteryStatsImpl extends BatteryStats {
             } else {
                 out.writeInt(0);
             }
-
-            for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                if (mWifiControllerTime[i] != null) {
-                    out.writeInt(1);
-                    mWifiControllerTime[i].writeToParcel(out);
-                } else {
-                    out.writeInt(0);
-                }
-            }
-
-            for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                if (mBluetoothControllerTime[i] != null) {
-                    out.writeInt(1);
-                    mBluetoothControllerTime[i].writeToParcel(out);
-                } else {
-                    out.writeInt(0);
-                }
-            }
         }
 
         void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
@@ -5483,22 +5389,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                 mNetworkByteActivityCounters = null;
                 mNetworkPacketActivityCounters = null;
             }
-
-            for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                if (in.readInt() != 0) {
-                    mWifiControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
-                } else {
-                    mWifiControllerTime[i] = null;
-                }
-            }
-
-            for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
-                if (in.readInt() != 0) {
-                    mBluetoothControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
-                } else {
-                    mBluetoothControllerTime[i] = null;
-                }
-            }
         }
 
         /**
@@ -6754,12 +6644,6 @@ public final class BatteryStatsImpl extends BatteryStats {
         readFromParcel(p);
     }
 
-    public void setPowerProfile(PowerProfile profile) {
-        synchronized (this) {
-            mPowerProfile = profile;
-        }
-    }
-
     public void setCallback(BatteryCallback cb) {
         mCallback = cb;
     }
@@ -7483,12 +7367,9 @@ public final class BatteryStatsImpl extends BatteryStats {
      * @param info The energy information from the WiFi controller.
      */
     public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
-        final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
-        NetworkStats delta = null;
+        final NetworkStats delta;
         try {
-            if (!ArrayUtils.isEmpty(mWifiIfaces)) {
-                delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
-            }
+            delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
         } catch (IOException e) {
             Slog.wtf(TAG, "Failed to get wifi network stats", e);
             return;
@@ -7498,19 +7379,14 @@ public final class BatteryStatsImpl extends BatteryStats {
             return;
         }
 
-        SparseLongArray rxPackets = new SparseLongArray();
-        SparseLongArray txPackets = new SparseLongArray();
-        long totalTxPackets = 0;
-        long totalRxPackets = 0;
         if (delta != null) {
             final int size = delta.size();
             for (int i = 0; i < size; i++) {
                 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-                if (DEBUG_ENERGY) {
+                if (DEBUG) {
                     Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
-                            + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
-                            + " txPackets=" + entry.txPackets);
+                            + " tx=" + entry.txBytes);
                 }
 
                 if (entry.rxBytes == 0 || entry.txBytes == 0) {
@@ -7522,13 +7398,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                         entry.rxPackets);
                 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
                         entry.txPackets);
-                rxPackets.put(u.getUid(), entry.rxPackets);
-                txPackets.put(u.getUid(), entry.txPackets);
-
-                // Sum the total number of packets so that the Rx Power and Tx Power can
-                // be evenly distributed amongst the apps.
-                totalRxPackets += entry.rxPackets;
-                totalTxPackets += entry.txPackets;
 
                 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
                         entry.rxBytes);
@@ -7542,119 +7411,6 @@ public final class BatteryStatsImpl extends BatteryStats {
         }
 
         if (info != null) {
-            // Measured in mAms
-            final long txTimeMs = info.getControllerTxTimeMillis();
-            final long rxTimeMs = info.getControllerRxTimeMillis();
-            final long idleTimeMs = info.getControllerIdleTimeMillis();
-            final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
-
-            long leftOverRxTimeMs = rxTimeMs;
-
-            if (DEBUG_ENERGY) {
-                Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
-                Slog.d(TAG, "  Tx Time:    " + txTimeMs + " ms");
-                Slog.d(TAG, "  Rx Time:    " + rxTimeMs + " ms");
-                Slog.d(TAG, "  Idle Time:  " + idleTimeMs + " ms");
-                Slog.d(TAG, "  Total Time: " + totalTimeMs + " ms");
-            }
-
-            long totalWifiLockTimeMs = 0;
-            long totalScanTimeMs = 0;
-
-            // On the first pass, collect some totals so that we can normalize power
-            // calculations if we need to.
-            final int uidStatsSize = mUidStats.size();
-            for (int i = 0; i < uidStatsSize; i++) {
-                final Uid uid = mUidStats.valueAt(i);
-
-                // Sum the total scan power for all apps.
-                totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
-                        elapsedRealtimeMs * 1000) / 1000;
-
-                // Sum the total time holding wifi lock for all apps.
-                totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
-                        elapsedRealtimeMs * 1000) / 1000;
-            }
-
-            if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
-                Slog.d(TAG, "  !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
-                        + rxTimeMs + " ms). Normalizing scan time.");
-            }
-
-            // Actually assign and distribute power usage to apps.
-            for (int i = 0; i < uidStatsSize; i++) {
-                final Uid uid = mUidStats.valueAt(i);
-
-                long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
-                        elapsedRealtimeMs * 1000) / 1000;
-                if (scanTimeSinceMarkMs > 0) {
-                    // Set the new mark so that next time we get new data since this point.
-                    uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
-
-                    if (totalScanTimeMs > rxTimeMs) {
-                        // Our total scan time is more than the reported Rx time.
-                        // This is possible because the cost of a scan is approximate.
-                        // Let's normalize the result so that we evenly blame each app
-                        // scanning.
-                        //
-                        // This means that we may have apps that received packets not be blamed
-                        // for this, but this is fine as scans are relatively more expensive.
-                        scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
-                    }
-
-                    if (DEBUG_ENERGY) {
-                        Slog.d(TAG, "  ScanTime for UID " + uid.getUid() + ": "
-                                + scanTimeSinceMarkMs + " ms)");
-                    }
-                    uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
-                    leftOverRxTimeMs -= scanTimeSinceMarkMs;
-                }
-
-                // Distribute evenly the power consumed while Idle to each app holding a WiFi
-                // lock.
-                final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
-                        elapsedRealtimeMs * 1000) / 1000;
-                if (wifiLockTimeSinceMarkMs > 0) {
-                    // Set the new mark so that next time we get new data since this point.
-                    uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
-
-                    final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
-                            / totalWifiLockTimeMs;
-                    if (DEBUG_ENERGY) {
-                        Slog.d(TAG, "  IdleTime for UID " + uid.getUid() + ": "
-                                + myIdleTimeMs + " ms");
-                    }
-                    uid.noteWifiControllerActivityLocked(CONTROLLER_IDLE_TIME, myIdleTimeMs);
-                }
-            }
-
-            if (DEBUG_ENERGY) {
-                Slog.d(TAG, "  New RxPower: " + leftOverRxTimeMs + " ms");
-            }
-
-            // Distribute the Tx power appropriately between all apps that transmitted packets.
-            for (int i = 0; i < txPackets.size(); i++) {
-                final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
-                final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
-                if (DEBUG_ENERGY) {
-                    Slog.d(TAG, "  TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
-                }
-                uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, myTxTimeMs);
-            }
-
-            // Distribute the remaining Rx power appropriately between all apps that received
-            // packets.
-            for (int i = 0; i < rxPackets.size(); i++) {
-                final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
-                final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
-                if (DEBUG_ENERGY) {
-                    Slog.d(TAG, "  RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
-                }
-                uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, myRxTimeMs);
-            }
-
-            // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
-
             // Update WiFi controller stats.
             mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
                     info.getControllerRxTimeMillis());
@@ -7662,29 +7418,19 @@ public final class BatteryStatsImpl extends BatteryStats {
                     info.getControllerTxTimeMillis());
             mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
                     info.getControllerIdleTimeMillis());
-
-            final double powerDrainMaMs;
-            if (mPowerProfile.getAveragePower(
-                    PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) == 0) {
-                powerDrainMaMs = 0.0;
-            } else {
-                powerDrainMaMs = info.getControllerEnergyUsed()
-                        / mPowerProfile.getAveragePower(
-                        PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE);
-            }
-            mWifiActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked((long) powerDrainMaMs);
+            mWifiActivityCounters[CONTROLLER_ENERGY].addCountLocked(
+                    info.getControllerEnergyUsed());
         }
     }
 
     /**
      * Distribute Cell radio energy info and network traffic to apps.
      */
-    public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
-        NetworkStats delta = null;
+    public void updateMobileRadioStateLocked(long elapsedRealtimeMs) {
+        final NetworkStats delta;
+
         try {
-            if (!ArrayUtils.isEmpty(mMobileIfaces)) {
-                delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
-            }
+            delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
         } catch (IOException e) {
             Slog.wtf(TAG, "Failed to get mobile network stats", e);
             return;
@@ -7694,24 +7440,14 @@ public final class BatteryStatsImpl extends BatteryStats {
             return;
         }
 
-        long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
-                elapsedRealtimeMs * 1000);
-        mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
+        long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(elapsedRealtimeMs);
         long totalPackets = delta.getTotalPackets();
 
         final int size = delta.size();
         for (int i = 0; i < size; i++) {
             final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-            if (entry.rxBytes == 0 || entry.txBytes == 0) {
-                continue;
-            }
-
-            if (DEBUG_ENERGY) {
-                Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
-                        + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
-                        + " txPackets=" + entry.txPackets);
-            }
+            if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
             final Uid u = getUidStatsLocked(mapUid(entry.uid));
             u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
@@ -7752,14 +7488,14 @@ public final class BatteryStatsImpl extends BatteryStats {
      * @param info The energy information from the bluetooth controller.
      */
     public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
-        if (info != null && mOnBatteryInternal && false) {
+        if (info != null && mOnBatteryInternal) {
             mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
                     info.getControllerRxTimeMillis());
             mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
                     info.getControllerTxTimeMillis());
             mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
                     info.getControllerIdleTimeMillis());
-            mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
+            mBluetoothActivityCounters[CONTROLLER_ENERGY].addCountLocked(
                     info.getControllerEnergyUsed());
         }
     }
diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
deleted file mode 100644 (file)
index 3557209..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-import android.util.Log;
-
-public class BluetoothPowerCalculator extends PowerCalculator {
-    private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
-    private static final String TAG = "BluetoothPowerCalculator";
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        // No per-app distribution yet.
-    }
-
-    @Override
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-        final long idleTimeMs = stats.getBluetoothControllerActivity(
-                BatteryStats.CONTROLLER_IDLE_TIME, statsType);
-        final long txTimeMs = stats.getBluetoothControllerActivity(
-                BatteryStats.CONTROLLER_TX_TIME, statsType);
-        final long rxTimeMs = stats.getBluetoothControllerActivity(
-                BatteryStats.CONTROLLER_RX_TIME, statsType);
-        final long powerMaMs = stats.getBluetoothControllerActivity(
-                BatteryStats.CONTROLLER_POWER_DRAIN, statsType);
-        final double powerMah = powerMaMs / (double)(1000*60*60);
-        final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs;
-
-        if (DEBUG && powerMah != 0) {
-            Log.d(TAG, "Bluetooth active: time=" + (totalTimeMs)
-                    + " power=" + BatteryStatsHelper.makemAh(powerMah));
-        }
-
-        app.usagePowerMah = powerMah;
-        app.usageTimeMs = totalTimeMs;
-    }
-}
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
deleted file mode 100644 (file)
index 6c3f958..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-import android.util.ArrayMap;
-import android.util.Log;
-
-public class CpuPowerCalculator extends PowerCalculator {
-    private static final String TAG = "CpuPowerCalculator";
-    private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
-
-    private final double[] mPowerCpuNormal;
-
-    /**
-     * Reusable array for calculations.
-     */
-    private final long[] mSpeedStepTimes;
-
-    public CpuPowerCalculator(PowerProfile profile) {
-        final int speedSteps = profile.getNumSpeedSteps();
-        mPowerCpuNormal = new double[speedSteps];
-        mSpeedStepTimes = new long[speedSteps];
-        for (int p = 0; p < speedSteps; p++) {
-            mPowerCpuNormal[p] = profile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
-        }
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        final int speedSteps = mSpeedStepTimes.length;
-
-        // Keep track of the package with highest drain.
-        double highestDrain = 0;
-
-        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
-        final int processStatsCount = processStats.size();
-        for (int i = 0; i < processStatsCount; i++) {
-            final BatteryStats.Uid.Proc ps = processStats.valueAt(i);
-            final String processName = processStats.keyAt(i);
-
-            app.cpuFgTimeMs += ps.getForegroundTime(statsType);
-            final long totalCpuTime = ps.getUserTime(statsType) + ps.getSystemTime(statsType);
-            app.cpuTimeMs += totalCpuTime;
-
-            // Calculate the total CPU time spent at the various speed steps.
-            long totalTimeAtSpeeds = 0;
-            for (int step = 0; step < speedSteps; step++) {
-                mSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, statsType);
-                totalTimeAtSpeeds += mSpeedStepTimes[step];
-            }
-            totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
-
-            // Then compute the ratio of time spent at each speed and figure out
-            // the total power consumption.
-            double cpuPower = 0;
-            for (int step = 0; step < speedSteps; step++) {
-                final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
-                final double cpuSpeedStepPower = ratio * totalCpuTime * mPowerCpuNormal[step];
-                if (DEBUG && ratio != 0) {
-                    Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
-                            + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
-                            + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
-                }
-                cpuPower += cpuSpeedStepPower;
-            }
-
-            if (DEBUG && cpuPower != 0) {
-                Log.d(TAG, String.format("process %s, cpu power=%s",
-                        processName, BatteryStatsHelper.makemAh(cpuPower / (60 * 60 * 1000))));
-            }
-            app.cpuPowerMah += cpuPower;
-
-            // Each App can have multiple packages and with multiple running processes.
-            // Keep track of the package who's process has the highest drain.
-            if (app.packageWithHighestDrain == null ||
-                    app.packageWithHighestDrain.startsWith("*")) {
-                highestDrain = cpuPower;
-                app.packageWithHighestDrain = processName;
-            } else if (highestDrain < cpuPower && !processName.startsWith("*")) {
-                highestDrain = cpuPower;
-                app.packageWithHighestDrain = processName;
-            }
-        }
-
-        // Ensure that the CPU times make sense.
-        if (app.cpuFgTimeMs > app.cpuTimeMs) {
-            if (DEBUG && app.cpuFgTimeMs > app.cpuTimeMs + 10000) {
-                Log.d(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time");
-            }
-
-            // Statistics may not have been gathered yet.
-            app.cpuTimeMs = app.cpuFgTimeMs;
-        }
-
-        // Convert the CPU power to mAh
-        app.cpuPowerMah /= (60 * 60 * 1000);
-    }
-}
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
deleted file mode 100644 (file)
index 9711c3b..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-public class MobileRadioPowerCalculator extends PowerCalculator {
-    private static final String TAG = "MobileRadioPowerController";
-    private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
-    private final double mPowerRadioOn;
-    private final double[] mPowerBins = new double[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
-    private final double mPowerScan;
-    private BatteryStats mStats;
-    private long mTotalAppMobileActiveMs = 0;
-
-    /**
-     * Return estimated power (in mAs) of sending or receiving a packet with the mobile radio.
-     */
-    private double getMobilePowerPerPacket(long rawRealtimeUs, int statsType) {
-        final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
-        final double MOBILE_POWER = mPowerRadioOn / 3600;
-
-        final long mobileRx = mStats.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
-                statsType);
-        final long mobileTx = mStats.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA,
-                statsType);
-        final long mobileData = mobileRx + mobileTx;
-
-        final long radioDataUptimeMs =
-                mStats.getMobileRadioActiveTime(rawRealtimeUs, statsType) / 1000;
-        final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0)
-                ? (mobileData / (double)radioDataUptimeMs)
-                : (((double)MOBILE_BPS) / 8 / 2048);
-        return (MOBILE_POWER / mobilePps) / (60*60);
-    }
-
-    public MobileRadioPowerCalculator(PowerProfile profile, BatteryStats stats) {
-        mPowerRadioOn = profile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE);
-        for (int i = 0; i < mPowerBins.length; i++) {
-            mPowerBins[i] = profile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE, i);
-        }
-        mPowerScan = profile.getAveragePower(PowerProfile.POWER_RADIO_SCANNING);
-        mStats = stats;
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        // Add cost of mobile traffic.
-        app.mobileRxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
-                statsType);
-        app.mobileTxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA,
-                statsType);
-        app.mobileActive = u.getMobileRadioActiveTime(statsType) / 1000;
-        app.mobileActiveCount = u.getMobileRadioActiveCount(statsType);
-        app.mobileRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_RX_DATA,
-                statsType);
-        app.mobileTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_TX_DATA,
-                statsType);
-
-        if (app.mobileActive > 0) {
-            // We are tracking when the radio is up, so can use the active time to
-            // determine power use.
-            mTotalAppMobileActiveMs += app.mobileActive;
-            app.mobileRadioPowerMah = (app.mobileActive * mPowerRadioOn) / (1000*60*60);
-        } else {
-            // We are not tracking when the radio is up, so must approximate power use
-            // based on the number of packets.
-            app.mobileRadioPowerMah = (app.mobileRxPackets + app.mobileTxPackets)
-                    * getMobilePowerPerPacket(rawRealtimeUs, statsType);
-        }
-        if (DEBUG && app.mobileRadioPowerMah != 0) {
-            Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
-                    + (app.mobileRxPackets + app.mobileTxPackets)
-                    + " active time " + app.mobileActive
-                    + " power=" + BatteryStatsHelper.makemAh(app.mobileRadioPowerMah));
-        }
-    }
-
-    @Override
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-        double power = 0;
-        long signalTimeMs = 0;
-        long noCoverageTimeMs = 0;
-        for (int i = 0; i < mPowerBins.length; i++) {
-            long strengthTimeMs = stats.getPhoneSignalStrengthTime(i, rawRealtimeUs, statsType)
-                    / 1000;
-            final double p = (strengthTimeMs * mPowerBins[i]) / (60*60*1000);
-            if (DEBUG && p != 0) {
-                Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power="
-                        + BatteryStatsHelper.makemAh(p));
-            }
-            power += p;
-            signalTimeMs += strengthTimeMs;
-            if (i == 0) {
-                noCoverageTimeMs = strengthTimeMs;
-            }
-        }
-
-        final long scanningTimeMs = stats.getPhoneSignalScanningTime(rawRealtimeUs, statsType)
-                / 1000;
-        final double p = (scanningTimeMs * mPowerScan) / (60*60*1000);
-        if (DEBUG && p != 0) {
-            Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs
-                    + " power=" + BatteryStatsHelper.makemAh(p));
-        }
-        power += p;
-        long radioActiveTimeMs = mStats.getMobileRadioActiveTime(rawRealtimeUs, statsType) / 1000;
-        long remainingActiveTimeMs = radioActiveTimeMs - mTotalAppMobileActiveMs;
-        if (remainingActiveTimeMs > 0) {
-            power += (mPowerRadioOn * remainingActiveTimeMs) / (1000*60*60);
-        }
-
-        if (power != 0) {
-            app.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
-            app.mobileActive = remainingActiveTimeMs;
-            app.mobileActiveCount = stats.getMobileRadioActiveUnknownCount(statsType);
-            app.mobileRadioPowerMah = power;
-        }
-    }
-
-    @Override
-    public void reset() {
-        mTotalAppMobileActiveMs = 0;
-    }
-
-    public void reset(BatteryStats stats) {
-        reset();
-        mStats = stats;
-    }
-}
diff --git a/core/java/com/android/internal/os/PowerCalculator.java b/core/java/com/android/internal/os/PowerCalculator.java
deleted file mode 100644 (file)
index cd69d68..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-
-/**
- * Calculates power use of a device subsystem for an app.
- */
-public abstract class PowerCalculator {
-    /**
-     * Calculate the amount of power an app used for this subsystem.
-     * @param app The BatterySipper that represents the power use of an app.
-     * @param u The recorded stats for the app.
-     * @param rawRealtimeUs The raw system realtime in microseconds.
-     * @param rawUptimeUs The raw system uptime in microseconds.
-     * @param statsType The type of stats. Can be {@link BatteryStats#STATS_CURRENT},
-     *                  {@link BatteryStats#STATS_SINCE_CHARGED}, or
-     *                  {@link BatteryStats#STATS_SINCE_UNPLUGGED}.
-     */
-    public abstract void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                                      long rawUptimeUs, int statsType);
-
-    /**
-     * Calculate the remaining power that can not be attributed to an app.
-     * @param app The BatterySipper that will represent this remaining power.
-     * @param stats The BatteryStats object from which to retrieve data.
-     * @param rawRealtimeUs The raw system realtime in microseconds.
-     * @param rawUptimeUs The raw system uptime in microseconds.
-     * @param statsType The type of stats. Can be {@link BatteryStats#STATS_CURRENT},
-     *                  {@link BatteryStats#STATS_SINCE_CHARGED}, or
-     *                  {@link BatteryStats#STATS_SINCE_UNPLUGGED}.
-     */
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-    }
-
-    /**
-     * Reset any state maintained in this calculator.
-     */
-    public void reset() {
-    }
-}
index 7e6706c..944eb5a 100644 (file)
@@ -18,7 +18,6 @@ package com.android.internal.os;
 
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 
 import com.android.internal.util.XmlUtils;
@@ -76,21 +75,10 @@ public class PowerProfile {
      */
     public static final String POWER_WIFI_ACTIVE = "wifi.active";
 
-    //
-    // Updated power constants. These are not estimated, they are real world
-    // currents and voltages for the underlying bluetooth and wifi controllers.
-    //
-
-    public static final String POWER_WIFI_CONTROLLER_IDLE = "wifi.controller.idle";
-    public static final String POWER_WIFI_CONTROLLER_RX = "wifi.controller.rx";
-    public static final String POWER_WIFI_CONTROLLER_TX = "wifi.controller.tx";
-    public static final String POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE = "wifi.controller.voltage";
-
-    public static final String POWER_BLUETOOTH_CONTROLLER_IDLE = "bluetooth.controller.idle";
-    public static final String POWER_BLUETOOTH_CONTROLLER_RX = "bluetooth.controller.rx";
-    public static final String POWER_BLUETOOTH_CONTROLLER_TX = "bluetooth.controller.tx";
-    public static final String POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE =
-            "bluetooth.controller.voltage";
+    /**
+     * Operating voltage of the WiFi controller.
+     */
+    public static final String OPERATING_VOLTAGE_WIFI = "wifi.voltage";
 
     /**
      * Power consumption when GPS is on.
@@ -112,6 +100,10 @@ public class PowerProfile {
      */
     public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
 
+    /**
+     * Operating voltage of the Bluetooth controller.
+     */
+    public static final String OPERATING_VOLTAGE_BLUETOOTH = "bluetooth.voltage";
 
     /**
      * Power consumption when screen is on, not including the backlight power.
@@ -170,7 +162,7 @@ public class PowerProfile {
      */
     public static final String POWER_BATTERY_CAPACITY = "battery.capacity";
 
-    static final HashMap<String, Object> sPowerMap = new HashMap<>();
+    static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>();
 
     private static final String TAG_DEVICE = "device";
     private static final String TAG_ITEM = "item";
@@ -188,8 +180,7 @@ public class PowerProfile {
 
     private void readPowerValuesFromXml(Context context) {
         int id = com.android.internal.R.xml.power_profile;
-        final Resources resources = context.getResources();
-        XmlResourceParser parser = resources.getXml(id);
+        XmlResourceParser parser = context.getResources().getXml(id);
         boolean parsingArray = false;
         ArrayList<Double> array = new ArrayList<Double>();
         String arrayName = null;
@@ -240,36 +231,6 @@ public class PowerProfile {
         } finally {
             parser.close();
         }
-
-        // Now collect other config variables.
-        int[] configResIds = new int[] {
-                com.android.internal.R.integer.config_bluetooth_idle_cur_ma,
-                com.android.internal.R.integer.config_bluetooth_rx_cur_ma,
-                com.android.internal.R.integer.config_bluetooth_tx_cur_ma,
-                com.android.internal.R.integer.config_bluetooth_operating_voltage_mv,
-                com.android.internal.R.integer.config_wifi_idle_receive_cur_ma,
-                com.android.internal.R.integer.config_wifi_active_rx_cur_ma,
-                com.android.internal.R.integer.config_wifi_tx_cur_ma,
-                com.android.internal.R.integer.config_wifi_operating_voltage_mv,
-        };
-
-        String[] configResIdKeys = new String[] {
-                POWER_BLUETOOTH_CONTROLLER_IDLE,
-                POWER_BLUETOOTH_CONTROLLER_RX,
-                POWER_BLUETOOTH_CONTROLLER_TX,
-                POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE,
-                POWER_WIFI_CONTROLLER_IDLE,
-                POWER_WIFI_CONTROLLER_RX,
-                POWER_WIFI_CONTROLLER_TX,
-                POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE,
-        };
-
-        for (int i = 0; i < configResIds.length; i++) {
-            int value = resources.getInteger(configResIds[i]);
-            if (value > 0) {
-                sPowerMap.put(configResIdKeys[i], (double) value);
-            }
-        }
     }
 
     /**
diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java
deleted file mode 100644 (file)
index c98639b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-import android.os.BatteryStats;
-import android.util.SparseArray;
-
-import java.util.List;
-
-public class SensorPowerCalculator extends PowerCalculator {
-    private final List<Sensor> mSensors;
-    private final double mGpsPowerOn;
-
-    public SensorPowerCalculator(PowerProfile profile, SensorManager sensorManager) {
-        mSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
-        mGpsPowerOn = profile.getAveragePower(PowerProfile.POWER_GPS_ON);
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        // Process Sensor usage
-        final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
-        final int NSE = sensorStats.size();
-        for (int ise = 0; ise < NSE; ise++) {
-            final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
-            final int sensorHandle = sensorStats.keyAt(ise);
-            final BatteryStats.Timer timer = sensor.getSensorTime();
-            final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
-            switch (sensorHandle) {
-                case BatteryStats.Uid.Sensor.GPS:
-                    app.gpsTimeMs = sensorTime;
-                    app.gpsPowerMah = (app.gpsTimeMs * mGpsPowerOn) / (1000*60*60);
-                    break;
-                default:
-                    final int sensorsCount = mSensors.size();
-                    for (int i = 0; i < sensorsCount; i++) {
-                        final Sensor s = mSensors.get(i);
-                        if (s.getHandle() == sensorHandle) {
-                            app.sensorPowerMah += (sensorTime * s.getPower()) / (1000*60*60);
-                            break;
-                        }
-                    }
-                    break;
-            }
-        }
-    }
-}
diff --git a/core/java/com/android/internal/os/WakelockPowerCalculator.java b/core/java/com/android/internal/os/WakelockPowerCalculator.java
deleted file mode 100644 (file)
index 7575010..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-import android.util.ArrayMap;
-import android.util.Log;
-
-public class WakelockPowerCalculator extends PowerCalculator {
-    private static final String TAG = "WakelockPowerCalculator";
-    private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
-    private final double mPowerWakelock;
-    private long mTotalAppWakelockTimeMs = 0;
-
-    public WakelockPowerCalculator(PowerProfile profile) {
-        mPowerWakelock = profile.getAveragePower(PowerProfile.POWER_CPU_AWAKE);
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawUptimeUs,
-                             long rawRealtimeUs, int statsType) {
-        long wakeLockTimeUs = 0;
-        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats =
-                u.getWakelockStats();
-        final int wakelockStatsCount = wakelockStats.size();
-        for (int i = 0; i < wakelockStatsCount; i++) {
-            final BatteryStats.Uid.Wakelock wakelock = wakelockStats.valueAt(i);
-
-            // Only care about partial wake locks since full wake locks
-            // are canceled when the user turns the screen off.
-            BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
-            if (timer != null) {
-                wakeLockTimeUs += timer.getTotalTimeLocked(rawRealtimeUs, statsType);
-            }
-        }
-        app.wakeLockTimeMs = wakeLockTimeUs / 1000; // convert to millis
-        mTotalAppWakelockTimeMs += app.wakeLockTimeMs;
-
-        // Add cost of holding a wake lock.
-        app.wakeLockPowerMah = (app.wakeLockTimeMs * mPowerWakelock) / (1000*60*60);
-        if (DEBUG && app.wakeLockPowerMah != 0) {
-            Log.d(TAG, "UID " + u.getUid() + ": wake " + app.wakeLockTimeMs
-                    + " power=" + BatteryStatsHelper.makemAh(app.wakeLockPowerMah));
-        }
-    }
-
-    @Override
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-        long wakeTimeMillis = stats.getBatteryUptime(rawUptimeUs) / 1000;
-        wakeTimeMillis -= mTotalAppWakelockTimeMs
-                + (stats.getScreenOnTime(rawRealtimeUs, statsType) / 1000);
-        if (wakeTimeMillis > 0) {
-            final double power = (wakeTimeMillis * mPowerWakelock) / (1000*60*60);
-            if (DEBUG) {
-                Log.d(TAG, "OS wakeLockTime " + wakeTimeMillis + " power "
-                        + BatteryStatsHelper.makemAh(power));
-            }
-            app.wakeLockTimeMs += wakeTimeMillis;
-            app.wakeLockPowerMah += power;
-        }
-    }
-
-    @Override
-    public void reset() {
-        mTotalAppWakelockTimeMs = 0;
-    }
-}
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
deleted file mode 100644 (file)
index 4e77f6b..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-
-/**
- * WiFi power calculator for when BatteryStats supports energy reporting
- * from the WiFi controller.
- */
-public class WifiPowerCalculator extends PowerCalculator {
-    private final double mIdleCurrentMa;
-    private final double mTxCurrentMa;
-    private final double mRxCurrentMa;
-    private double mTotalAppPowerDrain = 0;
-
-    public WifiPowerCalculator(PowerProfile profile) {
-        mIdleCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE);
-        mTxCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_TX);
-        mRxCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX);
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        final long idleTime = u.getWifiControllerActivity(BatteryStats.CONTROLLER_IDLE_TIME,
-                statsType);
-        final long txTime = u.getWifiControllerActivity(BatteryStats.CONTROLLER_TX_TIME, statsType);
-        final long rxTime = u.getWifiControllerActivity(BatteryStats.CONTROLLER_RX_TIME, statsType);
-        app.wifiRunningTimeMs = idleTime + rxTime + txTime;
-        app.wifiPowerMah =
-                ((idleTime * mIdleCurrentMa) + (txTime * mTxCurrentMa) + (rxTime * mRxCurrentMa))
-                / (1000*60*60);
-        mTotalAppPowerDrain += app.wifiPowerMah;
-
-        app.wifiRxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
-                statsType);
-        app.wifiTxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
-                statsType);
-        app.wifiRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
-                statsType);
-        app.wifiTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
-                statsType);
-    }
-
-    @Override
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-        final long idleTimeMs = stats.getWifiControllerActivity(BatteryStats.CONTROLLER_IDLE_TIME,
-                statsType);
-        final long rxTimeMs = stats.getWifiControllerActivity(BatteryStats.CONTROLLER_RX_TIME,
-                statsType);
-        final long txTimeMs = stats.getWifiControllerActivity(BatteryStats.CONTROLLER_TX_TIME,
-                statsType);
-        app.wifiRunningTimeMs = idleTimeMs + rxTimeMs + txTimeMs;
-
-        double powerDrain = stats.getWifiControllerActivity(BatteryStats.CONTROLLER_POWER_DRAIN,
-                statsType) / (1000*60*60);
-        if (powerDrain == 0) {
-            // Some controllers do not report power drain, so we can calculate it here.
-            powerDrain = ((idleTimeMs * mIdleCurrentMa) + (txTimeMs * mTxCurrentMa)
-                    + (rxTimeMs * mRxCurrentMa)) / (1000*60*60);
-        }
-        app.wifiPowerMah = Math.max(0, powerDrain - mTotalAppPowerDrain);
-    }
-
-    @Override
-    public void reset() {
-        mTotalAppPowerDrain = 0;
-    }
-}
diff --git a/core/java/com/android/internal/os/WifiPowerEstimator.java b/core/java/com/android/internal/os/WifiPowerEstimator.java
deleted file mode 100644 (file)
index 0172367..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 com.android.internal.os;
-
-import android.os.BatteryStats;
-
-/**
- * Estimates WiFi power usage based on timers in BatteryStats.
- */
-public class WifiPowerEstimator extends PowerCalculator {
-    private final double mWifiPowerPerPacket;
-    private final double mWifiPowerOn;
-    private final double mWifiPowerScan;
-    private final double mWifiPowerBatchScan;
-    private long mTotalAppWifiRunningTimeMs = 0;
-
-    public WifiPowerEstimator(PowerProfile profile) {
-        mWifiPowerPerPacket = getWifiPowerPerPacket(profile);
-        mWifiPowerOn = profile.getAveragePower(PowerProfile.POWER_WIFI_ON);
-        mWifiPowerScan = profile.getAveragePower(PowerProfile.POWER_WIFI_SCAN);
-        mWifiPowerBatchScan = profile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN);
-    }
-
-    /**
-     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
-     */
-    private static double getWifiPowerPerPacket(PowerProfile profile) {
-        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
-        final double WIFI_POWER = profile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
-                / 3600;
-        return (WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048)) / (60*60);
-    }
-
-    @Override
-    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
-                             long rawUptimeUs, int statsType) {
-        app.wifiRxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
-                statsType);
-        app.wifiTxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
-                statsType);
-        app.wifiRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
-                statsType);
-        app.wifiTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
-                statsType);
-
-        final double wifiPacketPower = (app.wifiRxPackets + app.wifiTxPackets)
-                * mWifiPowerPerPacket;
-
-        app.wifiRunningTimeMs = u.getWifiRunningTime(rawRealtimeUs, statsType) / 1000;
-        mTotalAppWifiRunningTimeMs += app.wifiRunningTimeMs;
-        final double wifiLockPower = (app.wifiRunningTimeMs * mWifiPowerOn) / (1000*60*60);
-
-        final long wifiScanTimeMs = u.getWifiScanTime(rawRealtimeUs, statsType);
-        final double wifiScanPower = (wifiScanTimeMs * mWifiPowerScan) / (1000*60*60);
-
-        double wifiBatchScanPower = 0;
-        for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
-            final long batchScanTimeMs =
-                    u.getWifiBatchedScanTime(bin, rawRealtimeUs, statsType) / 1000;
-            final double batchScanPower = (batchScanTimeMs * mWifiPowerBatchScan) / (1000*60*60);
-            wifiBatchScanPower += batchScanPower;
-        }
-
-        app.wifiPowerMah = wifiPacketPower + wifiLockPower + wifiScanPower + wifiBatchScanPower;
-    }
-
-    @Override
-    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
-                                   long rawUptimeUs, int statsType) {
-        final long totalRunningTimeMs = stats.getGlobalWifiRunningTime(rawRealtimeUs, statsType)
-                / 1000;
-        final double powerDrain = ((totalRunningTimeMs - mTotalAppWifiRunningTimeMs) * mWifiPowerOn)
-                / (1000*60*60);
-        app.wifiRunningTimeMs = totalRunningTimeMs;
-        app.wifiPowerMah = Math.max(0, powerDrain);
-    }
-
-    @Override
-    public void reset() {
-        mTotalAppWifiRunningTimeMs = 0;
-    }
-}
index 1ac1c8a..eb394c3 100644 (file)
@@ -1487,7 +1487,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
                 NetworkCapabilities.TRANSPORT_WIFI)) {
             timeout = Settings.Global.getInt(mContext.getContentResolver(),
                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
-                                             5);
+                                             0);
             type = ConnectivityManager.TYPE_WIFI;
         } else {
             // do not track any other networks
index b5b62b4..7b542be 100644 (file)
@@ -210,7 +210,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub
 
     private boolean mMobileActivityFromRadio = false;
     private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-    private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
 
     private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
             new RemoteCallbackList<INetworkActivityListener>();
@@ -435,16 +434,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub
             }
         }
 
-        if (ConnectivityManager.isNetworkTypeWifi(type)) {
-            if (mLastPowerStateFromWifi != powerState) {
-                mLastPowerStateFromWifi = powerState;
-                try {
-                    getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos);
-                } catch (RemoteException e) {
-                }
-            }
-        }
-
         boolean isActive = powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
                 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
 
index ac70d88..c8db3be 100644 (file)
@@ -40,7 +40,6 @@ import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.util.Slog;
@@ -123,7 +122,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
         mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_radioScanningTimeout)
                 * 1000L);
-        mStats.setPowerProfile(new PowerProfile(context));
     }
 
     /**
@@ -543,15 +541,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
         }
     }
 
-    @Override
-    public void noteWifiRadioPowerState(int powerState, long tsNanos) {
-        enforceCallingPermission();
-
-        // There was a change in WiFi power state.
-        // Collect data now for the past activity.
-        mHandler.scheduleSync();
-    }
-
     public void noteWifiRunning(WorkSource ws) {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -1106,29 +1095,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                 result.mTimestamp = info.getTimeStamp();
                 result.mStackState = info.getStackState();
                 result.mControllerTxTimeMs =
-                        info.mControllerTxTimeMs - mLastInfo.mControllerTxTimeMs;
+                        info.getControllerTxTimeMillis()- mLastInfo.mControllerTxTimeMs;
                 result.mControllerRxTimeMs =
-                        info.mControllerRxTimeMs - mLastInfo.mControllerRxTimeMs;
-                result.mControllerEnergyUsed =
-                        info.mControllerEnergyUsed - mLastInfo.mControllerEnergyUsed;
-
-                // WiFi calculates the idle time as a difference from the on time and the various
-                // Rx + Tx times. There seems to be some missing time there because this sometimes
-                // becomes negative. Just cap it at 0 and move on.
+                        info.getControllerRxTimeMillis() - mLastInfo.mControllerRxTimeMs;
                 result.mControllerIdleTimeMs =
-                        Math.max(0, info.mControllerIdleTimeMs - mLastInfo.mControllerIdleTimeMs);
-
-                if (result.mControllerTxTimeMs < 0 ||
-                        result.mControllerRxTimeMs < 0) {
-                    // The stats were reset by the WiFi system (which is why our delta is negative).
-                    // Returns the unaltered stats.
-                    result.mControllerEnergyUsed = info.mControllerEnergyUsed;
-                    result.mControllerRxTimeMs = info.mControllerRxTimeMs;
-                    result.mControllerTxTimeMs = info.mControllerTxTimeMs;
-                    result.mControllerIdleTimeMs = info.mControllerIdleTimeMs;
-
-                    Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
-                }
+                        info.getControllerIdleTimeMillis() - mLastInfo.mControllerIdleTimeMs;
+                result.mControllerEnergyUsed =
+                        info.getControllerEnergyUsed() - mLastInfo.mControllerEnergyUsed;
                 mLastInfo = info;
                 return result;
             }
@@ -1160,12 +1133,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
      */
     void updateExternalStats() {
         synchronized (mExternalStatsLock) {
-            if (mContext == null) {
-                // We haven't started yet (which means the BatteryStatsImpl object has
-                // no power profile. Don't consume data we can't compute yet.
-                return;
-            }
-
             final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
             final BluetoothActivityEnergyInfo bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
             synchronized (mStats) {