1 /*
2  * Copyright (C) 2015 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.cts.verifier;
18 
19 import android.annotation.TargetApi;
20 import android.content.Context;
21 import android.os.Handler;
22 import android.os.SystemClock;
23 import android.util.AttributeSet;
24 import android.widget.ProgressBar;
25 
26 /**
27  * Can be used to show time outs for events. A progress bar will be displayed to the user.
28  * On calling start, it will start filling up.
29  */
30 public class TimerProgressBar extends ProgressBar {
TimerProgressBar(Context context)31   public TimerProgressBar(Context context) {
32     super(context);
33     setHandler(context);
34   }
35 
TimerProgressBar(Context context, AttributeSet attrs)36   public TimerProgressBar(Context context, AttributeSet attrs) {
37     super(context, attrs);
38     setHandler(context);
39   }
40 
TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr)41   public TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
42     super(context, attrs, defStyleAttr);
43     setHandler(context);
44   }
45 
46   @TargetApi(21)
TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)47   public TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
48     super(context, attrs, defStyleAttr, defStyleRes);
49     setHandler(context);
50   }
51 
setHandler(Context context)52   private void setHandler(Context context) {
53     mHandler = new Handler(context.getMainLooper());
54   }
55 
56   private Handler mHandler;
57   private TimerExpiredCallback mTimerExpiredCallback;
58   private long mStartTime;
59   private long mDuration;
60   private long mStepSize;
61   private boolean mForceComplete;
62 
63   private Runnable mProgressCallback = new Runnable() {
64     @Override
65     public void run() {
66       if (mForceComplete) {
67         TimerProgressBar.this.setProgress(TimerProgressBar.this.getMax());
68         return;
69       }
70 
71       long currentTime = SystemClock.elapsedRealtime();
72       int progress = (int) ((currentTime - mStartTime) / mStepSize);
73       progress = Math.min(progress, TimerProgressBar.this.getMax());
74       TimerProgressBar.this.setProgress(progress);
75 
76       if (mStartTime + mDuration > currentTime) {
77         mHandler.postDelayed(this, mStepSize);
78       } else {
79         if (mTimerExpiredCallback != null) {
80           mTimerExpiredCallback.onTimerExpired();
81         }
82       }
83     }
84   };
85 
start(long duration, long stepSize)86   public void start(long duration, long stepSize) {
87     start(duration, stepSize, null);
88   }
89 
90   /**
91    * Start filling up the progress bar.
92    *
93    * @param duration Time in milliseconds the progress bar takes to fill up completely
94    * @param stepSize Time in milliseconds between consecutive updates to progress bar's progress
95    * @param callback Callback that should be executed after the progress bar is filled completely (i.e. timer expires)
96    */
start(long duration, long stepSize, TimerExpiredCallback callback)97   public void start(long duration, long stepSize, TimerExpiredCallback callback) {
98     mDuration = duration;
99     mStepSize = stepSize;
100     mStartTime = SystemClock.elapsedRealtime();
101     mForceComplete = false;
102     mTimerExpiredCallback = callback;
103     this.setMax((int) (duration / stepSize));
104     this.setProgress(0);
105     mHandler.post(mProgressCallback);
106   }
107 
108   /**
109    * Fill the progress bar completely. Timer expired callback won't be executed.
110    */
forceComplete()111   public void forceComplete() {
112     mForceComplete = true;
113   }
114 
115   public interface TimerExpiredCallback {
onTimerExpired()116     void onTimerExpired();
117   }
118 
119 }
120