• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.launcher3;
18 
19 import android.os.Handler;
20 import android.os.Looper;
21 import android.os.SystemClock;
22 
23 import androidx.annotation.VisibleForTesting;
24 
25 public 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;
35     private boolean mAlarmPending = false;
36     private long mLastSetTimeout;
37 
Alarm()38     public Alarm() {
39         this(Looper.myLooper());
40     }
41 
Alarm(Looper looper)42     public Alarm(Looper looper) {
43         mHandler = new Handler(looper);
44     }
45 
setOnAlarmListener(OnAlarmListener alarmListener)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
setAlarm(long millisecondsInFuture)52     public void setAlarm(long millisecondsInFuture) {
53         long currentTime = SystemClock.uptimeMillis();
54         mAlarmPending = true;
55         long oldTriggerTime = mAlarmTriggerTime;
56         mAlarmTriggerTime = currentTime + millisecondsInFuture;
57         mLastSetTimeout = millisecondsInFuture;
58 
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         }
64         if (!mWaitingForCallback) {
65             mHandler.postDelayed(this, mAlarmTriggerTime - currentTime);
66             mWaitingForCallback = true;
67         }
68     }
69 
cancelAlarm()70     public void cancelAlarm() {
71         mAlarmPending = false;
72     }
73 
74     // this is called when our timer runs out
run()75     public void run() {
76         mWaitingForCallback = false;
77         if (mAlarmPending) {
78             long currentTime = SystemClock.uptimeMillis();
79             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 {
85                 mAlarmPending = false;
86                 if (mAlarmListener != null) {
87                     mAlarmListener.onAlarm(this);
88                 }
89             }
90         }
91     }
92 
alarmPending()93     public boolean alarmPending() {
94         return mAlarmPending;
95     }
96 
97     /** Returns the last value passed to {@link #setAlarm(long)} */
getLastSetTimeout()98     public long getLastSetTimeout() {
99         return mLastSetTimeout;
100     }
101 
102     /** Simulates the alarm firing for tests. */
103     @VisibleForTesting
finishAlarm()104     public void finishAlarm() {
105         if (!mAlarmPending) return;
106         mAlarmPending = false;
107         mHandler.removeCallbacks(this);
108         mAlarmListener.onAlarm(this);
109     }
110 }
111