FileDocCategorySizeDatePackage
NextAlarmTracker.javaAPI DocAndroid 5.1 API10060Thu Mar 12 22:22:42 GMT 2015com.android.server.notification

NextAlarmTracker

public class NextAlarmTracker extends Object
Helper for tracking updates to the current user's next alarm.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final String
ACTION_TRIGGER
private static final String
EXTRA_TRIGGER
private static final int
REQUEST_CODE
private static final long
SECONDS
private static final long
MINUTES
private static final long
NEXT_ALARM_UPDATE_DELAY
private static final long
EARLY
private static final long
WAIT_AFTER_INIT
private static final long
WAIT_AFTER_BOOT
private final android.content.Context
mContext
private final H
mHandler
private final ArrayList
mCallbacks
private long
mInit
private boolean
mRegistered
private android.app.AlarmManager
mAlarmManager
private int
mCurrentUserId
private long
mScheduledAlarmTime
private long
mBootCompleted
private PowerManager.WakeLock
mWakeLock
private final android.content.BroadcastReceiver
mReceiver
Constructors Summary
public NextAlarmTracker(android.content.Context context)


       
        mContext = context;
    
Methods Summary
public voidaddCallback(com.android.server.notification.NextAlarmTracker$Callback callback)

        mCallbacks.add(callback);
    
public voiddestroy()

        if (mRegistered) {
            mContext.unregisterReceiver(mReceiver);
            mRegistered = false;
        }
    
public voiddump(java.io.PrintWriter pw, com.android.server.notification.NotificationManagerService.DumpFilter filter)

        pw.println("    NextAlarmTracker:");
        pw.print("      len(mCallbacks)="); pw.println(mCallbacks.size());
        pw.print("      mRegistered="); pw.println(mRegistered);
        pw.print("      mInit="); pw.println(mInit);
        pw.print("      mBootCompleted="); pw.println(mBootCompleted);
        pw.print("      mCurrentUserId="); pw.println(mCurrentUserId);
        pw.print("      mScheduledAlarmTime="); pw.println(formatAlarmDebug(mScheduledAlarmTime));
        pw.print("      mWakeLock="); pw.println(mWakeLock);
    
public voidevaluate()

        mHandler.postEvaluate(0);
    
private voidfireEvaluate(android.app.AlarmManager.AlarmClockInfo nextAlarm, long wakeupTime, boolean booted)

        for (Callback callback : mCallbacks) {
            callback.onEvaluate(nextAlarm, wakeupTime, booted);
        }
    
public java.lang.StringformatAlarm(android.app.AlarmManager.AlarmClockInfo alarm)

        return alarm != null ? formatAlarm(alarm.getTriggerTime()) : null;
    
private java.lang.StringformatAlarm(long time)

        return formatAlarm(time, "Hm", "hma");
    
private java.lang.StringformatAlarm(long time, java.lang.String skeleton24, java.lang.String skeleton12)

        final String skeleton = DateFormat.is24HourFormat(mContext) ? skeleton24 : skeleton12;
        final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
        return DateFormat.format(pattern, time).toString();
    
public java.lang.StringformatAlarmDebug(android.app.AlarmManager.AlarmClockInfo alarm)

        return formatAlarmDebug(alarm != null ? alarm.getTriggerTime() : 0);
    
public java.lang.StringformatAlarmDebug(long time)

        if (time <= 0) return Long.toString(time);
        return String.format("%s (%s)", time, formatAlarm(time, "Hms", "hmsa"));
    
public static java.lang.StringformatDuration(long millis)

        final StringBuilder sb = new StringBuilder();
        TimeUtils.formatDuration(millis, sb);
        return sb.toString();
    
public intgetCurrentUserId()

        return mCurrentUserId;
    
public static longgetEarlyTriggerTime(android.app.AlarmManager.AlarmClockInfo alarm)

        return alarm != null ? (alarm.getTriggerTime() - EARLY) : 0;
    
public android.app.AlarmManager.AlarmClockInfogetNextAlarm()

        return mAlarmManager.getNextAlarmClock(mCurrentUserId);
    
private voidhandleEvaluate()

        final AlarmClockInfo nextAlarm = mAlarmManager.getNextAlarmClock(mCurrentUserId);
        final long triggerTime = getEarlyTriggerTime(nextAlarm);
        final long now = System.currentTimeMillis();
        final boolean alarmUpcoming = triggerTime > now;
        final boolean booted = isDoneWaitingAfterBoot(now);
        if (DEBUG) Slog.d(TAG, "handleEvaluate nextAlarm=" + formatAlarmDebug(triggerTime)
                + " alarmUpcoming=" + alarmUpcoming
                + " booted=" + booted);
        fireEvaluate(nextAlarm, triggerTime, booted);
        if (!booted) {
            // recheck after boot
            final long recheckTime = (mBootCompleted > 0 ? mBootCompleted : now) + WAIT_AFTER_BOOT;
            rescheduleAlarm(recheckTime);
            return;
        }
        if (alarmUpcoming) {
            // wake up just before the next alarm
            rescheduleAlarm(triggerTime);
        }
    
public voidinit()

        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        final PowerManager p = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = p.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        mInit = System.currentTimeMillis();
        reset();
    
private booleanisDoneWaitingAfterBoot(long time)

        if (mBootCompleted > 0) return (time - mBootCompleted) > WAIT_AFTER_BOOT;
        if (mInit > 0) return (time - mInit) > WAIT_AFTER_INIT;
        return true;
    
public voidonUserSwitched()

        reset();
    
public voidremoveCallback(com.android.server.notification.NextAlarmTracker$Callback callback)

        mCallbacks.remove(callback);
    
private voidrescheduleAlarm(long time)

        if (DEBUG) Slog.d(TAG, "rescheduleAlarm " + time);
        final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
                new Intent(ACTION_TRIGGER)
                        .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                        .putExtra(EXTRA_TRIGGER, time),
                PendingIntent.FLAG_UPDATE_CURRENT);
        alarms.cancel(pendingIntent);
        mScheduledAlarmTime = time;
        if (time > 0) {
            if (DEBUG) Slog.d(TAG, String.format("Scheduling alarm for %s (in %s)",
                    formatAlarmDebug(time), formatDuration(time - System.currentTimeMillis())));
            alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        }
    
public voidreset()

        if (mRegistered) {
            mContext.unregisterReceiver(mReceiver);
        }
        mCurrentUserId = ActivityManager.getCurrentUser();
        final IntentFilter filter = new IntentFilter();
        filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
        filter.addAction(ACTION_TRIGGER);
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
        mContext.registerReceiverAsUser(mReceiver, new UserHandle(mCurrentUserId), filter, null,
                null);
        mRegistered = true;
        evaluate();