Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7404e86 authored by Mao Jinlong's avatar Mao Jinlong Committed by Ricardo Cerqueira
Browse files

Alarm: Add one more RTC alarm type for poweroff alarm.

Now we use type of RTC_WAKEUP for the poweroff alarm.
Actually lots of other applications also use this type.
But these applications never expect the device will
power on after it has been shut down. So we need to
add dedicated alarm type for the Deskclock or similar
applications.

Change-Id: Ib515d8a737ab73cdd809597ad8cde57030c0a0a1
parent 8490abf1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3684,6 +3684,7 @@ package android.app {
    field public static final long INTERVAL_HOUR = 3600000L; // 0x36ee80L
    field public static final int RTC = 1; // 0x1
    field public static final int RTC_WAKEUP = 0; // 0x0
    field public static final int RTC_POWEROFF_WAKEUP = 4; // 0x4
  }
  public static final class AlarmManager.AlarmClockInfo implements android.os.Parcelable {
+7 −0
Original line number Diff line number Diff line
@@ -100,6 +100,13 @@ public class AlarmManager
     */
    public static final int ELAPSED_REALTIME = 3;

    /**
     * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
     * (wall clock time in UTC), which will wake up the device when
     * it goes off. And it will power on the devices when it shuts down.
     */
    public static final int RTC_POWEROFF_WAKEUP = 4;

    /**
     * Broadcast Action: Sent after the value returned by
     * {@link #getNextAlarmClock()} has changed.
+61 −8
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
import static android.app.AlarmManager.ELAPSED_REALTIME;
import static android.app.AlarmManager.RTC_POWEROFF_WAKEUP;

import com.android.internal.util.LocalLog;

@@ -75,12 +76,18 @@ class AlarmManagerService extends SystemService {
    // warning message.  The time duration is in milliseconds.
    private static final long LATE_ALARM_THRESHOLD = 10 * 1000;

    // The threshold for the power off alarm time can be set. The time
    // duration is in milliseconds.
    private static final long POWER_OFF_ALARM_THRESHOLD = 120 * 1000;

    private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
    private static final int RTC_MASK = 1 << RTC;
    private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
    private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME;
    private static final int RTC_POWEROFF_WAKEUP_MASK = 1 << RTC_POWEROFF_WAKEUP;
    static final int TIME_CHANGED_MASK = 1 << 16;
    static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK;
    static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK
            |RTC_POWEROFF_WAKEUP_MASK;

    // Mask for testing whether a given alarm type is wakeup vs non-wakeup
    static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup
@@ -109,6 +116,7 @@ class AlarmManagerService extends SystemService {

    long mNativeData;
    private long mNextWakeup;
    private long mNextRtcWakeup;
    private long mNextNonWakeup;
    int mBroadcastRefCount = 0;
    PowerManager.WakeLock mWakeLock;
@@ -203,6 +211,14 @@ class AlarmManagerService extends SystemService {
            return alarms.get(index);
        }

        long getWhenByElapsedTime(long whenElapsed) {
            for(int i=0;i< alarms.size();i++) {
                if(alarms.get(i).whenElapsed == whenElapsed)
                    return alarms.get(i).when;
            }
            return 0;
        }

        boolean canHold(long whenElapsed, long maxWhen) {
            return (end >= whenElapsed) && (start <= maxWhen);
        }
@@ -345,6 +361,18 @@ class AlarmManagerService extends SystemService {
            return false;
        }

        boolean isRtcPowerOffWakeup() {
            final int N = alarms.size();
            for (int i = 0; i < N; i++) {
                Alarm a = alarms.get(i);
                // non-wakeup alarms are types 1 and 3, i.e. have the low bit set
                if (a.type == RTC_POWEROFF_WAKEUP) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public String toString() {
            StringBuilder b = new StringBuilder(40);
@@ -443,7 +471,7 @@ class AlarmManagerService extends SystemService {
    }

    static long convertToElapsed(long when, int type) {
        final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
        final boolean isRtc = (type == RTC || type == RTC_WAKEUP  || type == RTC_POWEROFF_WAKEUP);
        if (isRtc) {
            when -= System.currentTimeMillis() - SystemClock.elapsedRealtime();
        }
@@ -592,7 +620,7 @@ class AlarmManagerService extends SystemService {
    @Override
    public void onStart() {
        mNativeData = init();
        mNextWakeup = mNextNonWakeup = 0;
        mNextWakeup = mNextRtcWakeup = mNextNonWakeup = 0;

        // We have to set current TimeZone info to kernel
        // because kernel doesn't keep this after reboot
@@ -698,7 +726,7 @@ class AlarmManagerService extends SystemService {
            windowLength = AlarmManager.INTERVAL_HOUR;
        }

        if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
        if (type < RTC_WAKEUP || type > RTC_POWEROFF_WAKEUP) {
            throw new IllegalArgumentException("Invalid alarm type " + type);
        }

@@ -1077,6 +1105,18 @@ class AlarmManagerService extends SystemService {
        return null;
    }

    private Batch findFirstRtcWakeupBatchLocked() {
        final int N = mAlarmBatches.size();
        for (int i = 0; i < N; i++) {
            Batch b = mAlarmBatches.get(i);
            long intervalTime  = b.start - SystemClock.elapsedRealtime();
            if (b.isRtcPowerOffWakeup() && intervalTime > POWER_OFF_ALARM_THRESHOLD) {
                return b;
            }
        }
        return null;
    }

    private AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
        synchronized (mLock) {
            return mNextAlarmClockForUser.get(userId);
@@ -1212,10 +1252,19 @@ class AlarmManagerService extends SystemService {
        if (mAlarmBatches.size() > 0) {
            final Batch firstWakeup = findFirstWakeupBatchLocked();
            final Batch firstBatch = mAlarmBatches.get(0);
            final Batch firstRtcWakeup = findFirstRtcWakeupBatchLocked();
            if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
                mNextWakeup = firstWakeup.start;
                setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
            }
            if (firstRtcWakeup != null && mNextRtcWakeup != firstRtcWakeup.start) {
                mNextRtcWakeup = firstRtcWakeup.start;
                long when = firstRtcWakeup.getWhenByElapsedTime(mNextRtcWakeup);

                if (when != 0) {
                    setLocked(RTC_POWEROFF_WAKEUP, when);
                }
            }
            if (firstBatch != firstWakeup) {
                nextNonWakeup = firstBatch.start;
            }
@@ -1366,6 +1415,7 @@ class AlarmManagerService extends SystemService {
        case RTC_WAKEUP : return "RTC_WAKEUP";
        case ELAPSED_REALTIME : return "ELAPSED";
        case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP";
        case RTC_POWEROFF_WAKEUP : return "RTC_POWEROFF_WAKEUP";
        default:
            break;
        }
@@ -1496,7 +1546,8 @@ class AlarmManagerService extends SystemService {
                AlarmManager.AlarmClockInfo _info, int _userId) {
            type = _type;
            wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP
                    || _type == AlarmManager.RTC_WAKEUP;
                    || _type == AlarmManager.RTC_WAKEUP
                    || _type == AlarmManager.RTC_POWEROFF_WAKEUP;
            when = _when;
            whenElapsed = _whenElapsed;
            windowLength = _windowLength;
@@ -1511,7 +1562,7 @@ class AlarmManagerService extends SystemService {

        public static String makeTag(PendingIntent pi, int type) {
            return pi.getTag(type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
                    ? "*walarm*:" : "*alarm*:");
                    || type == RTC_POWEROFF_WAKEUP ? "*walarm*:" : "*alarm*:");
        }

        @Override
@@ -1531,7 +1582,8 @@ class AlarmManagerService extends SystemService {

        public void dump(PrintWriter pw, String prefix, long nowRTC, long nowELAPSED,
                SimpleDateFormat sdf) {
            final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
            final boolean isRtc = (type == RTC || type == RTC_WAKEUP
                    || type == RTC_POWEROFF_WAKEUP);
            pw.print(prefix); pw.print("tag="); pw.println(tag);
            pw.print(prefix); pw.print("type="); pw.print(type);
                    pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed,
@@ -1640,7 +1692,8 @@ class AlarmManagerService extends SystemService {
                    fs.nesting++;
                }
                if (alarm.type == ELAPSED_REALTIME_WAKEUP
                        || alarm.type == RTC_WAKEUP) {
                        || alarm.type == RTC_WAKEUP
                        || alarm.type == RTC_POWEROFF_WAKEUP) {
                    bs.numWakeup++;
                    fs.numWakeup++;
                    if (alarm.workSource != null && alarm.workSource.size() > 0) {