summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/Notification.java7
-rw-r--r--core/java/android/os/BatteryStats.java176
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java346
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/Task.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java1
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java9
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java2
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java15
-rwxr-xr-xservices/core/java/com/android/server/pm/PackageManagerService.java34
-rw-r--r--services/core/jni/com_android_server_am_BatteryStatsService.cpp11
15 files changed, 565 insertions, 169 deletions
diff --git a/api/current.txt b/api/current.txt
index 4efe1daf9e1b..4c1f6fa27e47 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4214,6 +4214,7 @@ package android.app {
field public static final java.lang.String CATEGORY_MESSAGE = "msg";
field public static final java.lang.String CATEGORY_PROGRESS = "progress";
field public static final java.lang.String CATEGORY_PROMO = "promo";
+ field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
field public static final java.lang.String CATEGORY_SERVICE = "service";
field public static final java.lang.String CATEGORY_SOCIAL = "social";
field public static final java.lang.String CATEGORY_STATUS = "status";
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2e8fbb6f8b1e..13e74da569bf 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -504,6 +504,13 @@ public class Notification implements Parcelable
public static final String CATEGORY_SERVICE = "service";
/**
+ * Notification category: a specific, timely recommendation for a single thing.
+ * For example, a news app might want to recommend a news story it believes the user will
+ * want to read next.
+ */
+ public static final String CATEGORY_RECOMMENDATION = "recommendation";
+
+ /**
* Notification category: ongoing information about device or contextual status.
*/
public static final String CATEGORY_STATUS = "status";
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b0d94d59a70e..87beb95479c5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -155,6 +155,7 @@ public abstract class BatteryStats implements Parcelable {
private static final String FOREGROUND_DATA = "fg";
private static final String WAKELOCK_DATA = "wl";
private static final String KERNEL_WAKELOCK_DATA = "kwl";
+ private static final String WAKEUP_REASON_DATA = "wr";
private static final String NETWORK_DATA = "nt";
private static final String USER_ACTIVITY_DATA = "ua";
private static final String BATTERY_DATA = "bt";
@@ -201,6 +202,25 @@ public abstract class BatteryStats implements Parcelable {
}
/**
+ * State for keeping track of long counting information.
+ */
+ public static abstract class LongCounter {
+
+ /**
+ * Returns the count associated with this Counter for the
+ * selected type of statistics.
+ *
+ * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
+ */
+ public abstract long getCountLocked(int which);
+
+ /**
+ * Temporary for debugging.
+ */
+ public abstract void logState(Printer pw, String prefix);
+ }
+
+ /**
* State for keeping track of timing information.
*/
public static abstract class Timer {
@@ -552,8 +572,8 @@ 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<<31;
- public static final int STATE_SENSOR_ON_FLAG = 1<<30;
+ public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
+ public static final int STATE_WAKE_LOCK_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<<27;
@@ -562,9 +582,9 @@ public abstract class BatteryStats implements Parcelable {
public static final int STATE_WIFI_RUNNING_FLAG = 1<<24;
// 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_PHONE_SCANNING_FLAG = 1<<23;
+ public static final int STATE_SENSOR_ON_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_PHONE_SCANNING_FLAG = 1<<21;
public static final int STATE_SCREEN_ON_FLAG = 1<<20;
public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
@@ -577,6 +597,7 @@ public abstract class BatteryStats implements Parcelable {
public int states;
+ public static final int STATE2_VIDEO_ON_FLAG = 1<<0;
public int states2;
// The wake lock that was acquired at this point.
@@ -653,6 +674,7 @@ public abstract class BatteryStats implements Parcelable {
| ((((int)batteryVoltage)<<16)&0xffff0000);
dest.writeInt(bat);
dest.writeInt(states);
+ dest.writeInt(states2);
if (wakelockTag != null) {
wakelockTag.writeToParcel(dest, flags);
}
@@ -680,6 +702,7 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = (short)(bat2&0xffff);
batteryVoltage = (char)((bat2>>16)&0xffff);
states = src.readInt();
+ states2 = src.readInt();
if ((bat&0x10000000) != 0) {
wakelockTag = localWakelockTag;
wakelockTag.readFromParcel(src);
@@ -718,6 +741,7 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = 0;
batteryVoltage = 0;
states = 0;
+ states2 = 0;
wakelockTag = null;
wakeReasonTag = null;
eventCode = EVENT_NONE;
@@ -744,6 +768,7 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = o.batteryTemperature;
batteryVoltage = o.batteryVoltage;
states = o.states;
+ states2 = o.states2;
if (o.wakelockTag != null) {
wakelockTag = localWakelockTag;
wakelockTag.setTo(o.wakelockTag);
@@ -774,6 +799,7 @@ public abstract class BatteryStats implements Parcelable {
&& batteryTemperature == o.batteryTemperature
&& batteryVoltage == o.batteryVoltage
&& states == o.states
+ && states2 == o.states2
&& currentTime == o.currentTime;
}
@@ -970,6 +996,15 @@ public abstract class BatteryStats implements Parcelable {
public abstract int getMobileRadioActiveCount(int which);
/**
+ * Returns the time in microseconds that is the difference between the mobile radio
+ * time we saw based on the elapsed timestamp when going down vs. the given time stamp
+ * from the radio.
+ *
+ * {@hide}
+ */
+ public abstract long getMobileRadioActiveAdjustedTime(int which);
+
+ /**
* Returns the time in microseconds that the mobile network has been active
* (in a high power state) but not being able to blame on an app.
*
@@ -1026,9 +1061,10 @@ public abstract class BatteryStats implements Parcelable {
* {@hide}
*/
public abstract int getPhoneDataConnectionCount(int dataType, int which);
-
+
public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
= new BitDescription[] {
+ new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
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"),
@@ -1039,7 +1075,6 @@ public abstract class BatteryStats implements Parcelable {
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_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"),
@@ -1062,6 +1097,11 @@ public abstract class BatteryStats implements Parcelable {
SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
};
+ public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
+ = new BitDescription[] {
+ new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
+ };
+
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync"
};
@@ -1294,6 +1334,8 @@ public abstract class BatteryStats implements Parcelable {
*/
public abstract long computeRealtime(long curTime, int which);
+ public abstract Map<String, ? extends LongCounter> getWakeupReasonStats();
+
public abstract Map<String, ? extends Timer> getKernelWakelockStats();
/** Returns the number of different speeds that the CPU can run at */
@@ -1554,7 +1596,8 @@ public abstract class BatteryStats implements Parcelable {
wifiRunningTime / 1000, bluetoothOnTime / 1000,
mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
fullWakeLockTimeTotal, partialWakeLockTimeTotal,
- getInputEventCount(which), getMobileRadioActiveTime(rawRealtime, which));
+ getInputEventCount(which), getMobileRadioActiveTime(rawRealtime, which),
+ getMobileRadioActiveAdjustedTime(which));
// Dump screen brightness stats
Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
@@ -1626,16 +1669,22 @@ public abstract class BatteryStats implements Parcelable {
}
if (reqUid < 0) {
- Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+ Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
+ for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
sb.setLength(0);
printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
-
- dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
+ dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
sb.toString());
}
}
+ Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
+ if (wakeupReasons.size() > 0) {
+ for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
+ dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
+ "\"" + ent.getKey() + "\"", ent.getValue().getCountLocked(which));
+ }
+ }
}
BatteryStatsHelper helper = new BatteryStatsHelper(context);
@@ -2111,6 +2160,18 @@ public abstract class BatteryStats implements Parcelable {
pw.println(sb.toString());
}
+ final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
+ if (mobileActiveAdjustedTime != 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Mobile radio active adjusted time: ");
+ formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
+ sb.append("(");
+ sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
+ sb.append(")");
+ pw.println(sb.toString());
+ }
+
pw.print(prefix);
pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
@@ -2346,24 +2407,49 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
}
}
- }
- if (timers.size() > 0) {
- Collections.sort(timers, timerComparator);
- pw.print(prefix); pw.println(" All partial wake locks:");
- for (int i=0; i<timers.size(); i++) {
- TimerEntry timer = timers.get(i);
- sb.setLength(0);
- sb.append(" Wake lock ");
- UserHandle.formatUid(sb, timer.mId);
- sb.append(" ");
- sb.append(timer.mName);
- printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
- sb.append(" realtime");
- pw.println(sb.toString());
+ if (timers.size() > 0) {
+ Collections.sort(timers, timerComparator);
+ pw.print(prefix); pw.println(" All partial wake locks:");
+ for (int i=0; i<timers.size(); i++) {
+ TimerEntry timer = timers.get(i);
+ sb.setLength(0);
+ sb.append(" Wake lock ");
+ UserHandle.formatUid(sb, timer.mId);
+ sb.append(" ");
+ sb.append(timer.mName);
+ printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
+ sb.append(" realtime");
+ pw.println(sb.toString());
+ }
+ timers.clear();
+ pw.println();
+ }
+
+ Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
+ if (wakeupReasons.size() > 0) {
+ pw.print(prefix); pw.println(" All wakeup reasons:");
+ final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
+ for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
+ BatteryStats.LongCounter counter = ent.getValue();
+ reasons.add(new TimerEntry(ent.getKey(), 0, null,
+ ent.getValue().getCountLocked(which)));
+ }
+ Collections.sort(reasons, timerComparator);
+ for (int i=0; i<reasons.size(); i++) {
+ TimerEntry timer = reasons.get(i);
+ String linePrefix = ": ";
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Wakeup reason ");
+ sb.append(timer.mName);
+ sb.append(": ");
+ formatTimeMs(sb, timer.mTime);
+ sb.append("realtime");
+ pw.println(sb.toString());
+ }
+ pw.println();
}
- timers.clear();
- pw.println();
}
for (int iu=0; iu<NU; iu++) {
@@ -2772,6 +2858,7 @@ public abstract class BatteryStats implements Parcelable {
public static class HistoryPrinter {
int oldState = 0;
+ int oldState2 = 0;
int oldLevel = -1;
int oldStatus = -1;
int oldHealth = -1;
@@ -2780,7 +2867,8 @@ public abstract class BatteryStats implements Parcelable {
int oldVolt = -1;
long lastTime = -1;
- public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin) {
+ public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin,
+ boolean verbose) {
if (!checkin) {
pw.print(" ");
if (now >= 0) {
@@ -2831,16 +2919,18 @@ public abstract class BatteryStats implements Parcelable {
if (rec.batteryLevel < 10) pw.print("00");
else if (rec.batteryLevel < 100) pw.print("0");
pw.print(rec.batteryLevel);
- pw.print(" ");
- 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");
- else if (rec.states < 0x100000) pw.print("000");
- else if (rec.states < 0x1000000) pw.print("00");
- else if (rec.states < 0x10000000) pw.print("0");
- pw.print(Integer.toHexString(rec.states));
+ if (verbose) {
+ pw.print(" ");
+ 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");
+ else if (rec.states < 0x100000) pw.print("000");
+ else if (rec.states < 0x1000000) pw.print("00");
+ else if (rec.states < 0x10000000) pw.print("0");
+ pw.print(Integer.toHexString(rec.states));
+ }
} else {
if (oldLevel != rec.batteryLevel) {
oldLevel = rec.batteryLevel;
@@ -2934,6 +3024,8 @@ public abstract class BatteryStats implements Parcelable {
}
printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
HISTORY_STATE_DESCRIPTIONS, !checkin);
+ printBitDescriptions(pw, oldState2, rec.states2, null,
+ HISTORY_STATE2_DESCRIPTIONS, !checkin);
if (rec.wakeReasonTag != null) {
if (checkin) {
pw.print(",Wr=");
@@ -3010,6 +3102,7 @@ public abstract class BatteryStats implements Parcelable {
public static final int DUMP_CHARGED_ONLY = 1<<1;
public static final int DUMP_HISTORY_ONLY = 1<<2;
public static final int DUMP_INCLUDE_HISTORY = 1<<3;
+ public static final int DUMP_VERBOSE = 1<<4;
/**
* Dumps a human-readable summary of the battery statistics to the given PrintWriter.
@@ -3047,7 +3140,8 @@ public abstract class BatteryStats implements Parcelable {
while (getNextHistoryLocked(rec)) {
lastTime = rec.time;
if (rec.time >= histStart) {
- hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false);
+ hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false,
+ (flags&DUMP_VERBOSE) != 0);
}
}
if (histStart >= 0) {
@@ -3064,7 +3158,7 @@ public abstract class BatteryStats implements Parcelable {
pw.println("Old battery History:");
HistoryPrinter hprinter = new HistoryPrinter();
while (getNextOldHistoryLocked(rec)) {
- hprinter.printNextItem(pw, rec, now, false);
+ hprinter.printNextItem(pw, rec, now, false, (flags&DUMP_VERBOSE) != 0);
}
pw.println();
} finally {
@@ -3150,7 +3244,7 @@ public abstract class BatteryStats implements Parcelable {
if (rec.time >= histStart) {
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
pw.print(HISTORY_DATA); pw.print(',');
- hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true);
+ hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true, false);
}
}
if (histStart >= 0) {
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 5ba5c57ab90d..32f700d4517d 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -55,7 +55,7 @@ interface IBatteryStats {
void noteScreenOff();
void noteInputEvent();
void noteUserActivity(int uid, int event);
- void noteDataConnectionActive(int type, boolean active);
+ void noteDataConnectionActive(int type, boolean active, long timestampNs);
void notePhoneOn();
void notePhoneOff();
void notePhoneSignalStrength(in SignalStrength signalStrength);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 082f1a583763..1d885338cea3 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -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 = 99 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 101 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -191,7 +191,7 @@ public final class BatteryStatsImpl extends BatteryStats {
long mHistoryBaseTime;
boolean mHaveBatteryLevel = false;
- boolean mRecordingHistory = true;
+ boolean mRecordingHistory = false;
int mNumHistoryItems;
static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
@@ -200,6 +200,7 @@ public final class BatteryStatsImpl extends BatteryStats {
final HistoryItem mHistoryLastWritten = new HistoryItem();
final HistoryItem mHistoryLastLastWritten = new HistoryItem();
final HistoryItem mHistoryReadTmp = new HistoryItem();
+ final HistoryItem mHistoryAddTmp = new HistoryItem();
final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>();
String[] mReadHistoryStrings;
int[] mReadHistoryUids;
@@ -209,7 +210,8 @@ public final class BatteryStatsImpl extends BatteryStats {
int mHistoryBufferLastPos = -1;
boolean mHistoryOverflow = false;
long mLastHistoryElapsedRealtime = 0;
- long mLastHistoryUptime = 0;
+ long mTrackRunningHistoryElapsedRealtime = 0;
+ long mTrackRunningHistoryUptime = 0;
final HistoryItem mHistoryCur = new HistoryItem();
@@ -287,6 +289,7 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mMobileRadioActive;
StopwatchTimer mMobileRadioActiveTimer;
StopwatchTimer mMobileRadioActivePerAppTimer;
+ LongSamplingCounter mMobileRadioActiveAdjustedTime;
LongSamplingCounter mMobileRadioActiveUnknownTime;
LongSamplingCounter mMobileRadioActiveUnknownCount;
@@ -330,12 +333,21 @@ public final class BatteryStatsImpl extends BatteryStats {
private final HashMap<String, SamplingTimer> mKernelWakelockStats =
new HashMap<String, SamplingTimer>();
- public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
+ public Map<String, ? extends Timer> getKernelWakelockStats() {
return mKernelWakelockStats;
}
private static int sKernelWakelockUpdateVersion = 0;
+ String mLastWakeupReason = null;
+ long mLastWakeupUptimeMs = 0;
+ private final HashMap<String, LongSamplingCounter> mWakeupReasonStats =
+ new HashMap<String, LongSamplingCounter>();
+
+ public Map<String, ? extends LongCounter> getWakeupReasonStats() {
+ return mWakeupReasonStats;
+ }
+
private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
Process.PROC_QUOTES,
@@ -719,7 +731,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public static class LongSamplingCounter implements TimeBaseObs {
+ public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
final TimeBase mTimeBase;
long mCount;
long mLoadedCount;
@@ -775,6 +787,14 @@ public final class BatteryStatsImpl extends BatteryStats {
return val;
}
+ @Override
+ public void logState(Printer pw, String prefix) {
+ pw.println(prefix + "mCount=" + mCount
+ + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+ + " mUnpluggedCount=" + mUnpluggedCount
+ + " mPluggedCount=" + mPluggedCount);
+ }
+
void addCountLocked(long count) {
mCount += count;
}
@@ -1409,6 +1429,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return 0;
}
+ long getLastUpdateTimeMs() {
+ return mUpdateTime;
+ }
+
void stopRunningLocked(long elapsedRealtimeMs) {
// Ignore attempt to stop a timer that isn't running
if (mNesting == 0) {
@@ -1502,6 +1526,19 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ /*
+ * Get the wakeup reason counter, and create a new one if one
+ * doesn't already exist.
+ */
+ public LongSamplingCounter getWakeupReasonCounterLocked(String name) {
+ LongSamplingCounter counter = mWakeupReasonStats.get(name);
+ if (counter == null) {
+ counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
+ mWakeupReasonStats.put(name, counter);
+ }
+ return counter;
+ }
+
private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
FileInputStream is;
@@ -1759,6 +1796,10 @@ public final class BatteryStatsImpl extends BatteryStats {
if (stateIntChanged) {
firstToken |= DELTA_STATE_FLAG;
}
+ final boolean state2IntChanged = cur.states2 != last.states2;
+ if (state2IntChanged) {
+ firstToken |= DELTA_STATE2_FLAG;
+ }
if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
firstToken |= DELTA_WAKELOCK_FLAG;
}
@@ -1795,6 +1836,11 @@ public final class BatteryStatsImpl extends BatteryStats {
+ " batteryPlugType=" + cur.batteryPlugType
+ " states=0x" + Integer.toHexString(cur.states));
}
+ if (state2IntChanged) {
+ dest.writeInt(cur.states2);
+ if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
+ + Integer.toHexString(cur.states2));
+ }
if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
int wakeLockIndex;
int wakeReasonIndex;
@@ -1917,6 +1963,12 @@ public final class BatteryStatsImpl extends BatteryStats {
cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
}
+ if ((firstToken&DELTA_STATE2_FLAG) != 0) {
+ cur.states2 = src.readInt();
+ if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
+ + Integer.toHexString(cur.states2));
+ }
+
if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
int indexes = src.readInt();
int wakeLockIndex = indexes&0xffff;
@@ -1958,29 +2010,34 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs) {
+ void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
if (!mHaveBatteryLevel || !mRecordingHistory) {
return;
}
final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
- final int diffStates = mHistoryLastWritten.states^mHistoryCur.states;
+ final int diffStates = mHistoryLastWritten.states^cur.states;
+ final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
+ final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
+ Integer.toHexString(diffStates) + " lastDiff="
- + Integer.toHexString(lastDiffStates));
+ + Integer.toHexString(lastDiffStates) + " diff2="
+ + Integer.toHexString(diffStates2) + " lastDiff2="
+ + Integer.toHexString(lastDiffStates2));
if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
&& timeDiff < 1000 && (diffStates&lastDiffStates) == 0
- && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null)
- && (mHistoryLastWritten.wakeReasonTag == null || mHistoryCur.wakeReasonTag == null)
+ && (diffStates2&lastDiffStates2) == 0
+ && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
+ && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
&& (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
- || mHistoryCur.eventCode == HistoryItem.EVENT_NONE)
- && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel
- && mHistoryLastWritten.batteryStatus == mHistoryCur.batteryStatus
- && mHistoryLastWritten.batteryHealth == mHistoryCur.batteryHealth
- && mHistoryLastWritten.batteryPlugType == mHistoryCur.batteryPlugType
- && mHistoryLastWritten.batteryTemperature == mHistoryCur.batteryTemperature
- && mHistoryLastWritten.batteryVoltage == mHistoryCur.batteryVoltage) {
+ || cur.eventCode == HistoryItem.EVENT_NONE)
+ && mHistoryLastWritten.batteryLevel == cur.batteryLevel
+ && mHistoryLastWritten.batteryStatus == cur.batteryStatus
+ && mHistoryLastWritten.batteryHealth == cur.batteryHealth
+ && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
+ && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
+ && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
// We can merge this new change in with the last one. Merging is
// allowed as long as only the states have changed, and within those states
// as long as no bit has changed both between now and the last entry, as
@@ -1994,23 +2051,23 @@ public final class BatteryStatsImpl extends BatteryStats {
// Note that the condition above made sure that we aren't in a case where
// both it and the current history item have a wakelock tag.
if (mHistoryLastWritten.wakelockTag != null) {
- mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
- mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
+ cur.wakelockTag = cur.localWakelockTag;
+ cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
}
// If the last written history had a wake reason tag, 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 a wakelock tag.
if (mHistoryLastWritten.wakeReasonTag != null) {
- mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
- mHistoryCur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
+ cur.wakeReasonTag = cur.localWakeReasonTag;
+ cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
}
// 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);
+ cur.eventCode = mHistoryLastWritten.eventCode;
+ cur.eventTag = cur.localEventTag;
+ cur.eventTag.setTo(mHistoryLastWritten.eventTag);
}
mHistoryLastWritten.setTo(mHistoryLastLastWritten);
}
@@ -2019,8 +2076,8 @@ public final class BatteryStatsImpl extends BatteryStats {
if (dataSize >= MAX_HISTORY_BUFFER) {
if (!mHistoryOverflow) {
mHistoryOverflow = true;
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW);
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
return;
}
@@ -2028,43 +2085,64 @@ public final class BatteryStatsImpl extends BatteryStats {
// record changes to the battery level and the most interesting states.
// Once we've reached the maximum maximum number of items, we only
// record changes to the battery level.
- if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
+ if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
(dataSize >= MAX_MAX_HISTORY_BUFFER
- || ((mHistoryLastWritten.states^mHistoryCur.states)
+ || ((mHistoryLastWritten.states^cur.states)
& HistoryItem.MOST_INTERESTING_STATES) == 0)) {
return;
}
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
return;
}
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE);
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
}
- private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) {
+ private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
+ HistoryItem cur) {
if (mIteratingHistory) {
throw new IllegalStateException("Can't do this while iterating history!");
}
mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
mHistoryLastLastWritten.setTo(mHistoryLastWritten);
- mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur);
+ mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
mLastHistoryElapsedRealtime = elapsedRealtimeMs;
- mLastHistoryUptime = uptimeMs;
- mHistoryCur.wakelockTag = null;
- mHistoryCur.wakeReasonTag = null;
- mHistoryCur.eventCode = HistoryItem.EVENT_NONE;
- mHistoryCur.eventTag = null;
+ cur.wakelockTag = null;
+ cur.wakeReasonTag = null;
+ cur.eventCode = HistoryItem.EVENT_NONE;
+ cur.eventTag = null;
if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
+ " now " + mHistoryBuffer.dataPosition()
+ " size is now " + mHistoryBuffer.dataSize());
}
int mChangedStates = 0;
+ int mChangedStates2 = 0;
void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs);
+ if (mTrackRunningHistoryElapsedRealtime != 0) {
+ final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
+ final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
+ if (diffUptime < (diffElapsed-20)) {
+ final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
+ mHistoryAddTmp.setTo(mHistoryLastWritten);
+ mHistoryAddTmp.wakelockTag = null;
+ mHistoryAddTmp.wakeReasonTag = null;
+ mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
+ mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
+ addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
+ }
+ }
+ mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
+ mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
+ mTrackRunningHistoryUptime = uptimeMs;
+ addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
+ }
+
+ void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
if (!USE_OLD_HISTORY) {
return;
@@ -2080,25 +2158,28 @@ public final class BatteryStatsImpl extends BatteryStats {
// into one record.
if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
&& (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
- && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
+ && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
+ && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
// If the current is the same as the one before, then we no
// longer need the entry.
if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
&& (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
- && mHistoryLastEnd.sameNonEvent(mHistoryCur)) {
+ && mHistoryLastEnd.sameNonEvent(cur)) {
mHistoryLastEnd.next = null;
mHistoryEnd.next = mHistoryCache;
mHistoryCache = mHistoryEnd;
mHistoryEnd = mHistoryLastEnd;
mHistoryLastEnd = null;
} else {
- mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
- mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
+ mChangedStates |= mHistoryEnd.states^cur.states;
+ mChangedStates2 |= mHistoryEnd.states^cur.states2;
+ mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
}
return;
}
mChangedStates = 0;
+ mChangedStates2 = 0;
if (mNumHistoryItems == MAX_HISTORY_ITEMS
|| mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
@@ -2111,9 +2192,9 @@ public final class BatteryStatsImpl extends BatteryStats {
// Once we've reached the maximum maximum number of items, we only
// record changes to the battery level.
if (mHistoryEnd != null && mHistoryEnd.batteryLevel
- == mHistoryCur.batteryLevel &&
+ == cur.batteryLevel &&
(mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
- || ((mHistoryEnd.states^mHistoryCur.states)
+ || ((mHistoryEnd.states^cur.states)
& HistoryItem.MOST_INTERESTING_STATES) == 0)) {
return;
}
@@ -2128,17 +2209,18 @@ public final class BatteryStatsImpl extends BatteryStats {
mHistoryCur.eventTag = mHistoryCur.localEventTag;
mHistoryCur.eventTag.string = name;
mHistoryCur.eventTag.uid = uid;
- addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs);
+ // XXX should be calling addHistoryRecordLocked()?
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
}
- void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) {
+ void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
HistoryItem rec = mHistoryCache;
if (rec != null) {
mHistoryCache = rec.next;
} else {
rec = new HistoryItem();
}
- rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur);
+ rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
addHistoryRecordLocked(rec);
}
@@ -2168,7 +2250,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mHistoryBaseTime = 0;
mLastHistoryElapsedRealtime = 0;
- mLastHistoryUptime = 0;
+ mTrackRunningHistoryElapsedRealtime = 0;
+ mTrackRunningHistoryUptime = 0;
mHistoryBuffer.setDataSize(0);
mHistoryBuffer.setDataPosition(0);
@@ -2284,6 +2367,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (type == WAKE_TYPE_PARTIAL) {
// Only care about partial wake locks, since full wake locks
// will be canceled when the user puts the screen to sleep.
+ aggregateLastWakeupUptimeLocked(uptime);
if (mWakeLockNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
@@ -2372,14 +2456,26 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public void noteWakeupReasonLocked(int irq, String reason) {
+ void aggregateLastWakeupUptimeLocked(long uptimeMs) {
+ if (mLastWakeupReason != null) {
+ long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
+ LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason);
+ timer.addCountLocked(deltaUptime);
+ mLastWakeupReason = null;
+ }
+ }
+
+ public void noteWakeupReasonLocked(String reason) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
- if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason irq #" + irq + "\"" + reason +"\": "
+ if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": "
+ Integer.toHexString(mHistoryCur.states));
+ aggregateLastWakeupUptimeLocked(uptime);
mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
mHistoryCur.wakeReasonTag.string = reason;
- mHistoryCur.wakeReasonTag.uid = irq;
+ mHistoryCur.wakeReasonTag.uid = 0;
+ mLastWakeupReason = reason;
+ mLastWakeupUptimeMs = uptime;
addHistoryRecordLocked(elapsedRealtime, uptime);
}
@@ -2670,13 +2766,28 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public void noteDataConnectionActive(int type, boolean active) {
+ public void noteDataConnectionActive(int type, boolean active, long timestampNs) {
if (ConnectivityManager.isNetworkTypeMobile(type)) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
if (mMobileRadioActive != active) {
- if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
- else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+ long realElapsedRealtimeMs;
+ if (active) {
+ realElapsedRealtimeMs = elapsedRealtime;
+ mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+ } else {
+ realElapsedRealtimeMs = timestampNs / (1000*1000);
+ long lastUpdateTimeMs = mMobileRadioActiveTimer.getLastUpdateTimeMs();
+ if (realElapsedRealtimeMs < lastUpdateTimeMs) {
+ Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
+ + " is before start time " + lastUpdateTimeMs);
+ realElapsedRealtimeMs = elapsedRealtime;
+ } else if (realElapsedRealtimeMs < elapsedRealtime) {
+ mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
+ - realElapsedRealtimeMs);
+ }
+ 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, uptime);
@@ -2685,9 +2796,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
} else {
- updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
- mMobileRadioActiveTimer.stopRunningLocked(elapsedRealtime);
- mMobileRadioActivePerAppTimer.stopRunningLocked(elapsedRealtime);
+ mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
+ mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
+ updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs);
}
}
}
@@ -2978,7 +3089,7 @@ public final class BatteryStatsImpl extends BatteryStats {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
if (!mVideoOn) {
- mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
+ mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -2993,7 +3104,7 @@ public final class BatteryStatsImpl extends BatteryStats {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
if (mVideoOn) {
- mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
@@ -3398,6 +3509,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return mMobileRadioActiveTimer.getCountLocked(which);
}
+ @Override public long getMobileRadioActiveAdjustedTime(int which) {
+ return mMobileRadioActiveAdjustedTime.getCountLocked(which);
+ }
+
@Override public long getMobileRadioActiveUnknownTime(int which) {
return mMobileRadioActiveUnknownTime.getCountLocked(which);
}
@@ -5458,6 +5573,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
+ mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
mWifiOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
@@ -5543,9 +5659,9 @@ public final class BatteryStatsImpl extends BatteryStats {
PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
pw.println("Histories differ!");
pw.println("Old history:");
- (new HistoryPrinter()).printNextItem(pw, out, now, false);
+ (new HistoryPrinter()).printNextItem(pw, out, now, false, true);
pw.println("New history:");
- (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false);
+ (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false, true);
pw.flush();
}
}
@@ -5719,6 +5835,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActiveTimer.reset(false);
mMobileRadioActivePerAppTimer.reset(false);
+ mMobileRadioActiveAdjustedTime.reset(false);
mMobileRadioActiveUnknownTime.reset(false);
mMobileRadioActiveUnknownCount.reset(false);
mWifiOnTimer.reset(false);
@@ -5744,7 +5861,14 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mKernelWakelockStats.clear();
}
-
+
+ if (mWakeupReasonStats.size() > 0) {
+ for (LongSamplingCounter timer : mWakeupReasonStats.values()) {
+ mOnBatteryScreenOffTimeBase.remove(timer);
+ }
+ mWakeupReasonStats.clear();
+ }
+
initDischarge();
clearHistoryLocked();
@@ -5828,9 +5952,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
+ Integer.toHexString(mHistoryCur.states));
- mHistoryCur.currentTime = System.currentTimeMillis();
- addHistoryBufferLocked(mSecRealtime, mSecUptime, HistoryItem.CMD_CURRENT_TIME);
- mHistoryCur.currentTime = 0;
+ if (reset) {
+ mRecordingHistory = true;
+ startRecordingHistory(mSecRealtime, mSecUptime, reset);
+ }
addHistoryRecordLocked(mSecRealtime, mSecUptime);
mDischargeCurrentLevel = mDischargeUnplugLevel = level;
if (mScreenOn) {
@@ -5843,9 +5968,6 @@ public final class BatteryStatsImpl extends BatteryStats {
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenOff = 0;
updateTimeBasesLocked(true, !mScreenOn, uptime, realtime);
- if (reset) {
- initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
- }
} else {
pullPendingStateUpdatesLocked();
mHistoryCur.batteryLevel = (byte)level;
@@ -5868,6 +5990,18 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
+ boolean reset) {
+ mRecordingHistory = true;
+ mHistoryCur.currentTime = System.currentTimeMillis();
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
+ mHistoryCur);
+ mHistoryCur.currentTime = 0;
+ if (reset) {
+ initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
+ }
+ }
+
// This should probably be exposed in the API, though it's not critical
private static final int BATTERY_PLUGGED_NONE = 0;
@@ -5895,7 +6029,15 @@ public final class BatteryStatsImpl extends BatteryStats {
}
if (onBattery) {
mDischargeCurrentLevel = level;
- mRecordingHistory = true;
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtime, uptime, true);
+ }
+ } else if (level < 96) {
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtime, uptime, true);
+ }
}
if (onBattery != mOnBattery) {
mHistoryCur.batteryLevel = (byte)level;
@@ -6497,15 +6639,14 @@ public final class BatteryStatsImpl extends BatteryStats {
}
if (mHistoryBuffer.dataPosition() > 0) {
+ mRecordingHistory = true;
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
if (USE_OLD_HISTORY) {
- addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START);
+ addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
}
- addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START);
- mHistoryCur.currentTime = System.currentTimeMillis();
- addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_CURRENT_TIME);
- mHistoryCur.currentTime = 0;
+ addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
+ startRecordingHistory(elapsedRealtime, uptime, false);
}
}
@@ -6681,6 +6822,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mMobileRadioActive = false;
mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
+ mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
mWifiOn = false;
@@ -6708,6 +6850,18 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ int NWR = in.readInt();
+ if (NWR > 10000) {
+ Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
+ return;
+ }
+ for (int iwr = 0; iwr < NWR; iwr++) {
+ if (in.readInt() != 0) {
+ String reasonName = in.readString();
+ getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in);
+ }
+ }
+
sNumSpeedSteps = in.readInt();
if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
@@ -6915,6 +7069,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -6933,7 +7088,19 @@ public final class BatteryStatsImpl extends BatteryStats {
if (kwlt != null) {
out.writeInt(1);
out.writeString(ent.getKey());
- ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ out.writeInt(mWakeupReasonStats.size());
+ for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
+ LongSamplingCounter counter = ent.getValue();
+ if (counter != null) {
+ out.writeInt(1);
+ out.writeString(ent.getKey());
+ counter.writeSummaryFromParcelLocked(out);
} else {
out.writeInt(0);
}
@@ -7171,6 +7338,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
in);
+ mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
mWifiOn = false;
@@ -7205,12 +7373,22 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int ikw = 0; ikw < NKW; ikw++) {
if (in.readInt() != 0) {
String wakelockName = in.readString();
- in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in);
mKernelWakelockStats.put(wakelockName, kwlt);
}
}
+ mWakeupReasonStats.clear();
+ int NWR = in.readInt();
+ for (int iwr = 0; iwr < NWR; iwr++) {
+ if (in.readInt() != 0) {
+ String reasonName = in.readString();
+ LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase,
+ in);
+ mWakeupReasonStats.put(reasonName, counter);
+ }
+ }
+
mPartialTimers.clear();
mFullTimers.clear();
mWindowTimers.clear();
@@ -7283,6 +7461,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
+ mMobileRadioActiveAdjustedTime.writeToParcel(out);
mMobileRadioActiveUnknownTime.writeToParcel(out);
mMobileRadioActiveUnknownCount.writeToParcel(out);
mWifiOnTimer.writeToParcel(out, uSecRealtime);
@@ -7313,7 +7492,18 @@ public final class BatteryStatsImpl extends BatteryStats {
if (kwlt != null) {
out.writeInt(1);
out.writeString(ent.getKey());
- Timer.writeTimerToParcel(out, kwlt, uSecRealtime);
+ kwlt.writeToParcel(out, uSecRealtime);
+ } else {
+ out.writeInt(0);
+ }
+ }
+ out.writeInt(mWakeupReasonStats.size());
+ for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
+ LongSamplingCounter counter = ent.getValue();
+ if (counter != null) {
+ out.writeInt(1);
+ out.writeString(ent.getKey());
+ counter.writeToParcel(out);
} else {
out.writeInt(0);
}
@@ -7383,6 +7573,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
pr.println("*** Mobile network active timer:");
mMobileRadioActiveTimer.logState(pr, " ");
+ pr.println("*** Mobile network active adjusted timer:");
+ mMobileRadioActiveAdjustedTime.logState(pr, " ");
pr.println("*** Wifi timer:");
mWifiOnTimer.logState(pr, " ");
pr.println("*** WifiRunning timer:");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index c5e325e7829a..cdbee8299d44 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -29,45 +29,73 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
import android.util.LruCache;
+import android.util.Pair;
import com.android.systemui.recents.model.SpaceNode;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
/** A bitmap load queue */
class TaskResourceLoadQueue {
ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>();
+ ConcurrentHashMap<Task.TaskKey, Boolean> mForceLoadSet =
+ new ConcurrentHashMap<Task.TaskKey, Boolean>();
- Task nextTask() {
- Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|nextTask]");
- return mQueue.poll();
- }
+ static final Boolean sFalse = new Boolean(false);
- void addTask(Task t) {
+ /** Adds a new task to the load queue */
+ void addTask(Task t, boolean forceLoad) {
Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|addTask]");
if (!mQueue.contains(t)) {
mQueue.add(t);
}
+ if (forceLoad) {
+ mForceLoadSet.put(t.key, new Boolean(true));
+ }
synchronized(this) {
notifyAll();
}
}
+ /**
+ * Retrieves the next task from the load queue, as well as whether we want that task to be
+ * force reloaded.
+ */
+ Pair<Task, Boolean> nextTask() {
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|nextTask]");
+ Task task = mQueue.poll();
+ Boolean forceLoadTask = null;
+ if (task != null) {
+ forceLoadTask = mForceLoadSet.remove(task.key);
+ }
+ if (forceLoadTask == null) {
+ forceLoadTask = sFalse;
+ }
+ return new Pair<Task, Boolean>(task, forceLoadTask);
+ }
+
+ /** Removes a task from the load queue */
void removeTask(Task t) {
Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|removeTask]");
mQueue.remove(t);
+ mForceLoadSet.remove(t.key);
}
+ /** Clears all the tasks from the load queue */
void clearTasks() {
Console.log(Constants.DebugFlags.App.TaskDataLoader, " [TaskResourceLoadQueue|clearTasks]");
mQueue.clear();
+ mForceLoadSet.clear();
}
+ /** Returns whether the load queue is empty */
boolean isEmpty() {
return mQueue.isEmpty();
}
@@ -147,16 +175,19 @@ class TaskResourceLoader implements Runnable {
}
} else {
// Load the next item from the queue
- final Task t = mLoadQueue.nextTask();
+ Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();
+ final Task t = nextTaskData.first;
+ final boolean forceLoadTask = nextTaskData.second;
if (t != null) {
try {
Drawable loadIcon = mIconCache.get(t.key);
Bitmap loadThumbnail = mThumbnailCache.get(t.key);
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [TaskResourceLoader|load]",
- t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail);
+ t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
+ " forceLoad: " + forceLoadTask);
// Load the icon
- if (loadIcon == null) {
+ if (loadIcon == null || forceLoadTask) {
PackageManager pm = mContext.getPackageManager();
ActivityInfo info = pm.getActivityInfo(t.key.intent.getComponent(),
PackageManager.GET_META_DATA);
@@ -172,7 +203,7 @@ class TaskResourceLoader implements Runnable {
}
}
// Load the thumbnail
- if (loadThumbnail == null) {
+ if (loadThumbnail == null || forceLoadTask) {
ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id);
@@ -197,7 +228,7 @@ class TaskResourceLoader implements Runnable {
mMainThreadHandler.post(new Runnable() {
@Override
public void run() {
- t.notifyTaskDataLoaded(newThumbnail, newIcon);
+ t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask);
}
});
}
@@ -329,9 +360,11 @@ public class RecentsTaskLoader {
/** Reload the set of recent tasks */
SpaceNode reload(Context context, int preloadCount) {
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
+ ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
TaskStack stack = new TaskStack(context);
SpaceNode root = new SpaceNode(context);
root.setStack(stack);
+
try {
long t1 = System.currentTimeMillis();
@@ -387,6 +420,12 @@ public class RecentsTaskLoader {
// Load the icon (if possible and not the foremost task, from the cache)
if (!isForemostTask) {
task.icon = mIconCache.get(task.key);
+
+ if (task.icon != null) {
+ // Even though we get things from the cache, we should update them if
+ // they've changed in the bg
+ tasksToForceLoad.add(task);
+ }
}
if (task.icon == null) {
task.icon = info.loadIcon(pm);
@@ -400,6 +439,12 @@ public class RecentsTaskLoader {
// Load the thumbnail (if possible and not the foremost task, from the cache)
if (!isForemostTask) {
task.thumbnail = mThumbnailCache.get(task.key);
+
+ if (task.thumbnail != null) {
+ // Even though we get things from the cache, we should update them if
+ // they've changed in the bg
+ tasksToForceLoad.add(task);
+ }
}
if (task.thumbnail == null) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
@@ -451,6 +496,11 @@ public class RecentsTaskLoader {
// Start the task loader
mLoader.start(context);
+ // Add all the tasks that we are force/re-loading
+ for (Task t : tasksToForceLoad) {
+ mLoadQueue.addTask(t, true);
+ }
+
return root;
}
@@ -473,9 +523,9 @@ public class RecentsTaskLoader {
requiresLoad = true;
}
if (requiresLoad) {
- mLoadQueue.addTask(t);
+ mLoadQueue.addTask(t, false);
}
- t.notifyTaskDataLoaded(thumbnail, icon);
+ t.notifyTaskDataLoaded(thumbnail, icon, false);
}
/** Releases the task resource data back into the pool. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 0c3c528b223d..edcf9b2edef8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -29,7 +29,7 @@ public class Task {
/* Task callbacks */
public interface TaskCallbacks {
/* Notifies when a task has been bound */
- public void onTaskDataLoaded();
+ public void onTaskDataLoaded(boolean reloadingTaskData);
/* Notifies when a task has been unbound */
public void onTaskDataUnloaded();
}
@@ -84,11 +84,11 @@ public class Task {
}
/** Notifies the callback listeners that this task has been loaded */
- public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon) {
+ public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon, boolean reloadingTaskData) {
this.icon = icon;
this.thumbnail = thumbnail;
if (mCb != null) {
- mCb.onTaskDataLoaded();
+ mCb.onTaskDataLoaded(reloadingTaskData);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 62cf394c2855..2b27a060ffa2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -881,6 +881,13 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
}
break;
}
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ final int index = ev.getActionIndex();
+ mActivePointerId = ev.getPointerId(index);
+ mLastMotionX = (int) ev.getX(index);
+ mLastMotionY = (int) ev.getY(index);
+ break;
+ }
case MotionEvent.ACTION_MOVE: {
if (mActivePointerId == INACTIVE_POINTER_ID) break;
@@ -957,6 +964,19 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
recycleVelocityTracker();
break;
}
+ case MotionEvent.ACTION_POINTER_UP: {
+ int pointerIndex = ev.getActionIndex();
+ int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // Select a new active pointer id and reset the motion state
+ final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ mLastMotionX = (int) ev.getX(newPointerIndex);
+ mLastMotionY = (int) ev.getY(newPointerIndex);
+ mVelocityTracker.clear();
+ }
+ break;
+ }
case MotionEvent.ACTION_CANCEL: {
if (mIsScrolling) {
// Disable HW layers
@@ -1006,10 +1026,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
Task task = tv.getTask();
Activity activity = (Activity) mSv.getContext();
- // We have to disable the listener to ensure that we
- // don't hit this again
- tv.animate().setListener(null);
-
// Remove the task from the view
mSv.mStack.removeTask(task);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index f41171792d87..e6dce37555b1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -65,10 +65,7 @@ class TaskThumbnailView extends ImageView {
setImageBitmap(t.thumbnail);
if (animate) {
- setAlpha(0f);
- animate().alpha(1f)
- .setDuration(Constants.Values.TaskView.Animation.TaskDataUpdatedFadeDuration)
- .start();
+ // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
}
}
@@ -143,10 +140,7 @@ class TaskIconView extends ImageView {
if (t.icon != null) {
setImageDrawable(t.icon);
if (animate) {
- setAlpha(0f);
- animate().alpha(1f)
- .setDuration(Constants.Values.TaskView.Animation.TaskDataUpdatedFadeDuration)
- .start();
+ // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
}
}
@@ -311,6 +305,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
.translationY(0)
.setStartDelay(235)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
+ .withLayer()
.start();
}
}
@@ -333,13 +328,8 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
.setStartDelay(0)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
.setInterpolator(new DecelerateInterpolator())
- .setListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- r.run();
- }
- })
+ .withLayer()
+ .withEndAction(r)
.start();
}
}
@@ -379,10 +369,10 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
}
@Override
- public void onTaskDataLoaded() {
+ public void onTaskDataLoaded(boolean reloadingTaskData) {
// Bind each of the views to the new task data
- mThumbnailView.rebindToTask(mTask, false);
- mIconView.rebindToTask(mTask, false);
+ mThumbnailView.rebindToTask(mTask, reloadingTaskData);
+ mIconView.rebindToTask(mTask, reloadingTaskData);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 034edf947790..68c8364addd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -757,6 +757,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void toggleRecentsActivity() {
if (mRecents != null) {
+ sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS);
mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView());
}
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 9de3efee3db6..41ffdc18ef13 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -103,6 +103,7 @@ class AlarmManagerService extends SystemService {
private long mNextNonWakeup;
int mBroadcastRefCount = 0;
PowerManager.WakeLock mWakeLock;
+ boolean mLastWakeLockUnimportantForLogging;
ArrayList<InFlight> mInFlight = new ArrayList<InFlight>();
final AlarmHandler mHandler = new AlarmHandler();
ClockReceiver mClockReceiver;
@@ -1345,17 +1346,21 @@ class AlarmManagerService extends SystemService {
*/
void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) {
try {
- mWakeLock.setUnimportantForLogging(pi == mTimeTickSender);
+ final boolean unimportant = pi == mTimeTickSender;
+ mWakeLock.setUnimportantForLogging(unimportant);
if (ws != null) {
- if (first) {
+ if (first || mLastWakeLockUnimportantForLogging) {
mWakeLock.setHistoryTag(pi.getTag(
type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
? "*walarm*:" : "*alarm*:"));
} else {
mWakeLock.setHistoryTag(null);
}
+ mLastWakeLockUnimportantForLogging = unimportant;
mWakeLock.setWorkSource(ws);
return;
+ } else {
+ mLastWakeLockUnimportantForLogging = false;
}
final int uid = ActivityManagerNative.getDefault()
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index a09d6059f281..5273cec092c8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -348,7 +348,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
*/
private void notifyInterfaceClassActivity(int type, boolean active, long tsNanos) {
try {
- getBatteryStats().noteDataConnectionActive(type, active);
+ getBatteryStats().noteDataConnectionActive(type, active, tsNanos);
} catch (RemoteException e) {
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index fa4a9d12feeb..0ddb8272cd5e 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -248,10 +248,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
- public void noteDataConnectionActive(int type, boolean active) {
+ public void noteDataConnectionActive(int type, boolean active, long timestampNs) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteDataConnectionActive(type, active);
+ mStats.noteDataConnectionActive(type, active, timestampNs);
}
}
@@ -570,9 +570,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
int num;
while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
synchronized (mStats) {
- for (int i=0; i<num; i++) {
- //Slog.i(TAG, "Wakeup: irq #" + mIrqs[i] + " reason=" + mReasons[i]);
- mStats.noteWakeupReasonLocked(mIrqs[i], mReasons[i]);
+ if (num > 0) {
+ for (int i=0; i<num; i++) {
+ mStats.noteWakeupReasonLocked(mReasons[i]);
+ }
+ } else {
+ mStats.noteWakeupReasonLocked("unknown");
}
}
}
@@ -653,7 +656,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
dumpHelp(pw);
return;
} else if ("-a".equals(arg)) {
- // fall through
+ flags |= BatteryStats.DUMP_VERBOSE;
} else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
dumpHelp(pw);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cb4cf982ca00..a01c58627826 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -200,6 +200,9 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final boolean GET_CERTIFICATES = true;
+ // Cap the size of permission trees that 3rd party apps can define
+ private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text
+
private static final int REMOVE_EVENTS =
FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
private static final int ADD_EVENTS =
@@ -2357,7 +2360,35 @@ public class PackageManagerService extends IPackageManager.Stub {
//if (pi1.descriptionRes != pi2.descriptionRes) return false;
return true;
}
-
+
+ int permissionInfoFootprint(PermissionInfo info) {
+ int size = info.name.length();
+ if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
+ if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
+ return size;
+ }
+
+ int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
+ int size = 0;
+ for (BasePermission perm : mSettings.mPermissions.values()) {
+ if (perm.uid == tree.uid) {
+ size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
+ }
+ }
+ return size;
+ }
+
+ void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
+ // We calculate the max size of permissions defined by this uid and throw
+ // if that plus the size of 'info' would exceed our stated maximum.
+ if (tree.uid != Process.SYSTEM_UID) {
+ final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
+ if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
+ throw new SecurityException("Permission tree size cap exceeded");
+ }
+ }
+ }
+
boolean addPermissionLocked(PermissionInfo info, boolean async) {
if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
throw new SecurityException("Label must be specified in permission");
@@ -2368,6 +2399,7 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean changed = true;
int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
if (added) {
+ enforcePermissionCapLocked(info, tree);
bp = new BasePermission(info.name, tree.sourcePackage,
BasePermission.TYPE_DYNAMIC);
} else if (bp.type != BasePermission.TYPE_DYNAMIC) {
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 22cc5191b4b8..da4cc48793ab 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -139,16 +139,21 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
}
endpos++;
}
- if (i == 0) {
+ // For now we are not separating out the first irq.
+ // This is because in practice there are always multiple
+ // lines of wakeup reasons, so it is better to just treat
+ // them all together as a single string.
+ if (false && i == 0) {
firstirq = irq;
} else {
- int len = snprintf(mergedreasonpos, remainreasonlen, ":%d", irq);
+ int len = snprintf(mergedreasonpos, remainreasonlen,
+ i == 0 ? "%d" : ":%d", irq);
if (len >= 0 && len < remainreasonlen) {
mergedreasonpos += len;
remainreasonlen -= len;
}
}
- int len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%s" : ":%s", pos);
+ int len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
if (len >= 0 && len < remainreasonlen) {
mergedreasonpos += len;
remainreasonlen -= len;