Add WorkSource capability to AlarmManager
Change-Id: Ibcff01a9f54a89fde6e7e5b7658e9a90b9a2445b
This commit is contained in:
@ -385,13 +385,13 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
if (batch.standalone) {
|
||||
// this will also be the only alarm in the batch
|
||||
a = new Alarm(a.type, a.when, whenElapsed, maxElapsed,
|
||||
a.repeatInterval, a.operation);
|
||||
a.repeatInterval, a.operation, a.workSource);
|
||||
Batch newBatch = new Batch(a);
|
||||
newBatch.standalone = true;
|
||||
addBatchLocked(mAlarmBatches, newBatch);
|
||||
} else {
|
||||
setImplLocked(a.type, a.when, whenElapsed, maxElapsed,
|
||||
a.repeatInterval, a.operation, false);
|
||||
a.repeatInterval, a.operation, false, a.workSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -400,12 +400,14 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
|
||||
private static final class InFlight extends Intent {
|
||||
final PendingIntent mPendingIntent;
|
||||
final WorkSource mWorkSource;
|
||||
final Pair<String, ComponentName> mTarget;
|
||||
final BroadcastStats mBroadcastStats;
|
||||
final FilterStats mFilterStats;
|
||||
|
||||
InFlight(AlarmManagerService service, PendingIntent pendingIntent) {
|
||||
InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
|
||||
mPendingIntent = pendingIntent;
|
||||
mWorkSource = workSource;
|
||||
Intent intent = pendingIntent.getIntent();
|
||||
mTarget = intent != null
|
||||
? new Pair<String, ComponentName>(intent.getAction(), intent.getComponent())
|
||||
@ -502,12 +504,17 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
|
||||
@Override
|
||||
public void set(int type, long triggerAtTime, long windowLength, long interval,
|
||||
PendingIntent operation) {
|
||||
set(type, triggerAtTime, windowLength, interval, operation, false);
|
||||
PendingIntent operation, WorkSource workSource) {
|
||||
if (workSource != null) {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.UPDATE_DEVICE_STATS,
|
||||
"AlarmManager.set");
|
||||
}
|
||||
set(type, triggerAtTime, windowLength, interval, operation, false, workSource);
|
||||
}
|
||||
|
||||
public void set(int type, long triggerAtTime, long windowLength, long interval,
|
||||
PendingIntent operation, boolean isStandalone) {
|
||||
PendingIntent operation, boolean isStandalone, WorkSource workSource) {
|
||||
if (operation == null) {
|
||||
Slog.w(TAG, "set/setRepeating ignored because there is no intent");
|
||||
return;
|
||||
@ -544,13 +551,13 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
+ " interval=" + interval + " standalone=" + isStandalone);
|
||||
}
|
||||
setImplLocked(type, triggerAtTime, triggerElapsed, maxElapsed,
|
||||
interval, operation, isStandalone);
|
||||
interval, operation, isStandalone, workSource);
|
||||
}
|
||||
}
|
||||
|
||||
private void setImplLocked(int type, long when, long whenElapsed, long maxWhen, long interval,
|
||||
PendingIntent operation, boolean isStandalone) {
|
||||
Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation);
|
||||
PendingIntent operation, boolean isStandalone, WorkSource workSource) {
|
||||
Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation, workSource);
|
||||
removeLocked(operation);
|
||||
|
||||
final boolean reschedule;
|
||||
@ -962,7 +969,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
final long nextElapsed = alarm.whenElapsed + delta;
|
||||
setImplLocked(alarm.type, alarm.when + delta, nextElapsed,
|
||||
maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
|
||||
alarm.repeatInterval, alarm.operation, batch.standalone);
|
||||
alarm.repeatInterval, alarm.operation, batch.standalone,
|
||||
alarm.workSource);
|
||||
}
|
||||
|
||||
}
|
||||
@ -994,15 +1002,17 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
public long maxWhen; // also in the elapsed time base
|
||||
public long repeatInterval;
|
||||
public PendingIntent operation;
|
||||
public WorkSource workSource;
|
||||
|
||||
public Alarm(int _type, long _when, long _whenElapsed, long _maxWhen,
|
||||
long _interval, PendingIntent _op) {
|
||||
long _interval, PendingIntent _op, WorkSource _ws) {
|
||||
type = _type;
|
||||
when = _when;
|
||||
whenElapsed = _whenElapsed;
|
||||
maxWhen = _maxWhen;
|
||||
repeatInterval = _interval;
|
||||
operation = _op;
|
||||
workSource = _ws;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1116,11 +1126,11 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
|
||||
// we have an active broadcast so stay awake.
|
||||
if (mBroadcastRefCount == 0) {
|
||||
setWakelockWorkSource(alarm.operation);
|
||||
setWakelockWorkSource(alarm.operation, alarm.workSource);
|
||||
mWakeLock.acquire();
|
||||
}
|
||||
final InFlight inflight = new InFlight(AlarmManagerService.this,
|
||||
alarm.operation);
|
||||
alarm.operation, alarm.workSource);
|
||||
mInFlight.add(inflight);
|
||||
mBroadcastRefCount++;
|
||||
|
||||
@ -1162,8 +1172,18 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
void setWakelockWorkSource(PendingIntent pi) {
|
||||
/**
|
||||
* Attribute blame for a WakeLock.
|
||||
* @param pi PendingIntent to attribute blame to if ws is null.
|
||||
* @param ws WorkSource to attribute blame.
|
||||
*/
|
||||
void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
|
||||
try {
|
||||
if (ws != null) {
|
||||
mWakeLock.setWorkSource(ws);
|
||||
return;
|
||||
}
|
||||
|
||||
final int uid = ActivityManagerNative.getDefault()
|
||||
.getUidForIntentSender(pi.getTarget());
|
||||
if (uid >= 0) {
|
||||
@ -1246,8 +1266,9 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
// the top of the next minute.
|
||||
final long tickEventDelay = nextTime - currentTime;
|
||||
|
||||
final WorkSource workSource = null; // Let system take blame for time tick events.
|
||||
set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
|
||||
0, mTimeTickSender, true);
|
||||
0, mTimeTickSender, true, workSource);
|
||||
}
|
||||
|
||||
public void scheduleDateChangedEvent() {
|
||||
@ -1258,8 +1279,9 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
|
||||
set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true);
|
||||
|
||||
final WorkSource workSource = null; // Let system take blame for date change events.
|
||||
set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true, workSource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1375,7 +1397,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
|
||||
} else {
|
||||
// the next of our alarms is now in flight. reattribute the wakelock.
|
||||
if (mInFlight.size() > 0) {
|
||||
setWakelockWorkSource(mInFlight.get(0).mPendingIntent);
|
||||
InFlight inFlight = mInFlight.get(0);
|
||||
setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
|
||||
} else {
|
||||
// should never happen
|
||||
mLog.w("Alarm wakelock still held but sent queue empty");
|
||||
|
Reference in New Issue
Block a user