1d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka/*
2d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * Copyright (C) 2010 The Android Open Source Project
3d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka *
4d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
5d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * you may not use this file except in compliance with the License.
6d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * You may obtain a copy of the License at
7d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka *
8d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
9d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka *
10d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * Unless required by applicable law or agreed to in writing, software
11d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
12d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * See the License for the specific language governing permissions and
14d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * limitations under the License.
15d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka */
16d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
18d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
19d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurkaimport android.os.Handler;
20a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyalimport android.os.SystemClock;
21d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
22d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurkapublic class Alarm implements Runnable{
23d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // if we reach this time and the alarm hasn't been cancelled, call the listener
24d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    private long mAlarmTriggerTime;
25d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
26d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // if we've scheduled a call to run() (ie called mHandler.postDelayed), this variable is true.
27d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // We use this to avoid having multiple pending callbacks
28d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    private boolean mWaitingForCallback;
29d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
30d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    private Handler mHandler;
31d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    private OnAlarmListener mAlarmListener;
3267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen    private boolean mAlarmPending = false;
33d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
34d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    public Alarm() {
35d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        mHandler = new Handler();
36d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    }
37d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
38d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    public void setOnAlarmListener(OnAlarmListener alarmListener) {
39d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        mAlarmListener = alarmListener;
40d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    }
41d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
42d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // Sets the alarm to go off in a certain number of milliseconds. If the alarm is already set,
43d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // it's overwritten and only the new alarm setting is used
44d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    public void setAlarm(long millisecondsInFuture) {
45a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        long currentTime = SystemClock.uptimeMillis();
4667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen        mAlarmPending = true;
47a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        long oldTriggerTime = mAlarmTriggerTime;
48d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        mAlarmTriggerTime = currentTime + millisecondsInFuture;
49a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal
50a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        // If the previous alarm was set for a longer duration, cancel it.
51a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) {
52a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal            mHandler.removeCallbacks(this);
53a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal            mWaitingForCallback = false;
54a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        }
55d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        if (!mWaitingForCallback) {
56d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka            mHandler.postDelayed(this, mAlarmTriggerTime - currentTime);
57d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka            mWaitingForCallback = true;
58d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        }
59d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    }
60d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
61d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    public void cancelAlarm() {
6267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen        mAlarmPending = false;
63d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    }
64d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka
65d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    // this is called when our timer runs out
66d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    public void run() {
67d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        mWaitingForCallback = false;
68a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal        if (mAlarmPending) {
69a2125e1d102034e1d638b5d1e973b5b77cfe1efdSunny Goyal            long currentTime = SystemClock.uptimeMillis();
70d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka            if (mAlarmTriggerTime > currentTime) {
71d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                // We still need to wait some time to trigger spring loaded mode--
72d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                // post a new callback
73d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                mHandler.postDelayed(this, Math.max(0, mAlarmTriggerTime - currentTime));
74d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                mWaitingForCallback = true;
75d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka            } else {
7667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen                mAlarmPending = false;
77d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                if (mAlarmListener != null) {
78d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                    mAlarmListener.onAlarm(this);
79d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka                }
80d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka            }
81d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka        }
82d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka    }
8367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen
8467bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen    public boolean alarmPending() {
8567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen        return mAlarmPending;
8667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen    }
87d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka}
88