Hold a wake lock while dispatching network activity events.

Also add new API for determining whether the current data network
is active, and thus better scheduling network operations.  This
API is designed to not be tied to a mobile network -- regardless
of the network, apps can use it to determine whether they should
initiate activity or wait.  On non-mobile networks, it simply always
reports as the network being active.

This changed involved reworking how the idle timers are done so
that we only register an idle timer with the current default
network.  This way, we can know whether we currently expect to
get callbacks about the network being active, or should just always
report that it is active.  (Ultimately we need to be getting this
radio active data from the radio itself.)

Change-Id: Iaf6cc91a960d7542a70b72f87a7db26d12c4ea8e
This commit is contained in:
Dianne Hackborn
2014-02-26 16:20:52 -08:00
parent 454a038470
commit 77b987f1a1
17 changed files with 476 additions and 143 deletions

View File

@ -52,7 +52,7 @@ interface IBatteryStats {
void noteScreenOff();
void noteInputEvent();
void noteUserActivity(int uid, int event);
void noteDataConnectionActive(String label, boolean active);
void noteDataConnectionActive(int type, boolean active);
void notePhoneOn();
void notePhoneOff();
void notePhoneSignalStrength(in SignalStrength signalStrength);

View File

@ -35,6 +35,7 @@ public class BatterySipper implements Comparable<BatterySipper> {
public long mobileRxPackets;
public long mobileTxPackets;
public long mobileActive;
public int mobileActiveCount;
public double mobilemspp; // milliseconds per packet
public long wifiRxPackets;
public long wifiTxPackets;

View File

@ -458,6 +458,7 @@ public class BatteryStatsHelper {
app.mobileRxPackets = mobileRx;
app.mobileTxPackets = mobileTx;
app.mobileActive = mobileActive / 1000;
app.mobileActiveCount = u.getMobileRadioActiveCount(mStatsType);
app.wifiRxPackets = wifiRx;
app.wifiTxPackets = wifiTx;
app.mobileRxBytes = mobileRxB;
@ -595,6 +596,7 @@ public class BatteryStatsHelper {
bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
}
bs.mobileActive = remainingActiveTime;
bs.mobileActiveCount = mStats.getMobileRadioActiveUnknownCount(mStatsType);
}
}
@ -610,6 +612,7 @@ public class BatteryStatsHelper {
bs.mobileRxPackets += wbs.mobileRxPackets;
bs.mobileTxPackets += wbs.mobileTxPackets;
bs.mobileActive += wbs.mobileActive;
bs.mobileActiveCount += wbs.mobileActiveCount;
bs.wifiRxPackets += wbs.wifiRxPackets;
bs.wifiTxPackets += wbs.wifiTxPackets;
bs.mobileRxBytes += wbs.mobileRxBytes;

View File

@ -87,7 +87,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
private static final int VERSION = 90 + (USE_OLD_HISTORY ? 1000 : 0);
private static final int VERSION = 94 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@ -283,6 +283,7 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mMobileRadioActive;
StopwatchTimer mMobileRadioActiveTimer;
StopwatchTimer mMobileRadioActivePerAppTimer;
LongSamplingCounter mMobileRadioActiveUnknownTime;
LongSamplingCounter mMobileRadioActiveUnknownCount;
@ -2373,33 +2374,31 @@ public final class BatteryStatsImpl extends BatteryStats {
}
public void noteUserActivityLocked(int uid, int event) {
uid = mapUid(uid);
getUidStatsLocked(uid).noteUserActivityLocked(event);
if (mOnBatteryInternal) {
uid = mapUid(uid);
getUidStatsLocked(uid).noteUserActivityLocked(event);
}
}
public void noteDataConnectionActive(String label, boolean active) {
try {
int type = Integer.parseInt(label);
if (ConnectivityManager.isNetworkTypeMobile(type)) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
if (mMobileRadioActive != active) {
if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime);
mMobileRadioActive = active;
if (active) {
mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
} else {
updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
}
public void noteDataConnectionActive(int type, boolean active) {
if (ConnectivityManager.isNetworkTypeMobile(type)) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
if (mMobileRadioActive != active) {
if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime);
mMobileRadioActive = active;
if (active) {
mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
mMobileRadioActivePerAppTimer.startRunningLocked(this, elapsedRealtime);
} else {
updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
mMobileRadioActivePerAppTimer.stopRunningLocked(this, elapsedRealtime);
}
}
} catch (NumberFormatException e) {
Slog.w(TAG, "Bad data connection label: " + label, e);
return;
}
}
@ -3038,6 +3037,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
@Override public int getScreenOnCount(int which) {
return mScreenOnTimer.getCountLocked(which);
}
@Override public long getScreenBrightnessTime(int brightnessBin,
long batteryRealtime, int which) {
return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
@ -3052,6 +3055,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
@Override public int getPhoneOnCount(int which) {
return mPhoneOnTimer.getCountLocked(which);
}
@Override public long getPhoneSignalStrengthTime(int strengthBin,
long batteryRealtime, int which) {
return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
@ -5143,6 +5150,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
}
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables);
mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mUnpluggables);
mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables);
mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables);
mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
@ -5411,6 +5419,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].reset(false);
}
mMobileRadioActiveTimer.reset(this, false);
mMobileRadioActivePerAppTimer.reset(this, false);
mMobileRadioActiveUnknownTime.reset(false);
mMobileRadioActiveUnknownCount.reset(false);
mWifiOnTimer.reset(this, false);
@ -5491,6 +5500,9 @@ public final class BatteryStatsImpl extends BatteryStats {
public void pullPendingStateUpdatesLocked() {
updateKernelWakelocksLocked();
updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
if (mOnBatteryInternal) {
updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
}
}
void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
@ -5696,49 +5708,53 @@ public final class BatteryStatsImpl extends BatteryStats {
mCurMobileSnapshot = snapshot;
mLastMobileSnapshot = last;
final NetworkStats delta = NetworkStats.subtract(snapshot, last,
null, null, mTmpNetworkStats);
mTmpNetworkStats = delta;
if (mOnBatteryInternal) {
final NetworkStats delta = NetworkStats.subtract(snapshot, last,
null, null, mTmpNetworkStats);
mTmpNetworkStats = delta;
long radioTime = mMobileRadioActiveTimer.checkpointRunningLocked(this,
elapsedRealtime);
long totalPackets = delta.getTotalPackets();
long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(this,
elapsedRealtime);
long totalPackets = delta.getTotalPackets();
final int size = delta.size();
for (int i = 0; i < size; i++) {
final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
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 (entry.rxBytes == 0 || entry.txBytes == 0) continue;
final Uid u = getUidStatsLocked(entry.uid);
u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
entry.txPackets);
final Uid u = getUidStatsLocked(entry.uid);
u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
entry.txPackets);
if (radioTime > 0) {
// Distribute total radio active time in to this app.
long appPackets = entry.rxPackets + entry.txPackets;
long appRadioTime = (radioTime*appPackets)/totalPackets;
u.noteMobileRadioActiveTimeLocked(appRadioTime);
// Remove this app from the totals, so that we don't lose any time
// due to rounding.
radioTime -= appRadioTime;
totalPackets -= appPackets;
if (radioTime > 0) {
// Distribute total radio active time in to this app.
long appPackets = entry.rxPackets + entry.txPackets;
long appRadioTime = (radioTime*appPackets)/totalPackets;
u.noteMobileRadioActiveTimeLocked(appRadioTime);
// Remove this app from the totals, so that we don't lose any time
// due to rounding.
radioTime -= appRadioTime;
totalPackets -= appPackets;
}
mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
entry.rxBytes);
mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
entry.txBytes);
mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
entry.rxPackets);
mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
entry.txPackets);
}
mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(entry.rxBytes);
mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(entry.txBytes);
mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
entry.rxPackets);
mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
entry.txPackets);
}
if (radioTime > 0) {
// Whoops, there is some radio time we can't blame on an app!
mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
mMobileRadioActiveUnknownCount.addCountLocked(1);
if (radioTime > 0) {
// Whoops, there is some radio time we can't blame on an app!
mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
mMobileRadioActiveUnknownCount.addCountLocked(1);
}
}
}
@ -5756,33 +5772,39 @@ public final class BatteryStatsImpl extends BatteryStats {
mCurWifiSnapshot = snapshot;
mLastWifiSnapshot = last;
final NetworkStats delta = NetworkStats.subtract(snapshot, last,
null, null, mTmpNetworkStats);
mTmpNetworkStats = delta;
if (mOnBatteryInternal) {
final NetworkStats delta = NetworkStats.subtract(snapshot, last,
null, null, mTmpNetworkStats);
mTmpNetworkStats = delta;
final int size = delta.size();
for (int i = 0; i < size; i++) {
final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
final int size = delta.size();
for (int i = 0; i < size; i++) {
final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
if (DEBUG) {
final NetworkStats.Entry cur = snapshot.getValues(i, null);
Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+ " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
+ " tx=" + cur.txBytes);
if (DEBUG) {
final NetworkStats.Entry cur = snapshot.getValues(i, null);
Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+ " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
+ " tx=" + cur.txBytes);
}
if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
final Uid u = getUidStatsLocked(entry.uid);
u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
entry.txPackets);
mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
entry.rxBytes);
mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
entry.txBytes);
mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
entry.rxPackets);
mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
entry.txPackets);
}
if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
final Uid u = getUidStatsLocked(entry.uid);
u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, entry.txPackets);
mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(entry.rxBytes);
mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(entry.txBytes);
mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
entry.rxPackets);
mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
entry.txPackets);
}
}
}
@ -6371,6 +6393,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActive = false;
mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
mWifiOn = false;
@ -6606,6 +6629,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
}
mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL);
mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL);
mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@ -6852,6 +6876,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActive = false;
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables, in);
mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mUnpluggables, in);
mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables, in);
mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables, in);
mWifiOn = false;
@ -6971,6 +6996,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].writeToParcel(out);
}
mMobileRadioActiveTimer.writeToParcel(out, batteryRealtime);
mMobileRadioActivePerAppTimer.writeToParcel(out, batteryRealtime);
mMobileRadioActiveUnknownTime.writeToParcel(out);
mMobileRadioActiveUnknownCount.writeToParcel(out);
mWifiOnTimer.writeToParcel(out, batteryRealtime);