diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-02-05 13:38:56 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2014-02-05 16:40:51 -0800 |
commit | 3d658bf20e2d56e36941e7407deebeec1276fbcf (patch) | |
tree | e30aba466e8ec0739292ebd6396594c35bcb80e0 /services/core/java | |
parent | e8d916c04c3fb40667fbacb9b6fd1c775ce00b42 (diff) | |
download | frameworks_base-3d658bf20e2d56e36941e7407deebeec1276fbcf.zip frameworks_base-3d658bf20e2d56e36941e7407deebeec1276fbcf.tar.gz frameworks_base-3d658bf20e2d56e36941e7407deebeec1276fbcf.tar.bz2 |
Improve logging of first wake lock, history size.
We now try to have a better label for the first wake lock
that is acquired in the log. This is done in two ways:
- The alarm manager now sorts the alarms it is going to
execute so that wakeup alarms are first, which are more
important w.r.t. which one should be logged.
- There is a new power manager facility to make a wake lock
as "unimportant for logging," which just means in battery
stats that a wake lock acquired after that can be considered
the actual one to log. This is only used by the alarm manager
to mark its TIME_TICK alarms as unimportant for logging.
Also reworked the battery history code to be cleaner and a bit
smaller. There is no longer a separate EVENT command, instead
the event code and tag are just another thing that can be included
in an UPDATE command.
The bits used in the first history int are also re-arrange, so
that only the ones that really change a fair amount in the state
bits are up at the top and there is no longer space used for
the command code (since now it is always just UPDATE). This
allows us to have more room for the time delta at the bottom,
to better avoid situations where we need to write an int delta.
Change-Id: I1bb860ae5b558a248800b090b03a84fbf7acd68a
Diffstat (limited to 'services/core/java')
4 files changed, 145 insertions, 70 deletions
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); |