vim base/services/core/java/com/android/server/AlarmManagerService.java

AlarmManager 调用 IAlarmManager, AlarmManagerService 是IAlarmManager的实现

private final IBinder mService = new IAlarmManager.Stub() {
@Override
public void set(int type, long triggerAtTime, long windowLength, long interval, int flags,
PendingIntent operation, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock) {
final int callingUid = Binder.getCallingUid();
if (workSource != null) {
getContext().enforcePermission(
android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), callingUid, "AlarmManager.set");
} // No incoming callers can request either WAKE_FROM_IDLE or
// ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.
flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE
| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED); // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
// manager when to come out of idle mode, which is only for DeviceIdleController.
if (callingUid != Process.SYSTEM_UID) {
flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
} // If the caller is a core system component, and not calling to do work on behalf
// of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. This means we
// will allow these alarms to go off as normal even while idle, with no timing
// restrictions.
if (callingUid < Process.FIRST_APPLICATION_UID && workSource == null) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
} // If this is an exact time alarm, then it can't be batched with other alarms.
if (windowLength == AlarmManager.WINDOW_EXACT) {
flags |= AlarmManager.FLAG_STANDALONE;
} // If this alarm is for an alarm clock, then it must be standalone and we will
// use it to wake early from idle if needed.
if (alarmClock != null) {
flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;
} setImpl(type, triggerAtTime, windowLength, interval, operation,
flags, workSource, alarmClock, callingUid);
}
void setImpl(int type, long triggerAtTime, long windowLength, long interval,
PendingIntent operation, int flags, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock, int callingUid) {
if (operation == null) {
Slog.w(TAG, "set/setRepeating ignored because there is no intent");
return;
} // Sanity check the window length. This will catch people mistakenly
// trying to pass an end-of-window timestamp rather than a duration.
if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
Slog.w(TAG, "Window length " + windowLength
+ "ms suspiciously long; limiting to 1 hour");
windowLength = AlarmManager.INTERVAL_HOUR;
} // Sanity check the recurrence interval. This will catch people who supply
// seconds when the API expects milliseconds.
final long minInterval = mConstants.MIN_INTERVAL;
if (interval > 0 && interval < minInterval) {
Slog.w(TAG, "Suspiciously short interval " + interval
+ " millis; expanding to " + (minInterval/1000)
+ " seconds");
interval = minInterval;
} if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
throw new IllegalArgumentException("Invalid alarm type " + type);
} if (triggerAtTime < 0) {
final long what = Binder.getCallingPid();
Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid
+ " pid=" + what);
triggerAtTime = 0;
} final long nowElapsed = SystemClock.elapsedRealtime();
final long nominalTrigger = convertToElapsed(triggerAtTime, type);
// Try to prevent spamming by making sure we aren't firing alarms in the immediate future
final long minTrigger = nowElapsed + mConstants.MIN_FUTURITY;
final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; final long maxElapsed;
if (windowLength == AlarmManager.WINDOW_EXACT) {
maxElapsed = triggerElapsed;
} else if (windowLength < 0) {
maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
// Fix this window in place, so that as time approaches we don't collapse it.
windowLength = maxElapsed - triggerElapsed;
} else {
maxElapsed = triggerElapsed + windowLength;
} synchronized (mLock) {
if (DEBUG_BATCH) {
Slog.v(TAG, "set(" + operation + ") : type=" + type
+ " triggerAtTime=" + triggerAtTime + " win=" + windowLength
+ " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
+ " interval=" + interval + " flags=0x" + Integer.toHexString(flags));
}
setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
interval, operation, flags, true, workSource, alarmClock, callingUid);
}
} private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
long maxWhen, long interval, PendingIntent operation, int flags,
boolean doValidate, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock,
int uid) {
Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
operation, workSource, flags, alarmClock, uid);
removeLocked(operation);
setImplLocked(a, false, doValidate);
} private void setImplLocked(Alarm a, boolean rebatching, boolean doValidate) {
if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {
// This is a special alarm that will put the system into idle until it goes off.
// The caller has given the time they want this to happen at, however we need
// to pull that earlier if there are existing alarms that have requested to
// bring us out of idle at an earlier time.
if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) {
a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed;
}
// Add fuzz to make the alarm go off some time before the actual desired time.
final long nowElapsed = SystemClock.elapsedRealtime();
final int fuzz = fuzzForDuration(a.whenElapsed-nowElapsed);
if (fuzz > 0) {
if (mRandom == null) {
mRandom = new Random();
}
final int delta = mRandom.nextInt(fuzz);
a.whenElapsed -= delta;
if (false) {
Slog.d(TAG, "Alarm when: " + a.whenElapsed);
Slog.d(TAG, "Delta until alarm: " + (a.whenElapsed-nowElapsed));
Slog.d(TAG, "Applied fuzz: " + fuzz);
Slog.d(TAG, "Final delta: " + delta);
Slog.d(TAG, "Final when: " + a.whenElapsed);
}
a.when = a.maxWhenElapsed = a.whenElapsed;
} } else if (mPendingIdleUntil != null) {
// We currently have an idle until alarm scheduled; if the new alarm has
// not explicitly stated it wants to run while idle, then put it on hold.
if ((a.flags&(AlarmManager.FLAG_ALLOW_WHILE_IDLE
| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
| AlarmManager.FLAG_WAKE_FROM_IDLE))
== 0) {
mPendingWhileIdleAlarms.add(a);
return;
}
} int whichBatch = ((a.flags&AlarmManager.FLAG_STANDALONE) != 0)
? -1 : attemptCoalesceLocked(a.whenElapsed, a.maxWhenElapsed);
if (whichBatch < 0) {
Batch batch = new Batch(a);
addBatchLocked(mAlarmBatches, batch);
} else {
Batch batch = mAlarmBatches.get(whichBatch);
if (batch.add(a)) {
// The start time of this batch advanced, so batch ordering may
// have just been broken. Move it to where it now belongs.
mAlarmBatches.remove(whichBatch);
addBatchLocked(mAlarmBatches, batch);
}
} if (a.alarmClock != null) {
mNextAlarmClockMayChange = true;
} boolean needRebatch = false; if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {
mPendingIdleUntil = a;
mConstants.updateAllowWhileIdleMinTimeLocked();
needRebatch = true;
} else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) {
mNextWakeFromIdle = a;
// If this wake from idle is earlier than whatever was previously scheduled,
// and we are currently idling, then we need to rebatch alarms in case the idle
// until time needs to be updated.
if (mPendingIdleUntil != null) {
needRebatch = true;
}
}
} if (!rebatching) {
if (DEBUG_VALIDATE) {
if (doValidate && !validateConsistencyLocked()) {
Slog.v(TAG, "Tipping-point operation: type=" + a.type + " when=" + a.when
+ " when(hex)=" + Long.toHexString(a.when)
+ " whenElapsed=" + a.whenElapsed
+ " maxWhenElapsed=" + a.maxWhenElapsed
+ " interval=" + a.repeatInterval + " op=" + a.operation
+ " flags=0x" + Integer.toHexString(a.flags));
rebatchAllAlarmsLocked(false);
needRebatch = false;
}
} if (needRebatch) {
rebatchAllAlarmsLocked(false);
} rescheduleKernelAlarmsLocked();
updateNextAlarmClockLocked();
}
}

rtc关机闹钟4 AlarmManagerService.java的更多相关文章

  1. rtc关机闹钟6 AlarmManagerService研究

    这个是 private void setLocked(int type, long when) { if (mNativeData != 0) {            // The kernel n ...

  2. rtc关机闹钟3 IAlarmManager

    vim framework/base/core/java/android/app/IAlarmManager.aidl import android.app.AlarmManager;import a ...

  3. rtc关机闹钟5 AlarmManager研究

    AlarmManager研究 侯 亮 转自 http://blog.csdn.net/codefly/article/details/17058425 1.概述 在Android系统中,闹钟和唤醒功能 ...

  4. rtc 关机闹钟1 app层

    private static void enableAlertPowerOn(Context context, final Alarm alarm, final long atTimeInMillis ...

  5. rtc关机闹钟7 jni层 com_android_server_AlarmManagerService

    frameworks/base/services/core/jni/com_android_server_AlarmManagerService.cpp int AlarmImplAlarmDrive ...

  6. rtc关机闹钟2 Alarm manager

    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis, PendingInten ...

  7. Android关机闹钟实现

    Android关机闹钟实现 时间转换网站:http://tool.chinaz.com/Tools/unixtime.aspx 1.apk层 这个还是比较简单的,百度一下就可以看到apk的代码,我之前 ...

  8. [置顶] android关机闹钟设计思路

    1: 首先需要硬件支持,支持alarm中断触发开机,目前高通平台几乎都支持: 2:关机前需要在rtc-xxx.c中做到enable_irq_wake,和不disable alarm功能(默认开机后al ...

  9. Android进程绝杀技--forceStop

    一.概述 1.1 引言 话说Android开源系统拥有着App不计其数,百家争鸣,都想在这"大争之世"寻得系统存活的一席之地.然则系统资源有限,如若都割据为王,再强劲的CPU也会忙 ...

随机推荐

  1. Function.prototype.bind接口浅析

    本文大部分内容翻译自 MDN内容, 翻译内容经过自己的理解. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glo ...

  2. Java基础之泛型——使用通配符类型参数(TryWildCard)

    控制台程序 使用通配符类型参数可以设定方法的参数类型,其中的代码对于泛型类的实际类型参数不能有任何依赖.如果将方法的参数类型设定为Binary<?>,那么方法可以接受BinaryTree& ...

  3. PAT 解题报告 1047. Student List for Course (25)

    1047. Student List for Course (25) Zhejiang University has 40000 students and provides 2500 courses. ...

  4. 不等高cell的tableView界面搭建

    一.搭建界面 1.界面分析 分析界面的层次结构,分析界面应该用什么控件来搭建 2.界面层次结构 分析之后,我们可以把这个界面分为四个模块(topView middleView commentView ...

  5. java io读书笔记(4)字符数据

    Number只是java程序中需要读出和写入的一种数据类型.很多java程序需要处理有一大堆的字符组成的text,因为计算机真正懂得的只有数字,因此,字符按照某种编码规则,和数字对应. 比如:在ASC ...

  6. ini,config文件的读取修改

    修改ini配置文件 // 声明INI文件的写操作函数 WritePrivateProfileString() [System.Runtime.InteropServices.DllImport(&qu ...

  7. ajax测试异步提交

    今天测试了$.ajax()方法: $("a").click(function(){        $.ajax({           url:"MyJsp.jsp&qu ...

  8. java dyn proxy

    package dyn; public interface RealService { void buy(); } =================== package dyn; public cl ...

  9. 关于wxwidgets图形界面的关闭窗口的按钮无效的解决办法

    这是使用wxsmith设计界面时的情况,如果用纯代码写的界面,关闭按钮就很奇怪地有效 道听途说,窗口的关闭是由一个方法控制着.大概是这样的: void PlainFrame::OnClose(wxCl ...

  10. 《聚焦3D地形编程》学习点

    痞子龙的译本虽然称不上好,但却保留了原汁原味,看这本书时最好结合原文与痞子龙的译文.另外,如果有过地形生成的经验再看这本书时有些帮助,这本书介绍的专业的室外地形开发,很全面的介绍. 仅是个人总结,可能 ...