summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2012-04-06 14:19:13 -0700
committerChristopher Tate <ctate@google.com>2012-04-06 14:23:12 -0700
commitc4a07d1caa9befd4fa8165ff05fa5e92480d8e27 (patch)
tree21b4785e8bad532974031cbb2f580164689ec2bd /services
parente4d8a5dd42070d919dbd774f24c6684ecf1e350e (diff)
downloadframeworks_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.java36
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java11
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;