只是做下笔记
关于闹铃怎么触发的,当你设置好闹铃后,时间到了就会走这里触发。前面的流程不分析。闹铃触发就是发一个广播给你自己的app(alarm.operation.send),然后做处理。你可以显示一个闹钟界面,也可以是service做一些处理。
这里好像有2中形式,看注释。不是很清楚。
PendingIntent alarm
Direct listener callback alarm
Alarm alarm包含了一些信息,比如packagename,等等。
frameworks/base/services/core/java/com/android/server/AlarmManagerService.java
/**
* Deliver an alarm and set up the post-delivery handling appropriately
*/
public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) {
if (alarm.operation != null) {
// PendingIntent alarm
try {
Log.i("a", "deliverLocked alarm.operation.send ----------");
Log.i("a", ""+alarm);
if(alarm.alarmClock!=null)
Log.i("a", ""+alarm.alarmClock);
Log.i("a", "----------------------");
alarm.operation.send(getContext(), 0,
mBackgroundIntent.putExtra(
Intent.EXTRA_ALARM_COUNT, alarm.count),
mDeliveryTracker, mHandler, null,
allowWhileIdle ? mIdleOptions : null);
} catch (PendingIntent.CanceledException e) {
if (alarm.repeatInterval > 0) {
// This IntentSender is no longer valid, but this
// is a repeating alarm, so toss it
removeImpl(alarm.operation);
}
// No actual delivery was possible, so the delivery tracker's
// 'finished' callback won't be invoked. We also don't need
// to do any wakelock or stats tracking, so we have nothing
// left to do here but go on to the next thing.
return;
}
} else {
if(mNotificationManager.getZenMode()==Global.ZEN_MODE_GAME&&alarm.alarmClock!=null) {
return;
}
// Direct listener callback alarm
try {
if (DEBUG_LISTENER_CALLBACK) {
Slog.v(TAG, "Alarm to uid=" + alarm.uid
+ " listener=" + alarm.listener.asBinder());
}
alarm.listener.doAlarm(this);
mHandler.sendMessageDelayed(
mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT,
alarm.listener.asBinder()),
mConstants.LISTENER_TIMEOUT);
} catch (Exception e) {
if (DEBUG_LISTENER_CALLBACK) {
Slog.i(TAG, "Alarm undeliverable to listener "
+ alarm.listener.asBinder(), e);
}
// As in the PendingIntent.CanceledException case, delivery of the
// alarm was not possible, so we have no wakelock or timeout or
// stats management to do. It threw before we posted the delayed
// timeout message, so we're done here.
return;
}
}
// The alarm is now in flight; now arrange wakelock and stats tracking
if (DEBUG_WAKELOCK) {
Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1));
}
if (mBroadcastRefCount == 0) {
setWakelockWorkSource(alarm.operation, alarm.workSource,
alarm.type, alarm.statsTag, (alarm.operation == null) ? alarm.uid : -1,
true);
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
}
mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget();
}
final InFlight inflight = new InFlight(AlarmManagerService.this,
alarm.operation, alarm.listener, alarm.workSource, alarm.uid,
alarm.packageName, alarm.type, alarm.statsTag, nowELAPSED);
mInFlight.add(inflight);
mBroadcastRefCount++;
qcNsrmExt.addTriggeredUid((alarm.operation != null) ?
alarm.operation.getCreatorUid() :
alarm.uid);
if (allowWhileIdle) {
// Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
mLastAllowWhileIdleDispatch.put(alarm.uid, nowELAPSED);
if (RECORD_DEVICE_IDLE_ALARMS) {
IdleDispatchEntry ent = new IdleDispatchEntry();
ent.uid = alarm.uid;
ent.pkg = alarm.packageName;
ent.tag = alarm.statsTag;
ent.op = "DELIVER";
ent.elapsedRealtime = nowELAPSED;
mAllowWhileIdleDispatches.add(ent);
}
}
final BroadcastStats bs = inflight.mBroadcastStats;
bs.count++;
if (bs.nesting == 0) {
bs.nesting = 1;
bs.startTime = nowELAPSED;
} else {
bs.nesting++;
}
final FilterStats fs = inflight.mFilterStats;
fs.count++;
if (fs.nesting == 0) {
fs.nesting = 1;
fs.startTime = nowELAPSED;
} else {
fs.nesting++;
}
if (alarm.type == ELAPSED_REALTIME_WAKEUP
|| alarm.type == RTC_WAKEUP) {
bs.numWakeup++;
fs.numWakeup++;
if (alarm.workSource != null && alarm.workSource.size() > 0) {
for (int wi=0; wifinal String wsName = alarm.workSource.getName(wi);
ActivityManager.noteWakeupAlarm(
alarm.operation, alarm.workSource.get(wi),
(wsName != null) ? wsName : alarm.packageName,
alarm.statsTag);
}
} else {
ActivityManager.noteWakeupAlarm(
alarm.operation, alarm.uid, alarm.packageName, alarm.statsTag);
}
}
}
}
}