Android8.0 AlarmManagerService

只是做下笔记

关于闹铃怎么触发的,当你设置好闹铃后,时间到了就会走这里触发。前面的流程不分析。闹铃触发就是发一个广播给你自己的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; wi<alarm.workSource.size(); wi++) {
                        final 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);
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值