diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/doze/DozeUi.java | 25 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java | 93 |
2 files changed, 100 insertions, 18 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index cf87fca56f39..97731cf24774 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -23,6 +23,7 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; +import com.android.systemui.util.AlarmTimeout; import com.android.systemui.util.wakelock.WakeLock; import java.util.Calendar; @@ -35,26 +36,23 @@ public class DozeUi implements DozeMachine.Part { private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min private final Context mContext; - private final AlarmManager mAlarmManager; private final DozeHost mHost; private final Handler mHandler; private final WakeLock mWakeLock; private final DozeMachine mMachine; - private final AlarmManager.OnAlarmListener mTimeTick; + private final AlarmTimeout mTimeTicker; - private boolean mTimeTickScheduled = false; private long mLastTimeTickElapsed = 0; public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine, WakeLock wakeLock, DozeHost host, Handler handler) { mContext = context; - mAlarmManager = alarmManager; mMachine = machine; mWakeLock = wakeLock; mHost = host; mHandler = handler; - mTimeTick = this::onTimeTick; + mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler); } private void pulseWhileDozing(int reason) { @@ -112,25 +110,21 @@ public class DozeUi implements DozeMachine.Part { } private void scheduleTimeTick() { - if (mTimeTickScheduled) { + if (mTimeTicker.isScheduled()) { return; } long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis(); - mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler); - - mTimeTickScheduled = true; + mTimeTicker.schedule(delta, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED); mLastTimeTickElapsed = SystemClock.elapsedRealtime(); } private void unscheduleTimeTick() { - if (!mTimeTickScheduled) { + if (!mTimeTicker.isScheduled()) { return; } verifyLastTimeTick(); - mAlarmManager.cancel(mTimeTick); - mTimeTickScheduled = false; + mTimeTicker.cancel(); } private void verifyLastTimeTick() { @@ -153,10 +147,6 @@ public class DozeUi implements DozeMachine.Part { } private void onTimeTick() { - if (!mTimeTickScheduled) { - // Alarm was canceled, but we still got the callback. Ignore. - return; - } verifyLastTimeTick(); mHost.dozeTimeTick(); @@ -164,7 +154,6 @@ public class DozeUi implements DozeMachine.Part { // Keep wakelock until a frame has been pushed. mHandler.post(mWakeLock.wrap(() -> {})); - mTimeTickScheduled = false; scheduleTimeTick(); } } diff --git a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java new file mode 100644 index 000000000000..f7f61aff9849 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.util; + +import android.app.AlarmManager; +import android.os.Handler; +import android.os.SystemClock; + +/** + * Schedules a timeout through AlarmManager. Ensures that the timeout is called even when + * the device is asleep. + */ +public class AlarmTimeout implements AlarmManager.OnAlarmListener { + + public static final int MODE_CRASH_IF_SCHEDULED = 0; + public static final int MODE_IGNORE_IF_SCHEDULED = 1; + public static final int MODE_RESCHEDULE_IF_SCHEDULED = 2; + + private final AlarmManager mAlarmManager; + private final AlarmManager.OnAlarmListener mListener; + private final String mTag; + private final Handler mHandler; + private boolean mScheduled; + + public AlarmTimeout(AlarmManager alarmManager, AlarmManager.OnAlarmListener listener, + String tag, Handler handler) { + mAlarmManager = alarmManager; + mListener = listener; + mTag = tag; + mHandler = handler; + } + + public void schedule(long timeout, int mode) { + switch (mode) { + case MODE_CRASH_IF_SCHEDULED: + if (mScheduled) { + throw new IllegalStateException(mTag + " timeout is already scheduled"); + } + break; + case MODE_IGNORE_IF_SCHEDULED: + if (mScheduled) { + return; + } + break; + case MODE_RESCHEDULE_IF_SCHEDULED: + if (mScheduled) { + cancel(); + } + break; + default: + throw new IllegalArgumentException("Illegal mode: " + mode); + } + + mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + timeout, mTag, this, mHandler); + mScheduled = true; + } + + public boolean isScheduled() { + return mScheduled; + } + + public void cancel() { + if (mScheduled) { + mAlarmManager.cancel(this); + mScheduled = false; + } + } + + @Override + public void onAlarm() { + if (!mScheduled) { + // We canceled the alarm, but it still fired. Ignore. + return; + } + mScheduled = false; + mListener.onAlarm(); + } +} |