OSDN Git Service

Follow network stats changes.
authorJeff Sharkey <jsharkey@android.com>
Tue, 4 Jun 2013 19:29:05 +0000 (12:29 -0700)
committerJeff Sharkey <jsharkey@android.com>
Thu, 6 Jun 2013 21:35:37 +0000 (14:35 -0700)
Now Wi-Fi and mobile traffic is recorded separately, which means we
can compute much more accurate usage estimates.

Bug: 5543387
Change-Id: I26120a219649a3c84806fab0fd1602ab07509410

res/values/strings.xml
src/com/android/settings/fuelgauge/BatterySipper.java
src/com/android/settings/fuelgauge/PowerUsageDetail.java
src/com/android/settings/fuelgauge/PowerUsageSummary.java

index 4d09484..81c81f8 100644 (file)
     <string name="usage_type_phone" product="tablet">Tablet</string>
     <!-- Label for Phone usage time -->
     <string name="usage_type_phone" product="default">Phone</string>
-    <!-- Label for Data sent -->
-    <string name="usage_type_data_send">Data sent</string>
-    <!-- Label for Data received -->
-    <string name="usage_type_data_recv">Data received</string>
+    <!-- Label for mobile network data sent [CHAR LIMIT=32] -->
+    <string name="usage_type_data_send">Mobile data sent</string>
+    <!-- Label for mobile network data received [CHAR LIMIT=32] -->
+    <string name="usage_type_data_recv">Mobile data received</string>
+    <!-- Label for Wi-Fi network data sent [CHAR LIMIT=32] -->
+    <string name="usage_type_data_wifi_send">Wi\u2011Fi data sent</string>
+    <!-- Label for Wi-Fi network data received [CHAR LIMIT=32] -->
+    <string name="usage_type_data_wifi_recv">Wi\u2011Fi data received</string>
     <!-- Label for Audio usage time -->
     <string name="usage_type_audio">Audio</string>
     <!-- Label for Video usage time -->
index 9a8e783..d581fb4 100644 (file)
@@ -49,8 +49,10 @@ class BatterySipper implements Comparable<BatterySipper> {
     long wifiRunningTime;
     long cpuFgTime;
     long wakeLockTime;
-    long tcpBytesReceived;
-    long tcpBytesSent;
+    long mobileRxBytes;
+    long mobileTxBytes;
+    long wifiRxBytes;
+    long wifiTxBytes;
     double percent;
     double noCoveragePercent;
     String defaultPackageName;
index 8ecc659..945b86b 100644 (file)
@@ -316,6 +316,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
                 switch (mTypes[i]) {
                     case R.string.usage_type_data_recv:
                     case R.string.usage_type_data_send:
+                    case R.string.usage_type_data_wifi_recv:
+                    case R.string.usage_type_data_wifi_send:
                         final long bytes = (long) (mValues[i]);
                         value = Formatter.formatFileSize(getActivity(), bytes);
                         break;
index 39dc1d6..8307530 100644 (file)
 
 package com.android.settings.fuelgauge;
 
+import static android.os.BatteryStats.NETWORK_MOBILE_RX_BYTES;
+import static android.os.BatteryStats.NETWORK_MOBILE_TX_BYTES;
+import static android.os.BatteryStats.NETWORK_WIFI_RX_BYTES;
+import static android.os.BatteryStats.NETWORK_WIFI_TX_BYTES;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -24,7 +29,6 @@ import android.content.pm.UserInfo;
 import android.graphics.drawable.Drawable;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.net.Uri;
 import android.os.BatteryStats;
 import android.os.BatteryStats.Uid;
 import android.os.Bundle;
@@ -229,8 +233,10 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
                     R.string.usage_type_wake_lock,
                     R.string.usage_type_gps,
                     R.string.usage_type_wifi_running,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                     R.string.usage_type_audio,
                     R.string.usage_type_video,
                 };
@@ -240,8 +246,10 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
                     sipper.wakeLockTime,
                     sipper.gpsTime,
                     sipper.wifiRunningTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                     0,
                     0
                 };
@@ -279,16 +287,20 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
                     R.string.usage_type_cpu,
                     R.string.usage_type_cpu_foreground,
                     R.string.usage_type_wake_lock,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                 };
                 values = new double[] {
                     sipper.usageTime,
                     sipper.cpuTime,
                     sipper.cpuFgTime,
                     sipper.wakeLockTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                 };
             } break;
             case BLUETOOTH:
@@ -298,16 +310,20 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
                     R.string.usage_type_cpu,
                     R.string.usage_type_cpu_foreground,
                     R.string.usage_type_wake_lock,
-                    R.string.usage_type_data_send,
                     R.string.usage_type_data_recv,
+                    R.string.usage_type_data_send,
+                    R.string.usage_type_data_wifi_recv,
+                    R.string.usage_type_data_wifi_send,
                 };
                 values = new double[] {
                     sipper.usageTime,
                     sipper.cpuTime,
                     sipper.cpuFgTime,
                     sipper.wakeLockTime,
-                    sipper.tcpBytesSent,
-                    sipper.tcpBytesReceived,
+                    sipper.mobileRxBytes,
+                    sipper.mobileTxBytes,
+                    sipper.wifiRxBytes,
+                    sipper.wifiTxBytes,
                 };
             } break;
             default:
@@ -445,7 +461,8 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
         for (int p = 0; p < speedSteps; p++) {
             powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
         }
-        final double averageCostPerByte = getAverageDataCost();
+        final double mobilePowerPerByte = getMobilePowerPerByte();
+        final double wifiPowerPerByte = getWifiPowerPerByte();
         long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
         long appWakelockTime = 0;
         BatterySipper osApp = null;
@@ -454,8 +471,8 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
         final int NU = uidStats.size();
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            double p;
-            double power = 0;
+            double p; // in mAs
+            double power = 0; // in mAs
             double highestDrain = 0;
             String packageWithHighestDrain = null;
             //mUsageList.add(new AppUsage(u.getUid(), new double[] {power}));
@@ -535,12 +552,19 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
             power += p;
             if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p));
             
-            // Add cost of data traffic
-            long tcpBytesReceived = u.getTcpBytesReceived(mStatsType);
-            long tcpBytesSent = u.getTcpBytesSent(mStatsType);
-            p = (tcpBytesReceived+tcpBytesSent) * averageCostPerByte;
+            // Add cost of mobile traffic
+            final long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType);
+            final long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType);
+            p = (mobileRx + mobileTx) * mobilePowerPerByte;
             power += p;
-            if (DEBUG && p != 0) Log.i(TAG, String.format("tcp power=%.2f", p));
+            if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p));
+
+            // Add cost of wifi traffic
+            final long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, mStatsType);
+            final long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, mStatsType);
+            p = (wifiRx + wifiTx) * wifiPowerPerByte;
+            power += p;
+            if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p));
 
             // Add cost of keeping WIFI running.
             long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000;
@@ -602,8 +626,10 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
                 app.wifiRunningTime = wifiRunningTimeMs;
                 app.cpuFgTime = cpuFgTime;
                 app.wakeLockTime = wakelockTime;
-                app.tcpBytesReceived = tcpBytesReceived;
-                app.tcpBytesSent = tcpBytesSent;
+                app.mobileRxBytes = mobileRx;
+                app.mobileTxBytes = mobileTx;
+                app.wifiRxBytes = wifiRx;
+                app.wifiTxBytes = wifiTx;
                 if (u.getUid() == Process.WIFI_UID) {
                     mWifiSippers.add(app);
                 } else if (u.getUid() == Process.BLUETOOTH_UID) {
@@ -725,8 +751,10 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
             bs.wifiRunningTime += wbs.wifiRunningTime;
             bs.cpuFgTime += wbs.cpuFgTime;
             bs.wakeLockTime += wbs.wakeLockTime;
-            bs.tcpBytesReceived += wbs.tcpBytesReceived;
-            bs.tcpBytesSent += wbs.tcpBytesSent;
+            bs.mobileRxBytes += wbs.mobileRxBytes;
+            bs.mobileTxBytes += wbs.mobileTxBytes;
+            bs.wifiRxBytes += wbs.wifiRxBytes;
+            bs.wifiTxBytes += wbs.wifiTxBytes;
         }
     }
 
@@ -796,30 +824,34 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable {
         }
     }
 
-    private double getAverageDataCost() {
-        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system 
+    /**
+     * Return estimated power (in mAs) of sending a byte with the mobile radio.
+     */
+    private double getMobilePowerPerByte() {
         final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
-        final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
-                / 3600;
         final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                 / 3600;
-        final long mobileData = mStats.getMobileTcpBytesReceived(mStatsType) +
-                mStats.getMobileTcpBytesSent(mStatsType);
-        final long wifiData = mStats.getTotalTcpBytesReceived(mStatsType) +
-                mStats.getTotalTcpBytesSent(mStatsType) - mobileData;
+
+        final long mobileRx = mStats.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType);
+        final long mobileTx = mStats.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType);
+        final long mobileData = mobileRx + mobileTx;
+
         final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000;
         final long mobileBps = radioDataUptimeMs != 0
                 ? mobileData * 8 * 1000 / radioDataUptimeMs
                 : MOBILE_BPS;
 
-        double mobileCostPerByte = MOBILE_POWER / (mobileBps / 8);
-        double wifiCostPerByte = WIFI_POWER / (WIFI_BPS / 8);
-        if (wifiData + mobileData != 0) {
-            return (mobileCostPerByte * mobileData + wifiCostPerByte * wifiData)
-                    / (mobileData + wifiData);
-        } else {
-            return 0;
-        }
+        return MOBILE_POWER / (mobileBps / 8);
+    }
+
+    /**
+     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
+     */
+    private double getWifiPowerPerByte() {
+        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 / (WIFI_BPS / 8);
     }
 
     private void processMiscUsage() {