diff --git a/res/values/strings.xml b/res/values/strings.xml index 4d09484d990..81c81f84d81 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3314,10 +3314,14 @@ Tablet Phone - - Data sent - - Data received + + Mobile data sent + + Mobile data received + + Wi\u2011Fi data sent + + Wi\u2011Fi data received Audio diff --git a/src/com/android/settings/fuelgauge/BatterySipper.java b/src/com/android/settings/fuelgauge/BatterySipper.java index 9a8e7835c01..d581fb4374f 100644 --- a/src/com/android/settings/fuelgauge/BatterySipper.java +++ b/src/com/android/settings/fuelgauge/BatterySipper.java @@ -49,8 +49,10 @@ class BatterySipper implements Comparable { long wifiRunningTime; long cpuFgTime; long wakeLockTime; - long tcpBytesReceived; - long tcpBytesSent; + long mobileRxBytes; + long mobileTxBytes; + long wifiRxBytes; + long wifiTxBytes; double percent; double noCoveragePercent; String defaultPackageName; diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java index 8ecc659f329..945b86bc5f7 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java @@ -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; diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 39dc1d690ef..830753051aa 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -16,6 +16,11 @@ 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() {