diff options
author | Christopher Tate <ctate@google.com> | 2012-04-06 14:19:13 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2012-04-06 14:23:12 -0700 |
commit | c4a07d1caa9befd4fa8165ff05fa5e92480d8e27 (patch) | |
tree | 21b4785e8bad532974031cbb2f580164689ec2bd /services | |
parent | e4d8a5dd42070d919dbd774f24c6684ecf1e350e (diff) | |
download | frameworks_base-c4a07d1caa9befd4fa8165ff05fa5e92480d8e27.zip frameworks_base-c4a07d1caa9befd4fa8165ff05fa5e92480d8e27.tar.gz frameworks_base-c4a07d1caa9befd4fa8165ff05fa5e92480d8e27.tar.bz2 |
Attribute alarm broadcast wakelocks to the sender
Wakelock usage for the purpose of sending an alarm broadcast is now
attributed to the application which posted the alarm, not to the OS.
Bug 5911317
Change-Id: I8cb79c3bd5db467388716ab68285f4ab0bfe468b
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/AlarmManagerService.java | 36 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 11 |
2 files changed, 44 insertions, 3 deletions
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java index 0574405..32ac8e1 100644 --- a/services/java/com/android/server/AlarmManagerService.java +++ b/services/java/com/android/server/AlarmManagerService.java @@ -34,9 +34,9 @@ import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.WorkSource; import android.text.TextUtils; import android.text.format.Time; -import android.util.EventLog; import android.util.Slog; import android.util.TimeUtils; @@ -50,6 +50,7 @@ import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.Map; import java.util.TimeZone; @@ -89,6 +90,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private int mDescriptor; private int mBroadcastRefCount = 0; private PowerManager.WakeLock mWakeLock; + private LinkedList<PendingIntent> mInFlight = new LinkedList<PendingIntent>(); private final AlarmThread mWaitThread = new AlarmThread(); private final AlarmHandler mHandler = new AlarmHandler(); private ClockReceiver mClockReceiver; @@ -668,10 +670,12 @@ class AlarmManagerService extends IAlarmManager.Stub { Intent.EXTRA_ALARM_COUNT, alarm.count), mResultReceiver, mHandler); - // we have an active broadcast so stay awake. + // we have an active broadcast so stay awake. if (mBroadcastRefCount == 0) { + setWakelockWorkSource(alarm.operation); mWakeLock.acquire(); } + mInFlight.add(alarm.operation); mBroadcastRefCount++; BroadcastStats bs = getStatsLocked(alarm.operation); @@ -700,7 +704,22 @@ class AlarmManagerService extends IAlarmManager.Stub { } } } - + + void setWakelockWorkSource(PendingIntent pi) { + try { + final int uid = ActivityManagerNative.getDefault() + .getUidForIntentSender(pi.getTarget()); + if (uid >= 0) { + mWakeLock.setWorkSource(new WorkSource(uid)); + return; + } + } catch (Exception e) { + } + + // Something went wrong; fall back to attributing the lock to the OS + mWakeLock.setWorkSource(null); + } + private class AlarmHandler extends Handler { public static final int ALARM_EVENT = 1; public static final int MINUTE_CHANGE_EVENT = 2; @@ -876,9 +895,20 @@ class AlarmManagerService extends IAlarmManager.Stub { fs.count++; } } + mInFlight.removeFirst(); mBroadcastRefCount--; if (mBroadcastRefCount == 0) { mWakeLock.release(); + } else { + // the next of our alarms is now in flight. reattribute the wakelock. + final PendingIntent nowInFlight = mInFlight.peekFirst(); + if (nowInFlight != null) { + setWakelockWorkSource(nowInFlight); + } else { + // should never happen + Slog.e(TAG, "Alarm wakelock still held but sent queue empty"); + mWakeLock.setWorkSource(null); + } } } } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 33250b8..a953824 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4444,6 +4444,17 @@ public final class ActivityManagerService extends ActivityManagerNative return null; } + public int getUidForIntentSender(IIntentSender sender) { + if (sender instanceof PendingIntentRecord) { + try { + PendingIntentRecord res = (PendingIntentRecord)sender; + return res.uid; + } catch (ClassCastException e) { + } + } + return -1; + } + public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { if (!(pendingResult instanceof PendingIntentRecord)) { return false; |