1 /*
2  * Copyright (C) 2012 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.camera.ui;
18 
19 import java.util.Locale;
20 
21 import android.content.Context;
22 import android.media.AudioManager;
23 import android.media.SoundPool;
24 import android.os.Handler;
25 import android.os.Message;
26 import android.util.AttributeSet;
27 import android.util.Log;
28 import android.view.View;
29 import android.view.animation.Animation;
30 import android.view.animation.AnimationUtils;
31 import android.widget.FrameLayout;
32 import android.widget.TextView;
33 
34 import com.android.camera.R;
35 
36 public class CountDownView extends FrameLayout {
37 
38     private static final String TAG = "CAM_CountDownView";
39     private static final int SET_TIMER_TEXT = 1;
40     private TextView mRemainingSecondsView;
41     private int mRemainingSecs = 0;
42     private OnCountDownFinishedListener mListener;
43     private Animation mCountDownAnim;
44     private SoundPool mSoundPool;
45     private int mBeepTwice;
46     private int mBeepOnce;
47     private boolean mPlaySound;
48     private final Handler mHandler = new MainHandler();
49 
CountDownView(Context context, AttributeSet attrs)50     public CountDownView(Context context, AttributeSet attrs) {
51         super(context, attrs);
52         mCountDownAnim = AnimationUtils.loadAnimation(context, R.anim.count_down_exit);
53         // Load the beeps
54         mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
55         mBeepOnce = mSoundPool.load(context, R.raw.beep_once, 1);
56         mBeepTwice = mSoundPool.load(context, R.raw.beep_twice, 1);
57     }
58 
isCountingDown()59     public boolean isCountingDown() {
60         return mRemainingSecs > 0;
61     };
62 
63     public interface OnCountDownFinishedListener {
onCountDownFinished()64         public void onCountDownFinished();
65     }
66 
remainingSecondsChanged(int newVal)67     private void remainingSecondsChanged(int newVal) {
68         mRemainingSecs = newVal;
69         if (newVal == 0) {
70             // Countdown has finished
71             setVisibility(View.INVISIBLE);
72             mListener.onCountDownFinished();
73         } else {
74             Locale locale = getResources().getConfiguration().locale;
75             String localizedValue = String.format(locale, "%d", newVal);
76             mRemainingSecondsView.setText(localizedValue);
77             // Fade-out animation
78             mCountDownAnim.reset();
79             mRemainingSecondsView.clearAnimation();
80             mRemainingSecondsView.startAnimation(mCountDownAnim);
81 
82             // Play sound effect for the last 3 seconds of the countdown
83             if (mPlaySound) {
84                 if (newVal == 1) {
85                     mSoundPool.play(mBeepTwice, 1.0f, 1.0f, 0, 0, 1.0f);
86                 } else if (newVal <= 3) {
87                     mSoundPool.play(mBeepOnce, 1.0f, 1.0f, 0, 0, 1.0f);
88                 }
89             }
90             // Schedule the next remainingSecondsChanged() call in 1 second
91             mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000);
92         }
93     }
94 
95     @Override
onFinishInflate()96     protected void onFinishInflate() {
97         super.onFinishInflate();
98         mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds);
99     }
100 
setCountDownFinishedListener(OnCountDownFinishedListener listener)101     public void setCountDownFinishedListener(OnCountDownFinishedListener listener) {
102         mListener = listener;
103     }
104 
startCountDown(int sec, boolean playSound)105     public void startCountDown(int sec, boolean playSound) {
106         if (sec <= 0) {
107             Log.w(TAG, "Invalid input for countdown timer: " + sec + " seconds");
108             return;
109         }
110         setVisibility(View.VISIBLE);
111         mPlaySound = playSound;
112         remainingSecondsChanged(sec);
113     }
114 
cancelCountDown()115     public void cancelCountDown() {
116         if (mRemainingSecs > 0) {
117             mRemainingSecs = 0;
118             mHandler.removeMessages(SET_TIMER_TEXT);
119             setVisibility(View.INVISIBLE);
120         }
121     }
122 
123     private class MainHandler extends Handler {
124         @Override
handleMessage(Message message)125         public void handleMessage(Message message) {
126             if (message.what == SET_TIMER_TEXT) {
127                 remainingSecondsChanged(mRemainingSecs -1);
128             }
129         }
130     }
131 }