diff options
8 files changed, 313 insertions, 195 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 27c0f5d..4879be6 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -507,10 +507,7 @@ public abstract class BatteryStats implements Parcelable { public long time; - // The command codes 0-3 can be written with delta updates; all others require - // that a full entry be written. - public static final byte CMD_UPDATE = 0; - public static final byte CMD_EVENT = 1; + public static final byte CMD_UPDATE = 0; // These can be written as deltas public static final byte CMD_NULL = -1; public static final byte CMD_START = 4; public static final byte CMD_OVERFLOW = 5; @@ -520,15 +517,8 @@ public abstract class BatteryStats implements Parcelable { /** * Return whether the command code is a delta data update. */ - public static boolean isDeltaData(byte cmd) { - return cmd >= 0 && cmd <= 3; - } - - /** - * Return whether the command code is a delta data update. - */ public boolean isDeltaData() { - return cmd >= 0 && cmd <= 3; + return cmd == CMD_UPDATE; } public byte batteryLevel; @@ -555,16 +545,16 @@ public abstract class BatteryStats implements Parcelable { // These states always appear directly in the first int token // of a delta change; they should be ones that change relatively // frequently. - public static final int STATE_WAKE_LOCK_FLAG = 1<<30; - public static final int STATE_SENSOR_ON_FLAG = 1<<29; - public static final int STATE_GPS_ON_FLAG = 1<<28; - public static final int STATE_PHONE_SCANNING_FLAG = 1<<27; - public static final int STATE_WIFI_RUNNING_FLAG = 1<<26; - public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25; - public static final int STATE_WIFI_SCAN_FLAG = 1<<24; - public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23; + public static final int STATE_WAKE_LOCK_FLAG = 1<<31; + public static final int STATE_SENSOR_ON_FLAG = 1<<30; + public static final int STATE_GPS_ON_FLAG = 1<<29; + public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28; + public static final int STATE_WIFI_SCAN_FLAG = 1<<29; + public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26; // These are on the lower bits used for the command; if they change // we need to write another int of data. + public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; + public static final int STATE_PHONE_SCANNING_FLAG = 1<<23; public static final int STATE_AUDIO_ON_FLAG = 1<<22; public static final int STATE_VIDEO_ON_FLAG = 1<<21; public static final int STATE_SCREEN_ON_FLAG = 1<<20; @@ -628,7 +618,8 @@ public abstract class BatteryStats implements Parcelable { } else { dest.writeInt(0); } - if (cmd == CMD_EVENT) { + dest.writeInt(eventCode); + if (eventCode != EVENT_NONE) { dest.writeInt(eventCode); eventTag.writeToParcel(dest, flags); } @@ -652,13 +643,10 @@ public abstract class BatteryStats implements Parcelable { } else { wakelockTag = null; } - if (cmd == CMD_EVENT) { - eventCode = src.readInt(); + eventCode = src.readInt(); + if (eventCode != EVENT_NONE) { eventTag = localEventTag; eventTag.readFromParcel(src); - } else { - eventCode = EVENT_NONE; - eventTag = null; } numReadInts += (src.dataPosition()-start)/4; } @@ -681,6 +669,16 @@ public abstract class BatteryStats implements Parcelable { public void setTo(HistoryItem o) { time = o.time; cmd = o.cmd; + setToCommon(o); + } + + public void setTo(long time, byte cmd, HistoryItem o) { + this.time = time; + this.cmd = cmd; + setToCommon(o); + } + + private void setToCommon(HistoryItem o) { batteryLevel = o.batteryLevel; batteryStatus = o.batteryStatus; batteryHealth = o.batteryHealth; @@ -703,32 +701,6 @@ public abstract class BatteryStats implements Parcelable { } } - public void setTo(long time, byte cmd, int eventCode, int eventUid, String eventName, - HistoryItem o) { - this.time = time; - this.cmd = cmd; - this.eventCode = eventCode; - if (eventCode != EVENT_NONE) { - eventTag = localEventTag; - eventTag.setTo(eventName, eventUid); - } else { - eventTag = null; - } - batteryLevel = o.batteryLevel; - batteryStatus = o.batteryStatus; - batteryHealth = o.batteryHealth; - batteryPlugType = o.batteryPlugType; - batteryTemperature = o.batteryTemperature; - batteryVoltage = o.batteryVoltage; - states = o.states; - if (o.wakelockTag != null) { - wakelockTag = localWakelockTag; - wakelockTag.setTo(o.wakelockTag); - } else { - wakelockTag = null; - } - } - public boolean sameNonEvent(HistoryItem o) { return batteryLevel == o.batteryLevel && batteryStatus == o.batteryStatus @@ -938,36 +910,36 @@ public abstract class BatteryStats implements Parcelable { public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] { - new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), - new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), + new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), + new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"), - new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"), - new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), - new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi", "W"), - new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"), new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"), new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"), - new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"), + new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), + new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video", "v"), - new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), - new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), - new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, - HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb", - SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES), + new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), + new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), + new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"), + new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi", "W"), + new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"), + new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, + HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn", + DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES), + new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, + HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst", + new String[] {"in", "out", "emergency", "off"}, + new String[] {"in", "out", "em", "off"}), new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK, HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", "Pss", SignalStrength.SIGNAL_STRENGTH_NAMES, new String[] { "0", "1", "2", "3", "4" }), - new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK, - HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst", - new String[] {"in", "out", "emergency", "off"}, - new String[] {"in", "out", "em", "off"}), - new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK, - HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn", - DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES), + new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK, + HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb", + SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES), }; /** @@ -2464,7 +2436,8 @@ public abstract class BatteryStats implements Parcelable { else if (rec.batteryLevel < 100) pw.print("0"); pw.print(rec.batteryLevel); pw.print(" "); - if (rec.states < 0x10) pw.print("0000000"); + if (rec.states < 0) ; + else if (rec.states < 0x10) pw.print("0000000"); else if (rec.states < 0x100) pw.print("000000"); else if (rec.states < 0x1000) pw.print("00000"); else if (rec.states < 0x10000) pw.print("0000"); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 3a9611e..0439eeb 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -223,6 +223,13 @@ public final class PowerManager { public static final int ON_AFTER_RELEASE = 0x20000000; /** + * Wake lock flag: This wake lock is not important for logging events. If a later + * wake lock is acquired that is important, it will be considered the one to log. + * @hide + */ + public static final int UNIMPORTANT_FOR_LOGGING = 0x40000000; + + /** * Flag for {@link WakeLock#release release(int)} to defer releasing a * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns * a negative value. @@ -634,8 +641,8 @@ public final class PowerManager { * </p> */ public final class WakeLock { - private final int mFlags; - private final String mTag; + private int mFlags; + private String mTag; private final String mPackageName; private final IBinder mToken; private int mCount; @@ -829,6 +836,17 @@ public final class PowerManager { } } + /** @hide */ + public void setTag(String tag) { + mTag = tag; + } + + /** @hide */ + public void setUnimportantForLogging(boolean state) { + if (state) mFlags |= UNIMPORTANT_FOR_LOGGING; + else mFlags &= ~UNIMPORTANT_FOR_LOGGING; + } + @Override public String toString() { synchronized (mToken) { diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 1946d86..9a04760 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -35,10 +35,11 @@ interface IBatteryStats { void noteEvent(int code, String name, int uid); - void noteStartWakelock(int uid, int pid, String name, int type); + void noteStartWakelock(int uid, int pid, String name, int type, boolean unimportantForLogging); void noteStopWakelock(int uid, int pid, String name, int type); - void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type); + void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type, + boolean unimportantForLogging); void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type); void noteVibratorOn(int uid, long durationMillis); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 68c41fa..21d2e52 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -77,7 +77,7 @@ 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 = true; private static final boolean DEBUG_HISTORY = false; private static final boolean USE_OLD_HISTORY = false; // for debugging. @@ -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 = 75 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 77 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -226,6 +226,9 @@ public final class BatteryStatsImpl extends BatteryStats { long mRealtimeStart; long mLastRealtime; + int mWakeLockNesting; + boolean mWakeLockImportant; + boolean mScreenOn; StopwatchTimer mScreenOnTimer; @@ -1513,23 +1516,23 @@ public final class BatteryStatsImpl extends BatteryStats { } // Part of initial delta int that specifies the time delta. - static final int DELTA_TIME_MASK = 0x1ffff; - static final int DELTA_TIME_LONG = 0x1ffff; // The delta is a following long - static final int DELTA_TIME_INT = 0x1fffe; // The delta is a following int - static final int DELTA_TIME_ABS = 0x1fffd; // Following is an entire abs update. - // Part of initial delta int holding the command code. - static final int DELTA_CMD_MASK = 0x3; - static final int DELTA_CMD_SHIFT = 17; + static final int DELTA_TIME_MASK = 0xfffff; + static final int DELTA_TIME_LONG = 0xfffff; // The delta is a following long + static final int DELTA_TIME_INT = 0xffffe; // The delta is a following int + static final int DELTA_TIME_ABS = 0xffffd; // Following is an entire abs update. // Flag in delta int: a new battery level int follows. - static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; + static final int DELTA_BATTERY_LEVEL_FLAG = 0x00400000; // Flag in delta int: a new full state and battery status int follows. - static final int DELTA_STATE_FLAG = 0x00100000; + static final int DELTA_STATE_FLAG = 0x00800000; // Flag in delta int: contains a wakelock tag. - static final int DELTA_WAKELOCK_FLAG = 0x00200000; - static final int DELTA_STATE_MASK = 0xffc00000; + static final int DELTA_WAKELOCK_FLAG = 0x01000000; + // Flag in delta int: contains an event description. + static final int DELTA_EVENT_FLAG = 0x02000000; + // These upper bits are the frequently changing state bits. + static final int DELTA_STATE_MASK = 0xfc000000; public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { - if (last == null || !last.isDeltaData() || !cur.isDeltaData()) { + if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { dest.writeInt(DELTA_TIME_ABS); cur.writeToParcel(dest, 0); return; @@ -1547,9 +1550,7 @@ public final class BatteryStatsImpl extends BatteryStats { } else { deltaTimeToken = (int)deltaTime; } - int firstToken = deltaTimeToken - | (cur.cmd<<DELTA_CMD_SHIFT) - | (cur.states&DELTA_STATE_MASK); + int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); final int batteryLevelInt = buildBatteryLevelInt(cur); final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; if (batteryLevelIntChanged) { @@ -1563,6 +1564,9 @@ public final class BatteryStatsImpl extends BatteryStats { if (cur.wakelockTag != null) { firstToken |= DELTA_WAKELOCK_FLAG; } + if (cur.eventCode != HistoryItem.EVENT_NONE) { + firstToken |= DELTA_EVENT_FLAG; + } dest.writeInt(firstToken); if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) + " deltaTime=" + deltaTime); @@ -1599,7 +1603,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); } - if (cur.cmd == HistoryItem.CMD_EVENT) { + if (cur.eventCode != HistoryItem.EVENT_NONE) { int index = writeHistoryTag(cur.eventTag); int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); dest.writeInt(codeAndIndex); @@ -1625,7 +1629,7 @@ public final class BatteryStatsImpl extends BatteryStats { public void readHistoryDelta(Parcel src, HistoryItem cur) { int firstToken = src.readInt(); int deltaTimeToken = firstToken&DELTA_TIME_MASK; - cur.cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK); + cur.cmd = HistoryItem.CMD_UPDATE; cur.numReadInts = 1; if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) + " deltaTimeToken=" + deltaTimeToken); @@ -1691,7 +1695,7 @@ public final class BatteryStatsImpl extends BatteryStats { cur.wakelockTag = null; } - if (cur.cmd == HistoryItem.CMD_EVENT) { + if ((firstToken&DELTA_EVENT_FLAG) != 0) { cur.eventTag = cur.localEventTag; final int codeAndIndex = src.readInt(); cur.eventCode = (codeAndIndex&0xffff); @@ -1720,6 +1724,8 @@ public final class BatteryStatsImpl extends BatteryStats { if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null) + && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE + || mHistoryCur.eventCode == HistoryItem.EVENT_NONE) && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel && mHistoryLastWritten.batteryStatus == mHistoryCur.batteryStatus && mHistoryLastWritten.batteryHealth == mHistoryCur.batteryHealth @@ -1742,6 +1748,14 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); } + // If the last written history had an event, we need to retain it. + // Note that the condition above made sure that we aren't in a case where + // both it and the current history item have an event. + if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { + mHistoryCur.eventCode = mHistoryLastWritten.eventCode; + mHistoryCur.eventTag = mHistoryCur.localEventTag; + mHistoryCur.eventTag.setTo(mHistoryLastWritten.eventTag); + } mHistoryLastWritten.setTo(mHistoryLastLastWritten); } @@ -1772,26 +1786,18 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE); } - void addHistoryBufferLocked(long curTime, byte cmd) { - addHistoryBufferLocked(curTime, cmd, HistoryItem.EVENT_NONE, null, 0); - } - - void addHistoryBufferEventLocked(long curTime, int eventCode, String eventName, int eventUid) { - addHistoryBufferLocked(curTime, HistoryItem.CMD_EVENT, eventCode, eventName, eventUid); - } - - private void addHistoryBufferLocked(long curTime, byte cmd, - int eventCode, String eventName, int eventUid) { + private void addHistoryBufferLocked(long curTime, byte cmd) { if (mIteratingHistory) { throw new IllegalStateException("Can't do this while iterating history!"); } mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); mHistoryLastLastWritten.setTo(mHistoryLastWritten); - mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, - eventCode, eventUid, eventName, mHistoryCur); + mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); mLastHistoryTime = curTime; mHistoryCur.wakelockTag = null; + mHistoryCur.eventCode = HistoryItem.EVENT_NONE; + mHistoryCur.eventTag = null; if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos + " now " + mHistoryBuffer.dataPosition() + " size is now " + mHistoryBuffer.dataSize()); @@ -1829,8 +1835,7 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryLastEnd = null; } else { mChangedStates |= mHistoryEnd.states^mHistoryCur.states; - mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, - HistoryItem.EVENT_NONE, 0, null, mHistoryCur); + mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur); } return; } @@ -1860,7 +1865,11 @@ public final class BatteryStatsImpl extends BatteryStats { } void addHistoryEventLocked(long curTime, int code, String name, int uid) { - addHistoryBufferEventLocked(curTime, code, name, uid); + mHistoryCur.eventCode = code; + mHistoryCur.eventTag = mHistoryCur.localEventTag; + mHistoryCur.eventTag.string = name; + mHistoryCur.eventTag.uid = uid; + addHistoryBufferLocked(curTime); } void addHistoryRecordLocked(long curTime, byte cmd) { @@ -1870,8 +1879,7 @@ public final class BatteryStatsImpl extends BatteryStats { } else { rec = new HistoryItem(); } - rec.setTo(mHistoryBaseTime + curTime, cmd, - HistoryItem.EVENT_NONE, 0, null, mHistoryCur); + rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); addHistoryRecordLocked(rec); } @@ -1905,8 +1913,8 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryBuffer.setDataSize(0); mHistoryBuffer.setDataPosition(0); mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); - mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL; - mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; + mHistoryLastLastWritten.clear(); + mHistoryLastWritten.clear(); mHistoryTagPool.clear(); mNextHistoryTagIdx = 0; mNumHistoryTagChars = 0; @@ -1942,8 +1950,6 @@ public final class BatteryStatsImpl extends BatteryStats { mBluetoothPingStart = -1; } - int mWakeLockNesting; - public void addIsolatedUidLocked(int isolatedUid, int appUid) { mIsolatedUids.put(isolatedUid, appUid); } @@ -1965,7 +1971,8 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(SystemClock.elapsedRealtime(), code, name, uid); } - public void noteStartWakeLocked(int uid, int pid, String name, int type) { + public void noteStartWakeLocked(int uid, int pid, String name, int type, + boolean unimportantForLogging) { uid = mapUid(uid); if (type == WAKE_TYPE_PARTIAL) { // Only care about partial wake locks, since full wake locks @@ -1977,7 +1984,18 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; mHistoryCur.wakelockTag.string = name; mHistoryCur.wakelockTag.uid = uid; + mWakeLockImportant = !unimportantForLogging; addHistoryRecordLocked(SystemClock.elapsedRealtime()); + } else if (!mWakeLockImportant && !unimportantForLogging) { + if (mHistoryLastWritten.wakelockTag != null) { + // We'll try to update the last tag. + mHistoryLastWritten.wakelockTag = null; + mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; + mHistoryCur.wakelockTag.string = name; + mHistoryCur.wakelockTag.uid = uid; + addHistoryRecordLocked(SystemClock.elapsedRealtime()); + } + mWakeLockImportant = true; } mWakeLockNesting++; } @@ -2010,10 +2028,11 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) { + public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type, + boolean unimportantForLogging) { int N = ws.size(); for (int i=0; i<N; i++) { - noteStartWakeLocked(ws.get(i), pid, name, type); + noteStartWakeLocked(ws.get(i), pid, name, type, unimportantForLogging); } } @@ -2224,7 +2243,7 @@ public final class BatteryStatsImpl extends BatteryStats { // Fake a wake lock, so we consider the device waked as long // as the screen is on. - noteStartWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL); + noteStartWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, false); // Update discharge amounts. if (mOnBatteryInternal) { @@ -4979,6 +4998,9 @@ public final class BatteryStatsImpl extends BatteryStats { public boolean startIteratingHistoryLocked() { if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() + " pos=" + mHistoryBuffer.dataPosition()); + if (mHistoryBuffer.dataSize() <= 0) { + return false; + } mHistoryBuffer.setDataPosition(0); mReadOverflow = false; mIteratingHistory = true; @@ -4992,7 +5014,7 @@ public final class BatteryStatsImpl extends BatteryStats { mReadHistoryUids[idx] = tag.uid; mReadHistoryChars += tag.string.length() + 1; } - return mHistoryBuffer.dataSize() > 0; + return true; } @Override @@ -5075,8 +5097,37 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOff = 0; mDischargeAmountScreenOffSinceCharge = 0; } - - public void resetAllStatsLocked() { + + public void resetAllStatsCmdLocked() { + resetAllStatsLocked(); + long uptime = SystemClock.uptimeMillis() * 1000; + long mSecRealtime = SystemClock.elapsedRealtime(); + long realtime = mSecRealtime * 1000; + mDischargeStartLevel = mHistoryCur.batteryLevel; + pullPendingStateUpdatesLocked(); + addHistoryRecordLocked(mSecRealtime); + mDischargeCurrentLevel = mDischargeUnplugLevel = mHistoryCur.batteryLevel; + if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0) { + mTrackBatteryPastUptime = 0; + mTrackBatteryPastRealtime = 0; + } else { + mTrackBatteryUptimeStart = uptime; + mTrackBatteryRealtimeStart = realtime; + mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); + mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); + if (mScreenOn) { + mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; + mDischargeScreenOffUnplugLevel = 0; + } else { + mDischargeScreenOnUnplugLevel = 0; + mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; + } + mDischargeAmountScreenOn = 0; + mDischargeAmountScreenOff = 0; + } + } + + private void resetAllStatsLocked() { mStartCount = 0; initTimes(); mScreenOnTimer.reset(this, false); @@ -5292,7 +5343,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { // We don't record history while we are plugged in and fully charged. // The next time we are unplugged, history will be cleared. - mRecordingHistory = false; + mRecordingHistory = DEBUG; } } } diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index cb5ae96..eb347bb 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -39,8 +39,10 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.WorkSource; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Pair; import android.util.Slog; +import android.util.SparseArray; import android.util.TimeUtils; import java.io.ByteArrayOutputStream; @@ -53,9 +55,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; -import java.util.HashMap; import java.util.LinkedList; -import java.util.Map; import java.util.TimeZone; import static android.app.AlarmManager.RTC_WAKEUP; @@ -313,7 +313,22 @@ class AlarmManagerService extends SystemService { return 0; } } - + + final Comparator<Alarm> mAlarmDispatchComparator = new Comparator<Alarm>() { + @Override + public int compare(Alarm lhs, Alarm rhs) { + if (lhs.wakeup != rhs.wakeup) { + return lhs.wakeup ? -1 : 1; + } + if (lhs.whenElapsed < rhs.whenElapsed) { + return -1; + } else if (lhs.whenElapsed > rhs.whenElapsed) { + return 1; + } + return 0; + } + }; + // minimum recurrence period or alarm futurity for us to be able to fuzz it static final long MIN_FUZZABLE_INTERVAL = 10000; static final BatchTimeOrder sBatchOrder = new BatchTimeOrder(); @@ -442,6 +457,7 @@ class AlarmManagerService extends SystemService { } static final class BroadcastStats { + final int mUid; final String mPackageName; long aggregateTime; @@ -449,16 +465,17 @@ class AlarmManagerService extends SystemService { int numWakeup; long startTime; int nesting; - final HashMap<Pair<String, ComponentName>, FilterStats> filterStats - = new HashMap<Pair<String, ComponentName>, FilterStats>(); + final ArrayMap<Pair<String, ComponentName>, FilterStats> filterStats + = new ArrayMap<Pair<String, ComponentName>, FilterStats>(); - BroadcastStats(String packageName) { + BroadcastStats(int uid, String packageName) { + mUid = uid; mPackageName = packageName; } } - final HashMap<String, BroadcastStats> mBroadcastStats - = new HashMap<String, BroadcastStats>(); + final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats + = new SparseArray<ArrayMap<String, BroadcastStats>>(); @Override public void onStart() { @@ -470,7 +487,7 @@ class AlarmManagerService extends SystemService { setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY)); PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*"); mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0, new Intent(Intent.ACTION_TIME_TICK).addFlags( @@ -743,24 +760,26 @@ class AlarmManagerService extends SystemService { } }; int len = 0; - for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { - BroadcastStats bs = be.getValue(); - for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe - : bs.filterStats.entrySet()) { - FilterStats fs = fe.getValue(); - int pos = len > 0 - ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; - if (pos < 0) { - pos = -pos - 1; - } - if (pos < topFilters.length) { - int copylen = topFilters.length - pos - 1; - if (copylen > 0) { - System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); + for (int iu=0; iu<mBroadcastStats.size(); iu++) { + ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); + for (int ip=0; ip<uidStats.size(); ip++) { + BroadcastStats bs = uidStats.valueAt(ip); + for (int is=0; is<bs.filterStats.size(); is++) { + FilterStats fs = bs.filterStats.valueAt(is); + int pos = len > 0 + ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; + if (pos < 0) { + pos = -pos - 1; } - topFilters[pos] = fs; - if (len < topFilters.length) { - len++; + if (pos < topFilters.length) { + int copylen = topFilters.length - pos - 1; + if (copylen > 0) { + System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); + } + topFilters[pos] = fs; + if (len < topFilters.length) { + len++; + } } } } @@ -774,7 +793,8 @@ class AlarmManagerService extends SystemService { TimeUtils.formatDuration(fs.aggregateTime, pw); pw.print(" running, "); pw.print(fs.numWakeup); pw.print(" wakeups, "); pw.print(fs.count); - pw.print(" alarms: "); pw.print(fs.mBroadcastStats.mPackageName); + pw.print(" alarms: "); UserHandle.formatUid(pw, fs.mBroadcastStats.mUid); + pw.print(":"); pw.print(fs.mBroadcastStats.mPackageName); pw.println(); pw.print(" "); if (fs.mTarget.first != null) { @@ -790,35 +810,39 @@ class AlarmManagerService extends SystemService { pw.println(" "); pw.println(" Alarm Stats:"); final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); - for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { - BroadcastStats bs = be.getValue(); - pw.print(" "); - if (bs.nesting > 0) pw.print("*ACTIVE* "); - pw.print(be.getKey()); - pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw); - pw.print(" running, "); pw.print(bs.numWakeup); - pw.println(" wakeups:"); - tmpFilters.clear(); - for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe - : bs.filterStats.entrySet()) { - tmpFilters.add(fe.getValue()); - } - Collections.sort(tmpFilters, comparator); - for (int i=0; i<tmpFilters.size(); i++) { - FilterStats fs = tmpFilters.get(i); - pw.print(" "); - if (fs.nesting > 0) pw.print("*ACTIVE* "); - TimeUtils.formatDuration(fs.aggregateTime, pw); - pw.print(" "); pw.print(fs.numWakeup); - pw.print(" wakes " ); pw.print(fs.count); - pw.print(" alarms:"); - if (fs.mTarget.first != null) { - pw.print(" act="); pw.print(fs.mTarget.first); - } - if (fs.mTarget.second != null) { - pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString()); - } - pw.println(); + for (int iu=0; iu<mBroadcastStats.size(); iu++) { + ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); + for (int ip=0; ip<uidStats.size(); ip++) { + BroadcastStats bs = uidStats.valueAt(ip); + pw.print(" "); + if (bs.nesting > 0) pw.print("*ACTIVE* "); + UserHandle.formatUid(pw, bs.mUid); + pw.print(":"); + pw.print(bs.mPackageName); + pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw); + pw.print(" running, "); pw.print(bs.numWakeup); + pw.println(" wakeups:"); + tmpFilters.clear(); + for (int is=0; is<bs.filterStats.size(); is++) { + tmpFilters.add(bs.filterStats.valueAt(is)); + } + Collections.sort(tmpFilters, comparator); + for (int i=0; i<tmpFilters.size(); i++) { + FilterStats fs = tmpFilters.get(i); + pw.print(" "); + if (fs.nesting > 0) pw.print("*ACTIVE* "); + TimeUtils.formatDuration(fs.aggregateTime, pw); + pw.print(" "); pw.print(fs.numWakeup); + pw.print(" wakes " ); pw.print(fs.count); + pw.print(" alarms:"); + if (fs.mTarget.first != null) { + pw.print(" act="); pw.print(fs.mTarget.first); + } + if (fs.mTarget.second != null) { + pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString()); + } + pw.println(); + } } } @@ -1037,7 +1061,8 @@ class AlarmManagerService extends SystemService { private native int waitForAlarm(long nativeData); private native int setKernelTimezone(long nativeData, int minuteswest); - void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) { + void triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED, + final long nowRTC) { // batches are temporally sorted, so we need only pull from the // start of the list until we either empty it or hit a batch // that is not yet deliverable @@ -1076,6 +1101,14 @@ class AlarmManagerService extends SystemService { } } + + Collections.sort(triggerList, mAlarmDispatchComparator); + + if (localLOGV) { + for (int i=0; i<triggerList.size(); i++) { + Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i)); + } + } } /** @@ -1096,7 +1129,8 @@ class AlarmManagerService extends SystemService { } private static class Alarm { - public int type; + public final int type; + public final boolean wakeup; public int count; public long when; public long windowLength; @@ -1109,6 +1143,8 @@ class AlarmManagerService extends SystemService { public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, long _interval, PendingIntent _op, WorkSource _ws) { type = _type; + wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP + || _type == AlarmManager.RTC_WAKEUP; when = _when; whenElapsed = _whenElapsed; windowLength = _windowLength; @@ -1126,6 +1162,8 @@ class AlarmManagerService extends SystemService { sb.append(Integer.toHexString(System.identityHashCode(this))); sb.append(" type "); sb.append(type); + sb.append(" when "); + sb.append(when); sb.append(" "); sb.append(operation.getTargetPackage()); sb.append('}'); @@ -1231,6 +1269,15 @@ class AlarmManagerService extends SystemService { // we have an active broadcast so stay awake. if (mBroadcastRefCount == 0) { setWakelockWorkSource(alarm.operation, alarm.workSource); + mWakeLock.setUnimportantForLogging( + alarm.operation == mTimeTickSender); + // XXX debugging + /* + Intent intent = alarm.operation.getIntent(); + mWakeLock.setTag(intent.getAction() != null ? intent.getAction() + : (intent.getComponent() != null + ? intent.getComponent().toShortString() : TAG)); + */ mWakeLock.acquire(); } final InFlight inflight = new InFlight(AlarmManagerService.this, @@ -1450,7 +1497,14 @@ class AlarmManagerService extends SystemService { if (pkgList != null && (pkgList.length > 0)) { for (String pkg : pkgList) { removeLocked(pkg); - mBroadcastStats.remove(pkg); + for (int i=mBroadcastStats.size()-1; i>=0; i--) { + ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i); + if (uidStats.remove(pkg) != null) { + if (uidStats.size() <= 0) { + mBroadcastStats.removeAt(i); + } + } + } } } } @@ -1458,11 +1512,17 @@ class AlarmManagerService extends SystemService { } private final BroadcastStats getStatsLocked(PendingIntent pi) { - String pkg = pi.getTargetPackage(); - BroadcastStats bs = mBroadcastStats.get(pkg); + String pkg = pi.getCreatorPackage(); + int uid = pi.getCreatorUid(); + ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid); + if (uidStats == null) { + uidStats = new ArrayMap<String, BroadcastStats>(); + mBroadcastStats.put(uid, uidStats); + } + BroadcastStats bs = uidStats.get(pkg); if (bs == null) { - bs = new BroadcastStats(pkg); - mBroadcastStats.put(pkg, bs); + bs = new BroadcastStats(uid, pkg); + uidStats.put(pkg, bs); } return bs; } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index eda08a9..8a29ac7 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -126,10 +126,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } - public void noteStartWakelock(int uid, int pid, String name, int type) { + public void noteStartWakelock(int uid, int pid, String name, int type, + boolean unimportantForLogging) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteStartWakeLocked(uid, pid, name, type); + mStats.noteStartWakeLocked(uid, pid, name, type, unimportantForLogging); } } @@ -140,10 +141,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } - public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type) { + public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type, + boolean unimportantForLogging) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteStartWakeFromSourceLocked(ws, pid, name, type); + mStats.noteStartWakeFromSourceLocked(ws, pid, name, type, unimportantForLogging); } } @@ -557,7 +559,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { isUnpluggedOnly = true; } else if ("--reset".equals(arg)) { synchronized (mStats) { - mStats.resetAllStatsLocked(); + mStats.resetAllStatsCmdLocked(); pw.println("Battery stats reset."); noOutput = true; } diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java index f1be504..b63f625 100644 --- a/services/core/java/com/android/server/power/DisplayPowerController.java +++ b/services/core/java/com/android/server/power/DisplayPowerController.java @@ -536,6 +536,14 @@ final class DisplayPowerController { mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); + + // Initialize screen on state. + if (mPowerState.isScreenOn()) { + mNotifier.onScreenOn(); + } else { + mNotifier.onScreenOff(); + } + mNotifier.onScreenBrightness(mPowerState.getScreenBrightness()); } private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 264e2e9..09be3a8 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -34,6 +34,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -139,10 +140,14 @@ final class Notifier { try { final int monitorType = getBatteryStatsWakeLockMonitorType(flags); + boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0 + && ownerUid == Process.SYSTEM_UID; if (workSource != null) { - mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType); + mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType, + unimportantForLogging); } else { - mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType); + mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType, + unimportantForLogging); // XXX need to deal with disabled operations. mAppOps.startOperation(AppOpsManager.getToken(mAppOps), AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName); |