blob: e516ad088b6ed24affa7f5afae28d8eae7c004e3 [file] [log] [blame]
Michael Jurkad3ef3062010-11-23 16:23:58 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Michael Jurkad3ef3062010-11-23 16:23:58 -080018
19import android.os.Handler;
Sunny Goyal72a74662024-02-14 12:32:59 -080020import android.os.Looper;
Sunny Goyala2125e12016-08-27 15:33:16 -070021import android.os.SystemClock;
Michael Jurkad3ef3062010-11-23 16:23:58 -080022
Brian Isganitis3231ba02024-07-15 14:19:01 -040023import androidx.annotation.VisibleForTesting;
24
Michael Jurkad3ef3062010-11-23 16:23:58 -080025public class Alarm implements Runnable{
26 // if we reach this time and the alarm hasn't been cancelled, call the listener
27 private long mAlarmTriggerTime;
28
29 // if we've scheduled a call to run() (ie called mHandler.postDelayed), this variable is true.
30 // We use this to avoid having multiple pending callbacks
31 private boolean mWaitingForCallback;
32
33 private Handler mHandler;
34 private OnAlarmListener mAlarmListener;
Adam Cohen67bd9cc2011-07-29 14:07:04 -070035 private boolean mAlarmPending = false;
Tony Wickhamc2143352022-06-22 11:29:20 -070036 private long mLastSetTimeout;
Michael Jurkad3ef3062010-11-23 16:23:58 -080037
38 public Alarm() {
Sunny Goyal72a74662024-02-14 12:32:59 -080039 this(Looper.myLooper());
40 }
41
42 public Alarm(Looper looper) {
43 mHandler = new Handler(looper);
Michael Jurkad3ef3062010-11-23 16:23:58 -080044 }
45
46 public void setOnAlarmListener(OnAlarmListener alarmListener) {
47 mAlarmListener = alarmListener;
48 }
49
50 // Sets the alarm to go off in a certain number of milliseconds. If the alarm is already set,
51 // it's overwritten and only the new alarm setting is used
52 public void setAlarm(long millisecondsInFuture) {
Sunny Goyala2125e12016-08-27 15:33:16 -070053 long currentTime = SystemClock.uptimeMillis();
Adam Cohen67bd9cc2011-07-29 14:07:04 -070054 mAlarmPending = true;
Sunny Goyala2125e12016-08-27 15:33:16 -070055 long oldTriggerTime = mAlarmTriggerTime;
Michael Jurkad3ef3062010-11-23 16:23:58 -080056 mAlarmTriggerTime = currentTime + millisecondsInFuture;
Tony Wickhamc2143352022-06-22 11:29:20 -070057 mLastSetTimeout = millisecondsInFuture;
Sunny Goyala2125e12016-08-27 15:33:16 -070058
59 // If the previous alarm was set for a longer duration, cancel it.
60 if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) {
61 mHandler.removeCallbacks(this);
62 mWaitingForCallback = false;
63 }
Michael Jurkad3ef3062010-11-23 16:23:58 -080064 if (!mWaitingForCallback) {
65 mHandler.postDelayed(this, mAlarmTriggerTime - currentTime);
66 mWaitingForCallback = true;
67 }
68 }
69
70 public void cancelAlarm() {
Adam Cohen67bd9cc2011-07-29 14:07:04 -070071 mAlarmPending = false;
Michael Jurkad3ef3062010-11-23 16:23:58 -080072 }
73
74 // this is called when our timer runs out
75 public void run() {
76 mWaitingForCallback = false;
Sunny Goyala2125e12016-08-27 15:33:16 -070077 if (mAlarmPending) {
78 long currentTime = SystemClock.uptimeMillis();
Michael Jurkad3ef3062010-11-23 16:23:58 -080079 if (mAlarmTriggerTime > currentTime) {
80 // We still need to wait some time to trigger spring loaded mode--
81 // post a new callback
82 mHandler.postDelayed(this, Math.max(0, mAlarmTriggerTime - currentTime));
83 mWaitingForCallback = true;
84 } else {
Adam Cohen67bd9cc2011-07-29 14:07:04 -070085 mAlarmPending = false;
Michael Jurkad3ef3062010-11-23 16:23:58 -080086 if (mAlarmListener != null) {
87 mAlarmListener.onAlarm(this);
88 }
89 }
90 }
91 }
Adam Cohen67bd9cc2011-07-29 14:07:04 -070092
93 public boolean alarmPending() {
94 return mAlarmPending;
95 }
Tony Wickhamc2143352022-06-22 11:29:20 -070096
97 /** Returns the last value passed to {@link #setAlarm(long)} */
98 public long getLastSetTimeout() {
99 return mLastSetTimeout;
100 }
Brian Isganitis3231ba02024-07-15 14:19:01 -0400101
102 /** Simulates the alarm firing for tests. */
103 @VisibleForTesting
104 public void finishAlarm() {
105 if (!mAlarmPending) return;
106 mAlarmPending = false;
107 mHandler.removeCallbacks(this);
108 mAlarmListener.onAlarm(this);
109 }
Michael Jurkad3ef3062010-11-23 16:23:58 -0800110}