1. package/apps/deskclock/src/com/android/deskclock/DeskClock.java
找AlarmClock类
根据time = Alarms.addAlarm(this, alarm);
4. packages/apps/deskclock/src/com/android/deskclock/Alarms.java
由AlarmManager am = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 可以回到AlarmManager的类5. frameworks/base/core/java/android/app/AlarmManager.java
6. 接下来要找提供这个Context.ALARM_SERVICE服务的实现,通过搜索可知是在SystemServer.java中添加上这个服务
frameworks/base/services/java/com/android/server/SystemServer.java
调用本地函数private native void set(int fd, int type, long seconds, long nanoseconds);
由上可知这个方法是通过JNI调用的,接下来搜索set,可知是被如下方法注册的
8. frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp
接下来找回过头看看传过来的fd是哪个设备文件
9. frameworks/base/services/java/com/android/server/AlarmManagerService.java
根据set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);找mDescriptor
10. 再回到frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp
原来操作的是下面的这个函数
onCreate(){
...
initViews();
}
接着看
private void initViews() {
final ImageButton alarmButton = (ImageButton) findViewById(R.id.alarm_button);
alarmButton.setOnClickListener(alarmClickListener);
}
if (alarmClickListener == null) {
alarmClickListener = new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(DeskClock.this, AlarmClock.class));
}
};
}
找AlarmClock类
2. packages/apps/deskclock/src/com/android/deskclock/AlarmClock.java
protected void onCreate(Bundle icicle) {
...
updateLayout();
}
private void updateLayout() {
...
View addAlarm = findViewById(R.id.add_alarm);
addAlarm.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
addNewAlarm();
}
});
}
private void addNewAlarm() {
startActivity(new Intent(this, SetAlarm.class));
}
3. packages/apps/deskclock/src/com/android/deskclock/SetAlarm.java
protected void onCreate(Bundle icicle) {
...
Button b = (Button) findViewById(R.id.alarm_save);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//if there is a alarm witch has the same hour and minutes , show timepicker again
if(Alarms.isSametimeAlarm(getContentResolver(), mHour, mMinutes,mId)){
sameAlarmShow(mHour, mMinutes);
return;
}
saveAlarm(); //修改完毕,点击‘完成 ’生效
// Save the alarm and pop a toast.
if(mEnabledPref.isChecked()){
popAlarmSetToast(SetAlarm.this, mHour, mMinutes, mRepeatPref.getDaysOfWeek());
}
finish();
}
});
...
}
private long saveAlarm() {
if (alarm.id == -1) {
time = Alarms.addAlarm(this, alarm);
// addAlarm populates the alarm with the new id. Update mId so that
// changes to other preferences update the new alarm.
mId = alarm.id;
} else {
time = Alarms.setAlarm(this, alarm);
}
}
根据time = Alarms.addAlarm(this, alarm);
4. packages/apps/deskclock/src/com/android/deskclock/Alarms.java
public static long addAlarm(Context context, Alarm alarm) {
if (alarm.enabled) {//如果设置的闹钟为enable则
clearSnoozeIfNeeded(context, timeInMillis);//假设设置的时间离现在最近,则清除上次设置的闹铃时间
}
setNextAlert(context);
}
public static void setNextAlert(final Context context) {
Alarm alarm = calculateNextAlert(context);
long time = getSnoozeAlert(context);
if ((alarm != null && alarm.time <= time)
|| (alarm != null && time == -1)) {
enableAlert(context, alarm, alarm.time);
}
}
private static void enableAlert(Context context, final Alarm alarm, final long atTimeInMillis) {
...
Intent intent = new Intent(ALARM_ALERT_ACTION);
...
PendingIntent sender = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.POWER_OFF_WAKEUP, atTimeInMillis, sender);//原生默认设置闹钟时间
alarm_flag_setup(atTimeInMillis); //
}
private static void alarm_flag_setup(final long alarmTimeInMillis) {
// Flag for alarm exist or not
private static File ALARM_FLAG_FILE = new File("/productinfo/alarm_flag");
FileWriter command = new FileWriter(ALARM_FLAG_FILE);
try {
command.write(String.valueOf(timeDiffInSecs));
command.write("\n");
command.write(String.valueOf(alarmTimeInMillis/1000));
command.write("\n");
} finally {
command.close();
Log.v(ALARM_FLAG_FILE + " write done");
}
}
由AlarmManager am = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 可以回到AlarmManager的类5. frameworks/base/core/java/android/app/AlarmManager.java
public void set(int type, long triggerAtTime, PendingIntent operation) {
try {
mService.set(type, triggerAtTime, operation);
} catch (RemoteException ex) {
}
}
6. 接下来要找提供这个Context.ALARM_SERVICE服务的实现,通过搜索可知是在SystemServer.java中添加上这个服务
frameworks/base/services/java/com/android/server/SystemServer.java
AlarmManagerService alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
可知实现这个服务的是类AlarmManagerService
7. frameworks/base/services/java/com/android/server/AlarmManagerService.java
public void set(int type, long triggerAtTime, PendingIntent operation) {
setRepeating(type, triggerAtTime, 0, operation);
}
public void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation) {
int index = addAlarmLocked(alarm);
if (index == 0) {
setLocked(alarm);
}
}
private void setLocked(Alarm alarm){
...
set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);
}
调用本地函数private native void set(int fd, int type, long seconds, long nanoseconds);
由上可知这个方法是通过JNI调用的,接下来搜索set,可知是被如下方法注册的
8. frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"init", "()I", (void*)android_server_AlarmManagerService_init},
{"close", "(I)V", (void*)android_server_AlarmManagerService_close},
{"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set},
...
}
static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
{
#if HAVE_ANDROID_OS
struct timespec ts;
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds;
int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts);
if (result < 0)
{
LOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
}
#endif
}
接下来找回过头看看传过来的fd是哪个设备文件
9. frameworks/base/services/java/com/android/server/AlarmManagerService.java
根据set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);找mDescriptor
mDescriptor = init();
private native int init();
10. 再回到frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"init", "()I", (void*)android_server_AlarmManagerService_init},
...
}
原来操作的是下面的这个函数
static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)
{
#if HAVE_ANDROID_OS
return open("/dev/alarm", O_RDWR);
#else
return -1;
#endif
}