1/**
2 * Copyright (c) 2011, Google Inc.
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 */
16package com.android.mail;
17
18import android.app.ProgressDialog;
19import android.content.Context;
20import android.content.DialogInterface;
21import android.content.DialogInterface.OnShowListener;
22import android.os.Handler;
23
24/**
25 * MinTimeProgressDialog implements a ProgressDialog that waits MIN_DELAY ms to
26 * be dismissed before showing. Once visible, the dialog will be visible for at
27 * least MIN_SHOW_TIME to avoid "flashes" in the UI when an event could take a
28 * largely variable time to complete (from none, to a user perceivable amount)
29 *
30 * @author mindyp
31 */
32public class MinTimeProgressDialog extends ProgressDialog implements OnShowListener {
33    private static int sMinShowTime;
34
35    private static int sMinDelay;
36
37    private int mMinShowTime = -1;
38
39    private long mStartTime = -1;
40
41    private boolean mDismissed = false;
42
43    private final Handler mHandler = new Handler();
44
45    private final Runnable mDelayedDismiss = new Runnable() {
46        @Override
47        public void run() {
48            MinTimeProgressDialog.super.dismiss();
49        }
50    };
51
52    private final Runnable mDelayedShow = new Runnable() {
53        @Override
54        public void run() {
55            if (!mDismissed) {
56                MinTimeProgressDialog.super.show();
57            }
58        }
59    };
60
61    public MinTimeProgressDialog(Context context) {
62        super(context, R.style.MinTimeProgressDialogStyle);
63        sMinShowTime = context.getResources()
64            .getInteger(R.integer.batch_progress_display_time);
65        sMinDelay = context.getResources()
66            .getInteger(R.integer.batch_progress_wait_time);
67        mMinShowTime = sMinShowTime
68                + context.getResources().getInteger(R.integer.dialog_animationDefaultDur);
69    }
70
71    @Override
72    public void dismiss() {
73        mDismissed = true;
74        long diff = System.currentTimeMillis() - mStartTime;
75        if (diff >= mMinShowTime || mStartTime == -1) {
76            // This covers the case where the dialog was not shown
77            // at all yet OR enough time of the dialog showing
78            // has passed. If it wasn't shown at all yet, then it is
79            // just never shown.
80            super.dismiss();
81        } else {
82            mHandler.postDelayed(mDelayedDismiss, mMinShowTime - diff);
83        }
84    }
85
86    /**
87     * Dismiss the dialog, immediately if necessary.
88     *
89     * @param force If true, dismiss the dialog right away.
90     */
91    public void dismiss(boolean force) {
92        if (force) {
93            mDismissed = true;
94            super.dismiss();
95        } else {
96            dismiss();
97        }
98    }
99
100    @Override
101    public void show() {
102        mDismissed = false;
103        mHandler.postDelayed(mDelayedShow, sMinDelay);
104    }
105
106    @Override
107    public void onShow(DialogInterface dialog) {
108        // When the dialog is actually shown, start the timer.
109        mStartTime = System.currentTimeMillis();
110    }
111
112    /**
113     * Show a MinTimeProgressDialog.
114     */
115    public static MinTimeProgressDialog show(Context context, CharSequence title,
116            CharSequence message, boolean indeterminate, boolean cancelable,
117            OnCancelListener cancelListener) {
118
119        MinTimeProgressDialog dialog = new MinTimeProgressDialog(context);
120        dialog.setTitle(title);
121        dialog.setMessage(message);
122        dialog.setIndeterminate(indeterminate);
123        dialog.setCancelable(cancelable);
124        dialog.setOnCancelListener(cancelListener);
125        dialog.setOnShowListener(dialog);
126        dialog.show();
127
128        return dialog;
129    }
130}
131