Skip to content

Commit c4a07d1

Browse files
author
Christopher Tate
committed
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
1 parent e4d8a5d commit c4a07d1

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

core/java/android/app/ActivityManagerNative.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,16 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
867867
return true;
868868
}
869869

870+
case GET_UID_FOR_INTENT_SENDER_TRANSACTION: {
871+
data.enforceInterface(IActivityManager.descriptor);
872+
IIntentSender r = IIntentSender.Stub.asInterface(
873+
data.readStrongBinder());
874+
int res = getUidForIntentSender(r);
875+
reply.writeNoException();
876+
reply.writeInt(res);
877+
return true;
878+
}
879+
870880
case SET_PROCESS_LIMIT_TRANSACTION: {
871881
data.enforceInterface(IActivityManager.descriptor);
872882
int max = data.readInt();
@@ -2714,6 +2724,18 @@ public String getPackageForIntentSender(IIntentSender sender) throws RemoteExcep
27142724
reply.recycle();
27152725
return res;
27162726
}
2727+
public int getUidForIntentSender(IIntentSender sender) throws RemoteException {
2728+
Parcel data = Parcel.obtain();
2729+
Parcel reply = Parcel.obtain();
2730+
data.writeInterfaceToken(IActivityManager.descriptor);
2731+
data.writeStrongBinder(sender.asBinder());
2732+
mRemote.transact(GET_UID_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
2733+
reply.readException();
2734+
int res = reply.readInt();
2735+
data.recycle();
2736+
reply.recycle();
2737+
return res;
2738+
}
27172739
public void setProcessLimit(int max) throws RemoteException
27182740
{
27192741
Parcel data = Parcel.obtain();

core/java/android/app/IActivityManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public IIntentSender getIntentSender(int type,
175175
public boolean clearApplicationUserData(final String packageName,
176176
final IPackageDataObserver observer, int userId) throws RemoteException;
177177
public String getPackageForIntentSender(IIntentSender sender) throws RemoteException;
178+
public int getUidForIntentSender(IIntentSender sender) throws RemoteException;
178179

179180
public void setProcessLimit(int max) throws RemoteException;
180181
public int getProcessLimit() throws RemoteException;
@@ -531,6 +532,7 @@ private WaitResult(Parcel source) {
531532
int START_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+89;
532533
int BACKUP_AGENT_CREATED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+90;
533534
int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
535+
int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
534536

535537

536538
int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;

services/java/com/android/server/AlarmManagerService.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
import android.os.PowerManager;
3535
import android.os.SystemClock;
3636
import android.os.SystemProperties;
37+
import android.os.WorkSource;
3738
import android.text.TextUtils;
3839
import android.text.format.Time;
39-
import android.util.EventLog;
4040
import android.util.Slog;
4141
import android.util.TimeUtils;
4242

@@ -50,6 +50,7 @@
5050
import java.util.Date;
5151
import java.util.HashMap;
5252
import java.util.Iterator;
53+
import java.util.LinkedList;
5354
import java.util.Map;
5455
import java.util.TimeZone;
5556

@@ -89,6 +90,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
8990
private int mDescriptor;
9091
private int mBroadcastRefCount = 0;
9192
private PowerManager.WakeLock mWakeLock;
93+
private LinkedList<PendingIntent> mInFlight = new LinkedList<PendingIntent>();
9294
private final AlarmThread mWaitThread = new AlarmThread();
9395
private final AlarmHandler mHandler = new AlarmHandler();
9496
private ClockReceiver mClockReceiver;
@@ -668,10 +670,12 @@ public void run()
668670
Intent.EXTRA_ALARM_COUNT, alarm.count),
669671
mResultReceiver, mHandler);
670672

671-
// we have an active broadcast so stay awake.
673+
// we have an active broadcast so stay awake.
672674
if (mBroadcastRefCount == 0) {
675+
setWakelockWorkSource(alarm.operation);
673676
mWakeLock.acquire();
674677
}
678+
mInFlight.add(alarm.operation);
675679
mBroadcastRefCount++;
676680

677681
BroadcastStats bs = getStatsLocked(alarm.operation);
@@ -700,7 +704,22 @@ public void run()
700704
}
701705
}
702706
}
703-
707+
708+
void setWakelockWorkSource(PendingIntent pi) {
709+
try {
710+
final int uid = ActivityManagerNative.getDefault()
711+
.getUidForIntentSender(pi.getTarget());
712+
if (uid >= 0) {
713+
mWakeLock.setWorkSource(new WorkSource(uid));
714+
return;
715+
}
716+
} catch (Exception e) {
717+
}
718+
719+
// Something went wrong; fall back to attributing the lock to the OS
720+
mWakeLock.setWorkSource(null);
721+
}
722+
704723
private class AlarmHandler extends Handler {
705724
public static final int ALARM_EVENT = 1;
706725
public static final int MINUTE_CHANGE_EVENT = 2;
@@ -876,9 +895,20 @@ public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
876895
fs.count++;
877896
}
878897
}
898+
mInFlight.removeFirst();
879899
mBroadcastRefCount--;
880900
if (mBroadcastRefCount == 0) {
881901
mWakeLock.release();
902+
} else {
903+
// the next of our alarms is now in flight. reattribute the wakelock.
904+
final PendingIntent nowInFlight = mInFlight.peekFirst();
905+
if (nowInFlight != null) {
906+
setWakelockWorkSource(nowInFlight);
907+
} else {
908+
// should never happen
909+
Slog.e(TAG, "Alarm wakelock still held but sent queue empty");
910+
mWakeLock.setWorkSource(null);
911+
}
882912
}
883913
}
884914
}

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4444,6 +4444,17 @@ public String getPackageForIntentSender(IIntentSender pendingResult) {
44444444
return null;
44454445
}
44464446

4447+
public int getUidForIntentSender(IIntentSender sender) {
4448+
if (sender instanceof PendingIntentRecord) {
4449+
try {
4450+
PendingIntentRecord res = (PendingIntentRecord)sender;
4451+
return res.uid;
4452+
} catch (ClassCastException e) {
4453+
}
4454+
}
4455+
return -1;
4456+
}
4457+
44474458
public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
44484459
if (!(pendingResult instanceof PendingIntentRecord)) {
44494460
return false;

0 commit comments

Comments
 (0)